|
3 | 3 | import sys
|
4 | 4 | import time
|
5 | 5 | import requests
|
| 6 | +import subprocess |
| 7 | +import sqlite3 |
| 8 | +import tempfile |
| 9 | +import json |
6 | 10 |
|
7 | 11 | class HubFlistSyncer:
|
8 | 12 | def __init__(self, baseurl, localdir):
|
@@ -114,6 +118,12 @@ def local_sync_regular_file(self, username, entry, targetfile):
|
114 | 118 | with open(targetfile, "wb") as f:
|
115 | 119 | f.write(r.content)
|
116 | 120 |
|
| 121 | + # apply metadata transformation for our local settings |
| 122 | + # saving current cwd and restoring cwd after-call |
| 123 | + cwd = os.getcwd() |
| 124 | + self.metadata_update(targetfile) |
| 125 | + os.chdir(cwd) |
| 126 | + |
117 | 127 | # apply same modification time on symlink than remote host
|
118 | 128 | os.utime(targetfile, (now, entry['updated']))
|
119 | 129 |
|
@@ -202,6 +212,54 @@ def statistics(self):
|
202 | 212 | mbsize = self.downloaded / (1024 * 1024)
|
203 | 213 | print(f"[+] downloaded: {mbsize:.2f} MB ({self.files} files)")
|
204 | 214 |
|
| 215 | + # |
| 216 | + # metadata manipulation |
| 217 | + # |
| 218 | + def metadata_update(self, target): |
| 219 | + print("[+] updating low-level metadata") |
| 220 | + |
| 221 | + # we are not using 'import tarfile' and native python module |
| 222 | + # which is really slow compare to plain raw tar command (nearly 10x slower). |
| 223 | + |
| 224 | + with tempfile.TemporaryDirectory() as workspace: |
| 225 | + os.chdir(workspace) |
| 226 | + |
| 227 | + args = ["tar", "-xf", target, "-C", workspace] |
| 228 | + p = subprocess.Popen(args) |
| 229 | + p.wait() |
| 230 | + |
| 231 | + db = sqlite3.connect("flistdb.sqlite3") |
| 232 | + cursor = db.cursor() |
| 233 | + |
| 234 | + try: |
| 235 | + cursor.execute("SELECT key FROM metadata LIMIT 1") |
| 236 | + row = cursor.fetchone() |
| 237 | + # print(row) |
| 238 | + |
| 239 | + except sqlite3.OperationalError: |
| 240 | + # old flist files don't have metadata table at all, that feature |
| 241 | + # wasn't existing at that time, let's create it by the way |
| 242 | + |
| 243 | + print("[-] legacy flist, no metadata records found, initializing") |
| 244 | + cursor.execute("CREATE TABLE metadata (key VARCHAR(64) PRIMARY KEY, value TEXT);") |
| 245 | + |
| 246 | + # FIXME: takes theses settings from a main place |
| 247 | + backend = json.dumps({"namespace": "default", "host": "hub.updated.host", "port": 7900}) |
| 248 | + |
| 249 | + cursor.execute("REPLACE INTO metadata (key, value) VALUES ('backend', ?)", (backend,)) |
| 250 | + db.commit() |
| 251 | + db.close() |
| 252 | + |
| 253 | + updated = f"{target}.updated.tar.gz" |
| 254 | + |
| 255 | + args = ["tar", "-czf", updated, "flistdb.sqlite3"] |
| 256 | + p = subprocess.Popen(args) |
| 257 | + p.wait() |
| 258 | + |
| 259 | + # overwrite source file with updated version |
| 260 | + os.rename(updated, target) |
| 261 | + |
| 262 | + return True |
205 | 263 |
|
206 | 264 | if __name__ == "__main__":
|
207 | 265 | if len(sys.argv) < 3:
|
|
0 commit comments