Ethscriptions commited on
Commit
3021a47
·
verified ·
1 Parent(s): daca5f3

Upload r2_config_sync.py

Browse files
Files changed (1) hide show
  1. r2_config_sync.py +111 -0
r2_config_sync.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ from pathlib import Path
4
+ from typing import Optional
5
+
6
+ from r2_storage import R2Storage
7
+
8
+
9
+ ROOT_DIR = Path(__file__).resolve().parent
10
+
11
+
12
+ def build_settings_prefix() -> str:
13
+ cinema_id = (os.getenv("CINEMA_ID") or "").strip() or "default"
14
+ return f"{cinema_id}/app_settings"
15
+
16
+
17
+ def build_settings_key(file_name: str) -> str:
18
+ return f"{build_settings_prefix().rstrip('/')}/{str(file_name).lstrip('/')}"
19
+
20
+
21
+ def get_local_settings_path(file_name: str | Path) -> Path:
22
+ return ROOT_DIR / str(file_name)
23
+
24
+
25
+ def get_r2_storage_or_none() -> Optional[R2Storage]:
26
+ try:
27
+ return R2Storage()
28
+ except Exception:
29
+ return None
30
+
31
+
32
+ def upload_settings_file_to_r2(file_name: str | Path) -> bool:
33
+ storage = get_r2_storage_or_none()
34
+ if storage is None:
35
+ return False
36
+
37
+ local_path = get_local_settings_path(file_name)
38
+ if not local_path.exists():
39
+ return False
40
+
41
+ try:
42
+ storage.upload_file(local_path, build_settings_key(local_path.name), content_type="application/json")
43
+ return True
44
+ except Exception:
45
+ return False
46
+
47
+
48
+ def ensure_settings_file_from_r2(file_name: str | Path, force_download: bool = False) -> bool:
49
+ storage = get_r2_storage_or_none()
50
+ if storage is None:
51
+ return False
52
+
53
+ local_path = get_local_settings_path(file_name)
54
+ key = build_settings_key(local_path.name)
55
+
56
+ try:
57
+ remote_exists = storage.exists(key)
58
+ except Exception:
59
+ return False
60
+
61
+ if not remote_exists:
62
+ return False
63
+
64
+ if local_path.exists() and not force_download:
65
+ return False
66
+
67
+ try:
68
+ storage.download_file(key, local_path)
69
+ return True
70
+ except Exception:
71
+ return False
72
+
73
+
74
+ def ensure_settings_file_synced(file_name: str | Path) -> str:
75
+ storage = get_r2_storage_or_none()
76
+ if storage is None:
77
+ return "r2_unavailable"
78
+
79
+ local_path = get_local_settings_path(file_name)
80
+ key = build_settings_key(local_path.name)
81
+
82
+ try:
83
+ remote_exists = storage.exists(key)
84
+ except Exception:
85
+ return "r2_check_failed"
86
+
87
+ local_exists = local_path.exists()
88
+ if not local_exists and remote_exists:
89
+ try:
90
+ storage.download_file(key, local_path)
91
+ return "downloaded"
92
+ except Exception:
93
+ return "download_failed"
94
+
95
+ if local_exists and not remote_exists:
96
+ try:
97
+ storage.upload_file(local_path, key, content_type="application/json")
98
+ return "uploaded"
99
+ except Exception:
100
+ return "upload_failed"
101
+
102
+ if local_exists and remote_exists:
103
+ return "already_synced"
104
+
105
+ return "missing_both"
106
+
107
+
108
+ def write_json_file(file_name: str | Path, payload: dict) -> Path:
109
+ local_path = get_local_settings_path(file_name)
110
+ local_path.write_text(json.dumps(payload, ensure_ascii=False, indent=4), encoding="utf-8")
111
+ return local_path