vomebook commited on
Commit
6c4992c
·
verified ·
1 Parent(s): f7bc80b

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -3
app.py CHANGED
@@ -57,10 +57,14 @@ API_CACHE_TTL_SECONDS = 120
57
  SEARCH_CACHE_TTL_SECONDS = 300
58
  API_CACHE_MAX_ENTRIES = 500
59
  SEARCH_CACHE_MAX_ENTRIES = 500
 
 
60
  api_response_cache: dict[tuple, tuple[float, object]] = {}
61
  api_response_cache_lock = threading.Lock()
62
  search_response_cache: dict[tuple, tuple[float, object]] = {}
63
  search_response_cache_lock = threading.Lock()
 
 
64
  ZIP_TOKEN_TTL_SECONDS = 600
65
  ZIP_TOKEN_MAX_ENTRIES = 32
66
  zip_download_tokens: dict[str, tuple[float, list[str]]] = {}
@@ -1119,6 +1123,23 @@ def fulltext_search(q="", sources_filter=None, folders=None, min_size=None, max_
1119
  def get_doc_storage_path(doc: dict) -> Path:
1120
  return BASE_DIR / doc["storage_root"] / doc["storage_rel_path"]
1121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1122
  def get_folder_contents(source_slug: str, path: str) -> dict:
1123
  source_browser = folder_browser_data.get(source_slug, {})
1124
  if path in source_browser:
@@ -1412,7 +1433,7 @@ def api_preview(doc_id: str):
1412
  file_path = get_doc_storage_path(rec)
1413
  if not file_path.exists():
1414
  return JSONResponse({"error": f"missing file: {file_path.name}"}, status_code=404)
1415
- text = file_path.read_text(encoding="utf-8", errors="ignore")
1416
  return JSONResponse({"doc_id": doc_id, "title": rec["display_name"], "path": rec["display_rel_path"], "source": rec["source_name"], "text": text})
1417
  @app.get("/api/snippet/{doc_id}")
1418
 
@@ -1445,6 +1466,7 @@ def api_download(doc_id: str):
1445
  media_type="text/plain; charset=utf-8",
1446
  filename=f"{rec['display_name']}.txt",
1447
  content_disposition_type="attachment",
 
1448
  )
1449
  @app.post("/api/zip")
1450
 
@@ -1505,14 +1527,22 @@ app.mount("/static", StaticFiles(directory=str(BASE_DIR / "static"), html=True),
1505
  app.mount("/icons", StaticFiles(directory=str(BASE_DIR / "static/icons")), name="icons")
1506
  app.mount("/data/initial", StaticFiles(directory=str(BASE_DIR / "data/initial")), name="initial-data")
1507
  app.mount("/data/sidebar", StaticFiles(directory=str(BASE_DIR / "data/sidebar")), name="sidebar-data")
 
 
 
 
1508
  @app.get("/manifest.json")
1509
 
1510
  def serve_manifest():
1511
- return JSONResponse(json.loads((BASE_DIR / "static/manifest.json").read_text(encoding="utf-8")))
 
 
 
 
1512
  @app.get("/sw.js")
1513
 
1514
  def serve_sw():
1515
- return PlainTextResponse((BASE_DIR / "static/sw.js").read_text(encoding="utf-8"), media_type="application/javascript")
1516
 
1517
  def refresh_fulltext_loop() -> None:
1518
  while not fulltext_refresh_stop.wait(FULLTEXT_REFRESH_INTERVAL_SECONDS):
@@ -1544,6 +1574,7 @@ def sidebar_payload_for_path(rest_of_path: str) -> str | None:
1544
  return None
1545
  return payload_path.read_text(encoding="utf-8")
1546
 
 
1547
  def render_index_html(rest_of_path: str = "") -> str:
1548
  html = (BASE_DIR / "static/index.html").read_text(encoding="utf-8")
1549
  initial_payload = initial_payload_for_path(rest_of_path)
 
57
  SEARCH_CACHE_TTL_SECONDS = 300
58
  API_CACHE_MAX_ENTRIES = 500
59
  SEARCH_CACHE_MAX_ENTRIES = 500
60
+ PREVIEW_CACHE_MAX_ENTRIES = 64
61
+ PREVIEW_CACHE_MAX_ENTRY_BYTES = 2 * 1024 * 1024
62
  api_response_cache: dict[tuple, tuple[float, object]] = {}
63
  api_response_cache_lock = threading.Lock()
64
  search_response_cache: dict[tuple, tuple[float, object]] = {}
65
  search_response_cache_lock = threading.Lock()
66
+ preview_text_cache: dict[str, str] = {}
67
+ preview_text_cache_lock = threading.Lock()
68
  ZIP_TOKEN_TTL_SECONDS = 600
69
  ZIP_TOKEN_MAX_ENTRIES = 32
70
  zip_download_tokens: dict[str, tuple[float, list[str]]] = {}
 
1123
  def get_doc_storage_path(doc: dict) -> Path:
1124
  return BASE_DIR / doc["storage_root"] / doc["storage_rel_path"]
1125
 
1126
+ def read_preview_text(doc_id: str, file_path: Path) -> str:
1127
+ with preview_text_cache_lock:
1128
+ cached = preview_text_cache.get(doc_id)
1129
+ if cached is not None:
1130
+ return cached
1131
+ try:
1132
+ size = file_path.stat().st_size
1133
+ except OSError:
1134
+ size = PREVIEW_CACHE_MAX_ENTRY_BYTES + 1
1135
+ text = file_path.read_text(encoding="utf-8", errors="ignore")
1136
+ if size <= PREVIEW_CACHE_MAX_ENTRY_BYTES:
1137
+ with preview_text_cache_lock:
1138
+ preview_text_cache[doc_id] = text
1139
+ while len(preview_text_cache) > PREVIEW_CACHE_MAX_ENTRIES:
1140
+ preview_text_cache.pop(next(iter(preview_text_cache)), None)
1141
+ return text
1142
+
1143
  def get_folder_contents(source_slug: str, path: str) -> dict:
1144
  source_browser = folder_browser_data.get(source_slug, {})
1145
  if path in source_browser:
 
1433
  file_path = get_doc_storage_path(rec)
1434
  if not file_path.exists():
1435
  return JSONResponse({"error": f"missing file: {file_path.name}"}, status_code=404)
1436
+ text = read_preview_text(doc_id, file_path)
1437
  return JSONResponse({"doc_id": doc_id, "title": rec["display_name"], "path": rec["display_rel_path"], "source": rec["source_name"], "text": text})
1438
  @app.get("/api/snippet/{doc_id}")
1439
 
 
1466
  media_type="text/plain; charset=utf-8",
1467
  filename=f"{rec['display_name']}.txt",
1468
  content_disposition_type="attachment",
1469
+ headers={"Content-Encoding": "identity"},
1470
  )
1471
  @app.post("/api/zip")
1472
 
 
1527
  app.mount("/icons", StaticFiles(directory=str(BASE_DIR / "static/icons")), name="icons")
1528
  app.mount("/data/initial", StaticFiles(directory=str(BASE_DIR / "data/initial")), name="initial-data")
1529
  app.mount("/data/sidebar", StaticFiles(directory=str(BASE_DIR / "data/sidebar")), name="sidebar-data")
1530
+ @lru_cache(maxsize=1)
1531
+ def _manifest_payload() -> dict:
1532
+ return json.loads((BASE_DIR / "static/manifest.json").read_text(encoding="utf-8"))
1533
+
1534
  @app.get("/manifest.json")
1535
 
1536
  def serve_manifest():
1537
+ return JSONResponse(_manifest_payload())
1538
+ @lru_cache(maxsize=1)
1539
+ def _sw_source() -> str:
1540
+ return (BASE_DIR / "static/sw.js").read_text(encoding="utf-8")
1541
+
1542
  @app.get("/sw.js")
1543
 
1544
  def serve_sw():
1545
+ return PlainTextResponse(_sw_source(), media_type="application/javascript")
1546
 
1547
  def refresh_fulltext_loop() -> None:
1548
  while not fulltext_refresh_stop.wait(FULLTEXT_REFRESH_INTERVAL_SECONDS):
 
1574
  return None
1575
  return payload_path.read_text(encoding="utf-8")
1576
 
1577
+ @lru_cache(maxsize=64)
1578
  def render_index_html(rest_of_path: str = "") -> str:
1579
  html = (BASE_DIR / "static/index.html").read_text(encoding="utf-8")
1580
  initial_payload = initial_payload_for_path(rest_of_path)