MainWindow.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import sys
  2. from datetime import datetime
  3. from pathlib import Path
  4. from PySide6.QtCore import QDate, QDateTime
  5. from PySide6.QtWidgets import QMainWindow, QMessageBox
  6. from sqlalchemy.exc import OperationalError
  7. from logger import logger
  8. from module import create_filename, translate
  9. from module.cam import IPCam, USBCam
  10. from module.MyMessageBox import show_dialog
  11. from module.Printer import Print
  12. from module.QRCode import make as make_qr
  13. from module.TemplatePropusk import TemplatePropusk
  14. from module.WorkWithDB import *
  15. from module.wkhtmltopdf import get_path_wkhtmltopdf
  16. from module.ImageTool import rotate_image
  17. from widgets import PStackedWidget, create_widget_stacked
  18. from module.cam.USBCam import get_first_cam
  19. from .DialogAbout import DialogAbout
  20. from .DialogHistory import DialogHistory
  21. from .DialogSettingCam import DialogSettingCam
  22. from .ListPersonal import ListPersonal
  23. from .ListPlace import ListPlace
  24. from .ui_py.ui_MainWindow import Ui_MainWindow
  25. vecrot_cam_from_db = [str, str, str]
  26. class MainWindow(QMainWindow, Ui_MainWindow):
  27. __wwc: IPCam | USBCam = None
  28. data_propusk: dict = None
  29. stacked_face: PStackedWidget = None
  30. __file_name_document: str = None
  31. __file_name_face: str = None
  32. __mode: str = 'video'
  33. __cam_face: str = get_first_cam()
  34. __cam_document: str = get_first_cam()
  35. def __init__(self, parent=None) -> None:
  36. super(MainWindow, self).__init__(parent)
  37. self.setupUi(self)
  38. self.date_from.setDateTime(QDateTime().currentDateTime())
  39. self.date_to.setDateTime(QDateTime().currentDateTime())
  40. self.__check_wkhtmltopdf()
  41. self.__init_menu_action()
  42. self.__init_btn_action()
  43. self.__update_list_combobox()
  44. self.__check_setting_cam()
  45. self.__create_widget_face_cam()
  46. self.tabWidget.currentChanged.connect(
  47. self.change_tab
  48. )
  49. def __init_menu_action(self) -> None:
  50. self.action_open_history.triggered.connect(self.open_history)
  51. self.btn_show_personal_window.triggered.connect(
  52. self.__show_personal_window
  53. )
  54. self.btn_show_place_window.triggered.connect(
  55. self.__show_place_window
  56. )
  57. self.setting_cam.triggered.connect(
  58. self.__show_setting_cam_window
  59. )
  60. self.update_list.triggered.connect(
  61. self.__update_list_combobox
  62. )
  63. self.btn_show_about.triggered.connect(
  64. self.__show_about_dialog
  65. )
  66. def __init_btn_action(self) -> None:
  67. self.btn_start_cam.clicked.connect(
  68. self.__press_btn_start_cam
  69. )
  70. self.capturePhoto.clicked.connect(
  71. self.__take_image
  72. )
  73. self.btn_save.clicked.connect(self.__save)
  74. self.btn_clear.clicked.connect(self.__clear)
  75. self.btn_print.clicked.connect(self.__print)
  76. def __show_about_dialog(self):
  77. DialogAbout(self).exec_()
  78. def __show_personal_window(self) -> None:
  79. ListPersonal(self).exec_()
  80. self.__update_list_combobox()
  81. def __show_place_window(self) -> None:
  82. ListPlace(self).exec_()
  83. self.__update_list_combobox()
  84. def __show_setting_cam_window(self) -> None:
  85. self.__stop_cam()
  86. DialogSettingCam(self).exec_()
  87. self.__check_setting_cam()
  88. self.__create_widget_face_cam()
  89. def open_history(self) -> None:
  90. DialogHistory(self).exec_()
  91. def change_tab(self) -> None:
  92. self.__stop_cam()
  93. self.__check_setting_cam()
  94. if self.tabWidget.currentIndex() == 1:
  95. self.__mode = 'video'
  96. def __checked_rotate_document(self) -> bool:
  97. return self.rotate_image_document.isChecked()
  98. def __check_setting_cam(self) -> None:
  99. try:
  100. self.__mode, self.__cam_face, self.__cam_document = self.__get_selected_cam()
  101. except ValueError:
  102. logger.warning(translate('Cameras not configured'))
  103. if show_dialog(
  104. QMessageBox.Warning,
  105. translate('Cameras not configured'),
  106. translate('Set up the camera \nSettings -> Camera settings')
  107. ):
  108. self.__show_setting_cam_window()
  109. self.__check_setting_cam()
  110. else:
  111. self.close()
  112. except TypeError:
  113. logger.warning(translate('Cameras not configured'))
  114. def __check_wkhtmltopdf(self) -> None:
  115. if get_path_wkhtmltopdf() is None:
  116. logger.critical(translate('wkhtmltopdf not installed'))
  117. show_dialog(QMessageBox.Icon.Critical,
  118. translate("Not found wkhtmltopdf"),
  119. translate("wkhtmltopdf not installed"))
  120. sys.exit(0)
  121. def __update_list_combobox(self) -> None:
  122. self.__load_personal()
  123. self.__load_place()
  124. def __load_personal(self) -> None:
  125. self.personal_combobox.clear()
  126. with connect() as conn:
  127. for personal in conn.execute(
  128. list_personal.select()
  129. ).all():
  130. fio = F"{personal.lastname} {personal.firstname} {personal.middlename}"
  131. self.personal_combobox.addItem(
  132. fio,
  133. userData=personal.id
  134. )
  135. def __load_place(self) -> None:
  136. self.place_combobox.clear()
  137. with connect() as conn:
  138. for place in conn.execute(
  139. list_place.select()
  140. ).all():
  141. self.place_combobox.addItem(
  142. place.name_place,
  143. userData=place.id
  144. )
  145. def __get_selected_cam(self) -> vecrot_cam_from_db:
  146. '''
  147. return:
  148. str -> video, snapshot
  149. str -> ссылка для подключения к ip камеры или названия камеры (для лица)
  150. str -> названия камеры (для документа)
  151. '''
  152. with connect() as conn:
  153. cam = conn.execute(
  154. cam_setting.select()
  155. ).all()
  156. try:
  157. return cam[0].mode, cam[0].selected_cam, cam[1].selected_cam
  158. except:
  159. logger.error(translate('Missing camera records'))
  160. if show_dialog(
  161. QMessageBox.Icon.Critical,
  162. translate('Camera'),
  163. translate('Missing camera records')
  164. ):
  165. self.__show_setting_cam_window()
  166. self.__check_setting_cam()
  167. else:
  168. sys.exit(0)
  169. def __press_btn_start_cam(self):
  170. match self.tabWidget.currentIndex():
  171. case 0: self.__start_cam(self.stacked_face, self.__cam_face)
  172. case 1: self.__start_cam(self.stacked_document, self.__cam_document)
  173. def __start_cam(self, widget: PStackedWidget, cam: str) -> None:
  174. if self.__wwc is None:
  175. widget.to_video()
  176. self.__create_wwc(widget, cam)
  177. self.btn_start_cam.setText(translate('Launch сamera'))
  178. else:
  179. self.__stop_cam()
  180. widget.to_image()
  181. self.btn_start_cam.setText(translate('Stop camera'))
  182. def __create_wwc(self, widget: PStackedWidget, cam: str) -> None:
  183. if self.__mode in 'snapshot':
  184. self.__wwc = IPCam()
  185. self.__wwc.qLabel = widget.video
  186. self.__wwc.lnk_connect = cam
  187. self.__wwc.start()
  188. elif self.__mode in ('video', 'document'):
  189. self.__wwc = USBCam(widget.video, cam)
  190. self.__wwc.start_cam()
  191. else:
  192. logger.error(F"{translate('No corrected')}: {self.__mode}")
  193. def __take_image(self) -> None:
  194. if self.tabWidget.currentIndex() == 1:
  195. self.__file_name_document = self.__wwc.cupture_image(
  196. self.stacked_document.image)
  197. self.stacked_document.to_image()
  198. else:
  199. self.__file_name_face = self.__wwc.cupture_image(
  200. self.stacked_face.image)
  201. self.stacked_face.to_image()
  202. self.btn_start_cam.setText(translate('Launch сamera'))
  203. # self.__stop_cam()
  204. def __print(self) -> None:
  205. if self.data_propusk is None:
  206. self.__save()
  207. propusk_data = self.data_propusk.copy()
  208. if self.__checked_rotate_document():
  209. self.__file_name_document = rotate_image(self.__file_name_document)
  210. propusk_data.update({
  211. "personal": self.personal_combobox.currentText(),
  212. "place": self.place_combobox.currentText(),
  213. "date_from": self.date_from.dateTime().toString('dd.MM.yyyy hh:mm'),
  214. "date_to": self.date_to.dateTime().toString('dd.MM.yyyy hh:mm'),
  215. "face": self.__file_name_face,
  216. "document": self.__file_name_document,
  217. "qrcode": make_qr(propusk_data.get("id_propusk"), create_filename('qr')),
  218. "count_repeat": 2
  219. })
  220. render_text = TemplatePropusk(
  221. propusk_data,
  222. os.path.join(os.environ.get('ABSOLUTE_PATH'), 'docs')
  223. )
  224. Print(str(render_text))
  225. def __clear(self) -> None:
  226. if self.data_propusk is not None:
  227. self.data_propusk = None
  228. self.__set_default_data()
  229. def __save(self) -> None:
  230. date_from = self.date_from.dateTime().toMSecsSinceEpoch() / 1000
  231. date_to = self.date_to.dateTime().toMSecsSinceEpoch() / 1000
  232. self.data_propusk = {
  233. "id_propusk": int(self.number_propusk.text()),
  234. "date_from": datetime.fromtimestamp(date_from),
  235. "date_to": datetime.fromtimestamp(date_to),
  236. "personal": self.personal_combobox.currentData(),
  237. "place": self.place_combobox.currentData(),
  238. "receiving_man": self.receiving_man.toPlainText(),
  239. "purpose_visite": self.purpose_visite.toPlainText(),
  240. "face": F"{Path(self.__file_name_face).name}",
  241. "document": F"{Path(self.__file_name_document).name}"
  242. }
  243. with connect() as conn:
  244. try:
  245. conn.execute(
  246. list_propusk.insert().values(**self.data_propusk)
  247. )
  248. show_dialog(QMessageBox.Icon.Information, '', translate('Save success'))
  249. except OperationalError as er:
  250. logger.error(er)
  251. show_dialog(QMessageBox.Icon.Critical, translate('Error'),
  252. 'An error occurred while saving! \n Please contact your administrator')
  253. def __set_default_data(self) -> None:
  254. self.number_propusk.clear()
  255. self.date_from.setDate(QDate().currentDate())
  256. self.date_to.setDate(QDate().currentDate())
  257. if self.__wwc is not None:
  258. self.__stop_cam()
  259. self.stacked_document.set_default_image()
  260. self.stacked_face.set_default_image()
  261. self.receiving_man.clear()
  262. self.purpose_visite.clear()
  263. def __stop_cam(self):
  264. if self.__wwc is not None:
  265. self.__wwc.stop_cam()
  266. self.__wwc = None
  267. self.btn_start_cam.setText(translate('Launch сamera'))
  268. def __create_widget_face_cam(self) -> None:
  269. if self.stacked_face is not None:
  270. self.gridLayout.removeWidget(self.stacked_face)
  271. self.stacked_face = create_widget_stacked(
  272. name_object=u'stacked_face',
  273. obj=self.tab,
  274. layout=self.gridLayout,
  275. mode=self.__mode)
  276. self.stacked_face.currentChanged.connect(
  277. self.__change_text_btn
  278. )
  279. def __change_text_btn(self) -> None:
  280. if self.stacked_face.currentIndex() == 0:
  281. self.btn_start_cam.setText(translate('Stop camera'))
  282. else:
  283. self.btn_start_cam.setText(translate('Launch сamera'))