]>
Softwares of Agnibho - medscript.git/blob - index.py
2 # Copyright (C) 2023 Dr. Agnibho Mondal
3 # This file is part of MedScript.
4 # MedScript is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5 # MedScript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6 # You should have received a copy of the GNU General Public License along with MedScript. If not, see <https://www.gnu.org/licenses/>.
8 from PyQt6
. QtWidgets
import QWidget
, QMainWindow
, QFormLayout
, QVBoxLayout
, QHBoxLayout
, QPushButton
, QLineEdit
, QTableView
, QAbstractItemView
, QFileDialog
9 from PyQt6
. QtGui
import QIcon
, QStandardItemModel
, QStandardItem
10 from PyQt6
. QtCore
import Qt
, pyqtSignal
, QSortFilterProxyModel
, QThread
12 from zipfile
import ZipFile
13 from watchdog
. observers
import Observer
14 from watchdog
. events
import FileSystemEventHandler
15 from config
import config
16 from renderbox
import UnrenderBox
17 import logging
, os
, json
19 class Index ( QMainWindow
):
21 signal_open
= pyqtSignal ( str )
22 signal_copy
= pyqtSignal ( dict )
24 proxymodel
= QSortFilterProxyModel ()
26 def __init__ ( self
, * args
, ** kwargs
):
27 super () .__ init
__ (* args
, ** kwargs
)
29 self
. setWindowTitle ( "MedScript Index" )
30 self
. setGeometry ( 200 , 200 , 600 , 400 )
33 layout
= QVBoxLayout ( widget
)
34 self
. table
= QTableView ()
35 self
. table
. setSortingEnabled ( True )
36 self
. table
. setSelectionBehavior ( QAbstractItemView
. SelectionBehavior
. SelectRows
)
37 self
. table
. setSelectionMode ( QAbstractItemView
. SelectionMode
. SingleSelection
)
38 self
. table
. setEditTriggers ( QAbstractItemView
. EditTrigger
. NoEditTriggers
)
39 self
. table
. doubleClicked
. connect ( self
. cmd_view
)
41 self
. input_pid
= QLineEdit ()
42 self
. input_pid
. returnPressed
. connect ( self
. cmd_filter_pid
)
43 self
. input_id
= QLineEdit ()
44 self
. input_id
. returnPressed
. connect ( self
. cmd_filter_id
)
45 self
. input_name
= QLineEdit ()
46 self
. input_name
. returnPressed
. connect ( self
. cmd_filter_name
)
47 layout2
. addRow ( "Filter by PID:" , self
. input_pid
)
48 layout2
. addRow ( "Filter by ID:" , self
. input_id
)
49 layout2
. addRow ( "Filter by Name:" , self
. input_name
)
51 button_view
= QPushButton ( "View Prescription" )
52 button_view
. clicked
. connect ( self
. cmd_view
)
53 button_open
= QPushButton ( "Open Original" )
54 button_open
. clicked
. connect ( self
. cmd_open
)
55 button_copy
= QPushButton ( "Create Copy" )
56 button_copy
. clicked
. connect ( self
. cmd_copy
)
57 button_rebuild
= QPushButton ( "Rebuild Index" )
58 button_rebuild
. clicked
. connect ( self
. cmd_rebuild
)
59 button_browse
= QPushButton ( "File Browser" )
60 button_browse
. clicked
. connect ( self
. cmd_browse
)
61 layout3
. addWidget ( button_view
)
62 layout3
. addWidget ( button_open
)
63 layout3
. addWidget ( button_copy
)
64 layout3
. addWidget ( button_rebuild
)
65 layout3
. addWidget ( button_browse
)
66 layout
. addLayout ( layout2
)
67 layout
. addLayout ( layout3
)
68 layout
. addWidget ( self
. table
)
70 self
. unrenderbox
= UnrenderBox ()
73 self
. worker
. signal_update
. connect ( self
. update
)
76 self
. setCentralWidget ( widget
)
77 self
. setWindowIcon ( QIcon ( os
. path
. join ( "resource" , "icon_medscript.ico" )))
82 def update ( self
, event_type
, src_path
):
83 if ( src_path
. endswith ( ".mpaz" )):
84 if ( event_type
== "created" ):
86 elif ( event_type
== "modified" ):
88 elif ( event_type
== "deleted" ):
92 def cmd_rebuild ( self
):
96 def cmd_filter_pid ( self
):
97 self
. input_id
. setText ( "" )
98 self
. input_name
. setText ( "" )
99 self
. proxymodel
. setFilterKeyColumn ( 0 )
100 self
. proxymodel
. setFilterFixedString ( self
. input_pid
. text ())
102 def cmd_filter_id ( self
):
103 self
. input_pid
. setText ( "" )
104 self
. input_name
. setText ( "" )
105 self
. proxymodel
. setFilterKeyColumn ( 1 )
106 self
. proxymodel
. setFilterFixedString ( self
. input_id
. text ())
108 def cmd_filter_name ( self
):
109 self
. input_pid
. setText ( "" )
110 self
. input_id
. setText ( "" )
111 self
. proxymodel
. setFilterKeyColumn ( 2 )
112 self
. proxymodel
. setFilterFixedString ( self
. input_name
. text ())
116 file = self
. getSelectedFile ()
118 with
ZipFile ( file ) as zf
:
119 with zf
. open ( "prescription.json" ) as pf
:
120 prescription
= json
. loads ( pf
. read ())
121 self
. unrenderbox
. show ( prescription
). exec ()
122 except Exception as e
:
127 file = self
. getSelectedFile ()
129 self
. signal_open
. emit ( file )
131 except Exception as e
:
136 file = self
. getSelectedFile ()
138 with
ZipFile ( file ) as zf
:
139 with zf
. open ( "prescription.json" ) as pf
:
140 pres
= json
. loads ( pf
. read ())
141 self
. signal_copy
. emit ( pres
)
143 except Exception as e
:
146 def cmd_browse ( self
):
148 file = QFileDialog
. getOpenFileName ( self
, "Browse" , config
[ "document_directory" ], "Prescriptions (*.mpaz);; PDF (*.pdf);; All Files (*)" )[ 0 ]
150 with
ZipFile ( file ) as zf
:
151 with zf
. open ( "prescription.json" ) as pf
:
152 prescription
= json
. loads ( pf
. read ())
153 self
. unrenderbox
. show ( prescription
). exec ()
154 except Exception as e
:
157 def getSelectedFile ( self
):
159 selection
= self
. table
. selectedIndexes ()
160 file = selection
[- 1 ]. data ()
162 except IndexError as e
:
164 except Exception as e
:
169 files
= glob ( os
. path
. join ( config
[ "document_directory" ], "**" , "*.mpaz" ), recursive
= True )
173 except Exception as e
:
178 with
ZipFile ( file ) as zf
:
180 with zf
. open ( "prescription.json" ) as pf
:
181 pres
= json
. loads ( pf
. read ())
182 self
. index
[ file ]=[ pres
[ "pid" ], pres
[ "id" ], pres
[ "name" ], pres
[ "dob" ], pres
[ "age" ], pres
[ "sex" ], pres
[ "date" ], pres
[ "diagnosis" ], file ]
183 except KeyError as e
:
185 except Exception as e
:
187 except Exception as e
:
190 def delete ( self
, file ):
193 except KeyError as e
:
195 except Exception as e
:
198 def change ( self
, file ):
203 model
= QStandardItemModel ()
204 model
. setHorizontalHeaderLabels ([ "Patient ID" , "Prescription ID" , "Name" , "Date of Birth" , "Age" , "Sex" , "Date" , "Diagnosis" , "File" ])
205 for key
, item
in self
. index
. items ():
208 row
. append ( QStandardItem ( i
))
210 self
. proxymodel
. setSourceModel ( model
)
211 self
. proxymodel
. setFilterCaseSensitivity ( Qt
. CaseSensitivity
. CaseInsensitive
)
212 self
. table
. setModel ( self
. proxymodel
)
213 self
. table
. resizeColumnsToContents ()
215 class WatchHandler ( FileSystemEventHandler
):
216 def __init__ ( self
, signal
):
219 def on_any_event ( self
, event
):
220 if not event
. is_directory
:
221 self
. signal
. emit ( event
. event_type
, event
. src_path
)
223 class Worker ( QThread
):
224 signal_update
= pyqtSignal ( str , str )
226 self
. watchHandler
= WatchHandler ( self
. signal_update
)
227 self
. observer
= Observer ()
228 self
. observer
. schedule ( self
. watchHandler
, path
= config
[ "document_directory" ], recursive
= True )
229 self
. observer
. start ()