]> Softwares of Agnibho - medscript.git/commitdiff
Added package installer.
authorAgnibho Mondal <mondal@agnibho.com>
Tue, 7 Nov 2023 18:57:49 +0000 (00:27 +0530)
committerAgnibho Mondal <mondal@agnibho.com>
Tue, 7 Nov 2023 20:11:15 +0000 (01:41 +0530)
installer.py [new file with mode: 0644]
window.py

diff --git a/installer.py b/installer.py
new file mode 100644 (file)
index 0000000..6134115
--- /dev/null
@@ -0,0 +1,171 @@
+# MedScript
+# Copyright (C) 2023 Dr. Agnibho Mondal
+# This file is part of MedScript.
+# 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.
+# 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.
+# You should have received a copy of the GNU General Public License along with MedScript. If not, see <https://www.gnu.org/licenses/>.
+
+from PyQt6.QtWidgets import QWidget, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QListWidget, QMessageBox, QFileDialog
+from PyQt6.QtGui import QIcon, QStandardItemModel, QStandardItem
+from glob import glob
+from zipfile import ZipFile
+from config import config
+import logging, os, tempfile, shutil
+
+class Installer(QMainWindow):
+
+    preset={"name":[], "path":[]}
+    template={"name":[], "path":[]}
+    form={"name":[], "path":[]}
+    plugin={"name":[], "path":[]}
+
+    protected=["note", "report", "advice", "investigation", "medication", "additional", "certificate", "default", "medcert"]
+    directory=None
+
+    def cmd_install(self):
+        try:
+            file=QFileDialog.getOpenFileName(self, "Open Package", config["data_directory"], "Zip (*.zip);; All Files (*)")[0]
+            self.directory=tempfile.TemporaryDirectory()
+            with ZipFile(file, "r", strict_timestamps=False) as package:
+                package.extractall(self.directory.name)
+            for i in glob(os.path.join(self.directory.name, "preset", "*.csv")):
+                name=os.path.splitext(os.path.basename(i))[0]
+                if name not in self.protected:
+                    if name not in self.preset["name"]:
+                        if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm install", "Installing PRESET <strong>"+name+"</strong>. Continue?")):
+                            self.copy(i, config["preset_directory"])
+                    else:
+                        QMessageBox.information(self, "File exists", "PRESET <strong>"+name+"</strong> is already installed.")
+            for i in glob(os.path.join(self.directory.name, "template", "*")):
+                if os.path.exists(os.path.join(i, "index.html")):
+                    name=os.path.basename(i)
+                    if name not in self.protected:
+                        if name not in self.template["name"]:
+                            if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm install", "Installing TEMPLATE <strong>"+name+"</strong>. Continue?")):
+                                self.copy(i, os.path.join(config["template_directory"], name))
+                        else:
+                            QMessageBox.information(self, "File exists", "TEMPLATE <strong>"+name+"</strong> is already installed.")
+            for i in glob(os.path.join(self.directory.name, "form", "*.json")):
+                name=os.path.splitext(os.path.basename(i))[0]
+                if name not in self.protected:
+                    if name not in self.form["name"]:
+                        if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm install", "Installing FORM <strong>"+name+"</strong>. Continue?")):
+                            self.copy(i, config["form_directory"])
+                    else:
+                        QMessageBox.information(self, "File exists", "FORM <strong>"+name+"</strong> is already installed.")
+            for i in glob(os.path.join(self.directory.name, "plugin", "*")):
+                if os.path.exists(os.path.join(i, "main.py")):
+                    name=os.path.basename(i)
+                    if name not in self.protected:
+                        if name not in self.plugin["name"]:
+                            if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm install", "Installing PLUGIN <strong>"+name+"</strong>. Continue?")):
+                                self.copy(i, os.path.join(config["plugin_directory"], name))
+                        else:
+                            QMessageBox.information(self, "File exists", "PLUGIN <strong>"+name+"</strong> is already installed.")
+            QMessageBox.information(self, "Restart", "Please restart MedScript for the changes to take effect.")
+        except Exception as e:
+            logging.warning(e)
+
+    def cmd_uninstall(self):
+        txt=self.installed.currentItem().text().split("\t")
+        name=txt[1]
+        group=txt[0].replace("[", "").replace("]", "")
+        if name not in self.protected:
+            if(group=="preset"):
+                if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm uninstall", "Uninstalling PRESET <strong>"+name+"</strong>. Continue?")):
+                    idx=self.preset["name"].index(name)
+                    path=self.preset["path"][idx]
+                    self.delete(path)
+            elif(group=="template"):
+                if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm uninstall", "Uninstalling TEMPLATE <strong>"+name+"</strong>. Continue?")):
+                    idx=self.template["name"].index(name)
+                    path=self.template["path"][idx]
+                    self.delete(path)
+            elif(group=="form"):
+                if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm uninstall", "Uninstalling FORM <strong>"+name+"</strong>. Continue?")):
+                    idx=self.form["name"].index(name)
+                    path=self.form["path"][idx]
+                    self.delete(path)
+            elif(group=="plugin"):
+                if(QMessageBox.StandardButton.Yes==QMessageBox.question(self, "Confirm uninstall", "Uninstalling PLUGIN <strong>"+name+"</strong>. Continue?")):
+                    idx=self.plugin["name"].index(name)
+                    path=self.plugin["path"][idx]
+                    self.delete(path)
+            QMessageBox.information(self, "Restart", "Please restart MedScript for the changes to take effect.")
+        else:
+            QMessageBox.information(self, "Item protected", "Protected items cannot be deleted.")
+
+    def delete(self, path):
+        try:
+            os.unlink(path)
+        except IsADirectoryError:
+            shutil.rmtree(path)
+        except Exception as e:
+            logging.critical(e)
+        self.load()
+
+    def copy(self, path, destination):
+        try:
+            shutil.copytree(path, destination)
+        except NotADirectoryError:
+            shutil.copy(path, destination)
+        except Exception as e:
+            logging.critical(e)
+        self.load()
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.setWindowTitle("MedScript")
+        self.setGeometry(200, 200, 600, 400)
+
+        widget=QWidget(self)
+        layout=QVBoxLayout(widget)
+        self.installed=QListWidget()
+        layout.addWidget(self.installed)
+        layout2=QHBoxLayout()
+        button_install=QPushButton("Install")
+        button_install.clicked.connect(self.cmd_install)
+        button_uninstall=QPushButton("Uninstall")
+        button_uninstall.clicked.connect(self.cmd_uninstall)
+        layout2.addWidget(button_install)
+        layout2.addWidget(button_uninstall)
+        layout.addLayout(layout2)
+
+        self.setCentralWidget(widget)
+        self.setWindowIcon(QIcon(os.path.join("resource", "icon_medscript.ico")))
+
+        self.load()
+
+    def load(self, file=None):
+        self.preset={"name":[], "path":[]}
+        self.template={"name":[], "path":[]}
+        self.form={"name":[], "path":[]}
+        self.plugin={"name":[], "path":[]}
+        self.installed.clear()
+        try:
+            for i in glob(os.path.join(config["preset_directory"], "*.csv")):
+                self.preset["name"].append(os.path.splitext(os.path.basename(i))[0])
+                self.preset["path"].append(i)
+            for i in glob(os.path.join(config["template_directory"], "*")):
+                if(os.path.exists(os.path.join(i, "index.html"))):
+                   self.template["name"].append(os.path.basename(i))
+                   self.template["path"].append(i)
+            for i in glob(os.path.join(config["form_directory"], "*.json")):
+                self.form["name"].append(os.path.splitext(os.path.basename(i))[0])
+                self.form["path"].append(i)
+            for i in glob(os.path.join(config["plugin_directory"], "*")):
+                if(os.path.exists(os.path.join(i, "main.py"))):
+                   self.plugin["name"].append(os.path.basename(i))
+                   self.plugin["path"].append(i)
+
+            for i in self.preset["name"]:
+                self.installed.addItem("[preset]\t"+i)
+            for i in self.template["name"]:
+                self.installed.addItem("[template]\t"+i)
+            for i in self.form["name"]:
+                self.installed.addItem("[form]\t"+i)
+            for i in self.plugin["name"]:
+                self.installed.addItem("[plugin]\t"+i)
+        except Exception as e:
+            logging.warning(e)
index f308b1bd046ad2244701153ae56c4702cf24b5d4..2cc3f59386aca3628b8d142d572149123712ee10 100644 (file)
--- a/window.py
+++ b/window.py
@@ -28,6 +28,7 @@ from tabular import Tabular
 from index import Index
 from customform import CustomForm
 from plugin import Plugin
