|
30 | 30 |
|
31 | 31 | import mysql.connector |
32 | 32 |
|
| 33 | +FIXED_ZIP_TIMESTAMP = (1980, 1, 1, 0, 0, 0) # year, month, day, hour, min, sec |
| 34 | + |
33 | 35 |
|
34 | 36 | def get_db_connection(): |
35 | 37 | """Establish and return a MySQL connection using environment variables.""" |
@@ -109,20 +111,29 @@ def calc_md5(fname): |
109 | 111 | return hash_md5.hexdigest() |
110 | 112 |
|
111 | 113 | def zipdir(path, ziph): |
112 | | - # ziph is zipfile handle |
113 | | - |
114 | 114 | if not os.path.exists(path): |
115 | 115 | print(f"Warning: {path} does not exist, skipping") |
116 | 116 | return |
117 | 117 |
|
118 | 118 | if os.path.isdir(path): |
119 | 119 | for root, dirs, files in os.walk(path): |
| 120 | + files.sort() # deterministic order |
| 121 | + dirs.sort() # deterministic order |
120 | 122 | for file in files: |
121 | | - arcname = os.path.relpath(os.path.join(root, file), start=path) |
122 | | - ziph.write(os.path.join(root, file), arcname=arcname) |
123 | | - |
| 123 | + full_path = os.path.join(root, file) |
| 124 | + arcname = os.path.relpath(full_path, start=path) # preserve folder structure |
| 125 | + info = zipfile.ZipInfo(arcname, FIXED_ZIP_TIMESTAMP) |
| 126 | + with open(full_path, "rb") as f: |
| 127 | + data = f.read() |
| 128 | + ziph.writestr(info, data, compress_type=zipfile.ZIP_DEFLATED) |
124 | 129 | else: |
125 | | - ziph.write(path) |
| 130 | + # single file outside a directory |
| 131 | + arcname = os.path.basename(path) |
| 132 | + info = zipfile.ZipInfo(arcname, FIXED_ZIP_TIMESTAMP) |
| 133 | + with open(path, "rb") as f: |
| 134 | + data = f.read() |
| 135 | + ziph.writestr(info, data, compress_type=zipfile.ZIP_DEFLATED) |
| 136 | + |
126 | 137 |
|
127 | 138 |
|
128 | 139 | def create_file(conn, mod, fileId, version, name, source, target_dir, old_md5, dryrun): |
|
0 commit comments