示例#1
0
class CKANBrowserDialog(QtGui.QDialog, FORM_CLASS):

    def __init__(self, settings, iface, parent=None):
        """Constructor."""
        super(CKANBrowserDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        self.iface = iface
        self.main_win = parent
        self.search_txt = ''
        self.cur_package = None
        self.result_count = 0
        self.current_page = 1
        self.page_count = 0
        self.current_group = None
        # TODO:
        # * create settings dialog
        # * read SETTINGS

        self.settings = settings
        self.util = Util(self.settings, self.main_win)

        self.IDC_lblApiUrl.setText(self.util.tr('py_dlg_base_server') + self.settings.ckan_url)
        self.IDC_lblCacheDir.setText(self.util.tr('py_dlg_base_cache_path') + self.settings.cache_dir)
        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        # TODO: automatically populate version
        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111
        self.IDC_lblVersion.setText(self.util.tr('py_dlg_base_version').format(self.settings.version))
        self.IDC_lblSuchergebnisse.setText(self.util.tr('py_dlg_base_search_result'))
        self.IDC_lblPage.setText(self.util.tr('py_dlg_base_page_1_1'))

        icon_path = self.util.resolve(u'icon-copy.png')
        self.IDC_bCopy.setIcon(QtGui.QIcon(icon_path))

        self.cc = CkanConnector(self.settings, self.util)

        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.window_loaded)
        QApplication.setOverrideCursor(Qt.WaitCursor)

    def showEvent(self, event):
        self.util.msg_log('showevent')
        QDialog.showEvent(self, event)
        if self.timer is not None:
            self.timer.start(500)
        self.util.msg_log('showevent finished')

    def window_loaded(self):
        try:
            self.util.msg_log('window_loaded')
            self.util.msg_log('before stop')
            self.timer.stop()
            self.timer = None
            self.util.msg_log('before get_groupds')
            ok, result = self.cc.get_groups()
            if ok is False:
                QApplication.restoreOverrideCursor()
                self.util.dlg_warning(result)
                return

            if not result:
                self.list_all_clicked()
            else:
                for entry in result:
                    item = QListWidgetItem(entry['display_name'])
                    item.setData(Qt.UserRole, entry)
                    #item.setCheckState(Qt.Checked)
                    item.setCheckState(Qt.Unchecked)
                    self.IDC_listGroup.addItem(item)
        finally:
            QApplication.restoreOverrideCursor()


    def close_dlg(self):
        QDialog.reject(self)


    def show_disclaimer(self):
        self.dlg_disclaimer = CKANBrowserDialogDisclaimer(self.settings)
        self.dlg_disclaimer.show()

    def searchtextchanged(self, search_txt):
        self.search_txt = search_txt

    def suchen(self):
        self.current_page = 1
        self.current_group = None
        self.__search_package()

    def list_all_clicked(self):
        self.current_page = 1
        self.current_group = None
        # don't hint on wildcards, empty text works as well, as CKAN uses *:* as
        # default when ?q= has not text
        # self.IDC_lineSearch.setText('*:*')
        self.IDC_lineSearch.setText('')
        self.__search_package()

    def category_item_clicked(self, item):
        self.util.msg_log(item.data(Qt.UserRole)['name'])
        self.current_group = item.data(Qt.UserRole)['name']
        self.current_page = 1
        self.__search_package()

    def __search_package(self, page=None):
        self.IDC_listResults.clear()
        #if self.search_txt == u'' and self.current_group is None:
        #    return
        if page is not None:
            self.util.msg_log(u'page is not None, cp:{0} pg:{1}'.format(self.current_page, page))
            self.current_page = self.current_page + page
            if self.current_page > self.page_count:
                self.current_page = self.page_count
            if self.current_page < 1:
                self.current_page = 1
            self.util.msg_log(u'page is not None, cp:{0} pg:{1}'.format(self.current_page, page))
        QApplication.setOverrideCursor(Qt.WaitCursor)
        if self.current_group is None:
            # normal query: limit query to checked groups, or all if unchecked
            self.util.msg_log(u'normal query')
            groups = self.__get_selected_groups()
            ok, result = self.cc.package_search(self.search_txt, groups, self.current_page)
        else:
            # double click on group in list, ignore query and return all
            # packages for group
            self.util.msg_log(u'query everything for group:{0}'.format(self.current_group))
            ok, result = self.cc.show_group(self.current_group, self.current_page)
        QApplication.restoreOverrideCursor()
        if ok is False:
            self.util.dlg_warning(result)
            return
        #if self.current_group is None:
        #    self.result_count = result['count']
        #else:
        #    self.result_count = len(result)
        self.result_count = result['count']
        if self.result_count == 0:
            self.current_page = 1
            self.page_count = 1
            self.IDC_lblSuchergebnisse.setText(self.util.tr('py_dlg_base_search_result_0'))
            item = QListWidgetItem(self.util.tr('py_dlg_base_no_result'))
            item.setData(Qt.UserRole, None)
            self.IDC_listResults.addItem(item)
            return

        # self.current_page = 1
        self.page_count = int(math.ceil(self.result_count / self.settings.results_limit))
        if self.result_count % self.settings.results_limit != 0:
            self.page_count += 1
        erg_text = self.util.tr(u'py_dlg_base_result_count').format(self.result_count)
        page_text = self.util.tr(u'py_dlg_base_page_count').format(self.current_page, self.page_count)
        self.IDC_lblSuchergebnisse.setText(erg_text)
        self.IDC_lblPage.setText(page_text)

        #if self.current_group is None:
        #    results = result['results']
        #else:
        #    results = result
        results = result['results']

        for entry in results:
            title_txt = u'no title available'
            e = entry['title']
            if e is None:
                title_txt = 'no title'
            elif isinstance(e, dict):
                # HACK! use first value
                title_txt = e.itervalues().next()
            elif isinstance(e, list):
                # HACK! use first value
                title_txt = e[0]
            else:
                title_txt = e
            item = QListWidgetItem(title_txt)
            item.setData(Qt.UserRole, entry)
            self.IDC_listResults.addItem(item)

    def list_group_item_changed(self, item):
        self.searchtextchanged(self.IDC_lineSearch.text())

    def resultitemchanged(self, new_item):
        self.IDC_textDetails.setText('')
        self.IDC_listRessources.clear()
        self.IDC_plainTextLink.clear()
        if new_item is None:
            return
        package = new_item.data(Qt.UserRole)
        self.cur_package = package
        if package is None:
            return
        self.IDC_textDetails.setText(
            u'{0}\n\n{1}\n{2}\n\n{3}'.format(
                package.get('notes', 'no notes'),
                package.get('author', 'no author'),
                package.get('author_email', 'no author_email'),
                package.get('license_id', 'no license_id')
            )
        )
        if package.get('num_resources', 0) > 0:
            for res in package['resources']:
                item = QListWidgetItem(u'{0}: {1}'.format(
                    res.get('format', 'no format')
                    , res.get('name', 'no name')
                ))
                item.setData(Qt.UserRole, res)
                item.setCheckState(Qt.Unchecked)
                self.IDC_listRessources.addItem(item)

    def resource_item_changed(self, new_item):
        if new_item is None:
            return
        url = new_item.data(Qt.UserRole)['url']
        self.util.msg_log(url)
        self.__fill_link_box(url)


    def load_resource_clicked(self):
        res = self.__get_selected_resources()
        if res is None:
            self.util.dlg_warning(self.util.tr(u'py_dlg_base_warn_no_resource'))
            return
        #self.util.dlg_warning(u'pkg:{0} res:{1} {2}'.format(self.cur_package['id'], res[0]['id'], res[0]['url']))
        for resource in res:
            if resource['name'] is None:
