fileman.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #! /usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import shutil
  5. import time
  6. import datetime
  7. import logging
  8. import asyncio
  9. import re
  10. # любитель філе, а не файл людина
  11. class Fileman:
  12. def __init__(self, watch_target_subpath):
  13. """
  14. watch_target_subpath = {
  15. "watch": "path/to/watch",
  16. "target": "path/to/target",
  17. "subpaths":[
  18. {"name": ["ext1", "ext2"]},
  19. {"name2": ["ext3", "ext4"]}
  20. ]
  21. }
  22. """
  23. time.sleep(0.3)
  24. self.id = time.time_ns()
  25. print(f"Fileman ID: {self.id}")
  26. self.watch = watch_target_subpath['watch']
  27. self.target = watch_target_subpath['target']
  28. self.subpaths = watch_target_subpath['subpaths']
  29. self.check_dirs()
  30. def check_dirs(self):
  31. assert os.path.exists(self.watch), f"Папки `{self.watch}` не існує"
  32. if not os.path.exists(self.target):
  33. os.makedirs(self.target)
  34. for subpath in self.subpaths:
  35. subpath = list(subpath.keys())[0]
  36. subpath = self.path_plus_path(self.target, subpath)
  37. if not os.path.exists(subpath):
  38. os.makedirs(subpath)
  39. return True
  40. def path_plus_path(self, path_1, path_2):
  41. return f"{path_1}/{path_2}".replace('\\', '/')
  42. def target_by_file(self, files):
  43. files_to_move = {}
  44. iterations = 0
  45. for subpath in self.subpaths:
  46. key = list(subpath.keys())[0]
  47. exts = subpath[key]
  48. files_to_move[key] = []
  49. iterations += 1
  50. for ext in exts:
  51. iterations += 1
  52. for file in files:
  53. iterations += 1
  54. if file.lower().endswith(f".{ext}"):
  55. files_to_move[key].append(file)
  56. logging.info(f"target_by_file ітерації: {iterations}")
  57. return files_to_move
  58. def rename_file(self, target, file):
  59. path_to = self.path_plus_path(target, file)
  60. if not os.path.exists(path_to):
  61. return path_to
  62. else:
  63. match = re.match(r'^\[(\d{1,})\]', file)
  64. if match:
  65. num = int(match.group(1)) + 1
  66. file = re.sub(r'^\[(\d{1,})\]', f'[{num}]', file)
  67. else:
  68. file = f"[0] {file}"
  69. return self.rename_file(target, file)
  70. def move_files(self, files):
  71. keys = list(files.keys())
  72. for key in keys:
  73. target = self.path_plus_path(self.target, key)
  74. for file in files[key]:
  75. try:
  76. path_from = self.path_plus_path(self.watch, file)
  77. path_to = self.rename_file(target, file)
  78. shutil.move(path_from, path_to)
  79. except PermissionError:
  80. logging.info(f"Або нема дозволу або файл {file} відкрито в іншій програмі")
  81. logging.info(" В наступній перевірці файлів спробу перемістити буде повторено")
  82. def check_files(self):
  83. files = os.listdir(self.watch)
  84. target_files = self.target_by_file(files)
  85. self.move_files(target_files)
  86. def work(self, pause):
  87. """ pause - пауза між перевірками в секундах """
  88. while True:
  89. self.check_files()
  90. time.sleep(pause)
  91. print(f"\r [{datetime.datetime.now()}] [{self.id}] Працюю, прикинь", end="")
  92. logging.info(f"Працюю, прикинь [{self.id}]")
  93. async def async_work(self, pause):
  94. while True:
  95. self.check_files()
  96. await asyncio.sleep(pause)
  97. print(f"\r [{datetime.datetime.now()}] [{self.id}] Працюю, прикинь", end="")
  98. logging.info(f"Працюю, прикинь [{self.id}]")