1st commit

This commit is contained in:
Mateusz Gruszczyński
2025-10-06 08:27:10 +02:00
commit b26b979a6a
16 changed files with 644 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
import os
import requests
import tarfile
import shutil
from pathlib import Path
def download_maxmind(license_key: str, db_name: str, dest_path: str, url_template: str):
url = url_template.format(DBNAME=db_name, LICENSE_KEY=license_key)
tmp = Path("/tmp") / "maxmind_download.tar.gz"
r = requests.get(url, stream=True, timeout=60)
r.raise_for_status()
with open(tmp, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
with tarfile.open(tmp, "r:gz") as tar:
for member in tar.getmembers():
if member.name.endswith(".mmdb"):
member_f = tar.extractfile(member)
if member_f is None:
continue
dest = Path(dest_path)
dest.parent.mkdir(parents=True, exist_ok=True)
with open(dest, "wb") as out_f:
shutil.copyfileobj(member_f, out_f)
return str(dest)
raise RuntimeError("Nie znaleziono pliku .mmdb w archiwum")
def download_file(url: str, dest_path: str):
r = requests.get(url, stream=True, timeout=60)
r.raise_for_status()
Path(dest_path).parent.mkdir(parents=True, exist_ok=True)
with open(dest_path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
return dest_path
def github_latest_mmdb(repo: str, token: str | None = None) -> str | None:
"""
Zwraca URL do najnowszego assetu .mmdb z releases/latest dla repo (owner/name).
Preferencja: City -> Country -> ASN.
"""
api = f"https://api.github.com/repos/{repo}/releases/latest"
headers = {"Accept": "application/vnd.github+json"}
if token:
headers["Authorization"] = f"Bearer {token}"
r = requests.get(api, headers=headers, timeout=30)
r.raise_for_status()
data = r.json()
assets = data.get("assets", [])
urls = [a.get("browser_download_url") for a in assets if (a.get("browser_download_url") or "").lower().endswith(".mmdb")]
if not urls:
return None
lower = [u.lower() for u in urls]
for key in ("city", "country", "asn"):
for i, u in enumerate(lower):
if key in u:
return urls[i]
return urls[0]

60
scripts/updater.py Normal file
View File

@@ -0,0 +1,60 @@
import time
import os
import logging
from scripts.download_helpers import download_maxmind, download_file, github_latest_mmdb
from app.config import settings
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("db_updater")
def update_once():
provider = settings.geo_provider.lower()
try:
if provider == "maxmind":
# 1) GitHub Releases (latest)
repo = os.getenv("MAXMIND_GITHUB_REPO") or "P3TERX/GeoLite.mmdb"
token = os.getenv("GITHUB_TOKEN")
gh_url = None
try:
gh_url = github_latest_mmdb(repo, token)
except Exception as e:
log.warning("GitHub latest check failed: %s", e)
if gh_url:
download_file(gh_url, settings.maxmind_db_path)
log.info("MaxMind DB pobrana z GitHub Releases: %s", gh_url)
return
# 2) Bezpośredni URL do .mmdb
direct_url = os.getenv("MAXMIND_DIRECT_DB_URL")
if direct_url:
download_file(direct_url, settings.maxmind_db_path)
log.info("MaxMind DB pobrana z direct URL: %s", direct_url)
return
# 3) Oficjalne pobieranie MaxMind (wymaga licencji)
key = os.getenv("MAXMIND_LICENSE_KEY")
if not key:
log.error("Brak źródła bazy: ustaw MAXMIND_GITHUB_REPO lub MAXMIND_DIRECT_DB_URL lub MAXMIND_LICENSE_KEY")
return
download_maxmind(key, settings.maxmind_db_name, settings.maxmind_db_path, settings.maxmind_download_url_template)
log.info("MaxMind DB zaktualizowana (MaxMind download)")
elif provider == "ip2location":
url = os.getenv("IP2LOCATION_DOWNLOAD_URL")
if not url:
log.error("Brak IP2LOCATION_DOWNLOAD_URL w env")
return
download_file(url, settings.ip2location_db_path)
log.info("IP2Location DB zaktualizowana")
else:
log.error("Nieznany provider: %s", provider)
except Exception as e:
log.exception("Błąd przy aktualizacji bazy: %s", e)
if __name__ == "__main__":
interval = settings.update_interval_seconds
while True:
update_once()
time.sleep(interval)