Beispiel #1
0
class Query():
    '''
    Class used to set search data for a file on the FAIRDOMHUB website :
                (https://www.fairdomhub.org)

    To use :
        import seek_library as s
        x= s.read()
        x.query()
        x.search()

    '''
    def __init__(self, json_handler):
        '''
        Sets up varaiables for class
        Contains details on what the search items are
        Gets all the user names and IDs of all FAIRDOM users

        '''
        self.widget = Widget()
        self.json = None

        self.json_handler = json_handler
        self.call_search = Call_Search(self.json_handler)

        # self.search_and_display_handler =  search_and_display()
        self.search_doc_id = None
        self.doc_option_selected = None
        self.current_blob = None

        self.settings_dict_from_file = {}
        self.settings_dict = {}

        self.dict_of_users_and_ids = {}
        self.list_of_user_names = []
        self.list_of_user_ids = []
        self.user_list_alphabet_order = []

        self.search_person_list = []
        self.max_ID_value = 0

        self.name_search_widget = None
        self.people_search_ID_widget = None

        self.query_tab = None
        self.maxProcesses = 5

        self.load_default_settings()
        # self.get_all_FAIRDOM_user_names_and_ID()

    def set_json_handler(self, json_handler):
        '''
        Sets the json_handler to the most recent changed version
        This allows users to login and access private data
        '''
        self.json_handler = json_handler
        self.call_search.set_json_handler(json_handler)

    def get_all_FAIRDOM_user_names_and_ID(self):
        '''
        Gets a dictionary of all users and IDs
        as well as lists for both users and IDs
        '''
        self.dict_of_users_and_ids.clear()

        temp_list = []
        self.dict_of_users_and_ids = self.json_handler.get_dictionary_of_user_and_id(
        )
        temp_list = self.json_handler.get_list_of_user_ids()
        self.list_of_user_ids = temp_list
        temp_list = self.json_handler.get_list_of_user_names()
        self.list_of_user_names = temp_list

    def get_dict_of_user_names_and_ids(self):
        '''
        RETURNS Dictionary of names and ids
        '''
        return self.dict_of_users_and_ids

    def get_list_of_user_names(self):
        '''
        RETURNS List of names
        '''
        return self.list_of_user_names

    def get_list_of_user_ids(self):
        '''
        RETURNS List of ids
        '''
        return self.list_of_user_ids

    def read_settings_file(self):
        '''
        Get the saved settings for the search options
        Gets the information from a file named 'search_settings.txt'
        '''
        fn = 'search_settings.txt'
        try:
            file = open(fn, 'r')
        except IOError:
            file = open(fn, 'w+')

        try:

            with file as f:
                for line in f:
                    (key, value) = line.split()
                    self.settings_dict_from_file[key] = value

            self.settings_dict = dict(self.settings_dict_from_file)
            file.close()
        except:
            print('Error with settings file')
            print('Delete file to fix')

    def save_settings(self):
        '''
        Save the search options to a file
        Options are taken from the widgets
        '''
        self.get_updated_setting_options()
        fn = 'search_settings.txt'
        try:
            file = open(fn, 'w')

            for key in self.settings_dict:
                k = (key)
                val = (self.settings_dict.get(key))
                to_write = k + ' ' + val + '\n'
                file.write(to_write)

            file.close()
        except:
            print('Error with settings file')
            print('Delete file to fix')

    def load_settings(self):
        '''
        Load search option settings from the file
        and display the choices on the widgets on the settings tab
        '''
        self.read_settings_file()
        self.query_tab.children[2].children[0].children[0].children[
            0].children[0].value = self.settings_dict_from_file.get(
                'display_title')

        self.query_tab.children[2].children[0].children[0].children[
            0].children[1].value = self.settings_dict_from_file.get(
                'display_description')

        self.query_tab.children[2].children[0].children[0].children[
            0].children[2].value = self.settings_dict_from_file.get(
                'display_model_name')

        self.query_tab.children[2].children[0].children[0].children[
            0].children[3].value = self.settings_dict_from_file.get(
                'display_model')

        self.query_tab.children[2].children[0].children[0].children[
            0].children[4].value = self.settings_dict_from_file.get(
                'display_download_link')

        self.query_tab.children[2].children[0].children[0].children[
            1].children[0].value = self.settings_dict_from_file.get(
                'display_creators')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[1].value = self.settings_dict_from_file.get(
                'display_submitter')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[2].value = self.settings_dict_from_file.get(
                'display_related_people')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[3].value = self.settings_dict_from_file.get(
                'display_related_projects')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[4].value = self.settings_dict_from_file.get(
                'display_related_investigations')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[5].value = self.settings_dict_from_file.get(
                'display_related_studies')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[6].value = self.settings_dict_from_file.get(
                'display_related_assays')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[7].value = self.settings_dict_from_file.get(
                'display_related_data_files')

        self.query_tab.children[2].children[0].children[0].children[
            1].children[8].value = self.settings_dict_from_file.get(
                'display_related_publications')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[9].value = self.settings_dict_from_file.get(
                'display_related_events')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[10].value = self.settings_dict_from_file.get(
                'display_project_members')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[11].value = self.settings_dict_from_file.get(
                'display_project_administrators')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[12].value = self.settings_dict_from_file.get(
                'display_project_asset_housekeepers')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[13].value = self.settings_dict_from_file.get(
                'display_project_asset_gatekeepers')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[14].value = self.settings_dict_from_file.get(
                'display_project_organisms')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[15].value = self.settings_dict_from_file.get(
                'display_project_institutions')
        self.query_tab.children[2].children[0].children[0].children[
            1].children[16].value = self.settings_dict_from_file.get(
                'display_project_programmes')

    def load_default_settings(self):
        '''
        Default settings for the search options
        '''
        self.settings_dict['display_title'] = 'True'
        self.settings_dict['display_description'] = 'True'
        self.settings_dict['display_model_name'] = 'True'
        self.settings_dict['display_model'] = 'True'
        self.settings_dict['display_download_link'] = 'True'
        self.settings_dict['display_creators'] = 'True'
        self.settings_dict['display_submitter'] = 'True'
        self.settings_dict['display_related_people'] = 'True'
        self.settings_dict['display_related_projects'] = 'True'
        self.settings_dict['display_related_investigations'] = 'True'
        self.settings_dict['display_related_studies'] = 'True'
        self.settings_dict['display_related_assays'] = 'True'
        self.settings_dict['display_related_data_files'] = 'True'
        self.settings_dict['display_related_publications'] = 'True'
        self.settings_dict['display_related_events'] = 'True'
        self.settings_dict['display_project_members'] = 'True'
        self.settings_dict['display_project_administrators'] = 'True'
        self.settings_dict['display_project_asset_housekeepers'] = 'True'
        self.settings_dict['display_project_asset_gatekeepers'] = 'True'
        self.settings_dict['display_project_organisms'] = 'True'
        self.settings_dict['display_project_institutions'] = 'True'
        self.settings_dict['display_project_programmes'] = 'True'

    def change_settings_quick(self, value):
        '''
        Set all settings value to one value
        '''
        self.settings_dict['display_title'] = value
        self.query_tab.children[2].children[0].children[0].children[
            0].children[0].value = value
        self.settings_dict['display_description'] = value
        self.query_tab.children[2].children[0].children[0].children[
            0].children[1].value = value
        self.settings_dict['display_model_name'] = value
        self.query_tab.children[2].children[0].children[0].children[
            0].children[2].value = value
        self.settings_dict['display_model'] = value
        self.query_tab.children[2].children[0].children[0].children[
            0].children[3].value = value
        self.settings_dict['display_download_link'] = value
        self.query_tab.children[2].children[0].children[0].children[
            0].children[4].value = value
        self.settings_dict['display_creators'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[0].value = value
        self.settings_dict['display_submitter'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[1].value = value
        self.settings_dict['display_related_people'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[2].value = value
        self.settings_dict['display_related_projects'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[3].value = value
        self.settings_dict['display_related_investigations'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[4].value = value
        self.settings_dict['display_related_studies'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[5].value = value
        self.settings_dict['display_related_assays'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[6].value = value
        self.settings_dict['display_related_data_files'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[7].value = value
        self.settings_dict['display_related_publications'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[8].value = value
        self.settings_dict['display_related_events'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[9].value = value
        self.settings_dict['display_project_members'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[10].value = value
        self.settings_dict['display_project_administrators'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[11].value = value
        self.settings_dict['display_project_asset_housekeepers'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[12].value = value
        self.settings_dict['display_project_asset_gatekeepers'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[13].value = value
        self.settings_dict['display_project_organisms'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[14].value = value
        self.settings_dict['display_project_institutions'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[15].value = value
        self.settings_dict['display_project_programmes'] = value
        self.query_tab.children[2].children[0].children[0].children[
            1].children[16].value = value

    def change_made_name_search(self, change):
        '''
        Deals with any updates in the combo box widget for name in person tab
        If valid name is entered, update the id combo box widget in person tab
        with the corresponding ID
        '''
        #Prevent the ID widget from automatically updating
        #as update is forced done in this method
        self.people_search_ID_widget.unobserve(
            self.change_made_people_search_ID)

        #Remove ID when name box is made empty
        #If name is valid, update ID box
        if (change['new'] == ''):
            self.people_search_ID_widget.value = ''
        elif change['type'] == 'change' and change['name'] == 'value':
            name_selected = change['new']
            if name_selected in self.dict_of_users_and_ids.keys():
                ID_index_list = self.dict_of_users_and_ids.get(name_selected)
                #if name has multiple IDs, ask the user to choose which ID
                if len(ID_index_list) > 1:
                    self.people_search_ID_widget.value = ''
                    self.people_search_ID_widget.placeholder = 'Choose ID'
                    self.people_search_ID_widget.options = ID_index_list
                else:
                    self.people_search_ID_widget.value = str(ID_index_list[0])
            else:
                self.people_search_ID_widget.value = ''
                self.people_search_ID_widget.placeholder = 'Enter ID'
                self.people_search_ID_widget.options = []

        self.people_search_ID_widget.observe(self.change_made_people_search_ID)

    def change_made_people_search_ID(self, change):
        '''
        Deals with any updates in the ID combo box widget in person tab
        Updates the name combo box widget in person tab with corresponding ID
        '''
        #Prevent the name widget from automatically updating
        #as update is forced done in this method
        self.name_search_widget.unobserve(self.change_made_name_search)
        if change['new'] == '':
            self.name_search_widget.value = ''
            self.name_search_widget.options = []
        elif change['type'] == 'change' and change['name'] == 'value':
            ID = str(change['new'])
            #If ID is in database, display the name associated
            if (change['new'] in self.list_of_user_ids):
                name = self.list_of_user_names[self.list_of_user_ids.index(ID)]
                self.name_search_widget.value = name
            else:
                self.name_search_widget.value = ''
                # self.name_search_widget.options = self.user_list_alphabet_order

        self.name_search_widget.observe(self.change_made_name_search)

    def change_made_doc_option(self, change):
        '''
        Deals with update in Search Type dropdown widget in the Document Tab
        Store the working document type
        '''
        option = None
        if change['type'] == 'change' and change['name'] == 'value':
            if str(change['new']) == 'Project':
                option = 'Project'
            elif str(change['new']) == 'Investigation':
                option = 'Investigation'
            elif str(change['new']) == 'Study':
                option = 'Study'
            elif str(change['new']) == 'Assay':
                option = 'Assay'
            elif str(change['new']) == 'Data File':
                option = 'Data File'

            #sets the class variable to option
            self.doc_option_selected = option

    def change_made_ID(self, change):
        '''
        Deals with update in ID number int widget in the Document Tab
        Stores the selected ID number
        '''
        if change['type'] == 'change' and change['name'] == 'value':
            #print("changed to %s" % change['new'])
            self.search_doc_id = int(change['new'])

    def on_click_setting_load_save(self, button):
        '''
        Deals with button press for both Load Settings and Save Settings button
        in the Search settings tab
        Either loads settings from file or saves the settings to file depending
        on button pressed
        '''

        if button.description == 'Load Settings':
            self.load_settings()
        elif button.description == 'Save Settings':
            self.save_settings()

    def on_click_search(self, button):
        '''
        When search button is pressed, the item to search for is saved
        The item is then searched
        '''
        list_of_names = self.list_of_user_names
        list_of_ids = self.list_of_user_ids
        topic = self.get_topic()
        settings_dict = self.get_setting_options_dict()
        settings_dict = dict(settings_dict)
        id = self.get_id_to_search()
        type = self.get_type_to_search()
        self.call_search.search(list_of_names, list_of_ids, topic,
                                settings_dict, id, type)

    def on_click_convert(self, button):
        '''
        Converts widget buttons ( with info to be displayed ) to text format
        '''
        tab_index = self.query_tab.selected_index
        title = self.query_tab._titles.get(str(tab_index))
        clear_output()
        print('Query type       : {0}'.format(title))
        if tab_index == 0:
            type = self.query_tab.children[tab_index].children[0].value
            id = self.query_tab.children[tab_index].children[1].value
            print('File search type : {0}'.format(type))
            print('ID search        : {0}'.format(id))
        elif tab_index == 1:
            id = self.query_tab.children[tab_index].children[0].value
            print('ID search        : {0}'.format(id))

    def on_click_select_all(self, button):
        '''
        Sets all the settings to be true
        '''
        current_index = self.query_tab.selected_index
        topic = self.query_tab._titles.get(str(current_index))
        if topic == 'Search settings':
            self.change_settings_quick('True')

    def on_click_deselect_all(self, button):
        '''
        Sets all the settings to be False
        '''
        current_index = self.query_tab.selected_index
        topic = self.query_tab._titles.get(str(current_index))
        if topic == 'Search settings':
            self.change_settings_quick('False')

    def document_tab(self):
        '''
        Creates widgets relating to searching for a working document
        RETURNS container of widgets
        '''

        doc_select_widget_list = []
        options = ['Project', 'Investigation', 'Study', 'Assay', 'Data File']
        desc = 'Search Type:'
        doc_option_widget = self.widget.dropdown_widget(
            options, 'default', desc)
        doc_select_widget_list.append(doc_option_widget)
        #calls a function that handles updates in the drop down menu
        doc_option_widget.observe(self.change_made_doc_option)
        self.doc_option_selected = doc_option_widget.value

        value = 1
        desc = 'ID number:'
        bool = False
        min = 1
        max = sys.maxsize
        doc_id_search_widget = self.widget.bounded_int_text_widget(
            value, desc, bool, min, max)
        doc_select_widget_list.append(doc_id_search_widget)

        #calls a function that handles updates in the int box
        doc_id_search_widget.observe(self.change_made_ID)

        self.search_doc_id = doc_id_search_widget.value
        desc = 'Search'
        search = self.widget.button(desc)
        search.on_click(self.on_click_search)
        doc_select_widget_list.append(search)

        #Formats the widgets into a column
        doc_select_widgets_container = widgets.VBox([
            doc_select_widget_list[0], doc_select_widget_list[1],
            doc_select_widget_list[2]
        ])
        return doc_select_widgets_container

    def person_tab(self):
        '''
        Creates widgets relating to searching for a person
        RETURNS container of widgets
        '''
        #Get the list of users sorted in alphbetical order and removes
        #duplicates
        self.user_list_alphabet_order = []
        self.user_list_alphabet_order = list(self.list_of_user_names)
        #removes duplicates
        self.user_list_alphabet_order = list(
            dict.fromkeys(self.user_list_alphabet_order))
        #sort alphabetically
        self.user_list_alphabet_order.sort()
        #add empty string for when the widget is empty
        self.user_list_alphabet_order.append('')
        people_search_widget_list = []
        ph = 'Enter ID'
        options = []
        desc = 'ID :'
        ensure_option = False
        bool_active = False
        self.people_search_ID_widget = self.widget.combobox(
            ph, options, desc, ensure_option, bool_active)
        people_search_widget_list.append(self.people_search_ID_widget)
        #Handles update to ID widget
        self.people_search_ID_widget.observe(self.change_made_people_search_ID)

        ph = 'Enter Name'
        options = []
        desc = 'Name :'
        ensure_option = False
        bool_active = False
        self.name_search_widget = self.widget.combobox(ph, options, desc,
                                                       ensure_option,
                                                       bool_active)
        people_search_widget_list.append(self.name_search_widget)

        #Handles update to name widget
        self.name_search_widget.observe(self.change_made_name_search)
        desc = 'To Search'
        search = self.widget.button(desc)
        search.on_click(self.on_click_search)
        people_search_widget_list.append(search)
        #Formats the widgets into a column
        people_search_container = widgets.VBox([
            people_search_widget_list[0], people_search_widget_list[1],
            people_search_widget_list[2]
        ])

        return people_search_container

    def general_setting_widgets(self):
        '''
        Creates widgets relating to setting options
        RETURNS container of widgets
        '''
        setting_option_widget_list = []
        desc = 'Display Title:'
        value = self.settings_dict.get('display_title')
        title_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(title_option)

        desc = 'Display Description:'
        value = self.settings_dict.get('display_description')
        description_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(description_option)

        desc = 'Display Model Name:'
        value = self.settings_dict.get('display_model_name')
        model_name_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(model_name_option)

        desc = 'Display Model:'
        value = self.settings_dict.get('display_model')
        model_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(model_option)

        desc = 'Display Download Link:'
        value = self.settings_dict.get('display_download_link')
        download_link_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(download_link_option)

        column = widgets.VBox([
            setting_option_widget_list[0], setting_option_widget_list[1],
            setting_option_widget_list[2], setting_option_widget_list[3],
            setting_option_widget_list[4]
        ])

        return column

    def relationship_setting_widgets(self):
        '''
        Creates widgets relating to relationship setting options
        RETURNS container of widgets
        '''
        setting_option_widget_list = []
        desc = 'Display Creator:'
        value = self.settings_dict.get('display_creators')
        creators_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(creators_option)

        desc = 'Display Submitter:'
        value = self.settings_dict.get('display_submitter')
        submitter_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(submitter_option)

        desc = 'Display People:'
        value = self.settings_dict.get('display_related_people')
        related_people_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_people_option)

        desc = 'Display Related Projects:'
        value = self.settings_dict.get('display_related_projects')
        related_projects_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_projects_option)

        desc = 'Display Related Investigations:'
        value = self.settings_dict.get('display_related_investigations')
        related_investigations_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_investigations_option)

        desc = 'Display Related Studies:'
        value = self.settings_dict.get('display_related_studies')
        related_studies_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_studies_option)

        desc = 'Display Related Assays:'
        value = self.settings_dict.get('display_related_assays')
        related_assays_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_assays_option)

        desc = 'Display Related Data Files:'
        value = self.settings_dict.get('display_related_data_files')
        related_data_files_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_data_files_option)

        desc = 'Display Related Publications:'
        value = self.settings_dict.get('display_related_publications')
        related_publications_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_publications_option)

        desc = 'Display Related Events:'
        value = self.settings_dict.get('display_related_events')
        related_events_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(related_events_option)

        desc = 'Display Project Members:'
        value = self.settings_dict.get('display_project_members')
        project_members_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_members_option)

        desc = 'Display Project Admins:'
        value = self.settings_dict.get('display_project_administrators')
        project_admins_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_admins_option)

        desc = 'Display Project Assest HK:'
        value = self.settings_dict.get('display_project_asset_housekeepers')
        project_asset_HK_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_asset_HK_option)

        desc = 'Display Project Assest GK:'
        value = self.settings_dict.get('display_project_asset_gatekeepers')
        project_asset_GK_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_asset_GK_option)

        desc = 'Display Project Organisms:'
        value = self.settings_dict.get('display_project_organisms')
        project_organisms_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_organisms_option)

        desc = 'Display Project Institutions:'
        value = self.settings_dict.get('display_project_institutions')
        project_institutions_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_institutions_option)

        desc = 'Display Project Programmes:'
        value = self.settings_dict.get('display_project_programmes')
        project_institutions_option = self.widget.toggle_button(desc, value)
        setting_option_widget_list.append(project_institutions_option)

        column = widgets.VBox([
            setting_option_widget_list[0],
            setting_option_widget_list[1],
            setting_option_widget_list[2],
            setting_option_widget_list[3],
            setting_option_widget_list[4],
            setting_option_widget_list[5],
            setting_option_widget_list[6],
            setting_option_widget_list[7],
            setting_option_widget_list[8],
            setting_option_widget_list[9],
            setting_option_widget_list[10],
            setting_option_widget_list[11],
            setting_option_widget_list[12],
            setting_option_widget_list[13],
            setting_option_widget_list[14],
            setting_option_widget_list[15],
            setting_option_widget_list[16],
        ])

        return column

    def settings_tab(self):
        '''
        Creates tab relating to settings used for searching
        '''
        settings_widget_list = []
        desc = 'Load Settings'
        load_settings_option = self.widget.button(desc)
        settings_widget_list.append(load_settings_option)
        load_settings_option.on_click(self.on_click_setting_load_save)

        desc = 'Save Settings'
        save_settings_option = self.widget.button(desc)
        settings_widget_list.append(save_settings_option)
        save_settings_option.on_click(self.on_click_setting_load_save)

        desc = 'Select all :'
        select_all_button = self.widget.button(desc)
        settings_widget_list.append(select_all_button)
        select_all_button.on_click(self.on_click_select_all)

        desc = 'Deselect all :'
        deselect_all_button = self.widget.button(desc)
        settings_widget_list.append(deselect_all_button)
        deselect_all_button.on_click(self.on_click_deselect_all)

        widget_list = []
        general_setting_options_list = self.general_setting_widgets()
        widget_list.append(general_setting_options_list)
        relation_setting_option_list = self.relationship_setting_widgets()
        widget_list.append(relation_setting_option_list)

        settings_accordion = self.widget.accordion(widget_list)

        settings_accordion.set_title(0, 'General settings')
        settings_accordion.set_title(1, 'Relationship settings')

        settings_accordion.selected_index = None
        # general_settings_accordion.set_title(1, 'Relationship settings')

        left_column = widgets.VBox([settings_accordion])

        #right column widgets are for saving and loading the options
        right_column = widgets.VBox([
            settings_widget_list[0], settings_widget_list[1],
            settings_widget_list[2], settings_widget_list[3]
        ])

        #formatted in two columns
        settings_container = widgets.HBox([left_column, right_column])

        return settings_container

    def get_updated_setting_options(self):
        '''
        Get the newest values of the search options from the widgets in the
        Search settings tab
        '''
        value = self.get_query_tab_children_settings_values('display_title')
        self.settings_dict['display_title'] = value

        value = self.get_query_tab_children_settings_values(
            'display_description')
        self.settings_dict['display_description'] = value

        value = self.get_query_tab_children_settings_values(
            'display_model_name')
        self.settings_dict['display_model_name'] = value

        value = self.get_query_tab_children_settings_values(
            'display_download_link')
        self.settings_dict['display_download_link'] = value

        value = self.get_query_tab_children_settings_values('display_model')
        self.settings_dict['display_model'] = value

        value = self.get_query_tab_children_settings_values('display_creators')
        self.settings_dict['display_creators'] = value

        value = self.get_query_tab_children_settings_values(
            'display_submitter')
        self.settings_dict['display_submitter'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_people')
        self.settings_dict['display_related_people'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_projects')
        self.settings_dict['display_related_projects'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_investigations')
        self.settings_dict['display_related_investigations'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_studies')
        self.settings_dict['display_related_studies'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_assays')
        self.settings_dict['display_related_assays'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_data_files')
        self.settings_dict['display_related_data_files'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_publications')
        self.settings_dict['display_related_publications'] = value

        value = self.get_query_tab_children_settings_values(
            'display_related_events')
        self.settings_dict['display_related_events'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_members')
        self.settings_dict['display_project_members'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_administrators')
        self.settings_dict['display_project_administrators'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_asset_housekeepers')
        self.settings_dict['display_project_asset_housekeepers'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_asset_gatekeepers')
        self.settings_dict['display_project_asset_gatekeepers'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_organisms')
        self.settings_dict['display_project_organisms'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_institutions')
        self.settings_dict['display_project_institutions'] = value

        value = self.get_query_tab_children_settings_values(
            'display_project_programmes')
        self.settings_dict['display_project_programmes'] = value

    def get_query_tab_children_settings_values(self, setting):
        '''
        Get the newest values of the setting options from the widgets in the
        settings tab
        '''
        if setting == 'display_title':
            return self.query_tab.children[2].children[0].children[0].children[
                0].children[0].value
        elif setting == 'display_description':
            return self.query_tab.children[2].children[0].children[0].children[
                0].children[1].value
        elif setting == 'display_model_name':
            return self.query_tab.children[2].children[0].children[0].children[
                0].children[2].value
        elif setting == 'display_model':
            return self.query_tab.children[2].children[0].children[0].children[
                0].children[3].value
        elif setting == 'display_download_link':
            return self.query_tab.children[2].children[0].children[0].children[
                0].children[4].value

        elif setting == 'display_creators':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[0].value
        elif setting == 'display_submitter':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[1].value
        elif setting == 'display_related_people':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[2].value
        elif setting == 'display_related_projects':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[3].value
        elif setting == 'display_related_investigations':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[4].value
        elif setting == 'display_related_studies':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[5].value
        elif setting == 'display_related_assays':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[6].value
        elif setting == 'display_related_data_files':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[7].value
        elif setting == 'display_related_publications':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[8].value
        elif setting == 'display_related_events':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[9].value
        elif setting == 'display_project_members':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[10].value
        elif setting == 'display_project_administrators':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[11].value
        elif setting == 'display_project_asset_housekeepers':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[12].value
        elif setting == 'display_project_asset_gatekeepers':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[13].value
        elif setting == 'display_project_organisms':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[14].value
        elif setting == 'display_project_institutions':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[15].value
        elif setting == 'display_project_programmes':
            return self.query_tab.children[2].children[0].children[0].children[
                1].children[16].value
        else:
            return 'Error'

    def get_id_to_search(self):
        '''
        Get the ID to search based on the current selected tab
        RETURNS ID
        '''
        current_index = self.query_tab.selected_index
        topic = self.query_tab._titles.get(str(current_index))
        if topic == 'Document query':
            id = self.search_doc_id
        else:
            id = self.people_search_ID_widget.value
        return id

    def get_type_to_search(self):
        '''
        Get the TYPE to search based on the current selected tab
        RETURNS TYPE
        '''
        current_index = self.query_tab.selected_index
        topic = self.query_tab._titles.get(str(current_index))
        if topic == 'Document query':
            type = self.doc_option_selected
        else:
            type = 'Person'
        return type

    def get_topic(self):
        '''
        Get the topic to search based on the current selected tab
        RETURNS topic
        '''
        current_index = self.query_tab.selected_index
        topic = self.query_tab._titles.get(str(current_index))
        return topic

    def get_setting_options_dict(self):
        '''
        get the settings
        RETURNS settings
        '''
        self.get_updated_setting_options()
        return self.settings_dict

    def query(self):
        '''
        Displays interactive widgets seperated out into different tabs
        '''
        tab_list = []
        title_list = []
        doc_tab = self.document_tab()
        tab_list.append(doc_tab)
        title_list.append('Document query')
        person_tab = self.person_tab()
        tab_list.append(person_tab)
        title_list.append('Person query')

        settings_tab = self.settings_tab()
        tab_list.append(settings_tab)
        title_list.append('Search settings')

        self.query_tab = self.widget.tab(tab_list, title_list)

        display(self.query_tab)
        desc = 'Convert widgets to text'
        widgets_to_text_button = self.widget.button(desc)
        widgets_to_text_button.on_click(self.on_click_convert)
        display(widgets_to_text_button)
Beispiel #2
0
class Search():
    '''
    Class handles with sending requests to FAIRDOMHUB to get the
    chosen JSON file
    '''
    def __init__(self, json_handler):
        self.topic = None
        self.search_id = None
        self.search_type = None
        self.settings_dict = {}
        self.json = None
        self.current_blob = None
        self.json_handler = json_handler
        self.relationship_person_id = []
        self.list_of_ids = []
        self.list_of_names = []
        self.related_work_tab = None
        self.related_people_tab = None

        self.project_meta_data = None
        self.project_tab = None
        self.temp_list_of_ids = []
        self.project_names = []
        self.project_ids = []
        self.investigation_names = []
        self.investigation_ids = []
        self.study_names = []
        self.study_ids = []
        self.assay_names = []
        self.assay_ids = []
        self.data_file_names = []
        self.data_file_ids = []
        self.creator_names = []
        self.creator_ids = []
        self.submitter_names = []
        self.submitter_ids = []
        self.people_names = []
        self.people_ids = []
        self.project_members_names = []
        self.project_members_ids = []
        self.project_admins_names = []
        self.project_admins_ids = []
        self.project_asset_HK_names = []
        self.project_asset_HK_ids = []
        self.project_asset_GK_names = []
        self.project_asset_GK_ids = []
        self.project_people_names = []
        self.project_people_ids = []
        self.tab_title_names_list_doc = []
        self.tab_title_names_list_people = []
        self.project_tab_title_names_list = []
        self.widget = Widget()
        self.list_of_top_level_widgets = []
        self.title = None
        self.desc = None
        self.model_name = None
        self.csv = None
        self.download_link_text = None

    def set_json_handler(self, json_handler):
        '''
        Sets the json_handler to the most recent changed version
        This allows users to login and access private data
        '''
        self.json_handler = json_handler

    def display(self):
        '''
        displays the file by getting the appropriate data from the JSON tags
        '''
        #File ID to search for
        id = self.search_id
        # File type
        type = self.search_type
        self.json = self.json_handler.get_JSON(type, id)
        #title and description of file
        if self.json != []:
            self.display_basic_info()
            if type == 'Person':
                self.display_institution()
            if type == 'Data File':
                self.display_datafile()
            if type == 'Project':
                self.display_project()
            else:
                if type != 'Person':
                    self.display_people_relations()

            self.display_work_relations()

    def display_basic_info(self):
        '''
        Displays the Title and Description
        '''
        if self.settings_dict.get('display_title') == 'True':
            self.display_title()
        if self.settings_dict.get('display_description') == 'True':
            self.display_description()

    def display_title(self):
        '''
        Displays title
        '''
        title = self.json_handler.get_title(self.json)
        self.title = title + '\n'
        title = ('<h1><u>{0}</u></h1>'.format(title))

        title_widget = self.widget.HTML(title)
        display(title_widget)

    def display_description(self):
        '''
        Displays Description
        '''
        description = self.json_handler.get_description(self.json)
        print(description)
        self.desc = description

    def display_institution(self):
        '''
        Displays the institution related to the project
        '''
        #list of items to display
        container_list = []
        #name of items to display
        tab_title_names_list = []

        if self.settings_dict.get('display_project_institutions') == 'True':
            instituion_container = self.createRelationContainer(
                'Project Institute')
            container_list.append(instituion_container)
            tab_title_names_list.append('Institution')

        #If items are to be displayed, a tab is created for each item
        if container_list:
            related_work_tab = widgets.Tab()
            related_work_tab.children = container_list
            for index in range(len(tab_title_names_list)):
                related_work_tab.set_title(index, tab_title_names_list[index])
            display(related_work_tab)

    def display_people_relations(self):
        '''
        Shows all the related Projects / Studies / Assays related to current
        working document.

        Checks settings list to see which to display, then for each item, a
        container is created with the name of each related item

        Can be optimised by using multiprocessing
        '''
        #list of items to display
        container_list = []
        #name of items to display
        self.tab_title_names_list_people = []

        if self.settings_dict.get('display_creators') == 'True':
            creator_relationship_people_container = self.createRelationContainer(
                'Creator')
            container_list.append(creator_relationship_people_container)
            self.tab_title_names_list_people.append('Creator')

        if self.settings_dict.get('display_submitter') == 'True':
            submitter_relationship_people_container = self.createRelationContainer(
                'Submitter')
            container_list.append(submitter_relationship_people_container)
            self.tab_title_names_list_people.append('Submitter')

        if self.settings_dict.get('display_related_people') == 'True':
            people_relationship_people_container = self.createRelationContainer(
                'People')
            container_list.append(people_relationship_people_container)
            self.tab_title_names_list_people.append('Related People')

        #If items are to be displayed, a tab is created for each item
        if container_list:
            self.related_people_tab = widgets.Tab()
            self.related_people_tab.children = container_list
            for index in range(len(self.tab_title_names_list_people)):
                self.related_people_tab.set_title(
                    index, self.tab_title_names_list_people[index])
            display(self.related_people_tab)
            self.list_of_top_level_widgets.append(self.related_people_tab)

    def display_work_relations(self):
        '''
        Shows all the related Projects / Studies / Assays related to current
        working document.

        Checks settings list to see which to display, then for each item, a
        container is created with the name of each related item
        '''
        #list of items to display
        container_list = []
        #name of items to display
        self.tab_title_names_list_doc = []

        if self.settings_dict.get('display_related_projects') == 'True':
            project_relationship_container = self.createRelationContainer(
                'Project')
            container_list.append(project_relationship_container)
            self.tab_title_names_list_doc.append('Related Projects')

        if self.settings_dict.get('display_related_investigations') == 'True':
            investigation_relationship_container = self.createRelationContainer(
                'Investigation')
            container_list.append(investigation_relationship_container)
            self.tab_title_names_list_doc.append('Related Investigations')

        if self.settings_dict.get('display_related_studies') == 'True':
            study_relationship_container = self.createRelationContainer(
                'Study')
            container_list.append(study_relationship_container)
            self.tab_title_names_list_doc.append('Related Studies')

        if self.settings_dict.get('display_related_assays') == 'True':
            assay_relationship_container = self.createRelationContainer(
                'Assay')
            container_list.append(assay_relationship_container)
            self.tab_title_names_list_doc.append('Related Assays')

        if self.settings_dict.get('display_related_data_files') == 'True':
            data_file_relationship_container = self.createRelationContainer(
                'Data File')
            container_list.append(data_file_relationship_container)
            self.tab_title_names_list_doc.append('Related Data Files')

        #If items are to be displayed, a tab is created for each item
        if container_list:
            self.related_work_tab = self.widget.tab(
                container_list, self.tab_title_names_list_doc)
            display(self.related_work_tab)
            self.list_of_top_level_widgets.append(self.related_work_tab)

    def display_project(self):
        '''
        Shows all the related items related to current working document.
                - not including data files / docs

        Checks settings list to see which to display, then for each item, a
        container is created with the name of each related item
        '''
        container_list = []
        #name of items to display
        self.project_tab_title_names_list = []
        if self.settings_dict.get('display_project_members') == 'True':
            project_members_container = self.createRelationContainer(
                'Project Member')
            container_list.append(project_members_container)
            self.project_tab_title_names_list.append('Project Members')

        if self.settings_dict.get('display_project_administrators') == 'True':
            project_admin_container = self.createRelationContainer(
                'Project Admin')
            container_list.append(project_admin_container)
            self.project_tab_title_names_list.append('Project Admins')

        if self.settings_dict.get(
                'display_project_asset_housekeepers') == 'True':
            project_asset_HK_container = self.createRelationContainer(
                'Asset HK')
            container_list.append(project_asset_HK_container)
            self.project_tab_title_names_list.append('Project Asset HK')

        if self.settings_dict.get(
                'display_project_asset_gatekeepers') == 'True':
            project_asset_GK_container = self.createRelationContainer(
                'Asset GK')
            container_list.append(project_asset_GK_container)
            self.project_tab_title_names_list.append('Project Asset GK')

        if self.settings_dict.get('display_related_people') == 'True':
            people_relationship_people_container = self.createRelationContainer(
                'Project People')
            container_list.append(people_relationship_people_container)
            self.project_tab_title_names_list.append('Related People')

        if self.settings_dict.get('display_project_organisms') == 'True':
            project_organisms_container = self.createRelationContainer(
                'Project Organisms')
            container_list.append(project_organisms_container)
            self.project_tab_title_names_list.append('Project Organisms')

        if self.settings_dict.get('display_project_institutions') == 'True':
            project_institute_container = self.createRelationContainer(
                'Project Institute')
            container_list.append(project_institute_container)
            self.project_tab_title_names_list.append('Project Institutions')

        if self.settings_dict.get('display_project_programmes') == 'True':
            project_programmes_container = self.createRelationContainer(
                'Project Program')
            container_list.append(project_programmes_container)
            self.project_tab_title_names_list.append('Project Programmes')
        #If items are to be displayed, a tab is created for each item
        if container_list:
            self.project_tab = self.widget.tab(
                container_list, self.project_tab_title_names_list)
            display(self.project_tab)
            self.list_of_top_level_widgets.append(self.project_tab)

    def createRelationContainer(self, type):
        '''
        Creates the container for each item to be displayed

        Each item contains a dropbox of the titles of related documents and a#
        search button

        type            : document type
        increased_width : option for increased_width
                          0 = small
                          1 = medium
                          2 = large
        '''

        #Get a dictionary of data that contains ID amnd type
        #Iterate over dictionary to get the names from IDs
        desc = ''
        increased_width = 1
        if type == 'Creator':
            dict = self.json_handler.get_relationship_creators(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.creator_names = self.getValuesOfDict(dictIDAndName)
            names = self.creator_names
            self.creator_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Submitter':
            dict = self.json_handler.get_relationship_submitters(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.submitter_names = self.getValuesOfDict(dictIDAndName)
            names = self.submitter_names
            self.submitter_ids = self.getKeysOfDict(dictIDAndName)

            desc = 'Name :'
            increased_width = 0

        elif type == 'People':
            dict = self.json_handler.get_relationship_people(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.people_names = self.getValuesOfDict(dictIDAndName)
            names = self.people_names
            self.people_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Project':
            dict = self.json_handler.get_relationship_projects(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.project_names = self.getValuesOfDict(dictIDAndName)
            # print(self.project_names)
            names = self.project_names
            self.project_ids = self.getKeysOfDict(dictIDAndName)
            # print(self.project_ids)

            desc = 'Title :'
            increased_width = 2
        elif type == 'Investigation':
            dict = self.json_handler.get_relationship_investigations(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.investigation_names = self.getValuesOfDict(dictIDAndName)
            names = self.investigation_names
            self.investigation_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 2
        elif type == 'Study':
            dict = self.json_handler.get_relationship_studies(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.study_names = self.getValuesOfDict(dictIDAndName)
            names = self.study_names

            self.study_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 2
        elif type == 'Assay':
            dict = self.json_handler.get_relationship_assays(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.assay_names = self.getValuesOfDict(dictIDAndName)
            names = self.assay_names

            self.assay_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 2

        elif type == 'Data File':
            dict = self.json_handler.get_relationship_data_files(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.data_file_names = self.getValuesOfDict(dictIDAndName)
            names = self.data_file_names

            self.data_file_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 2
        elif type == 'Project Member':
            dict = self.json_handler.get_project_members(self.json)

            dictIDAndName = self.getDictOfIDandNamesPerson(dict, type)
            self.project_members_names = self.getValuesOfDict(dictIDAndName)
            names = self.project_members_names

            self.project_members_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Project Admin':
            dict = self.json_handler.get_project_admins(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.project_admins_names = self.getValuesOfDict(dictIDAndName)
            names = self.project_admins_names

            self.project_admins_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Asset HK':
            dict = self.json_handler.get_asset_HK(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.project_asset_HK_names = self.getValuesOfDict(dictIDAndName)
            names = self.project_asset_HK_names

            self.project_asset_HK_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Asset GK':
            dict = self.json_handler.get_asset_GK(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.project_asset_GK_names = self.getValuesOfDict(dictIDAndName)
            names = self.project_asset_GK_names

            self.project_asset_GK_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        elif type == 'Project Organisms':
            dict = self.json_handler.get_organisms(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            names = self.getValuesOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 0
        elif type == 'Project Institute':
            dict = self.json_handler.get_project_institutions(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            names = self.getValuesOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 0
        elif type == 'Project Program':
            dict = self.json_handler.get_project_programmes(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            names = self.getValuesOfDict(dictIDAndName)
            desc = 'Title :'
            increased_width = 0
        elif type == 'Project People':
            dict = self.json_handler.get_relationship_people(self.json)
            dictIDAndName = self.getDictOfIDandNames(dict, type)
            self.project_people_names = self.getValuesOfDict(dictIDAndName)
            names = self.project_people_names

            self.project_people_ids = self.getKeysOfDict(dictIDAndName)
            desc = 'Name :'
            increased_width = 0
        relationship_widget_list = []
        relationship_people_container = []
        relation = self.relationship_drop_box(names, increased_width, desc)
        relationship_widget_list.append(relation)
        desc = 'Search'
        relation_search_button = self.widget.button_optional(
            desc, relation.value)
        if type == 'Project' or type == 'Investigation' or type == 'Study' or type == 'Assay' or type == 'Data File':
            relation_search_button.on_click(self.on_click_search_doc)
        elif type == 'Creator' or type == 'Submitter' or type == 'People':
            relation_search_button.on_click(self.on_click_search_person)
        else:
            relation_search_button.on_click(
                self.on_click_search_project_meta_data)

        relationship_widget_list.append(relation_search_button)

        if type == 'Project Organisms' or type == 'Project Institute' or type == 'Project Program':
            relationship_people_container = widgets.VBox(
                [relationship_widget_list[0]])
        else:
            #Sorts positioning of container
            #dropbox above a search button

            relationship_people_container = widgets.VBox(
                [relationship_widget_list[0], relationship_widget_list[1]])

        return relationship_people_container

    def on_click_search_doc(self, button):
        '''
        Set the values to be searched and call the search function to get the
        data
        '''
        tab_index = self.related_work_tab.selected_index
        item_index = self.related_work_tab.children[tab_index].children[
            0].index[0]
        if self.tab_title_names_list_doc[tab_index] == 'Related Projects':
            topic = 'Document query'
            type = 'Project'
            id = self.project_ids[item_index]
        elif self.tab_title_names_list_doc[
                tab_index] == 'Related Investigations':
            topic = 'Document query'
            type = 'Investigation'
            id = self.investigation_ids[item_index]
        elif self.tab_title_names_list_doc[tab_index] == 'Related Studies':
            topic = 'Document query'
            type = 'Study'
            id = self.study_ids[item_index]
        elif self.tab_title_names_list_doc[tab_index] == 'Related Assays':
            topic = 'Document query'
            type = 'Assay'
            id = self.assay_ids[item_index]
        elif self.tab_title_names_list_doc[tab_index] == 'Related Data Files':
            topic = 'Document query'
            type = 'Data File'
            id = self.data_file_ids[item_index]

        settings_dict = self.settings_dict
        list_of_names = self.list_of_names
        list_of_ids = self.list_of_ids
        self.search_parameters(topic, id, type, settings_dict, list_of_names,
                               list_of_ids)
        # print(topic)
        # print(id)
        # print(type)
        self.search()

    def on_click_search_person(self, button):
        '''
        Set the values to be searched and call the search function to get the
        data
        '''
        tab_index = self.related_people_tab.selected_index
        item_index = self.related_people_tab.children[tab_index].children[
            0].index[0]
        if self.tab_title_names_list_people[tab_index] == 'Creator':
            topic = 'Document query'
            type = 'Person'
            id = self.creator_ids[item_index]
        elif self.tab_title_names_list_people[tab_index] == 'Submitter':
            topic = 'Document query'
            type = 'Person'
            id = self.submitter_ids[item_index]
        elif self.tab_title_names_list_people[tab_index] == 'Related People':
            topic = 'Document query'
            type = 'Person'
            id = self.people_ids[item_index]
        settings_dict = self.settings_dict
        list_of_names = self.list_of_names
        list_of_ids = self.list_of_ids
        self.search_parameters(topic, id, type, settings_dict, list_of_names,
                               list_of_ids)
        self.search()

    def on_click_search_project_meta_data(self, button):
        '''
        Set the values to be searched and call the search function to get the
        data
        '''
        tab_index = self.project_tab.selected_index
        item_index = self.project_tab.children[tab_index].children[0].index[0]

        if self.project_tab_title_names_list[tab_index] == 'Project Members':
            topic = 'Document query'
            type = 'Person'
            id = self.project_members_ids[item_index]
        elif self.project_tab_title_names_list[tab_index] == 'Project Admins':
            topic = 'Document query'
            type = 'Person'
            id = self.project_admins_ids[item_index]
        elif self.project_tab_title_names_list[
                tab_index] == 'Project Asset HK':
            topic = 'Document query'
            type = 'Person'
            id = self.project_asset_HK_ids[item_index]
        elif self.project_tab_title_names_list[
                tab_index] == 'Project Asset GK':
            topic = 'Document query'
            type = 'Person'
            id = self.project_asset_GK_ids[item_index]
        elif self.project_tab_title_names_list[tab_index] == 'Related People':
            topic = 'Document query'
            type = 'Person'
            id = self.project_people_ids[item_index]
        # topic =
        # type =
        settings_dict = self.settings_dict
        list_of_names = self.list_of_names
        list_of_ids = self.list_of_ids
        self.search_parameters(topic, id, type, settings_dict, list_of_names,
                               list_of_ids)
        self.search()

    def on_click_convert(self, button):
        '''
        Converts all widgets that display value (not relations) into text
        '''
        clear_output()

        if self.settings_dict.get('display_title') == 'True':
            if self.title is not None:
                print(self.title)
        if self.settings_dict.get('display_description') == 'True':
            if self.desc is not None:
                print(self.desc)
        if self.settings_dict.get('display_model_name') == 'True':
            if self.model_name is not None:
                print(self.model_name)
        if self.settings_dict.get('display_model') == 'True':
            if self.csv is not None:
                display(self.csv)
        if self.settings_dict.get('display_download_link') == 'True':
            if self.download_link_text is not None:
                print(self.download_link_text)
        # for index in len(self.list_of_top_level_widgets):
        #     tab_index = self.list_of_top_level_widgets[index].selected_index
        #     tab_title = self.list_of_top_level_widgets[index]._titles.get(str(tab_index))
        #     item_title = self.list_of_top_level_widgets[tab_index].children[0].value
        #     print('Query type       : {0}'.format(tab_title))
        #     print('Title of file    : {0}'.format(id))
    def getListOfNamesFromDict(self, dict, type):
        '''
        Get names of and ids from dict into two lists
        '''
        ids = []
        if type == 'Project Member':
            ids = self.iterate_over_json_list_person(dict, ids)
        else:
            ids = self.iterate_over_json_list(dict, ids)
        names = []
        for id in ids:
            name = self.list_of_names[self.list_of_ids.index(id)]
            names.append(name)
            if type == 'Creator':
                self.creator_ids.append(id)
            elif type == 'Submitter':
                self.submitter_ids.append(id)
            elif type == 'People':
                self.people_ids.append(id)
            elif type == 'Project Member':
                self.project_members.append(id)
            elif type == 'Project Admin':
                self.project_admins.append(id)
            elif type == 'Asset HK':
                self.project_asset_HK.append(id)
            elif type == 'Asset GK':
                self.project_asset_GK.append(id)
            elif type == 'Project People':
                self.project_people.append(id)

        return names

    def getKeysOfDict(self, dict):
        keys = dict.keys()
        return keys

    def getValuesOfDict(self, dict):
        values = dict.values()
        return values

    def getDictOfIDandNamesPerson(self, dict, sessionType):
        '''
        Uses multiprocessing to get the names from ids listed in a dict
        '''
        ids = []
        ids = self.iterate_over_json_list_person(dict, ids)
        # self.temp_list_of_ids = ids
        dictIDAndNames = {}

        dictIDAndNames = self.multiprocess_search(ids, sessionType)
        return dictIDAndNames

    def getDictOfIDandNames(self, dict, sessionType):
        '''
        Uses multiprocessing to get the names from ids listed in a dict
        '''
        ids = []
        ids = self.iterate_over_json_list(dict, ids)
        # self.temp_list_of_ids = ids
        dictIDAndNames = {}

        dictIDAndNames = self.multiprocess_search(ids, sessionType)
        return dictIDAndNames

    def relationship_drop_box(self, list_of_names, increased_width, desc):
        '''
        Creates a drop box to display the relationships
        '''
        options = list_of_names
        default_value = []
        number_of_rows = 1
        if list_of_names:
            default_value.append(options[0])
            if len(list_of_names) > 4:
                number_of_rows = 5
            else:
                number_of_rows = len(list_of_names)
                if number_of_rows < 2:
                    number_of_rows = 2

        relationship_dropdown_widget = self.widget.select_multiple(
            increased_width, options, default_value, number_of_rows, desc)

        relationship_dropdown_widget.observe(
            self.change_made_search_related_person, names='value')
        return relationship_dropdown_widget

    def iterate_over_json_list(self, data, list_type):
        '''
        Loop through dict and get a list of values
        '''
        list_type.clear()

        for value in data:
            list_type.append(value.get('id'))
        return list_type

    def iterate_over_json_list_person(self, data, list_type):
        '''
        Loop through dict and get a list of values for a person
        '''
        list_type.clear()

        for value in data:
            list_type.append(value.get('person_id'))
        return list_type

    def display_datafile(self):
        '''
        displays the data file by getting the appropriate data from the JSON
        tags
        '''
        self.current_blob = self.json_handler.get_blob(self.json)
        link = self.json_handler.get_link(self.current_blob)
        if self.settings_dict.get('display_model_name') == 'True':
            filename = self.json_handler.get_filename(self.current_blob)
            display(HTML('<h4>File Name: {0}</h4>'.format(filename)))
            self.model_name = filename
        # display(filename)
        if self.settings_dict.get('display_model') == 'True':
            self.csv = self.json_handler.get_csv_sheet(link)
            # Try display data file
            try:
                display(self.csv)
            except Exception as e:
                print('Could not display csv')

        if self.settings_dict.get('display_download_link') == 'True':
            self.download_link()

    def download_link(self):
        '''
        Displays download link
        '''
        link = self.json_handler.get_link(self.current_blob)
        filename = self.json_handler.get_filename(self.current_blob)
        download_link = link + "/download"
        print("Download link: " + download_link + "\n")
        HTML("<a href='" + download_link + "'>Download + " + filename + "</a>")
        self.download_link_text = download_link

    def retrieve_person_name(self, idNumber, dictData, pnumber):
        '''
        Gets person name from a JSON
        '''
        personMetaData = self.json_handler.get_JSON('people', idNumber)
        if not personMetaData:
            # return personMetaData
            dictData[idNumber] = personMetaData
        else:
            # return self.json_handler.get_title(personMetaData)
            dictData[idNumber] = self.json_handler.get_title(personMetaData)

    def retrieve_project_name(self, idNumber, dictData, pnumber):
        '''
        Gets project name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Project', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_investigation_name(self, idNumber, dictData, pnumber):
        '''
        Gets investigation name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Investigation', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_study_name(self, idNumber, dictData, pnumber):
        '''
        Gets study name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Study', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_assay_name(self, idNumber, dictData, pnumber):
        '''
        Gets assay name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Assay', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_data_file_name(self, idNumber, dictData, pnumber):
        '''
        Gets data file name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Data File', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_organism_name(self, idNumber, dictData, pnumber):
        '''
        Gets organism name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Project Organisms', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_institute_name(self, idNumber, dictData, pnumber):
        '''
        Gets institute name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Project Institute', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_program_name(self, idNumber, dictData, pnumber):
        '''
        Gets program name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Project Program', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def retrieve_project_people_name(self, idNumber, dictData, pnumber):
        '''
        Gets project person name from a JSON
        '''
        metaData = self.json_handler.get_JSON('Project People', idNumber)
        if not metaData:
            dictData[idNumber] = metaData
            # return metaData
        else:
            # return self.json_handler.get_title(metaData)
            dictData[idNumber] = self.json_handler.get_title(metaData)

    def multiprocess_search(self, idNumbers, sessionType):
        '''
        Multiprocessing is used to get the names of related data
        Needed as many calls via to API are made to get names
        JSON only provides ID of related files and not the names
        Therefore each related file needs to ge searched to get the name
        '''
        manager = mp.Manager()
        dict_return_data = manager.dict()
        processes = []
        # dataRec = []
        # processesBeingRun = Pool(processes = 8)
        if sessionType == 'Submitter' or sessionType == 'Creator' or sessionType == 'People':
            sessionType = 'people'
        for counter in range(len(idNumbers)):
            if sessionType == 'people':
                process = mp.Process(target=self.retrieve_person_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
                # dataRec = processesBeingRun.map(self.retrieve_person_name,idNumbers)
            elif sessionType == 'Project':
                process = mp.Process(target=self.retrieve_project_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
                # dataRec = processesBeingRun.map(self.retrieve_project_name,idNumbers)
            elif sessionType == 'Investigation':
                process = mp.Process(target=self.retrieve_investigation_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
                # dataRec = processesBeingRun.map(self.retrieve_investigation_name,idNumbers)
            elif sessionType == 'Study':
                process = mp.Process(target=self.retrieve_study_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
                # dataRec = processesBeingRun.map(self.retrieve_study_name,idNumbers)
            elif sessionType == 'Assay':
                process = mp.Process(target=self.retrieve_assay_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Data File':
                process = mp.Process(target=self.retrieve_data_file_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project Member':
                process = mp.Process(target=self.retrieve_person_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project Admin':
                process = mp.Process(target=self.retrieve_person_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
                # dataRec = processesBeingRun.map(self.retrieve_assay_name,idNumbers)
            elif sessionType == 'Asset HK':
                process = mp.Process(target=self.retrieve_person_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Asset GK':
                process = mp.Process(target=self.retrieve_person_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project Organisms':
                process = mp.Process(target=self.retrieve_organism_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project Institute':
                process = mp.Process(target=self.retrieve_institute_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project Program':
                process = mp.Process(target=self.retrieve_program_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))
            elif sessionType == 'Project People':
                process = mp.Process(target=self.retrieve_project_people_name,
                                     args=(idNumbers[counter],
                                           dict_return_data, counter))

            processes.append(process)
            process.start()

        for p in processes:
            p.join()
        # print(dict_return_data)
        # print(idNumbers)
        # time.sleep(10)
        # processesBeingRun.close()
        # yield processesBeingRun
        # processesBeingRun.terminate()

        return dict_return_data

    def change_made_search_related_person(self, change):
        '''
        Checks for any updates in the select multiple
        '''
        self.search_person_list = change['new']

    def search_parameters(self, topic, id, type, settings_dict, list_of_names,
                          list_of_ids):
        '''
        Searh parameters are set 
        '''
        self.creator_ids = []
        self.submitter_ids = []
        self.people_ids = []
        self.project_members = []
        self.project_admins = []
        self.project_asset_HK = []
        self.project_asset_GK = []
        self.project_people = []

        self.topic = topic
        self.search_id = id
        self.search_type = type
        self.settings_dict = settings_dict
        self.list_of_names = list_of_names
        self.list_of_ids = list_of_ids

    def search(self):
        '''
        Searches Fairdom for the file based on user input
        '''
        clear_output()
        # print(self.topic)
        if self.topic == 'Document query':
            self.display()
        elif self.topic == 'Person query':
            self.display()
        elif self.topic == 'To be implemented':
            pass

        desc = 'Convert widgets to text'
        widgets_to_text_button = self.widget.button(desc)
        widgets_to_text_button.on_click(self.on_click_convert)
        display(widgets_to_text_button)
Beispiel #3
0
class Write():
    '''
    Class handles posting json data to the SEEK database via FAIRDOM api
    Can either post new files or update existing ones
    '''
    def __init__(self, json_handler):
        self.json_handler = json_handler
        self.json = None
        self.widget = Widget()
        self.create_tab = None
        self.user_id = None

        self.parent_id = None
        self.post_query_container = None
        self.doc_write_compulsory_tab = None
        self.doc_write_assay_tab = None
        self.doc_write_data_file_tab = None
        self.doc_write_optional_tab = None
        self.post_accordion = None
        self.doc_write_tab = None
        # self.json
        self.choice_button = None
        self.choice_confirm_button = None
        self.choice = None
        self.lock = False

    def set_json_handler(self, json_handler):
        '''
        Sets the json handler so that if there exists login details, it can be used
        '''
        self.json_handler = json_handler

    def post_choice(self):
        '''
        Displays a option menu that lets the user decide to update / create a
        file
        '''
        # Choice option toggle button
        options = ['Create', 'Update']
        desc = 'Type'
        val = options[0]
        self.choice_button = self.widget.toggle_with_options_button(
            desc, val, options)
        display(self.choice_button)
        # Confirmation button
        desc = 'Select'
        self.choice_confirm_button = self.widget.button(desc)
        self.choice_confirm_button.on_click(self.on_click_select)
        display(self.choice_confirm_button)

    def on_click_select(self, button):
        '''
        Sets the choice made by user between Create / Update
        '''
        self.choice = self.choice_button.value
        clear_output()
        if self.choice == 'Create':
            self.create()
        else:
            self.update()

    def create(self):
        '''
        Sets tab for creating a json
        '''
        self.user_id = 0
        if self.user_id != None:
            desc = 'Create :'
            type = 'Create'
            self.post_tab_creation(desc, type)
            self.doc_write(type)

    def update(self):
        '''
        Sets tab for updating a json
        '''
        self.user_id = 0
        if self.user_id != None:
            desc = 'Update :'
            type = 'Update'
            self.post_tab_creation(desc, type)
            self.doc_write(type)

    def post_tab_creation(self, desc, type):
        '''
        Tab to get details for the file to be uploaded / created
        '''
        tab_list = []
        title_list = []
        post_query_widget_list = []
        desc = desc
        options = ['Investigation', 'Study', 'Assay', 'Data File']
        val = options[0]
        # widget for type of doc
        create_options_dropdown = self.widget.dropdown_widget(
            options, val, desc)
        post_query_widget_list.append(create_options_dropdown)

        if type == 'Create':
            desc = 'Parent ID :'
        else:
            desc = 'ID :'
        bool = False
        min = 1
        max = sys.maxsize
        val = min
        # Input box for ID
        # ID can either be for the current file or the parent Project file
        #           ID = updating current file
        #    Parent ID = creating new file
        id_widget = self.widget.bounded_int_text_widget(
            val, desc, bool, min, max)
        post_query_widget_list.append(id_widget)
        # extra widget for updating
        # the extra widget is used to fill the form with the current file
        # details
        if type == 'Create':
            self.post_query_container = widgets.VBox(
                [post_query_widget_list[0], post_query_widget_list[1]])
        else:
            desc = 'Load details'
            load_button = self.widget.button(desc)
            load_button.on_click(self.on_click_load_update)
            post_query_widget_list.append(load_button)
            #Formats the widgets into a column
            self.post_query_container = widgets.VBox([
                post_query_widget_list[0], post_query_widget_list[1],
                post_query_widget_list[2]
            ])
        tab_list.append(self.post_query_container)
        title_list.append('Post details')
        self.create_tab = self.widget.tab(tab_list, title_list)
        display(self.create_tab)

    def doc_write(self, type):
        '''
        Creates a tab that allows the user to fill the details for JSON to be
        uploaded
        '''
        tab_list = []
        title_list = []
        accordion_widget_list = []
        vbox_widget_list = []
        # Fields that are necessary for a json to be uploaded
        self.doc_write_compulsory_tab = self.compulsory_fields()
        accordion_widget_list.append(self.doc_write_compulsory_tab)
        # Fields that are necessary for a assay json to be uploaded
        self.doc_write_assay_tab = self.assay_fields()
        accordion_widget_list.append(self.doc_write_assay_tab)
        # Fields that are necessary for a data file json to be uploaded
        self.doc_write_data_file_tab = self.data_file_fields()
        accordion_widget_list.append(self.doc_write_data_file_tab)
        # Fields that are optional
        self.doc_write_optional_tab = self.optional_fields()
        accordion_widget_list.append(self.doc_write_optional_tab)

        self.post_accordion = self.widget.accordion(accordion_widget_list, 3)

        self.post_accordion.set_title(0, 'Compulsory')
        self.post_accordion.set_title(1, 'Assay options')
        self.post_accordion.set_title(2, 'Data File options')
        self.post_accordion.set_title(3, 'Optional')
        self.post_accordion.selected_index = 0
        vbox_widget_list.append(self.post_accordion)

        if type == 'Create':
            desc = 'Create'
        else:
            desc = 'Update'

        post_button = self.widget.button(desc)
        post_button.on_click(self.on_click_post)

        vbox_widget_list.append(post_button)
        doc_container = widgets.VBox(
            [vbox_widget_list[0], vbox_widget_list[1]])
        tab_list.append(doc_container)
        title_list.append('Document Details')
        self.doc_write_tab = self.widget.tab(tab_list, title_list)
        display(self.doc_write_tab)

    def compulsory_fields(self):
        '''
        Fields that are compulsory for JSON file
                - Title
                - Description
        '''
        doc_write_widget_list = []

        desc = 'Title :'
        val = ''
        title_input = self.widget.text_widget(val, desc, 2)
        doc_write_widget_list.append(title_input)

        desc = 'Description :'
        val = ''
        desc_input = self.widget.text_area_widget(val, desc, 2)
        doc_write_widget_list.append(desc_input)

        compulsory_container = widgets.VBox(
            [doc_write_widget_list[0], doc_write_widget_list[1]])
        return compulsory_container

    def data_file_fields(self):
        '''
        Fields that are compulsory for Data file JSON file
                - URL of data file
                - Filename
                - License

        Also allows the data file to be linked to related assays
        '''
        doc_write_widget_list = []

        desc = 'URL :'
        val = ''
        url_input = self.widget.text_widget(val, desc, 2)
        doc_write_widget_list.append(url_input)

        desc = 'Filename :'
        val = ''
        filename_input = self.widget.text_widget(val, desc, 2)
        doc_write_widget_list.append(filename_input)

        desc = 'Licences :'
        options = [
            'CC0-1.0', 'CC-BY-4.0', 'CC-BY-SA-4.0', 'ODC-BY-1.0', 'ODbL-1.0',
            'ODC-PDDL-1.0', 'notspecified', 'other-at', 'other-open',
            'other-pd', 'AFL-3.0', 'Against-DRM', 'CC-BY-NC-4.0', 'DSL',
            'FAL-1.3', 'GFDL-1.3-no-cover-texts-no-invariant-sections',
            'geogratis', 'hesa-withrights', 'localauth-withrights', 'MirOS',
            'NPOSL-3.0', 'OGL-UK-1.0', 'OGL-UK-2.0', 'OGL-UK-3.0',
            'OGL-Canada-2.0', 'OSL-3.0', 'dli-model-use', 'Talis',
            'ukclickusepsi', 'ukcrown-withrights', 'ukpsi'
        ]
        url_input = self.widget.select(desc, options, 1, 4)
        doc_write_widget_list.append(url_input)

        desc = 'Assay ID :'
        val = 1
        max = sys.maxsize
        min = 1
        assay_id_input = self.widget.bounded_int_text_widget(
            val, desc, False, min, max)
        doc_write_widget_list.append(assay_id_input)

        desc = 'Add :'
        add_button = self.widget.button(desc)
        add_button.on_click(self.on_click_add)
        doc_write_widget_list.append(add_button)

        desc = 'Assay list:'
        int_options = []
        default_value = []
        assay_ids_select = self.widget.select_multiple(0, int_options,
                                                       default_value, 3, desc)
        doc_write_widget_list.append(assay_ids_select)

        desc = 'Remove :'
        remove_button = self.widget.button(desc)
        remove_button.on_click(self.on_click_remove)
        doc_write_widget_list.append(remove_button)

        data_file_info_container = widgets.VBox([
            doc_write_widget_list[0], doc_write_widget_list[1],
            doc_write_widget_list[2], doc_write_widget_list[3],
            doc_write_widget_list[4], doc_write_widget_list[5],
            doc_write_widget_list[6]
        ])
        return data_file_info_container

    def optional_fields(self):
        '''
        Optional information displayed :
                - Version number
                - Public Access setting
        '''
        doc_write_widget_list = []
        ver = ''
        desc = 'Version :'
        version_widget = self.widget.text_widget(ver, desc)
        version_widget.disabled = True
        version_widget.value = '1.0'
        doc_write_widget_list.append(version_widget)

        desc = 'Access :'
        options = ['no_access', 'view', 'download', 'edit', 'manage']
        access_widget = self.widget.select(desc, options)
        doc_write_widget_list.append(access_widget)

        optional_container = widgets.VBox(
            [doc_write_widget_list[0], doc_write_widget_list[1]])
        return optional_container

    def check_access_chosen(self):
        access = self.doc_write_optional_tab.children[1].value
        options = ['no_access', 'view', 'download', 'edit', 'manage']
        create_doc = self.create_tab.children[0].children[0].value

        if create_doc == 'Project':
            pass
        elif create_doc == 'Investigation':
            if access != 'no_access' and access != 'view':
                access = 'view'
        elif create_doc == 'Study':
            if access != 'no_access' and access != 'view':
                access = 'view'
        elif create_doc == 'Assay':
            if access != 'no_access' and access != 'view':
                access = 'view'
        elif create_doc == 'Data File':
            if access != 'no_access' and access != 'view' and access != 'download':
                access = 'download'
        return access

    def assay_fields(self):
        '''
        Fields that are compulsory for assay JSON file
                - Title
                - Description
                - Assay Class
                - Assay Type
                - Assay Tech Type
        '''
        doc_write_widget_list = []

        desc = 'Assay Class :'
        options = ['EXP', 'MODEL']
        class_type_button = self.widget.toggle_with_options_button(
            desc, options[0], options)
        doc_write_widget_list.append(class_type_button)

        desc = 'Assay Type :'
        val = ''
        JERM_type_input = self.widget.text_widget(val, desc, 2)
        doc_write_widget_list.append(JERM_type_input)

        desc = 'Tech Type :'
        val = ''
        JERM_tech_type_input = self.widget.text_widget(val, desc, 2)
        doc_write_widget_list.append(JERM_tech_type_input)

        compulsory_container = widgets.VBox([
            doc_write_widget_list[0], doc_write_widget_list[1],
            doc_write_widget_list[2]
        ])

        return compulsory_container

    def on_click_load_update(self, button):
        '''
        Load data for widgets
        '''
        type = self.post_query_container.children[0].value
        id = self.post_query_container.children[1].value
        self.json = self.json_handler.get_JSON(type, id)

        if self.json:
            self.fill_form(type)

    def on_click_add(self, button):
        '''
        Add Assay ID to a list of assays to link
        '''
        id = self.doc_write_data_file_tab.children[3].value
        options = self.doc_write_data_file_tab.children[5].options
        # remove duplicates
        options = list(options)
        options.append(id)
        options = list(dict.fromkeys(options))
        # options.remove('None')
        self.doc_write_data_file_tab.children[5].options = options

    def on_click_remove(self, button):
        '''
        Remove Assay ID from a list of assays to link
        '''
        id = self.doc_write_data_file_tab.children[5].value
        id = list(id)
        id = id[0]
        options = self.doc_write_data_file_tab.children[5].options
        options = list(options)

        options.remove(id)
        self.doc_write_data_file_tab.children[5].options = options

    def fill_form(self, type):
        '''
        Fills widget boxes with the data from JSON downloaded
        Only used for a update function call
        '''
        self.doc_write_compulsory_tab.children[0].value =\
                                        self.json_handler.get_title(self.json)
        self.doc_write_compulsory_tab.children[1].value =\
                                        self.json_handler.get_description(self.json)
        self.doc_write_optional_tab.children[0].value =\
                                        self.json_handler.get_version(self.json)
        self.doc_write_optional_tab.children[1].value =\
                                        self.json_handler.get_public_access(self.json)

        if type == 'Data File':
            blob = self.json_handler.get_blob(self.json)
            self.doc_write_data_file_tab.children[0].value =\
                                            self.json_handler.get_url(blob)
            self.doc_write_data_file_tab.children[1].value =\
                                            self.json_handler.get_filename(blob)
            self.doc_write_data_file_tab.children[2].value =\
                                            self.json_handler.get_license(self.json)
            assays_list = self.json_handler.get_relationship_assays(self.json)
            assay_ids = self.iterate_over_json_list(assays_list)

            self.doc_write_data_file_tab.children[5].options = assay_ids
        elif type == 'Assay':
            assay_class = self.json_handler.get_assay_class(self.json)
            assay_class = assay_class.get('key')
            if assay_class == 'EXP':
                index = 0
            else:
                index = 1
            self.doc_write_assay_tab.children[0].value = \
                        self.doc_write_assay_tab.children[0].options[index]
            if assay_class == 'EXP':
                assay_type = self.json_handler.get_assay_type_uri(self.json)
                # print(assay_type)
                # assay_type = assay_class.get('uri')
                self.doc_write_assay_tab.children[1].value = assay_type

                technology_type = self.json_handler.get_assay_tech_type_uri(
                    self.json)
                # technology_type = assay_class.get('uri')
                self.doc_write_assay_tab.children[2].value = technology_type

    def on_click_post(self, button):
        '''
        Post JSON to fairdom by creating necessary hash (JSON)
        '''
        create_doc = self.create_tab.children[0].children[0].value
        id = self.create_tab.children[0].children[1].value
        title = self.doc_write_tab.children[0].children[0].children[
            0].children[0].value
        desc = self.doc_write_tab.children[0].children[0].children[0].children[
            1].value
        url = self.doc_write_data_file_tab.children[0].value
        filename = self.doc_write_data_file_tab.children[1].value
        license = self.doc_write_data_file_tab.children[2].value
        access = self.doc_write_optional_tab.children[1].value
        access = self.check_access_chosen()
        if self.choice == 'Update':
            current_id = str(id)
            id = self.get_parent_id()
        valid = True
        if title == '':
            valid = False
            print('Title can not be left empty')

        # if create_doc == 'Data File':
        #     if url == '':
        #         valid = False
        #         print('URL can not be left empty')
        #     if filename == '':
        #         valid = False
        #         print('Filename can not be left empty')

        if valid == True:
            if create_doc == 'Project':
                pass
            elif create_doc == 'Investigation':
                hash = self.investigation_hash(title, desc, access, id)
                type = 'Investigation'
            elif create_doc == 'Study':
                type = 'Study'
                hash = self.study_hash(title, desc, access, id)
            elif create_doc == 'Assay':
                assay_class = self.doc_write_assay_tab.children[0].value
                assay_type = self.doc_write_assay_tab.children[1].value
                assay_tech_type = self.doc_write_assay_tab.children[2].value
                type = 'Assay'
                hash = self.assay_hash(title, desc, access, id, assay_class,
                                       assay_type, assay_tech_type)
            elif create_doc == 'Data File':
                type = 'Data File'
                hash = self.data_file_hash(title, desc, access, id, license,
                                           url, filename)
            if self.choice == 'Update':
                id_returned = self.json_handler.post_json(
                    type, hash, self.choice, current_id)
            else:
                id_returned = self.json_handler.post_json(
                    type, hash, self.choice)
            if id_returned != None:
                if create_doc == 'Data File':
                    self.link_data_files_to_assays(id_returned)

        # print(id)
    def get_parent_id(self):
        '''
        Used in updating
        Gets the parent ID that the file is linked to
        '''
        doc_type = self.json_handler.get_type(self.json)
        if doc_type == 'investigations':
            parent_dict = self.json_handler.get_relationship_projects(
                self.json)
        elif doc_type == 'studies':
            parent_dict = self.json_handler.get_relationship_investigations(
                self.json)
        elif doc_type == 'assays':
            parent_dict = self.json_handler.get_relationship_studies(self.json)
        elif doc_type == 'data_files':
            parent_dict = self.json_handler.get_relationship_projects(
                self.json)
        id = self.iterate_over_json_list(parent_dict)
        return id

    def iterate_over_json_list(self, data):
        '''
        Gets list of dictionary keys
        '''
        ids = []
        for value in data:
            ids.append(value.get('id'))
        return ids

    def get_user_id(self):
        '''
        Gets user ID
        NOT IMPLEMENTED FOR CURRENT VERSION OF API
        '''
        self.user_id = self.json_handler.get_user_id()
        if user_id == {}:
            self.user_id = None
            print('Need Correct login details')

    def investigation_hash(self, title, desc, access, id):
        '''
        JSON for Investigation
        '''
        type = 'Investigation'
        investigation = {}
        investigation['data'] = {}
        investigation['data']['type'] = 'investigations'
        investigation['data']['attributes'] = {}
        investigation['data']['attributes']['title'] = title
        investigation['data']['attributes']['description'] = desc
        investigation['data']['attributes']['policy'] = {}

        investigation['data']['attributes']['policy']['access'] = access
        investigation['data']['relationships'] = {}
        investigation['data']['relationships']['projects'] = {}
        investigation['data']['relationships']['projects']['data'] = [{
            'id':
            id,
            'type':
            'projects'
        }]
        # id = self.json_handler.post_json(type,investigation)
        return investigation

    def study_hash(self, title, desc, access, id):
        '''
        JSON for Study
        '''
        type = 'Study'
        study = {}
        study['data'] = {}
        study['data']['type'] = 'studies'
        study['data']['attributes'] = {}
        study['data']['attributes']['title'] = title
        study['data']['attributes']['description'] = desc
        study['data']['attributes']['policy'] = {}

        study['data']['attributes']['policy']['access'] = access
        # study['data']['attributes']['policy'] = {'access':'view', 'permissions': [{'resource': {'id': '1','type': 'people'},'access': 'manage'}]}
        study['data']['relationships'] = {}
        study['data']['relationships']['investigation'] = {}
        study['data']['relationships']['investigation']['data'] = {
            'id': id,
            'type': 'investigations'
        }
        # id = self.json_handler.post_json(type,study)
        return study

    def assay_hash(self, title, desc, access, id, assay_class, assay_type,
                   assay_tech_type):
        '''
        JSON for Assay
        '''
        type = 'Assay'
        assay = {}
        assay['data'] = {}
        assay['data']['type'] = 'assays'
        assay['data']['attributes'] = {}
        assay['data']['attributes']['title'] = title
        assay['data']['attributes']['description'] = desc
        assay['data']['attributes']['policy'] = {}
        assay['data']['attributes']['policy']['access'] = access
        assay['data']['attributes']['assay_class'] = {}
        assay['data']['attributes']['assay_class']['key'] = assay_class
        if assay_class == 'EXP':
            assay['data']['attributes']['assay_type'] = {}
            assay['data']['attributes']['assay_type']['uri'] = assay_type
            assay['data']['attributes']['technology_type'] = {}
            assay['data']['attributes']['technology_type'][
                'uri'] = assay_tech_type
        assay['data']['relationships'] = {}
        assay['data']['relationships']['study'] = {}
        assay['data']['relationships']['study']['data'] = {
            'id': id,
            'type': 'studies'
        }
        # id = self.json_handler.post_json(type,assay)
        return assay

    def data_file_hash(self, title, desc, access, id, license, url, filename):
        '''
        JSON for Data File
        '''
        data_file = {}
        data_file['data'] = {}
        data_file['data']['type'] = 'data_files'
        data_file['data']['attributes'] = {}
        data_file['data']['attributes']['title'] = title
        data_file['data']['attributes']['description'] = desc
        data_file['data']['attributes']['license'] = license
        data_file['data']['attributes']['policy'] = {}
        data_file['data']['attributes']['policy']['access'] = access
        data_file['data']['relationships'] = {}
        data_file['data']['relationships']['projects'] = {}
        data_file['data']['relationships']['projects']['data'] = [{
            'id':
            id,
            'type':
            'projects'
        }]

        remote_blob = {'url': url, 'original_filename': filename}
        data_file['data']['attributes']['content_blobs'] = [remote_blob]
        return (data_file)

    def link_data_files_to_assays(self, id):
        '''
        Updates the JSON for Assays to include a relation to data file uploaded
        '''
        # list of assay ids to link
        assay_ids = self.doc_write_data_file_tab.children[5].options
        # for each id , update the JSON
        for item in assay_ids:
            assay_json = self.json_handler.get_JSON('Assay', item)
            assay_data_files = self.json_handler.get_relationship_data_files(
                assay_json)
            id_list = self.iterate_over_json_list(assay_data_files)
            # Create a dict so that it can check if that id already exists
            id_dict = {
                id_list[item_ID]: 'id'
                for item_ID in range(0, len(id_list))
            }
            assay = {}
            assay['data'] = {}
            assay['data']['type'] = 'assays'
            assay['data']['relationships'] = {}
            assay['data']['relationships']['data_files'] = {}
            if item not in id_dict:
                new_relation_data_file = {}
                new_relation_data_file = {'id': id, 'type': 'data_files'}
                assay_data_files.append(new_relation_data_file)
                assay['data']['relationships']['data_files'][
                    'data'] = assay_data_files
                id_returned = self.json_handler.post_json(
                    'Assay', assay, 'Update', str(item))