Skip to content
main_controller.py 13.4 KiB
Newer Older
"""

:Author: Franziska Koehn
:Created: 2015/01/13

Franziska Koehn's avatar
Franziska Koehn committed
This module contains the controller that provides the communication between views.
import gtk
import gobject

class QueryController(gobject.GObject):
Franziska Koehn's avatar
Franziska Koehn committed
    """Provides communication between different views."""
    _host = ""
    _user = ""
    _passw = ""
    _root = ""
    _query = []
    _labels = []

    @property
    def root(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """Root-Type of search"""
        return self._root

    @root.setter
    def root(self, new_root):
        self._root = new_root

    @property
    def labels(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """Fields of search (label of fields)"""
        return self._labels

    @labels.setter
    def labels(self, new_labels):
        self._labels = new_labels

    @property
    def query(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """List including constraints of query."""
        return self._query

    @query.setter
    def query(self, new_query):
        self._query = new_query

    @property
    def host(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """Host-address"""
        return self._host

    @host.setter
    def host(self, new_host):
        self._host = new_host

    @property
    def credentials_tuple(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """Credentials as tuple (user-name, password)"""
        return (self._user, self._passw)

    @credentials_tuple.setter
    def credentials_tuple(self, creds):
        self._user, self._passw = creds

    @property
    def credentials(self):
Franziska Koehn's avatar
Franziska Koehn committed
        """Credentials as http-auth-string (user-name:password)"""
        return "%s:%s" % self.credentials_tuple

    @credentials.setter
    def credentials(self, new_creds):
        self._user, _, self._passw = new_creds.partition(":")

    def send_query(self, *_):
Franziska Koehn's avatar
Franziska Koehn committed
        """Sends defined query to server, using xsa.queries

        **Parameters are ignored**
        """

        def on_search_query(host, credentials, root_type, query, fields):
            user, passw = credentials

            import xsa.queries as queries
Franziska Koehn's avatar
Franziska Koehn committed
            import xsa.errors
            if passw =='' or user=='' or host=='':
                md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
                                        buttons=gtk.BUTTONS_OK,
                                        message_format="Please set your Password, User-Name and Host-Address (Button 'Server Settings')."
                                        )
                md.run()
                md.destroy()
                return
            if query==[]:
                md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
                                        buttons=gtk.BUTTONS_OK,
                                        message_format="Please define a Query."
                                        )
                md.run()
                md.destroy()
                return

            try:
                query_results = queries.search_for( host,
                                                    root_type,
                                                    query,
                                                    fields,
                                                    user,
                                                    passw
                                                    )
Franziska Koehn's avatar
Franziska Koehn committed
            except xsa.errors.Error as e:
                md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
                                        buttons=gtk.BUTTONS_OK,
                                        message_format=str(e)
                                        )
                md.run()
                md.destroy()
                self.results = []
                md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
                                        buttons=gtk.BUTTONS_OK,
                                        message_format="An unexpected Error occured:"
                md.run()
                md.destroy()
                self.results = []
            else:
                self.results = query_results

            self.resultsview.show_data(self.results, root_type)
            self.statusbar.push(0, "%s Results"%len(self.results))
            self.chartview.update_chart_view(self.results, root_type)
        self.root=self.queryview.get_root_type()
        self.query=self.queryview.get_query()
        self.labels=self.queryview.get_fields()
        import xsa.datatypereader as type_reader
        fields = type_reader.get_fields_from_labels(self.labels,self.root)
        on_search_query(self.host,                             self.credentials_tuple,
                                self.root,
                                self.query,
                                fields)


    def __init__(self, main, queryview, menuview, chartview, resultsview, comparison_view, statusbar):
Franziska Koehn's avatar
Franziska Koehn committed
        Connects signals to views. Contains definitions for callbacks of toolbar-buttons.

        **Parameters**
            :main: gtk.Window, main-window
Franziska Koehn's avatar
Franziska Koehn committed
            :queryview: a gtk.Container, View for creating queries
            :menuview: a gtk.Container, View for Menu/Toolbar
            :chartview: a gtk.Container, View including all widgets for the chart
            :resultsview: a gtk.Container, View for showing the results of the search
            :statusbar: a gtk.Container, Statusbar
        super(QueryController, self).__init__()
        self.main = main
        self.queryview = queryview
        self.menuview = menuview
        self.chartview = chartview
        self.resultsview = resultsview
        self.comparison_view = comparison_view
        def callback_define_comparison(*_):
            dialog = gtk.Dialog("Define Comparison", None, 0,
                    (gtk.STOCK_OK, gtk.RESPONSE_OK, "Cancel", gtk.RESPONSE_CANCEL))
            dialog.set_resizable(True)
            dialog.set_size_request(900, 500)

            from xsagtk.comparison_dialog_view import ComparisonDialogView
            compdialog = ComparisonDialogView(self.root, self.results, self.host, self.credentials_tuple)
            dialog.vbox.pack_start(compdialog, True, True, 0)

            dialog.show_all()
            response = dialog.run()
            if response == gtk.RESPONSE_OK:
                table = compdialog.create_comparison_table()
                self.comparison_view.show_comparison(self.root, table)
            dialog.destroy()

        def callback_edit_Server_Settings(*_):
            dialog = gtk.Dialog(    "Server Settings",
                                    None, 0,
                                    (   gtk.STOCK_OK, gtk.RESPONSE_OK,
                                        "Cancel", gtk.RESPONSE_CANCEL)
                                    )
            dialog.set_resizable(False)
            dialog.set_size_request(330, 180)
            hbox = gtk.HBox(False, 8)
            hbox.set_border_width(8)
            dialog.vbox.pack_start(hbox, True, True, 0)

            stock = gtk.image_new_from_stock(
                    gtk.STOCK_DIALOG_AUTHENTICATION,
                    gtk.ICON_SIZE_DIALOG)
            hbox.pack_start(stock, False, False, 0)

            table = gtk.Table(2, 3)
            table.set_row_spacings(4)
            table.set_col_spacings(4)
            hbox.pack_start(table, True, True, 0)

            label_user =  gtk.Label()
            label_user.set_text("User:")
            table.attach(label_user, 0, 1, 0, 1)

            entry_user = gtk.Entry()
            entry_user.set_text(self.credentials_tuple[0])
            table.attach(entry_user, 1, 2, 0, 1)

            label_passw =  gtk.Label()
            label_passw.set_text("Password:")
            table.attach(label_passw, 0, 1, 1, 2)

            entry_passw = gtk.Entry()
            entry_passw.set_visibility(False)
            entry_passw.set_text(self.credentials_tuple[1])
            table.attach(entry_passw, 1, 2, 1, 2)

            label_host =  gtk.Label()
            label_host.set_text("Host:")
            table.attach(label_host, 0, 1, 2, 3)

            entry_host = gtk.Entry()
            entry_host.set_text(self.host)
            table.attach(entry_host, 1, 2, 2, 3)

            dialog.show_all()
            response = dialog.run()

            if response == gtk.RESPONSE_OK:
                self.credentials_tuple = (entry_user.get_text(),entry_passw.get_text())
                self.host = entry_host.get_text()
                import xsa.queries
                try:
                    xsa.queries.get_xnat_server_connection(force=True, host=self.host, user=self.credentials_tuple[0], passw=self.credentials_tuple[1])
                except Exception as e:
                    md = gtk.MessageDialog( type=gtk.MESSAGE_WARNING,
                                            buttons=gtk.BUTTONS_OK,
                                            message_format=str(e)
                                            )
                    md.run()
                    md.destroy()
        def event_clicked_toggle_selection(*_):
            self.resultsview.toggle_selection()

        def event_clicked_download(*_):

            if self.resultsview.get_selected_items() == []:
                return

            import xsa.queries as queries
            import xsa.datatypereader as type_reader

            dialog = gtk.FileChooserDialog( "Open..",
                                            None,
                                            gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)

            response = dialog.run()
            if response == gtk.RESPONSE_OK:
                rest = type_reader.get_rest(self.root)
                enabled = (d for d in self.resultsview.get_store() if d[0])
                for d in enabled:
                    def stop_spinner(_row):
                        _row[2] = False # Hide spinner
                        _row[0] = False # Checkbox to false
                    d[3] = 0
                    d[2] = True # Show Spinner
                    queries.download_async( d[1],
                                            self.host,
                                            self.credentials_tuple,
                                            rest,
                                            dialog.get_filename(),
                                            cb=stop_spinner,
                                            cb_args=(d,)
                                            )
            dialog.destroy()

        def disable_download_button(_, is_enable, text):
            self.menuview.disable_download_button(is_enable, text)
        def disable_adddata_button(_, is_enable, text):
            self.menuview.disable_adddata_button(is_enable, text)

        root_key = 'root'
        query_key = 'query'
        labels_key = 'labels'

        def save_query(*_):
Franziska Koehn's avatar
Franziska Koehn committed
            self.root = self.queryview.get_root_type()
            self.query = self.queryview.get_query()
            self.labels = self.queryview.get_fields()

            data = {}
            data.update({root_key: self.root})
            data.update({query_key: self.query})
            data.update({labels_key: self.labels})

            dialog = gtk.FileChooserDialog( "Save as..",
                                            None,
                                            gtk.FILE_CHOOSER_ACTION_SAVE,
                                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)
            response = dialog.run()

            if response == gtk.RESPONSE_OK:
                with open(dialog.get_filename(),'w') as file:
                    file_data = json.dumps(data)
                    file.write(file_data)

            dialog.destroy()

        def load_query(*_):
            dialog = gtk.FileChooserDialog( "Load..",
                                            None,
                                            gtk.FILE_CHOOSER_ACTION_OPEN,
                                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
            dialog.set_default_response(gtk.RESPONSE_OK)
            response = dialog.run()

            if response == gtk.RESPONSE_OK:
                with open(dialog.get_filename(), 'r') as file:
                    self.queryview.set_data(root_field = f[root_key],
                                            query = f[query_key],
                                            field_labels = f[labels_key]
                                            )

            dialog.destroy()


        self.menuview.connect("spawn-connection-dialog", callback_edit_Server_Settings)
        self.menuview.connect("send-query", self.send_query)
        self.menuview.connect("toggle-selection", event_clicked_toggle_selection)
        self.menuview.connect("download-selection", event_clicked_download)
        self.menuview.connect("save-query", save_query)
        self.menuview.connect("load-query", load_query)
        self.menuview.connect("spawn-comparison-dialog",callback_define_comparison)

        self.queryview.connect("rest-api", disable_download_button)
        #self.queryview.connect("adddata", disable_adddata_button)