SharpMeow commited on
Commit
a90fa96
·
verified ·
1 Parent(s): 1adc7c7

Vesuvius Radar 1.1.1: retry cut-off downloads (Scrolls 7094614, PR #287)

Browse files
Files changed (3) hide show
  1. app.py +1 -1
  2. radar_mcp.py +1 -1
  3. scanner.py +20 -11
app.py CHANGED
@@ -50,7 +50,7 @@ VECS_FILE = DATA_DIR / "vectors.npz"
50
  COLLECT = os.environ.get("RADAR_COLLECT", "1") != "0" # tests set 0: no background collector
51
  SEMANTIC = os.environ.get("RADAR_SEMANTIC", "1") != "0"
52
  PUBLIC_URL = "https://sharpmeow-vesuvius-radar.hf.space"
53
- VERSION = "1.1.0"
54
 
55
  CFG = scanner.load_config()
56
  SCORER = scanner.Scorer(CFG)
 
50
  COLLECT = os.environ.get("RADAR_COLLECT", "1") != "0" # tests set 0: no background collector
51
  SEMANTIC = os.environ.get("RADAR_SEMANTIC", "1") != "0"
52
  PUBLIC_URL = "https://sharpmeow-vesuvius-radar.hf.space"
53
+ VERSION = "1.1.1"
54
 
55
  CFG = scanner.load_config()
56
  SCORER = scanner.Scorer(CFG)
radar_mcp.py CHANGED
@@ -27,7 +27,7 @@ def bind(app_module):
27
 
28
  router = APIRouter()
29
  VERSIONS = ("2025-06-18", "2025-03-26", "2024-11-05")
30
- SERVER = {"name": "vesuvius-radar", "title": "Vesuvius Radar", "version": "1.1.0"}
31
  INSTRUCTIONS = (
32
  "Vesuvius Radar keeps collecting new work that could help read the Herculaneum scrolls (the Vesuvius Challenge): "
33
  "papers from arXiv and journals, GitHub repositories with ScrollPrize/villa pull requests, issues and releases, "
 
27
 
28
  router = APIRouter()
29
  VERSIONS = ("2025-06-18", "2025-03-26", "2024-11-05")
30
+ SERVER = {"name": "vesuvius-radar", "title": "Vesuvius Radar", "version": "1.1.1"}
31
  INSTRUCTIONS = (
32
  "Vesuvius Radar keeps collecting new work that could help read the Herculaneum scrolls (the Vesuvius Challenge): "
33
  "papers from arXiv and journals, GitHub repositories with ScrollPrize/villa pull requests, issues and releases, "
scanner.py CHANGED
@@ -17,6 +17,7 @@ import datetime as dt
17
  import email.utils
18
  import hashlib
19
  import html
 
20
  import json
21
  import math
22
  import os
@@ -93,8 +94,8 @@ class Fetcher:
93
  err = e
94
  if e.code not in (429, 500, 502, 503, 504):
95
  raise
96
- except (urllib.error.URLError, TimeoutError, ConnectionError) as e:
97
- err = e
98
  time.sleep(2 * (i + 1))
99
  raise err # type: ignore[misc]
100
 
@@ -550,6 +551,14 @@ def _gh_get(url):
550
  return FETCH.json(url, {"Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28"}, etag=True)
551
 
552
 
 
 
 
 
 
 
 
 
553
  # ---------------------------------------------------------------- GitHub: who made the latest update
554
 
555
  SLACK_S = 120 # an update this close to an item's updated time is the one that moved it
@@ -615,8 +624,8 @@ def gh_updates(repo: str, since: dt.datetime, notes: list, pages: int = 3) -> tu
615
  c["updated_at"] if edited else c["created_at"], text, c.get("html_url")))
616
  if len(rows) < 100:
617
  break
618
- except urllib.error.HTTPError as e:
619
- notes.append(f"{repo} {path}: HTTP {e.code}")
620
  try:
621
  calls += 1
622
  for e in _gh_get(f"{base}/issues/events?per_page=100"):
@@ -628,8 +637,8 @@ def gh_updates(repo: str, since: dt.datetime, notes: list, pages: int = 3) -> tu
628
  or (e.get("milestone") or {}).get("title") or "")
629
  out.setdefault(n, []).append(_act(what, (e.get("actor") or {}).get("login"), e["created_at"], clean(text)[:200],
630
  (e.get("issue") or {}).get("html_url")))
631
- except urllib.error.HTTPError as e:
632
- notes.append(f"{repo} issues/events: HTTP {e.code}")
633
  return out, calls
634
 
635
 
@@ -735,8 +744,8 @@ def c_github(sc, ctx):
735
  url=r["html_url"], date=t, text=(r.get("body") or "")[:1500], base=50,
736
  base_label=f"{repo} release", core_terms=False, who=repo.split("/")[0],
737
  topics_extra=["Scroll work"])
738
- except urllib.error.HTTPError as e:
739
- notes.append(f"{repo}: HTTP {e.code}")
740
  # Who made each item's latest update, and what it said: the item's own author is only who opened it.
741
  acts = {}
742
  if prs or issues:
