module_watch_dog.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. from watchdog.events import FileSystemEventHandler
  2. from watchdog.observers import Observer
  3. import settings
  4. import time
  5. import os
  6. from utils.utils_func import get_folder, check_path
  7. import datetime
  8. from utils.SingletonType import SingletonType
  9. from databases import CRUD, SqlQuery, PhotoRecord
  10. import asyncio
  11. def updateImageRaw(time_str, image_path, goods_art_no, image_index):
  12. session = SqlQuery()
  13. crud = CRUD(PhotoRecord)
  14. res = crud.read(
  15. session,
  16. conditions={
  17. "image_path": None,
  18. "goods_art_no": goods_art_no,
  19. "image_index": image_index,
  20. },
  21. )
  22. if res:
  23. # 格式化为年月日时分
  24. update = {
  25. "image_path": image_path,
  26. "photo_create_time": time_str,
  27. }
  28. crud.update(
  29. session,
  30. res.id,
  31. **update,
  32. )
  33. class FileEventHandler(FileSystemEventHandler, metaclass=SingletonType):
  34. instance = None
  35. init_flag = None
  36. def __init__(self):
  37. # if self.init_flag:
  38. # return
  39. # else:
  40. # self.init_flag = True
  41. self.goods_art_no = None
  42. self.image_index = -1
  43. self.mcu = None
  44. super().__init__()
  45. # self.window = window
  46. FileSystemEventHandler.__init__(self)
  47. self.receive_photo_data = []
  48. # 以下为测试用途
  49. self._get_image_index = -1
  50. self.observer = None
  51. self.last_create_time = datetime.datetime.now()
  52. def start_observer(self, path):
  53. if self.observer != None:
  54. return
  55. print("图片保存目录:", path)
  56. if path == None or path == "":
  57. return
  58. self.observer = Observer()
  59. watch_path = self.check_and_get_real_dir(path)
  60. if watch_path:
  61. self.observer.schedule(
  62. self, watch_path, recursive=True
  63. ) # recursive 遍历目录
  64. self.observer.start()
  65. print("开启开门狗目录监听")
  66. else:
  67. print("路径错误不存在")
  68. def check_and_get_real_dir(self, watch_path):
  69. """
  70. 逻辑:
  71. 1、检查当前路径如包含Originals 则定位到对应Originals的父级目录
  72. 2、如没有Originals,则认定为一个普通目录(且子文件夹没有Originals),否则定位到父级目录
  73. """
  74. if not os.path.exists(watch_path):
  75. return None
  76. if "Originals" in watch_path:
  77. root_path = watch_path.split("Originals", 1)[0]
  78. else:
  79. if "Originals" in [x["folder_name"] for x in get_folder(watch_path)]:
  80. root_path = watch_path
  81. else:
  82. return watch_path
  83. # 检查并创建日期
  84. now = datetime.datetime.now()
  85. year = now.year
  86. month = now.month
  87. day = now.day
  88. path = r"{root_path}\Originals\{year}\{month}\{day}".format(
  89. root_path=root_path, year=year, month=month, day=day
  90. )
  91. check_path(path)
  92. print("watch_path:", path)
  93. return path
  94. def on_moved(self, event):
  95. # if event.is_directory:
  96. # print("directory moved from {0} to {1}".format(event.src_path, event.dest_path))
  97. # else:
  98. # print("file moved from {0} to {1}".format(event.src_path, event.dest_path))
  99. # if os.path.split(event.dest_path)[0] == settings.PhotoOutputDir:
  100. # print("1111111")
  101. pass
  102. def updatePhotoRecord(self):
  103. session = SqlQuery()
  104. crud = CRUD(PhotoRecord)
  105. crud.read()
  106. async def sendCallback(
  107. self, file_path, goods_art_no=None, image_index=-1, msg_type="run_mcu_single"
  108. ):
  109. await asyncio.sleep(1)
  110. self.mcu.msg_type = msg_type
  111. # print("货号不存在,监听不写入", self.mcu.msg_type)
  112. self.mcu.sendSocketMessage(
  113. code=0,
  114. msg="拍摄完成",
  115. device_status=2,
  116. data={
  117. "file_path": file_path.replace("\\", "/"),
  118. "goods_art_no": goods_art_no,
  119. "image_index": image_index,
  120. },
  121. )
  122. self.msg_type = "mcu"
  123. def on_created(self, event):
  124. if not event.is_directory:
  125. file_path = event.src_path
  126. print("file created:{0}".format(file_path))
  127. self.receive_photo_data.append(file_path)
  128. # self.get_photo_info(file_path)
  129. # self.window.data_sign.emit({"_type": "photo_number_music_play"})
  130. try:
  131. take_time = time.time()
  132. self.send_log("获取文件file_path:{}".format(file_path))
  133. create_time = datetime.datetime.fromtimestamp(
  134. os.path.getctime(file_path)
  135. )
  136. # print("获取文件create_time:{}".format(create_time))
  137. self.get_photo_info(
  138. raw_path=file_path, create_time=create_time, take_time=take_time
  139. )
  140. self.send_log("获取文件create_time:{}".format(create_time))
  141. if file_path == None:
  142. print("file_path不存在,监听不写入")
  143. return
  144. if self.goods_art_no == None:
  145. # print("货号不存在,监听不写入")
  146. loop = asyncio.new_event_loop()
  147. asyncio.set_event_loop(loop)
  148. loop.run_until_complete(self.sendCallback(file_path))
  149. loop.close()
  150. return
  151. loop = asyncio.new_event_loop()
  152. asyncio.set_event_loop(loop)
  153. loop.run_until_complete(
  154. self.sendCallback(
  155. file_path,
  156. goods_art_no=self.goods_art_no,
  157. image_index=self.image_index,
  158. msg_type="run_mcu_update",
  159. )
  160. )
  161. loop.close()
  162. updateImageRaw(
  163. create_time, file_path, self.goods_art_no, self.image_index
  164. )
  165. except BaseException as e:
  166. print("获取文件create_time失败", e)
  167. self.send_log("获取文件处理失败{}".format(e))
  168. def send_log(self, text):
  169. print(text)
  170. def get_photo_info(self, raw_path, create_time, take_time):
  171. # 看门狗监听到系统有图片生成后,自动进行图片对应
  172. f_path = os.path.split(raw_path)[0]
  173. print("raw_path:", raw_path)
  174. # take_time = time.time() # 创建图片时间,默认为拍照时间
  175. time.sleep(0.2) # 等待原始图片文件写入
  176. # 查找真实的图片路径名称
  177. f = False
  178. if f:
  179. if not os.path.exists(raw_path):
  180. print("不存在", raw_path)
  181. for file in os.listdir(f_path):
  182. file_path = os.path.join(f_path, file)
  183. # 判断是否为文件
  184. if os.path.isfile(file_path):
  185. # 获取文件创建时间
  186. create_time = datetime.datetime.fromtimestamp(
  187. os.path.getctime(file_path)
  188. )
  189. # 更新最早时间
  190. if create_time > self.last_create_time:
  191. self.last_create_time = create_time
  192. raw_path = file_path
  193. # last_file_size = os.path.getsize(raw_path)
  194. # k = 30
  195. # # 检查文件是否有写入完成
  196. # flag = False
  197. # while k:
  198. # k -= 1
  199. # if k == 0:
  200. # break
  201. # _file_size = os.path.getsize(raw_path)
  202. # if last_file_size == _file_size:
  203. # flag = True
  204. # break
  205. # else:
  206. # last_file_size = _file_size
  207. # time.sleep(0.1)
  208. # if not flag:
  209. # return
  210. # 调用父程序,执行报错图片命令
  211. # self.window.show_img_on_photo_todo_list_sign(raw_path=raw_path, take_time=take_time)
  212. def stop(self):
  213. # 结束监听
  214. if self.observer is not None:
  215. self.observer.stop()
  216. print("结束监听")
  217. del self.observer
  218. def __new__(cls, *args, **kwargs):
  219. """如果当前没有实例时,调用父类__new__方法,生成示例,有则返回保存的内存地址。"""
  220. if not cls.instance:
  221. cls.instance = super().__new__(cls)
  222. return cls.instance
  223. def __del__(self):
  224. self.stop()
  225. print("结束监听,进程关闭")