#                 self.util.dlg_warning(self.util.tr(u'py_dlg_base_warn_no_resource_name').format(resource['id']))
#                 continue
                resource['name'] = "Unnamed resource"
            if self.settings.debug:
                self.util.msg_log(u'Bearbeite: {0}'.format(resource['name']))
            dest_dir = os.path.join(
                self.settings.cache_dir,
                self.cur_package['id'],
                resource['id']
            )
            if self.util.create_dir(dest_dir) is False:
                self.util.dlg_warning(self.util.tr(u'py_dlg_base_warn_cache_dir_not_created').format(dest_dir))
                return

            dest_file = os.path.join(dest_dir, os.path.split(resource['url'])[1])

            # wmts
            format_lower = resource['format'].lower()
            if format_lower == 'wms':
                format_lower = 'wmts'
            if format_lower == 'wmts':
                resource_url = resource['url']
                resource_url_lower = resource_url.lower()
                if not resource_url_lower.endswith('.qlr'):
                    dest_file += '.wmts'
                #pyperclip.copy(resource_url)
                """
                self.util.dlg_information(u'{0}\n{1}\n\n{2}\n{3}\n{4}'.format(
                    u'WMTS kann nicht automatisch geladen werden.',
                    u'Der Link wurde in die Zwischenablage kopiert.',
                    u'Layer -> Layer hinzufügen -> ',
                    u'WMS/WMTS-Layer hinzufügen ->',
                    u'Neu -> im Textfeld "URL" Strg+V drücken'
                ))
                continue
                """
            if format_lower == 'wfs':
                dest_file += '.wfs'
            if format_lower == 'georss':
                dest_file += '.georss'

            do_download = True
            do_delete = False
            if os.path.isfile(dest_file):
                if QMessageBox.Yes == self.util.dlg_yes_no(self.util.tr(u'py_dlg_base_data_already_loaded')):
                    do_delete = True
                    do_download = True
                else:
                    do_download = False
            if do_download is True:
                file_size_ok, file_size = self.cc.get_file_size(resource['url'])
                # Silently ignore the error
                if not file_size_ok:
                    file_size = 0
                #if not file_size_ok and QMessageBox.No == self.util.dlg_yes_no(self.util.tr(u'<b>The download size could not be determined, proceed anyway?</b><br> {}.').format(file_size)):
                #    continue
                #else:
                #    file_size = 0
                if file_size > 50 and QMessageBox.No == self.util.dlg_yes_no(self.util.tr(u'py_dlg_base_big_file').format(file_size)):
                    continue  # stop process if user does not want to download the file
                QApplication.setOverrideCursor(Qt.WaitCursor)
                ok, err_msg, new_file_name = self.cc.download_resource(
                    resource['url']
                    , resource['format']
                    , dest_file
                    , do_delete
                )
                QApplication.restoreOverrideCursor()
                if ok is False:
                    #self.util.dlg_warning(self.util.tr(u'py_dlg_base_download_error').format(err_msg))
                    self.util.dlg_warning(err_msg)
                    continue
                # set new file name obtained from service 'content-disposition'
                if new_file_name:
                    dest_file = new_file_name
                if os.path.basename(dest_file).lower().endswith('.zip'):
                    ok, err_msg = self.util.extract_zip(dest_file, dest_dir)
                    QApplication.restoreOverrideCursor()
                    if ok is False:
                        self.util.dlg_warning(self.util.tr(u'py_dlg_base_warn_not_extracted').format(err_msg))
                        continue

            #QApplication.setOverrideCursor(Qt.WaitCursor)
            ok, err_msg = self.util.add_lyrs_from_dir(dest_dir, resource['name'], resource['url'])
            #QApplication.restoreOverrideCursor()
            if ok is False:
