module_watch_dog.py 9.2 KB

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