File size: 2,125 Bytes
f3e52a7
 
 
 
 
 
5c45d3a
 
 
 
 
f3e52a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os, time, hashlib, tempfile, threading
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobClient
from dotenv import load_dotenv

load_dotenv()
ACCOUNT  = os.getenv("AZURE_STORAGE_ACCOUNT","yt-extractor-rg")  # storage account name
CONTAINER= os.getenv("COOKIES_CONTAINER","cookies")        # container name
BLOB     = os.getenv("COOKIES_BLOB","cookies.txt")     # blob name
OUT_PATH = os.getenv("COOKIES_PATH","/tmp/cookies.txt")  # local path to write cookies
REFRESH = int(os.getenv("COOKIES_REFRESH_SEC", "600"))  # Default to 10 minutes

def _sha256(b: bytes) -> str: return hashlib.sha256(b).hexdigest()
def _read(path: str) -> bytes:
    try:
        with open(path, "rb") as f: return f.read()
    except: return b""

def _atomic_write(path: str, data: bytes):
    d = os.path.dirname(path) or "."
    os.makedirs(d, exist_ok=True)
    fd, tmp = tempfile.mkstemp(prefix=".cookies.", dir=d)
    with os.fdopen(fd, "wb") as f: f.write(data)
    os.replace(tmp, path)
    try: os.chmod(path, 0o600)
    except: pass

def refresh_once():
    if not ACCOUNT: 
        print("[cookies] ACCOUNT not set"); return
    cred = DefaultAzureCredential()  # uses ACA managed identity
    bc = BlobClient(
        account_url=f"https://{ACCOUNT}.blob.core.windows.net",
        container_name=CONTAINER,
        blob_name=BLOB,
        credential=cred,
    )
    new = bc.download_blob(max_concurrency=1).readall()
    if not new.strip():
        print("[cookies] WARN: blob is empty; skipping")
        return
    if _sha256(new) != _sha256(_read(OUT_PATH)):
        _atomic_write(OUT_PATH, new)
        print(f"[cookies] updated -> {OUT_PATH} (bytes={len(new)})")

def start_cookies_refresher():
    # initial fetch before serving traffic
    try: refresh_once()
    except Exception as e: print(f"[cookies] initial refresh error: {e}")
    # periodic refresh
    def loop():
        while True:
            time.sleep(REFRESH)
            try: refresh_once()
            except Exception as e: print(f"[cookies] refresh error: {e}")
    threading.Thread(target=loop, daemon=True).start()