]>
Softwares of Agnibho - medscript.git/blob - installer.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
, QVBoxLayout
, QHBoxLayout
, QPushButton
, QListWidget
, QMessageBox
, QFileDialog
9 from PyQt6
. QtGui
import QIcon
, QStandardItemModel
, QStandardItem
11 from zipfile
import ZipFile
12 from config
import config
13 import logging
, os
, tempfile
, shutil
15 class Installer ( QMainWindow
):
17 preset
={ "name" :[], "path" :[]}
18 template
={ "name" :[], "path" :[]}
19 form
={ "name" :[], "path" :[]}
20 plugin
={ "name" :[], "path" :[]}
22 protected
=[ "note" , "report" , "advice" , "investigation" , "medication" , "additional" , "certificate" , "default" , "medcert" , "<unchanged>" ]
25 def cmd_install ( self
):
27 file = QFileDialog
. getOpenFileName ( self
, "Open Package" , config
[ "data_directory" ], "Zip (*.zip);; All Files (*)" )[ 0 ]
28 self
. directory
= tempfile
. TemporaryDirectory ()
29 with
ZipFile ( file , "r" , strict_timestamps
= False ) as package
:
30 package
. extractall ( self
. directory
. name
)
31 for i
in glob ( os
. path
. join ( self
. directory
. name
, "preset" , "*.csv" )):
32 name
= os
. path
. splitext ( os
. path
. basename ( i
))[ 0 ]
33 if name
not in self
. protected
:
34 if name
not in self
. preset
[ "name" ]:
35 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm install" , "Installing PRESET <strong>" + name
+ "</strong>. Continue?" )):
36 self
. copy ( i
, config
[ "preset_directory" ])
38 QMessageBox
. information ( self
, "File exists" , "PRESET <strong>" + name
+ "</strong> is already installed." )
39 for i
in glob ( os
. path
. join ( self
. directory
. name
, "template" , "*" )):
40 if os
. path
. exists ( os
. path
. join ( i
, "index.html" )):
41 name
= os
. path
. basename ( i
)
42 if name
not in self
. protected
:
43 if name
not in self
. template
[ "name" ]:
44 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm install" , "Installing TEMPLATE <strong>" + name
+ "</strong>. Continue?" )):
45 self
. copy ( i
, os
. path
. join ( config
[ "template_directory" ], name
))
47 QMessageBox
. information ( self
, "File exists" , "TEMPLATE <strong>" + name
+ "</strong> is already installed." )
48 for i
in glob ( os
. path
. join ( self
. directory
. name
, "form" , "*.json" )):
49 name
= os
. path
. splitext ( os
. path
. basename ( i
))[ 0 ]
50 if name
not in self
. protected
:
51 if name
not in self
. form
[ "name" ]:
52 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm install" , "Installing FORM <strong>" + name
+ "</strong>. Continue?" )):
53 self
. copy ( i
, config
[ "form_directory" ])
55 QMessageBox
. information ( self
, "File exists" , "FORM <strong>" + name
+ "</strong> is already installed." )
56 for i
in glob ( os
. path
. join ( self
. directory
. name
, "plugin" , "*" )):
57 if os
. path
. exists ( os
. path
. join ( i
, "main.py" )):
58 name
= os
. path
. basename ( i
)
59 if name
not in self
. protected
:
60 if name
not in self
. plugin
[ "name" ]:
61 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm install" , "Installing PLUGIN <strong>" + name
+ "</strong>. Continue?" )):
62 self
. copy ( i
, os
. path
. join ( config
[ "plugin_directory" ], name
))
64 QMessageBox
. information ( self
, "File exists" , "PLUGIN <strong>" + name
+ "</strong> is already installed." )
65 QMessageBox
. information ( self
, "Restart" , "Please restart MedScript for the changes to take effect." )
66 except Exception as e
:
69 def cmd_uninstall ( self
):
70 txt
= self
. installed
. currentItem (). text (). split ( " \t " )
72 group
= txt
[ 0 ]. replace ( "[" , "" ). replace ( "]" , "" )
73 if name
not in self
. protected
:
75 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm uninstall" , "Uninstalling PRESET <strong>" + name
+ "</strong>. Continue?" )):
76 idx
= self
. preset
[ "name" ]. index ( name
)
77 path
= self
. preset
[ "path" ][ idx
]
79 elif ( group
== "template" ):
80 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm uninstall" , "Uninstalling TEMPLATE <strong>" + name
+ "</strong>. Continue?" )):
81 idx
= self
. template
[ "name" ]. index ( name
)
82 path
= self
. template
[ "path" ][ idx
]
85 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm uninstall" , "Uninstalling FORM <strong>" + name
+ "</strong>. Continue?" )):
86 idx
= self
. form
[ "name" ]. index ( name
)
87 path
= self
. form
[ "path" ][ idx
]
89 elif ( group
== "plugin" ):
90 if ( QMessageBox
. StandardButton
. Yes
== QMessageBox
. question ( self
, "Confirm uninstall" , "Uninstalling PLUGIN <strong>" + name
+ "</strong>. Continue?" )):
91 idx
= self
. plugin
[ "name" ]. index ( name
)
92 path
= self
. plugin
[ "path" ][ idx
]
94 QMessageBox
. information ( self
, "Restart" , "Please restart MedScript for the changes to take effect." )
96 QMessageBox
. information ( self
, "Item protected" , "Protected items cannot be deleted." )
98 def delete ( self
, path
):
101 except ( IsADirectoryError
, PermissionError
):
103 except Exception as e
:
104 QMessageBox
. critical ( self
, "Failed" , "Uninstallation failed. Please manually delete package." )
108 def copy ( self
, path
, destination
):
110 shutil
. copytree ( path
, destination
)
111 except NotADirectoryError
:
112 shutil
. copy ( path
, destination
)
113 except Exception as e
:
117 def __init__ ( self
, * args
, ** kwargs
):
118 super () .__ init
__ (* args
, ** kwargs
)
120 self
. setWindowTitle ( "MedScript Package Installer" )
121 self
. setGeometry ( 200 , 200 , 600 , 400 )
124 layout
= QVBoxLayout ( widget
)
125 self
. installed
= QListWidget ()
126 layout
. addWidget ( self
. installed
)
127 layout2
= QHBoxLayout ()
128 button_install
= QPushButton ( "Install" )
129 button_install
. clicked
. connect ( self
. cmd_install
)
130 button_uninstall
= QPushButton ( "Uninstall" )
131 button_uninstall
. clicked
. connect ( self
. cmd_uninstall
)
132 layout2
. addWidget ( button_install
)
133 layout2
. addWidget ( button_uninstall
)
134 layout
. addLayout ( layout2
)
136 self
. setCentralWidget ( widget
)
137 self
. setWindowIcon ( QIcon ( os
. path
. join ( "resource" , "icon_medscript.ico" )))
141 def load ( self
, file = None ):
142 self
. preset
={ "name" :[], "path" :[]}
143 self
. template
={ "name" :[], "path" :[]}
144 self
. form
={ "name" :[], "path" :[]}
145 self
. plugin
={ "name" :[], "path" :[]}
146 self
. installed
. clear ()
148 for i
in glob ( os
. path
. join ( config
[ "preset_directory" ], "*.csv" )):
149 self
. preset
[ "name" ]. append ( os
. path
. splitext ( os
. path
. basename ( i
))[ 0 ])
150 self
. preset
[ "path" ]. append ( i
)
151 for i
in glob ( os
. path
. join ( config
[ "template_directory" ], "*" )):
152 if ( os
. path
. exists ( os
. path
. join ( i
, "index.html" ))):
153 self
. template
[ "name" ]. append ( os
. path
. basename ( i
))
154 self
. template
[ "path" ]. append ( i
)
155 for i
in glob ( os
. path
. join ( config
[ "form_directory" ], "*.json" )):
156 self
. form
[ "name" ]. append ( os
. path
. splitext ( os
. path
. basename ( i
))[ 0 ])
157 self
. form
[ "path" ]. append ( i
)
158 for i
in glob ( os
. path
. join ( config
[ "plugin_directory" ], "*" )):
159 if ( os
. path
. exists ( os
. path
. join ( i
, "main.py" ))):
160 self
. plugin
[ "name" ]. append ( os
. path
. basename ( i
))
161 self
. plugin
[ "path" ]. append ( i
)
163 for i
in self
. preset
[ "name" ]:
164 if i
not in self
. protected
:
165 self
. installed
. addItem ( "[preset] \t " + i
)
166 for i
in self
. template
[ "name" ]:
167 if i
not in self
. protected
:
168 self
. installed
. addItem ( "[template] \t " + i
)
169 for i
in self
. form
[ "name" ]:
170 if i
not in self
. protected
:
171 self
. installed
. addItem ( "[form] \t " + i
)
172 for i
in self
. plugin
[ "name" ]:
173 if i
not in self
. protected
:
174 self
. installed
. addItem ( "[plugin] \t " + i
)
175 except Exception as e
: