changeset 3198:5a25b62eeebb

Task #15167: Add new server wizard
author Chris Zimmerman <chris@teffalump.com>
date Sat, 09 Feb 2019 21:09:58 -0800
parents f6f8e54213cd
children ed41e03a7cba
files tryton/health_orthanc/__init__.py tryton/health_orthanc/health_orthanc.py tryton/health_orthanc/health_orthanc_view.xml tryton/health_orthanc/view/add_orthanc_server.xml tryton/health_orthanc/view/add_orthanc_server_result.xml tryton/health_orthanc/view/config_form.xml tryton/health_orthanc/wizard/__init__.py tryton/health_orthanc/wizard/wizard.py
diffstat 8 files changed, 172 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/tryton/health_orthanc/__init__.py
+++ b/tryton/health_orthanc/__init__.py
@@ -21,13 +21,17 @@
 
 from trytond.pool import Pool
 from .health_orthanc import *
+from .wizard import *
 
 def register():
     Pool.register(
+        AddOrthancInit,
+        AddOrthancResult,
         OrthancServerConfig,
         OrthancStudy,
         OrthancPatient,
         Orthanc,
         module='health_orthanc', type_='model')
-    # Pool.register(
-        # module='health_orthanc', type_='wizard')
+    Pool.register(
+        FullSyncOrthanc,
+        module='health_orthanc', type_='wizard')
--- a/tryton/health_orthanc/health_orthanc.py
+++ b/tryton/health_orthanc/health_orthanc.py
@@ -59,7 +59,6 @@
                ]
        cls._buttons.update({
               'do_sync': {},
-              'do_full_sync': {},
               })
 
     @classmethod
@@ -68,11 +67,6 @@
         cls.sync(servers)
 
     @classmethod
-    @ModelView.button
-    def do_full_sync(cls, servers):
-        cls.full_sync(servers)
-
-    @classmethod
     def sync(cls, servers=None):
         """Sync from changes endpoint"""
 
@@ -119,44 +113,6 @@
             logger.info('{} sync complete: {} new patients, {} new studies'.format(server.label, len(new_patients), len(new_studies)))
         cls.save(servers)
 
-    @classmethod
-    def full_sync(cls, servers=None):
-        """Import and create all current patients and studies on remote DICOM server
-
-                 Used as first sync on adding new server
-        """
-
-        pool = Pool()
-        Patient = pool.get('gnuhealth.orthanc.patient')
-        Study = pool.get('gnuhealth.orthanc.study')
-
-        if not servers:
-            servers = cls.search([('domain', '!=', None),
-                                    ('validated', '=', True)])
-
-        for server in servers:
-            logger.info('Full sync for <{}>'.format(server.label))
-            orthanc = RestClient(server.domain, auth=auth(server.user, server.password))
-            try:
-                patients = [p for p in orthanc.get_patients(params={'expand': ''})]
-                studies = [s for s in orthanc.get_studies(params={'expand': ''})]
-            except HTTPError as err:
-                if err.response.status_code == 401:
-                    cls.raise_user_error("Invalid credentials for {}".format(server.label))
-                else:
-                    cls.raise_user_error("Invalid domain {}".format(server.domain))
-            except:
-                cls.raise_user_error("Invalid domain {}".format(server.domain))
-            else:
-                Patient.create_patients(patients, server)
-                Study.create_studies(studies, server)
-                server.last = orthanc.get_changes(last=True).get('Last')
-                server.sync_time = datetime.now()
-                server.validated = True
-                logger.info('<{}> sync complete: {} new patients, {} new studies'.format(server.label, len(patients), len(studies)))
-            finally:
-                pass
-        cls.save(servers)
 
     @staticmethod
     def quick_check(domain, user, password):
--- a/tryton/health_orthanc/health_orthanc_view.xml
+++ b/tryton/health_orthanc/health_orthanc_view.xml
@@ -83,5 +83,22 @@
             <field name="model">gnuhealth.patient,-1</field>
             <field name="action" ref="act_relate_orthanc_studies"/>
         </record>
+
+        <!-- Wizard and Views to add server -->
+        <record model="ir.ui.view" id="view_orthanc_add_init">
+            <field name="model">gnuhealth.orthanc.add.init</field>
+            <field name="type">form</field>
+            <field name="name">add_orthanc_server</field>
+        </record>
+        <record model="ir.ui.view" id="view_orthanc_add_result">
+            <field name="model">gnuhealth.orthanc.add.result</field>
+            <field name="type">form</field>
+            <field name="name">add_orthanc_server_result</field>
+        </record>
+        <record model="ir.action.wizard" id="orthanc_add_server_init">
+            <field name="name">Add Orthanc Server</field>
+            <field name="wiz_name">gnuhealth.orthanc.wizard.full_sync</field>
+        </record>
+        <menuitem parent="orthanc_config_menu" action="orthanc_add_server_init" id="orthanc_add_server_menu" sequence="10" icon="gnuhealth-execute"/>
     </data>
 </tryton>
