Upload main.py
Browse files
main.py
CHANGED
@@ -247,10 +247,10 @@ class CivitAICrawler:
|
|
247 |
single_file_folder = os.path.join(old_versions_folder, "temp_single")
|
248 |
os.makedirs(single_file_folder, exist_ok=True)
|
249 |
try:
|
250 |
-
# 移動して「このファイルだけ」が入ったフォルダを作る
|
251 |
single_file_path = shutil.move(local_path, os.path.join(single_file_folder, file_name))
|
252 |
-
|
253 |
-
|
|
|
254 |
except Exception as e:
|
255 |
logger.error(f"Failed to encrypt/upload old version file: {e}")
|
256 |
finally:
|
@@ -259,28 +259,27 @@ class CivitAICrawler:
|
|
259 |
shutil.rmtree(single_file_folder)
|
260 |
logger.info(f"Removed temp_single folder {single_file_folder}")
|
261 |
|
262 |
-
def
|
263 |
"""
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
4. そのフォルダを self.upload_folder() (=HFにアップロード)
|
269 |
-
5. ローカル(平文フォルダ & 暗号フォルダ)削除
|
270 |
-
6. 最後に subfolder_label(論理上のフォルダ名)を return
|
271 |
"""
|
272 |
-
|
273 |
-
|
|
|
274 |
return None
|
275 |
|
276 |
encrypted_base_dir = os.path.join(os.getcwd(), "encrypted")
|
277 |
os.makedirs(encrypted_base_dir, exist_ok=True)
|
278 |
|
279 |
-
#
|
280 |
-
|
|
|
281 |
item_path = os.path.join(encrypted_base_dir, item)
|
282 |
try:
|
283 |
-
if os.path.isfile(item_path)
|
284 |
os.remove(item_path)
|
285 |
else:
|
286 |
shutil.rmtree(item_path)
|
@@ -288,7 +287,7 @@ class CivitAICrawler:
|
|
288 |
except Exception as e:
|
289 |
logger.warning(f"[CLEANUP] Failed to remove {item_path}: {e}")
|
290 |
|
291 |
-
#
|
292 |
subfolder_label = "enc_" + str(uuid.uuid4())[:8]
|
293 |
try:
|
294 |
subprocess.run(
|
@@ -300,53 +299,128 @@ class CivitAICrawler:
|
|
300 |
logger.error(f"rclone mkdir failed: {e}")
|
301 |
return None
|
302 |
|
303 |
-
#
|
304 |
-
|
305 |
try:
|
306 |
subprocess.run(
|
307 |
[
|
308 |
-
"rclone", "
|
309 |
-
|
310 |
-
f"cryptLocal:{subfolder_label}",
|
311 |
"--create-empty-src-dirs"
|
312 |
],
|
313 |
check=True
|
314 |
)
|
315 |
-
logger.info(f"[OK] rclone
|
316 |
except subprocess.CalledProcessError as e:
|
317 |
-
logger.error(f"rclone
|
318 |
return None
|
319 |
|
320 |
-
#
|
321 |
-
# それを差分検知で特定
|
322 |
-
before_dirs = set(os.listdir(encrypted_base_dir))
|
323 |
-
# mkdir/copy 直���に何らかのズレがあるかもしれないので再度 mkdir しなくてOK
|
324 |
-
# すでに上でやってるため、ここでやるなら:
|
325 |
-
# time.sleep(1) などで間を置いてみる手もある
|
326 |
-
|
327 |
after_dirs = set(os.listdir(encrypted_base_dir))
|
328 |
diff = after_dirs - before_dirs
|
329 |
-
# もし diff が空なら既にあるフォルダに上書きコピーされた可能性
|
330 |
if not diff:
|
331 |
-
logger.error("[ERROR] No new directory appeared in ./encrypted after rclone
|
332 |
return None
|
333 |
if len(diff) > 1:
|
334 |
-
logger.warning(f"[WARN] Multiple new directories found: {diff}
|
335 |
-
enc_folder_name = diff.pop()
|
336 |
-
enc_folder_path = os.path.join(encrypted_base_dir, enc_folder_name)
|
337 |
|
|
|
|
|
338 |
if not os.path.isdir(enc_folder_path):
|
339 |
logger.error(f"[ERROR] {enc_folder_path} is not a directory.")
|
340 |
return None
|
341 |
|
342 |
-
# 4)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
343 |
try:
|
344 |
self.upload_folder(enc_folder_path, path_in_repo=subfolder_label)
|
345 |
logger.info(f"Uploaded encrypted folder: {enc_folder_path}")
|
346 |
except Exception as e:
|
347 |
logger.error(f"Failed to upload encrypted folder {enc_folder_path}: {e}")
|
348 |
|
349 |
-
#
|
350 |
try:
|
351 |
shutil.rmtree(local_folder)
|
352 |
shutil.rmtree(enc_folder_path)
|
@@ -354,7 +428,6 @@ class CivitAICrawler:
|
|
354 |
except Exception as e:
|
355 |
logger.error(f"Failed to remove local folders: {e}")
|
356 |
|
357 |
-
# 6) 論理上のフォルダ名(rclone上の名称)を返す
|
358 |
return subfolder_label
|
359 |
|
360 |
def upload_file(self, file_path: str, repo_id: Optional[str] = None, path_in_repo: Optional[str] = None):
|
|
|
247 |
single_file_folder = os.path.join(old_versions_folder, "temp_single")
|
248 |
os.makedirs(single_file_folder, exist_ok=True)
|
249 |
try:
|
|
|
250 |
single_file_path = shutil.move(local_path, os.path.join(single_file_folder, file_name))
|
251 |
+
|
252 |
+
# ★ここでファイルのみを暗号化したいので encrypt_and_upload_single_file() を使用
|
253 |
+
self.encrypt_and_upload_single_file(os.path.join(single_file_folder, file_name))
|
254 |
except Exception as e:
|
255 |
logger.error(f"Failed to encrypt/upload old version file: {e}")
|
256 |
finally:
|
|
|
259 |
shutil.rmtree(single_file_folder)
|
260 |
logger.info(f"Removed temp_single folder {single_file_folder}")
|
261 |
|
262 |
+
def encrypt_and_upload_single_file(self, local_file: str) -> Optional[str]:
|
263 |
"""
|
264 |
+
単一ファイルを暗号化→アップロード→ローカル削除する。
|
265 |
+
- rclone mkdir cryptLocal:enc_xxxx
|
266 |
+
- rclone copyto local_file => cryptLocal:enc_xxxx/filename
|
267 |
+
- 差分検知で作られた暗号フォルダを発見→upload_folder()→削除
|
|
|
|
|
|
|
268 |
"""
|
269 |
+
import uuid
|
270 |
+
if not os.path.isfile(local_file):
|
271 |
+
logger.error(f"[encrypt_and_upload_single_file] Not a file: {local_file}")
|
272 |
return None
|
273 |
|
274 |
encrypted_base_dir = os.path.join(os.getcwd(), "encrypted")
|
275 |
os.makedirs(encrypted_base_dir, exist_ok=True)
|
276 |
|
277 |
+
# 古い暗号物を削除
|
278 |
+
before_dirs = set(os.listdir(encrypted_base_dir))
|
279 |
+
for item in before_dirs:
|
280 |
item_path = os.path.join(encrypted_base_dir, item)
|
281 |
try:
|
282 |
+
if os.path.isfile(item_path):
|
283 |
os.remove(item_path)
|
284 |
else:
|
285 |
shutil.rmtree(item_path)
|
|
|
287 |
except Exception as e:
|
288 |
logger.warning(f"[CLEANUP] Failed to remove {item_path}: {e}")
|
289 |
|
290 |
+
# 1) mkdir
|
291 |
subfolder_label = "enc_" + str(uuid.uuid4())[:8]
|
292 |
try:
|
293 |
subprocess.run(
|
|
|
299 |
logger.error(f"rclone mkdir failed: {e}")
|
300 |
return None
|
301 |
|
302 |
+
# 2) copyto (ファイル) => cryptLocal:enc_xxx/filename
|
303 |
+
filename_in_repo = os.path.basename(local_file)
|
304 |
try:
|
305 |
subprocess.run(
|
306 |
[
|
307 |
+
"rclone", "copyto",
|
308 |
+
local_file,
|
309 |
+
f"cryptLocal:{subfolder_label}/{filename_in_repo}",
|
310 |
"--create-empty-src-dirs"
|
311 |
],
|
312 |
check=True
|
313 |
)
|
314 |
+
logger.info(f"[OK] rclone copyto {local_file} => cryptLocal:{subfolder_label}/{filename_in_repo}")
|
315 |
except subprocess.CalledProcessError as e:
|
316 |
+
logger.error(f"rclone copyto failed: {e}")
|
317 |
return None
|
318 |
|
319 |
+
# 3) 差分検知
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
after_dirs = set(os.listdir(encrypted_base_dir))
|
321 |
diff = after_dirs - before_dirs
|
|
|
322 |
if not diff:
|
323 |
+
logger.error("[ERROR] No new directory appeared in ./encrypted after rclone copyto.")
|
324 |
return None
|
325 |
if len(diff) > 1:
|
326 |
+
logger.warning(f"[WARN] Multiple new directories found in ./encrypted: {diff}")
|
|
|
|
|
327 |
|
328 |
+
enc_folder_name = diff.pop() # 1つ抜き取る
|
329 |
+
enc_folder_path = os.path.join(encrypted_base_dir, enc_folder_name)
|
330 |
if not os.path.isdir(enc_folder_path):
|
331 |
logger.error(f"[ERROR] {enc_folder_path} is not a directory.")
|
332 |
return None
|
333 |
|
334 |
+
# 4) upload_folder
|
335 |
+
try:
|
336 |
+
self.upload_folder(enc_folder_path, path_in_repo=subfolder_label)
|
337 |
+
logger.info(f"[OK] Uploaded encrypted folder: {enc_folder_path}")
|
338 |
+
except Exception as e:
|
339 |
+
logger.error(f"Failed to upload encrypted folder {enc_folder_path}: {e}")
|
340 |
+
|
341 |
+
# 5) ローカル削除(暗号フォルダ + 元ファイル)
|
342 |
+
try:
|
343 |
+
if os.path.exists(local_file):
|
344 |
+
os.remove(local_file)
|
345 |
+
if os.path.isdir(enc_folder_path):
|
346 |
+
shutil.rmtree(enc_folder_path)
|
347 |
+
logger.info(f"[CLEANUP] Removed {local_file} and {enc_folder_path}")
|
348 |
+
except Exception as e:
|
349 |
+
logger.warning(f"[CLEANUP] Failed to remove local items: {e}")
|
350 |
+
|
351 |
+
return subfolder_label
|
352 |
+
|
353 |
+
def encrypt_and_upload_folder(self, local_folder: str) -> Optional[str]:
|
354 |
+
"""
|
355 |
+
1. rclone mkdir cryptLocal:subfolder_label で空フォルダを作る
|
356 |
+
2. rclone copy local_folder => cryptLocal:subfolder_label --create-empty-src-dirs
|
357 |
+
3. そのフォルダを self.upload_folder() でアップ
|
358 |
+
4. ローカル平文フォルダ & 暗号フォルダを削除
|
359 |
+
5. subfolder_label を返す
|
360 |
+
"""
|
361 |
+
if not os.path.exists(local_folder):
|
362 |
+
logger.error(f"encrypt_and_upload_folder: folder not found: {local_folder}")
|
363 |
+
return None
|
364 |
+
|
365 |
+
encrypted_base_dir = os.path.join(os.getcwd(), "encrypted")
|
366 |
+
os.makedirs(encrypted_base_dir, exist_ok=True)
|
367 |
+
|
368 |
+
# 既存の暗号ファイル削除(不要ならコメントアウト)
|
369 |
+
for item in os.listdir(encrypted_base_dir):
|
370 |
+
item_path = os.path.join(encrypted_base_dir, item)
|
371 |
+
try:
|
372 |
+
if os.path.isfile(item_path) or os.path.islink(item_path):
|
373 |
+
os.remove(item_path)
|
374 |
+
else:
|
375 |
+
shutil.rmtree(item_path)
|
376 |
+
logger.info(f"[CLEANUP] Removed old encrypted item: {item_path}")
|
377 |
+
except Exception as e:
|
378 |
+
logger.warning(f"[CLEANUP] Failed to remove {item_path}: {e}")
|
379 |
+
|
380 |
+
# サブフォルダ名を生成(enc_ + UUID)
|
381 |
+
subfolder_label = "enc_" + str(uuid.uuid4())[:8]
|
382 |
+
|
383 |
+
# ★ 追加: mkdir で先に空ディレクトリを作っておく
|
384 |
+
try:
|
385 |
+
subprocess.run(
|
386 |
+
["rclone", "mkdir", f"cryptLocal:{subfolder_label}"],
|
387 |
+
check=True
|
388 |
+
)
|
389 |
+
except subprocess.CalledProcessError as e:
|
390 |
+
logger.error(f"rclone mkdir failed: {e}")
|
391 |
+
return None
|
392 |
+
|
393 |
+
# ★ --create-empty-src-dirs オプションを付けて copy
|
394 |
+
try:
|
395 |
+
subprocess.run(
|
396 |
+
[
|
397 |
+
"rclone",
|
398 |
+
"copy",
|
399 |
+
local_folder,
|
400 |
+
f"cryptLocal:{subfolder_label}",
|
401 |
+
"--create-empty-src-dirs"
|
402 |
+
],
|
403 |
+
check=True
|
404 |
+
)
|
405 |
+
except subprocess.CalledProcessError as e:
|
406 |
+
logger.error(f"rclone copy failed: {e}")
|
407 |
+
return None
|
408 |
+
|
409 |
+
# 暗号フォルダのパス(必ずディレクトリができている前提)
|
410 |
+
enc_folder_path = os.path.join(encrypted_base_dir, subfolder_label)
|
411 |
+
|
412 |
+
if not os.path.isdir(enc_folder_path):
|
413 |
+
logger.error(f"[ERROR] {enc_folder_path} is not a directory, something is still off.")
|
414 |
+
return None
|
415 |
+
|
416 |
+
# アップロード
|
417 |
try:
|
418 |
self.upload_folder(enc_folder_path, path_in_repo=subfolder_label)
|
419 |
logger.info(f"Uploaded encrypted folder: {enc_folder_path}")
|
420 |
except Exception as e:
|
421 |
logger.error(f"Failed to upload encrypted folder {enc_folder_path}: {e}")
|
422 |
|
423 |
+
# ローカル削除
|
424 |
try:
|
425 |
shutil.rmtree(local_folder)
|
426 |
shutil.rmtree(enc_folder_path)
|
|
|
428 |
except Exception as e:
|
429 |
logger.error(f"Failed to remove local folders: {e}")
|
430 |
|
|
|
431 |
return subfolder_label
|
432 |
|
433 |
def upload_file(self, file_path: str, repo_id: Optional[str] = None, path_in_repo: Optional[str] = None):
|