+from installer import Installer
 
 class MainWindow(QMainWindow):
 
@@ -222,6 +223,9 @@ class MainWindow(QMainWindow):
     def cmd_preset(self):
         self.edit_preset.show()
 
+    def cmd_installer(self):
+        self.installer.show()
+
     def cmd_about(self):
         year=datetime.datetime.now().year
         if(year>2023):
@@ -566,6 +570,8 @@ class MainWindow(QMainWindow):
         action_switch.triggered.connect(self.cmd_switch)
         action_preset=QAction("Preset", self)
         action_preset.triggered.connect(self.cmd_preset)
+        action_installer=QAction("Installer", self)
+        action_installer.triggered.connect(self.cmd_installer)
         action_tabular=QAction("Tabular", self)
         action_tabular.triggered.connect(self.cmd_tabular)
         action_index=QAction("Index", self)
@@ -597,6 +603,7 @@ class MainWindow(QMainWindow):
         menu_settings.addAction(action_prescriber)
         menu_settings.addAction(action_switch)
         menu_settings.addAction(action_preset)
+        menu_settings.addAction(action_installer)
         menu_data=menubar.addMenu("Data")
         menu_data.addAction(action_index)
         menu_data.addAction(action_tabular)
@@ -898,6 +905,7 @@ class MainWindow(QMainWindow):
         self.viewbox=ViewBox()
         self.index=Index()
         self.edit_preset=EditPreset()
+        self.installer=Installer()
         self.index.signal_open.connect(self.cmd_open)
         self.index.signal_copy.connect(self.cmd_copy)
         self.signal_update.connect(self.show_update)