new file mode 100644
--- /dev/null
+++ b/tryton/health_orthanc/view/add_orthanc_server.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<form>
+    <group string="Server information" yfill="1">
+        <label name="label"/>
+        <field name="label"/>
+        <label name="domain"/>
+        <field name="domain"/>
+    </group>
+    <group string="User credentials" yfill="1">
+        <label name="user"/>
+        <field name="user"/>
+        <label name="password"/>
+        <field name="password"/>
+    </group>
+</form>
new file mode 100644
--- /dev/null
+++ b/tryton/health_orthanc/view/add_orthanc_server_result.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<form>
+    <field name="result" readonly="1"/>
+</form>
--- a/tryton/health_orthanc/view/config_form.xml
+++ b/tryton/health_orthanc/view/config_form.xml
@@ -24,6 +24,4 @@
     </group>
     <newline/>
     <button name="do_sync" help="Synchronize from Orthanc server" string="Sync" icon="gnuhealth-execute" confirm="Synchronize?"/>
-    <newline/>
-    <button name="do_full_sync" help="Fully synchronize from Orthanc server" string="Full sync" icon="gnuhealth-execute" confirm="Synchronize?"/>
 </form>
new file mode 100644
--- /dev/null
+++ b/tryton/health_orthanc/wizard/__init__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    GNU Health: The Free Health and Hospital Information System
+#
+#
+#    This program 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.
+#
+#    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from .wizard import *
new file mode 100644
--- /dev/null
+++ b/tryton/health_orthanc/wizard/wizard.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    GNU Health: The Free Health and Hospital Information System
+#
+#
+#    This program 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.
+#
+#    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import logging
+from datetime import datetime
+from trytond.model import ModelView, fields
+from trytond.wizard import Wizard, StateTransition, StateView, Button
+from trytond.transaction import Transaction
+from trytond.pool import Pool
+from requests.auth import HTTPBasicAuth as auth
+from requests.exceptions import HTTPError, ConnectionError
+from orthanc_rest_client import Orthanc as RestClient
+
+logger = logging.getLogger(__name__)
+
+__all__ = ['AddOrthancInit', 'FullSyncOrthanc', 'AddOrthancResult']
+
+class AddOrthancInit(ModelView):
+    """Init Full Orthanc Sync"""
+    __name__ = 'gnuhealth.orthanc.add.init'
+
+    label = fields.Char('Label', required=True, help="The label of the Orthanc server. Must be unique")
+    domain = fields.Char('URL', required=True, help="The full URL of the Orthanc server")
+    user = fields.Char('Username', required=True, help="Username for Orthanc REST server")
+    password = fields.Char('Password', required=True, help="Password for Orthanc REST server")
+
+class AddOrthancResult(ModelView):
+    """Display Result"""
+    __name__ = 'gnuhealth.orthanc.add.result'
+
+    result = fields.Text('Result', help="Information")
+
+class FullSyncOrthanc(Wizard):
+    'Full sync new orthanc server'
+    __name__ = 'gnuhealth.orthanc.wizard.full_sync'
+
+    start = StateView('gnuhealth.orthanc.add.init', 'health_orthanc.view_orthanc_add_init',
+            [
+                Button('Cancel', 'end', 'tryton-cancel'),
+                Button('Begin', 'first_sync', 'tryton-ok', default=True),
+            ])
+
+    first_sync = StateTransition()
+    result = StateView('gnuhealth.orthanc.add.result', 'health_orthanc.view_orthanc_add_result',
+            [
+                Button('Close', 'end', 'tryton-close'),
+            ])
+
+    def transition_first_sync(self):
+        """Import and create all current patients and studies on remote DICOM server
+        """
+
+        pool = Pool()
+        Patient = pool.get('gnuhealth.orthanc.patient')
+        Study = pool.get('gnuhealth.orthanc.study')
+        Config = pool.get('gnuhealth.orthanc.config')
+
+        orthanc = RestClient(self.start.domain, auth=auth(self.start.user, self.start.password))
+        try:
+            patients = [p for p in orthanc.get_patients(params={'expand': ''})]
+            studies = [s for s in orthanc.get_studies(params={'expand': ''})]
+        except HTTPError as err:
+            if err.response.status_code == 401:
+                self.result.result = "Invalid credentials provided"
+            else:
+                self.result.result = "Invalid domain provided"
+        except:
+            self.result.result = "Invalid domain provided"
+        else:
+            new_server = {
+                    'label': self.start.label,
+                    'domain': self.start.domain,
+                    'user': self.start.user,
+                    'password': self.start.password
+                    }
+            server, = Config.create([new_server])
+            Patient.create_patients(patients, server)
+            Study.create_studies(studies, server)
+            server.last = orthanc.get_changes(last=True).get('Last')
+            server.sync_time = datetime.now()
+            server.validated = True
+            logger.info('<{}> sync complete: {} new patients, {} new studies'.format(server.label, len(patients), len(studies)))
+            Config.save([server])
+            self.result.result = "Successfully added and synced <{}>".format(server.label)
+        finally:
+            return 'result'
+
+    def default_result(self, fields):
+        return {
+                'result': self.result.result
+                }