Spaces:
Running
Running
Upload 3 files
Browse files- app/config.py +2 -1
- app/data_loader.py +1 -0
- app/main.py +14 -4
app/config.py
CHANGED
|
@@ -5,7 +5,8 @@ DATA_ROOT = Path(os.environ.get("DATA_ROOT", str(APP_ROOT / "data")))
|
|
| 5 |
PARSED_ROOT = DATA_ROOT / "parsed"
|
| 6 |
INDEX_NAME = os.environ.get("ES_INDEX", "article")
|
| 7 |
ES_URL = os.environ.get("ES_URL", "http://127.0.0.1:9200")
|
| 8 |
-
REPO_PREFIX = os.environ.get("REPO_PREFIX", "https://github.com/
|
|
|
|
| 9 |
ARCHIVE_START = int(os.environ.get("ARCHIVE_START", "0"))
|
| 10 |
ARCHIVE_END = int(os.environ.get("ARCHIVE_END", "31"))
|
| 11 |
RESET_INDEX = os.environ.get("RESET_INDEX", "0") == "1"
|
|
|
|
| 5 |
PARSED_ROOT = DATA_ROOT / "parsed"
|
| 6 |
INDEX_NAME = os.environ.get("ES_INDEX", "article")
|
| 7 |
ES_URL = os.environ.get("ES_URL", "http://127.0.0.1:9200")
|
| 8 |
+
REPO_PREFIX = os.environ.get("REPO_PREFIX", "https://github.com/anftm")
|
| 9 |
+
SOURCE_REPO_OWNER = os.environ.get("SOURCE_REPO_OWNER", "anftm")
|
| 10 |
ARCHIVE_START = int(os.environ.get("ARCHIVE_START", "0"))
|
| 11 |
ARCHIVE_END = int(os.environ.get("ARCHIVE_END", "31"))
|
| 12 |
RESET_INDEX = os.environ.get("RESET_INDEX", "0") == "1"
|
app/data_loader.py
CHANGED
|
@@ -28,6 +28,7 @@ def ensure_parsed_data(progress: Callable[[int, int], None] | None = None) -> No
|
|
| 28 |
target = PARSED_ROOT / f"archives{archive_id}"
|
| 29 |
repo = f"{REPO_PREFIX}/banned-historical-archives{archive_id}.git"
|
| 30 |
if (target / ".git").exists():
|
|
|
|
| 31 |
run(["git", "fetch", "--depth", "1", "origin", "parsed"], target)
|
| 32 |
run(["git", "checkout", "parsed"], target)
|
| 33 |
run(["git", "reset", "--hard", "origin/parsed"], target)
|
|
|
|
| 28 |
target = PARSED_ROOT / f"archives{archive_id}"
|
| 29 |
repo = f"{REPO_PREFIX}/banned-historical-archives{archive_id}.git"
|
| 30 |
if (target / ".git").exists():
|
| 31 |
+
run(["git", "remote", "set-url", "origin", repo], target)
|
| 32 |
run(["git", "fetch", "--depth", "1", "origin", "parsed"], target)
|
| 33 |
run(["git", "checkout", "parsed"], target)
|
| 34 |
run(["git", "reset", "--hard", "origin/parsed"], target)
|
app/main.py
CHANGED
|
@@ -11,7 +11,7 @@ import socket
|
|
| 11 |
import tempfile
|
| 12 |
import threading
|
| 13 |
import time
|
| 14 |
-
from urllib.parse import quote, urlparse
|
| 15 |
from typing import Any
|
| 16 |
from zipfile import ZIP_DEFLATED, ZipFile
|
| 17 |
import httpx
|
|
@@ -24,7 +24,7 @@ from brotli_asgi import BrotliMiddleware
|
|
| 24 |
from starlette.background import BackgroundTask
|
| 25 |
from fastapi.staticfiles import StaticFiles
|
| 26 |
from pydantic import BaseModel, Field
|
| 27 |
-
from .config import APP_ROOT, DATA_ROOT, ES_URL, INDEX_NAME
|
| 28 |
from .doc_store import available_years, get_doc, random_doc, variants_for_title, warmup_db
|
| 29 |
from .search_store import SearchStoreError, get_search_docs, literal_match_ids
|
| 30 |
from .data_loader import initialize_search_tokenizer, search_words
|
|
@@ -561,6 +561,7 @@ async def start_ready_data_initialization():
|
|
| 561 |
@app.get("/api/ping")
|
| 562 |
def ping():
|
| 563 |
return Response(status_code=204, headers={"Cache-Control": "no-store"})
|
|
|
|
| 564 |
@app.on_event("shutdown")
|
| 565 |
|
| 566 |
async def close_source_client():
|
|
@@ -830,6 +831,14 @@ def validate_source_url(url: str) -> str | None:
|
|
| 830 |
return "source URL IP is not allowed"
|
| 831 |
return None
|
| 832 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 833 |
async def validate_source_target(url: str) -> str | None:
|
| 834 |
if error := validate_source_url(url):
|
| 835 |
return error
|
|
@@ -916,7 +925,7 @@ async def download_source(doc_id: str):
|
|
| 916 |
files = source.get("source_files") or []
|
| 917 |
if not files:
|
| 918 |
return JSONResponse({"error": "source file not available"}, status_code=404)
|
| 919 |
-
url =
|
| 920 |
suffix = Path(url.split("?", 1)[0]).suffix or ".bin"
|
| 921 |
filename = safe_filename(source_filename_base(source, doc_id), suffix)
|
| 922 |
try:
|
|
@@ -955,7 +964,8 @@ async def download_source_zip(doc_id: str):
|
|
| 955 |
downloaded: list[tuple[Path, str]] = []
|
| 956 |
total_bytes = 0
|
| 957 |
try:
|
| 958 |
-
for index,
|
|
|
|
| 959 |
source_path = temp_dir / f"source-{index:03d}"
|
| 960 |
size = await download_source_to_path(url, source_path, MAX_SOURCE_ZIP_BYTES - total_bytes)
|
| 961 |
total_bytes += size
|
|
|
|
| 11 |
import tempfile
|
| 12 |
import threading
|
| 13 |
import time
|
| 14 |
+
from urllib.parse import quote, urlparse, urlunparse
|
| 15 |
from typing import Any
|
| 16 |
from zipfile import ZIP_DEFLATED, ZipFile
|
| 17 |
import httpx
|
|
|
|
| 24 |
from starlette.background import BackgroundTask
|
| 25 |
from fastapi.staticfiles import StaticFiles
|
| 26 |
from pydantic import BaseModel, Field
|
| 27 |
+
from .config import APP_ROOT, DATA_ROOT, ES_URL, INDEX_NAME, SOURCE_REPO_OWNER
|
| 28 |
from .doc_store import available_years, get_doc, random_doc, variants_for_title, warmup_db
|
| 29 |
from .search_store import SearchStoreError, get_search_docs, literal_match_ids
|
| 30 |
from .data_loader import initialize_search_tokenizer, search_words
|
|
|
|
| 561 |
@app.get("/api/ping")
|
| 562 |
def ping():
|
| 563 |
return Response(status_code=204, headers={"Cache-Control": "no-store"})
|
| 564 |
+
|
| 565 |
@app.on_event("shutdown")
|
| 566 |
|
| 567 |
async def close_source_client():
|
|
|
|
| 831 |
return "source URL IP is not allowed"
|
| 832 |
return None
|
| 833 |
|
| 834 |
+
def mirror_source_url(url: str) -> str:
|
| 835 |
+
parsed = urlparse(str(url))
|
| 836 |
+
parts = parsed.path.split("/")
|
| 837 |
+
if parsed.hostname in {"github.com", "raw.githubusercontent.com"} and len(parts) > 2 and parts[1] == "banned-historical-archives":
|
| 838 |
+
parts[1] = SOURCE_REPO_OWNER
|
| 839 |
+
return urlunparse(parsed._replace(path="/".join(parts)))
|
| 840 |
+
return str(url)
|
| 841 |
+
|
| 842 |
async def validate_source_target(url: str) -> str | None:
|
| 843 |
if error := validate_source_url(url):
|
| 844 |
return error
|
|
|
|
| 925 |
files = source.get("source_files") or []
|
| 926 |
if not files:
|
| 927 |
return JSONResponse({"error": "source file not available"}, status_code=404)
|
| 928 |
+
url = mirror_source_url(files[0])
|
| 929 |
suffix = Path(url.split("?", 1)[0]).suffix or ".bin"
|
| 930 |
filename = safe_filename(source_filename_base(source, doc_id), suffix)
|
| 931 |
try:
|
|
|
|
| 964 |
downloaded: list[tuple[Path, str]] = []
|
| 965 |
total_bytes = 0
|
| 966 |
try:
|
| 967 |
+
for index, source_url in enumerate(files, start=1):
|
| 968 |
+
url = mirror_source_url(source_url)
|
| 969 |
source_path = temp_dir / f"source-{index:03d}"
|
| 970 |
size = await download_source_to_path(url, source_path, MAX_SOURCE_ZIP_BYTES - total_bytes)
|
| 971 |
total_bytes += size
|