#                 self.util.dlg_warning(self.util.tr(u'py_dlg_base_lyr_not_loaded').format(resource['name'], err_msg))
                if isinstance(err_msg, dict):
                    if QMessageBox.Yes == self.util.dlg_yes_no(self.util.tr(u'py_dlg_base_open_manager').format(resource['url'])):
                        self.util.open_in_manager(err_msg["dir_path"])
                else:
                    self.util.dlg_warning(self.util.tr(u'py_dlg_base_lyr_not_loaded').format(resource['name'], err_msg))
                continue

    def next_page_clicked(self):
        self.__search_package(page=+1)


    def previous_page_clicked(self):
        self.__search_package(page=-1)

    def copy_clipboard(self):
        pyperclip.copy(self.IDC_plainTextLink.toPlainText())

    def __fill_link_box(self, url):
        self.IDC_plainTextLink.setPlainText(url)

    def __get_selected_groups(self):
        groups = []
        for i in range(0, self.IDC_listGroup.count()):
            item = self.IDC_listGroup.item(i)
            if item.checkState() == Qt.Checked:
                groups.append(item.data(Qt.UserRole)['name'])

        # None: means search all groups
        if len(groups) < 1 or len(groups) == self.IDC_listGroup.count():
            return None
        return groups

    def __get_selected_resources(self):
        res = []
        for i in range(0, self.IDC_listRessources.count()):
            item = self.IDC_listRessources.item(i)
            if item.checkState() == Qt.Checked:
                res.append(item.data(Qt.UserRole))

        if len(res) < 1:
            return None
        return res


    def _shorten_path(self, s):
        """ private class to shorten string to 33 chars and place a html-linebreak inside"""
        result = u""
        if len(s) > 33:
            result = s[:33] + u'<br />' + self._shorten_path(s[33:])
        else:
            return s
        return result

    def help_ttip_search(self):
        self.util.dlg_information(self.util.tr(u'dlg_base_ttip_search'))

    def help_ttip_filter(self):
        self.util.dlg_information(self.util.tr(u'dlg_base_ttip_filter'))

    def help_ttip_data_list(self):
        self.util.dlg_information(self.util.tr(u'dlg_base_ttip_data_list'))

    def help_ttip_resource(self):
        self.util.dlg_information(self.util.tr(u'dlg_base_ttip_resource'))
示例#2
0
 def show_disclaimer(self):
     self.dlg_disclaimer = CKANBrowserDialogDisclaimer(self.settings)
     self.dlg_disclaimer.show()