Spaces:
Running
Running
File size: 3,096 Bytes
a31f556 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | """
modules/clipboard_intelligence.py - Phase 8 clipboard intelligence
Detects useful content types from clipboard history/current clipboard:
- URLs
- code snippets
- email addresses
- phone numbers
- postal-ish addresses (best-effort heuristic)
"""
from __future__ import annotations
import json
import re
from dataclasses import dataclass
from pathlib import Path
from modules.clipboard_control import _read_text, HIST_PATH
URL_RE = re.compile(r"https?://[^\s]+", re.I)
EMAIL_RE = re.compile(r"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b", re.I)
PHONE_RE = re.compile(r"(?:(?:\+?\d{1,3}[- ]?)?(?:\(?\d{3}\)?[- ]?)?\d{3}[- ]?\d{4,})")
CODE_HINTS = ("def ", "class ", "import ", "from ", "{", "}", "=>", "function ", "SELECT ", "CREATE ", "console.log")
@dataclass(frozen=True, slots=True)
class ClipInsight:
kind: str
preview: str
def _load_history(limit: int = 20) -> list[str]:
if not HIST_PATH.exists():
return []
try:
data = json.loads(HIST_PATH.read_text(encoding="utf-8"))
if not isinstance(data, list):
return []
return [str(item.get("text") or "") for item in data[-limit:]]
except Exception:
return []
def _detect_one(text: str) -> list[ClipInsight]:
t = (text or "").strip()
if not t:
return []
out: list[ClipInsight] = []
urls = URL_RE.findall(t)
if urls:
out.extend(ClipInsight("url", u[:120]) for u in urls[:3])
mails = EMAIL_RE.findall(t)
if mails:
out.extend(ClipInsight("email", m[:120]) for m in mails[:3])
phones = PHONE_RE.findall(t)
if phones:
out.extend(ClipInsight("phone", p[:40]) for p in phones[:3])
if any(h in t for h in CODE_HINTS):
out.append(ClipInsight("code", t[:120].replace("\n", " ")))
# Rough address heuristic: number + street-ish word + comma/city-like structure
if re.search(r"\b\d{1,5}\s+[A-Za-z0-9 .'-]{3,}\b(?:road|rd|street|st|avenue|ave|lane|ln|nagar|society|colony)\b", t, re.I):
out.append(ClipInsight("address", t[:140].replace("\n", " ")))
return out
def inspect_current() -> list[ClipInsight]:
return _detect_one(_read_text() or "")
def inspect_history(limit: int = 20) -> list[ClipInsight]:
seen = set()
out: list[ClipInsight] = []
for text in reversed(_load_history(limit)):
for insight in _detect_one(text):
key = (insight.kind, insight.preview)
if key in seen:
continue
seen.add(key)
out.append(insight)
return out
def summary() -> str:
items = inspect_current() or inspect_history(20)
if not items:
return "Clipboard intelligence: nothing structured detected."
kinds = {}
for item in items:
kinds[item.kind] = kinds.get(item.kind, 0) + 1
parts = [f"{k} x{v}" for k, v in sorted(kinds.items())]
preview = items[0].preview
return f"Clipboard intelligence: {', '.join(parts)}. Latest match: {preview}"
|