@@ -757,8 +766,8 @@ def c_github(sc, ctx):
757
  try:
758
  act = latest_update(acts.get(n, []) + gh_pr_latest(repo, n), p.get("created_at"), p.get("updated_at"))
759
  lookups[key] = {"updated": p.get("updated_at"), "act": act}
760
- except urllib.error.HTTPError as e:
761
- notes.append(f"{repo} #{n} reviews and commits: HTTP {e.code}")
762
  common = dict(url=p["html_url"], date=t, text=(p.get("body") or "")[:1500], core_terms=False,
763
  title=f"{repo} #{n}: {p['title']}", who=p["user"]["login"], created=p.get("created_at"),
764
  labels=[x["name"] for x in p.get("labels") or []][:6], topics_extra=["Scroll work"], activity=act)
@@ -983,7 +992,7 @@ def collect(source: str, since: dt.datetime, cfg: dict | None = None, scorer: Sc
983
  prog(f"scoring {len(items)} items")
984
  finish(items, scorer, sem, prog, head)
985
  items = [i for i in items if i["rule"] >= cfg["keep_score"]]
986
- bad = any(re.search(r"HTTP \d|Error|rate limited|skipped|timed out", n) for n in info["notes"])
987
  row.update(state="partial" if bad else "ok", read=info["read"], kept=len(items), notes=info["notes"])
988
  except Exception as e: # noqa: BLE001
989
  items = []
 
17
  import email.utils
18
  import hashlib
19
  import html
20
+ import http.client
21
  import json
22
  import math
23
  import os
 
94
  err = e
95
  if e.code not in (429, 500, 502, 503, 504):
96
  raise
97
+ except (urllib.error.URLError, http.client.HTTPException, TimeoutError, ConnectionError) as e:
98
+ err = e # a dropped or cut-off download (IncompleteRead) is tried again like a refused one
99
  time.sleep(2 * (i + 1))
100
  raise err # type: ignore[misc]
101
 
 
551
  return FETCH.json(url, {"Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28"}, etag=True)
552
 
553
 
554
+ # A failed villa listing costs only its own items: the repository search results of the same check are kept.
555
+ GH_ERRORS = (urllib.error.URLError, http.client.HTTPException, TimeoutError, ConnectionError, ValueError)
556
+
557
+
558
+ def _why(e) -> str:
559
+ return f"HTTP {e.code}" if isinstance(e, urllib.error.HTTPError) else f"network error ({type(e).__name__})"
560
+
561
+
562
  # ---------------------------------------------------------------- GitHub: who made the latest update
563
 
564
  SLACK_S = 120 # an update this close to an item's updated time is the one that moved it
 
624
  c["updated_at"] if edited else c["created_at"], text, c.get("html_url")))
625
  if len(rows) < 100:
626
  break
627
+ except GH_ERRORS as e:
628
+ notes.append(f"{repo} {path}: {_why(e)}")
629
  try:
630
  calls += 1
631
  for e in _gh_get(f"{base}/issues/events?per_page=100"):
 
637
  or (e.get("milestone") or {}).get("title") or "")
638
  out.setdefault(n, []).append(_act(what, (e.get("actor") or {}).get("login"), e["created_at"], clean(text)[:200],
639
  (e.get("issue") or {}).get("html_url")))
640
+ except GH_ERRORS as e:
641
+ notes.append(f"{repo} issues/events: {_why(e)}")
642
  return out, calls
643
 
644
 
 
744
  url=r["html_url"], date=t, text=(r.get("body") or "")[:1500], base=50,
745
  base_label=f"{repo} release", core_terms=False, who=repo.split("/")[0],
746
  topics_extra=["Scroll work"])
747
+ except GH_ERRORS as e:
748
+ notes.append(f"{repo}: {_why(e)}")
749
  # Who made each item's latest update, and what it said: the item's own author is only who opened it.
750
  acts = {}
751
  if prs or issues:
 
766
  try:
767
  act = latest_update(acts.get(n, []) + gh_pr_latest(repo, n), p.get("created_at"), p.get("updated_at"))
768
  lookups[key] = {"updated": p.get("updated_at"), "act": act}
769
+ except GH_ERRORS as e:
770
+ notes.append(f"{repo} #{n} reviews and commits: {_why(e)}")
771
  common = dict(url=p["html_url"], date=t, text=(p.get("body") or "")[:1500], core_terms=False,
772
  title=f"{repo} #{n}: {p['title']}", who=p["user"]["login"], created=p.get("created_at"),
773
  labels=[x["name"] for x in p.get("labels") or []][:6], topics_extra=["Scroll work"], activity=act)
 
992
  prog(f"scoring {len(items)} items")
993
  finish(items, scorer, sem, prog, head)
994
  items = [i for i in items if i["rule"] >= cfg["keep_score"]]
995
+ bad = any(re.search(r"HTTP \d|Error|rate limited|skipped|timed out|network error", n) for n in info["notes"])
996
  row.update(state="partial" if bad else "ok", read=info["read"], kept=len(items), notes=info["notes"])
997
  except Exception as e: # noqa: BLE001
998
  items = []