示例#1
0
class WebPage(QWebEnginePage):
    _s_kEnableJsOutput = qEnvironmentVariable('APP_ENABLE_JS_OUTPUT') != ''
    _s_kEnableJsNonBlockDialogs = qEnvironmentVariable('APP_ENABLE_JS_NONBLOCK_DIALOGS', 'yes') != '0'
    # JsWorld
    UnsafeJsWorld = QWebEngineScript.MainWorld
    SafeJsWorld = QWebEngineScript.ApplicationWorld

    # static members
    s_lastUploadLocation = ''
    s_lastUnsupportedUrl = QUrl()
    s_lastUnsupportedUrlTime = QTime()

    # private members
    _s_lastUploadLocation = QDir.homePath()
    _s_supportedSchemes = []  # QStringList
    def __init__(self, parent=None):
        super().__init__(gVar.app.webProfile(), parent)
        self._fileWatcher = None  # DelayedFileWatcher
        self._runningLoop = None  # QEventLoop

        self._autoFillUsernames = []  # QStringList
        # QWebEngineRegisterProtocolHandlerRequest
        self._registerProtocolHandlerRequest = None

        self._loadProgress = 0
        self._blockAlerts = False
        self._secureStatus = False

        self._contentsResizedConnection = None # QMetaObject::Connection

        channel = QWebChannel(self)
        ExternalJsObject.setupWebChannel(channel, self)
        self.setWebChannel(channel, self.SafeJsWorld)

        self.loadProgress.connect(self._progress)
        self.loadFinished.connect(self._finished)
        self.urlChanged.connect(self._urlChanged)
        self.featurePermissionRequested.connect(self._featurePermissionRequested)
        self.windowCloseRequested.connect(self._windowCloseRequested)
        self.fullScreenRequested.connect(self._fullScreenRequested)
        self.renderProcessTerminated.connect(self._renderProcessTerminated)

        def authFunc(url, auth, proxyHost):
            '''
            @param: url QUrl
            @param: auth QAuthenticator
            @param: proxyHost QString
            '''
            gVar.app.networkManager().proxyAuthentication(proxyHost, auth, self.view())
        self.authenticationRequired.connect(authFunc)

        # Workaround QWebEnginePage not scrolling to anchors when opened in
        # background tab
        def contentsResizeFunc():
            # QString
            fragment = self.url().fragment()
            if fragment:
                self.runJavaScript(Scripts.scrollToAnchor(fragment))
            self.contentsSizeChanged.disconnect(self._contentsResizedConnection)
        self._contentsResizedConnection = self.contentsSizeChanged.connect(contentsResizeFunc)

        # Workaround for broken load started/finished signals in QWebEngine 5.10 5.11
        # NOTE: if open this revise, will cause page and view loadFinished emit
        # multi time
        #def loadProgressFunc(progress):
        #    '''
        #    @param: progress int
        #    '''
        #    if progress == 100:
        #        self.loadFinished.emit(True)
        #self.loadProgress.connect(loadProgressFunc)

        if const.QTWEBENGINEWIDGETS_VERSION >= const.QT_VERSION_CHECK(5, 11, 0):
            def registerProtocolHandlerFunc(request):
                '''
                @param: request QWebEngineRegisterProtocolHandlerRequest
                '''
                del self._registerProtocolHandlerRequest
                self._registerProtocolHandlerRequest = QWebEngineRegisterProtocolHandlerRequest(request)
            self.registerProtocolHandlerRequested.connect(registerProtocolHandlerFunc)

        if const.QTWEBENGINEWIDGETS_VERSION >= const.QT_VERSION_CHECK(5, 12, 0):
            super().printRequested.connect(self.printRequested)

            def selectClientCertFunc(selection):
                '''
                @param: selection QWebEngineClientCertificateSelection
                '''
                # TODO: It should prompt user, and Falkon does not support yet.
                selection.select(selection.certificates()[0])
            self.selectClientCertificate.connect(selectClientCertFunc)

    def view(self):
        '''
        @return: WebView
        '''
        # return static_cast<WebView*>(QWebEnginePage::view())
        return super().view()

    def execPrintPage(self, printer, timeout=1000):
        '''
        @param: pointer QPointer
        @param: timeout int
        '''

    def execJavaScript(self, scriptSource, worldId=UnsafeJsWorld, timeout=500):
        '''
        @param: scriptSource QString
        @return: QVariant
        '''
        loop = QEventLoop()  # QPointer<QEventLoop>
        result = None
        QTimer.singleShot(timeout, loop.quit)

        def runCb(res):
            nonlocal result
            if loop and loop.isRunning():
                result = res
                loop.quit()

        self.runJavaScript(scriptSource, worldId, runCb)
        loop.exec_(QEventLoop.ExcludeUserInputEvents)

        return result

    def mapToViewport(self, pos):
        '''
        @param: pos QPointF
        @return: QPointF
        '''
        return QPointF(pos.x() / self.zoomFactor(), pos.y() / self.zoomFactor())

    def hitTestContent(self, pos):
        '''
        @param: QPoint
        @return: WebHitTestResult
        '''
        return WebHitTestResult(self, pos)

    def scroll(self, x, y):
        self.runJavaScript("window.scrollTo(window.scrollX + %s, window.scrollY + %s)" %
                (x, y), self.SafeJsWorld)

    def setScrollPosition(self, pos):
        '''
        @param: pos QPointF
        '''
        # QPointF
        v = self.mapToViewport(pos.toPoint())
        self.runJavaScript("window.scrollTo(%s, %s)" % (v.x(), v.y()), self.SafeJsWorld)

    # override
    def javaScriptPrompt(self, securityOrigin, msg, defaultValue):
        '''
        @param: securityOrigin QUrl
        @param: msg QString
        @param: defaultValue QString
        @return: ret bool, result QString
        '''
        if not self._s_kEnableJsNonBlockDialogs:
            return super().javaScriptPrompt(securityOrigin, msg, defaultValue)

        if self._runningLoop:
            return False, defaultValue

        widget = CloseableFrame(self.view().overlayWidget())

        widget.setObjectName('jsFrame')
        ui = uic.loadUi('mc/webengine/JsPrompt.ui', widget)
        ui.message.setText(msg)
        ui.lineEdit.setText(defaultValue)
        ui.lineEdit.setFocus()
        widget.resize(self.view().size())
        widget.show()

        # QAbstractButton
        clicked = None

        def clickedCb(button):
            nonlocal clicked
            clicked = button

        ui.buttonBox.clicked.connect(clickedCb)
        ui.lineEdit.returnPressed.connect(ui.buttonBox.button(QDialogButtonBox.Ok).animateClick)
        self.view().viewportResized.connect(widget.resize)

        eLoop = QEventLoop()
        self._runningLoop = eLoop
        widget.closeRequested.connect(eLoop.quit)
        ui.buttonBox.clicked.connect(eLoop.quit)

        if eLoop.exec_() == 1:
            return False
        self._runningLoop = None

        result = ui.lineEdit.text()
        ret = ui.buttonBox.buttonRole(clicked) == QDialogButtonBox.AcceptRole

        self.view().setFocus()
        self.view().viewportResized.disconnect(widget.resize)
        ui.buttonBox.clicked.disconnect(clickedCb)

        widget.close()
        widget.deleteLater()

        return ret, result

    # override
    def javaScriptConfirm(self, securityOrigin, msg):
        '''
        @param: securityOrigin QUrl
        @param: msg QString
        '''
        if not self._s_kEnableJsNonBlockDialogs:
            return super().javaScriptConfirm(securityOrigin, msg)

        if self._runningLoop:
            return False

        widget = CloseableFrame(self.view().overlayWidget())

        widget.setObjectName('jsFrame')
        ui = uic.loadUi('mc/webengine/JsConfirm.ui', widget)
        ui.message.setText(msg)
        ui.buttonBox.button(QDialogButtonBox.Ok).setFocus()
        widget.resize(self.view().size())
        widget.show()

        # QAbstractButton
        clicked = None

        def clickedCb(button):
            nonlocal clicked
            clicked = button

        ui.buttonBox.clicked.connect(clickedCb)
        self.view().viewportResized.connect(widget.resize)

        eLoop = QEventLoop()
        self._runningLoop = eLoop
        widget.closeRequested.connect(eLoop.quit)
        ui.buttonBox.clicked.connect(eLoop.quit)

        if eLoop.exec_() == 1:
            return False
        self._runningLoop = None

        result = ui.buttonBox.buttonRole(clicked) == QDialogButtonBox.AcceptRole

        self.view().setFocus()
        self.view().viewportResized.disconnect(widget.resize)
        ui.buttonBox.clicked.disconnect(clickedCb)

        widget.close()
        widget.deleteLater()

        return result

    # override
    def javaScriptAlert(self, securityOrigin, msg):
        '''
        @param: securityOrigin QUrl
        @param: msg QString
        '''
        if self._blockAlerts or self._runningLoop:
            return

        if not self._s_kEnableJsNonBlockDialogs:
            title = _('JavaScript alert')
            if self.url().host():
                title = '%s - %s' % (title, self.url().host())

            dialog = CheckBoxDialog(QMessageBox.Ok, self.view())
            dialog.setDefaultButton(QMessageBox.Ok)
            dialog.setWindowTitle(title)
            dialog.setText(msg)
            dialog.setCheckBoxText(_('Prevent this page from creating additional dialogs'))
            dialog.setIcon(QMessageBox.Information)
            dialog.exec_()

            self._blockAlerts = dialog.isChecked()
            return

        widget = CloseableFrame(self.view().overlayWidget())

        widget.setObjectName('jsFrame')
        ui = uic.loadUi('mc/webengine/JsAlert.ui', widget)
        ui.message.setText(msg)
        ui.buttonBox.button(QDialogButtonBox.Ok).setFocus()
        widget.resize(self.view().size())
        widget.show()

        self.view().viewportResized.connect(widget.resize)

        eLoop = QEventLoop()
        self._runningLoop = eLoop
        widget.closeRequested.connect(eLoop.quit)
        ui.buttonBox.clicked.connect(eLoop.quit)

        if eLoop.exec_() == 1:
            return
        self._runningLoop = None

        self._blockAlerts = ui.preventAlerts.isChecked()

        self.view().setFocus()
        self.view().viewportResized.disconnect(widget.resize)

        widget.close()
        widget.deleteLater()

    def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
        '''
        @param: level JavaScriptConsoleMessagelevel
        @param: message QString
        @param: lineNumber int
        @param: sourceID QString
        '''
        if not self._s_kEnableJsOutput:
            return

        prefix = ''
        if level == self.InfoMessageLevel:
            prefix = '[I]'
        elif level == self.WarningMessageLevel:
            prefix = '[W]'
        elif level == self.ErrorMessageLevel:
            prefix = '[E]'

        msg = '%s%s:%s %s' % (prefix, sourceID, lineNumber, message)
        print(msg)

    def autoFillUsernames(self):
        return []  # QStringList

    def registerProtocolHandlerRequestUrl(self):
        '''
        @return: QUrl
        '''
        return QUrl()

    def registerProtocolHandlerRequestScheme(self):
        '''
        @return: QString
        '''
        return ''

    def isRunningLoop(self):
        return self._runningLoop

    def isLoading(self):
        return self._loadProgress < 100

    @classmethod
    def internalSchemes(cls):
        '''
        @return: QStringList
        '''
        return [
            'http', 'https', 'file', 'ftp', 'data', 'about', 'view-source', 'chrome'
        ]

    @classmethod
    def supportedSchemes(cls):
        '''
        @return: QStringList
        '''
        if cls._s_supportedSchemes:
            cls._s_supportedSchemes = cls.internalSchemes()
        return cls._s_supportedSchemes

    @classmethod
    def addSupportedScheme(cls, scheme):
        cls._s_supportedSchemes = cls.supportedSchemes()[:]
        if scheme not in cls._s_supportedSchemes:
            cls._s_supportedSchemes.append(scheme)

    @classmethod
    def removeSupportedScheme(cls, scheme):
        cls._s_supportedSchemes.remove(scheme)

    # Q_SIGNALS
    privacyChanged = pyqtSignal(bool)  # status
    printRequested = pyqtSignal()
    # url, NavigationType type_, isMainFrame
    navigationRequestAccepted = pyqtSignal(QUrl, int, bool)

    # protected Q_SLOTS:
    def _progress(self, prog):
        '''
        @param: prog int
        '''
        self._loadProgress = prog

        secStatus = self.url().scheme() == 'https'

        if secStatus != self._secureStatus:
            self._secureStatus = secStatus
            self.privacyChanged.emit(secStatus)

    def _finished(self):
        self._progress(100)

        # File scheme watcher
        if self.url().scheme() == 'file':
            info = QFileInfo(self.url().toLocalFile())
            if info.isFile():
                if not self._fileWatcher:
                    self._fileWatcher = DelayedFileWatcher(self)
                    self._fileWatcher.delayedFileChanged.connect(self._watchedFileChanged)

                filePath = self.url().toLocalFile()

                if QFile.exists(filePath) and filePath not in self._fileWatcher.files():
                    self._fileWatcher.addPath(filePath)
        elif self._fileWatcher and self._fileWatcher.files():
            self._fileWatcher.removePathes(self._fileWatcher.files())

        # AutoFill
        self._autoFillUsernames = gVar.app.autoFill().completePage(self, self.url())

    # private Q_SLOTS:
    def _urlChanged(self, url):
        '''
        @param: url QUrl
        '''
        if self.isLoading():
            self._blockAlerts = False

    def _watchedFileChanged(self, file_):
        '''
        @param: file_ QString
        '''
        if self.url().toLocalFile() == file_:
            self.triggerAction(QWebEnginePage.Reload)

    def _windowCloseRequested(self):
        view = self.view()
        if not view:
            return
        view.closeView()

    def _fullScreenRequested(self, fullScreenRequest):
        '''
        @param: fullScreenRequest QWebEngineFullScreenRequest
        '''
        self.view().requestFullScreen(fullScreenRequest.toggleOn())

        accepted = fullScreenRequest.toggleOn() == self.view().isFullScreen()

        if accepted:
            fullScreenRequest.accept()
        else:
            fullScreenRequest.reject()

    def _featurePermissionRequested(self, origin, feature):
        '''
        @param: origin QUrl
        @param: feature QWebEnginePage::feature
        '''
        if feature == self.MouseLock and self.view().isFullScreen():
            self.setFeaturePermission(origin, feature, self.PermissionGrantedByUser)
        else:
            gVar.app.html5PermissionsManager().requestPermissions(self, origin, feature)

    def _renderProcessTerminated(self, terminationStatus, exitCode):
        '''
        @param: terminationStatus RenderProcessTerminationStatus
        @param: exitCode int
        '''
        if terminationStatus == self.NormalTerminationStatus:
            return

        def showCrashHtmlCb():
            page = gVar.appTools.readAllFileContents(':html/tabcrash.html')
            img = gVar.appTools.pixmapToDataUrl(IconProvider.standardIcon(
                QStyle.SP_MessageBoxWarning).pixmap(45)).toString()
            page = page.replace("%IMAGE%", img) \
                .replace("%TITLE%", _("Failed loading page")) \
                .replace("%HEADING%", _("Failed loading page")) \
                .replace("%LI-1%", _("Something went wrong while loading this page.")) \
                .replace("%LI-2%", _("Try reloading the page or closing some tabs to make more memory available.")) \
                .replace("%RELOAD-PAGE%", _("Reload page"))
            page = gVar.appTool.applyDirectionToPage(page)
            self.setHtml(page, self.url())

        QTimer.singleShot(0, showCrashHtmlCb)

    # private:
    # override
    def acceptNavigationRequest(self, url, type_, isMainFrame):
        '''
        @param: url QUrl
        @param: type_ QWebEnginePage.NavigationType
        @param: isMainFrame bool
        '''
        if gVar.app.isClosing():
            return super().acceptNavigationRequest(url, type_, isMainFrame)

        # TODO: plugins
        #if not gVar.app.plugins().acceptNavigationRequest(self, url, type_, isMainFrame):
        #    return False

        if url.scheme() == 'app':
            if url.path() == 'AddSearchProvider':
                query = QUrlQuery(url)
                gVar.app.searchEnginesManager().addEngine(query.queryItemValue('url'))
                return False
            if const.QTWEBENGINEWIDGETS_VERSION < const.QT_VERSION_CHECK(5, 12, 0):
                if url.path() == 'PrintPage':
                    self.printRequested.emit()
                    return False

        result = super().acceptNavigationRequest(url, type_, isMainFrame)
        if result:
            if isMainFrame:
                isWeb = url.scheme() in ('http', 'https', 'file')
                globalJsEnabled = gVar.app.webSettings().testAttribute(QWebEngineSettings.JavascriptEnabled)
                if isWeb:
                    enable = globalJsEnabled
                else:
                    enable = True
                self.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, enable)

            self.navigationRequestAccepted.emit(url, type_, isMainFrame)
        return result

    # override
    def certificateError(self, error):
        '''
        @param: error QWebEngineCertificateError
        '''
        return gVar.app.networkManager().certificateError(error, self.view())

    # override
    def chooseFiles(self, mode, oldFiles, acceptedMimeTypes):
        '''
        @param: mode FileSelectionMode
        @param: oldFiles QStringList
        @param: acceptedMimeTypes QStringList
        @return: QStringList
        '''
        files = []  # QStringList
        suggestedFileName = self._s_lastUploadLocation
        if oldFiles and oldFiles[0]:
            suggestedFileName = oldFiles[0]

        if mode == self.FileSelectOpen:
            path = gVar.appTools.getOpenFileName('WebPage-ChooseFile', self.view(),
                _('Choose file...'), suggestedFileName)
            files = [path, ]
        elif mode == self.FileSelectOpenMultiple:
            files = gVar.appTools.getOpenFileNames('WebPage-ChooseFile', self.view(),
                _('Choose file...'), suggestedFileName)
        else:
            files = super().chooseFiles(mode, oldFiles, acceptedMimeTypes)
        if files:
            self._s_lastUploadLocation = files[0]

        return files

    # override
    def createWindow(self, type_):
        '''
        @param: type_ QWebEnginePage::WebWindowType
        @return: QWebEnginePage
        '''
        # TabbedWebView
        tView = self.view()
        if tView:
            window = tView.browserWindow()
        else:
            window = gVar.app.getWindow()

        def createTab(pos):
            index = window.tabWidget().addViewByUrl(QUrl(), pos)
            view = window.weView(index)
            view.setPage(WebPage())
            if tView:
                tView.webTab().addChildTab(view.webTab())
            # Workaround focus issue when creating tab
            if pos & const.NT_SelectedTab:
                view.setFocus()

                def x():
                    if view and view.webTab().isCurrentTab():
                        view.setFocus()
                QTimer.singleShot(100, x)
            return view.page()

        if type_ == QWebEnginePage.WebBrowserWindow:
            window = gVar.app.createWindow(const.BW_NewWindow)
            page = WebPage()
            window.setStartPage(page)
            return page

        if type_ == QWebEnginePage.WebDialog:
            if not gVar.appSettings.openPopupsInTabs:
                from mc.popupwindow.PopupWebView import PopupWebView
                from mc.popupwindow.PopupWindow import PopupWindow
                view = PopupWebView()
                view.setPage(WebPage())
                popup = PopupWindow(view)
                popup.show()
                window.addDeleteOnCloseWidget(popup)
                return view.page()
            # else fallthrough

        if type_ == QWebEnginePage.WebBrowserTab:
            return createTab(const.NT_CleanSelectedTab)

        if type_ == QWebEnginePage.WebBrowserBackgroundTab:
            return createTab(const.NT_CleanNotSelectedTab)

        return None

    def handleUnknownProtocol(self, url):
        '''
        @param: url QUrl
        '''
        protocol = url.scheme()

        if protocol == 'mailto':
            self.desktopServicesOpen(url)
            return

        if protocol in gVar.appSettings.blockedProtocols:
            print('DEBUG: WebPage::handleUnknownProtocol', protocol, 'is blocked!')
            return

        if protocol in gVar.appSettings.autoOpenProtocols:
            self.desktopServicesOpen(url)
            return

        dialog = CheckBoxDialog(QMessageBox.Yes | QMessageBox.No, self.view())
        dialog.setDefaultButton(QMessageBox.Yes)

        wrappedUrl = gVar.appTools.alignTextToWidth(url.toString(), '<br/>',
                dialog.fontMetrics(), 450)
        text = _("Falkon cannot handle <b>%s:</b> links. The requested link "
                "is <ul><li>%s</li></ul>Do you want Falkon to try "
                "open this link in system application?") % (protocol, wrappedUrl)

        dialog.setText(text)
        dialog.setCheckBoxText(_("Remember my choice for this protocol"))
        dialog.setWindowTitle(_("External Protocol Request"))
        dialog.setIcon(QMessageBox.Question)
        ret = dialog.exec_()
        if ret == QMessageBox.Yes:
            if dialog.isChecked():
                gVar.appSettings.autoOpenProtocols.append(protocol)
                gVar.appSettings.saveSettings()

            QDesktopServices.openUrl(url)
        elif ret == QMessageBox.No:
            if dialog.isChecked():
                gVar.appSettings.autoOpenProtocols.append(protocol)
                gVar.appSettings.saveSettings()

    def desktopServicesOpen(self, url):
        '''
        @param: url QUrl
        '''
        # Open same url only once in 2 secs
        sameUrlTimeout = 2 * 1000
        if self.s_lastUnsupportedUrl != url or self.s_lastUnsupportedUrlTime.isNull() or \
                self.s_lastUnsupportedUrlTime.elapsed() > sameUrlTimeout:
            self.s_lastUnsupportedUrl = url
            self.s_lastUnsupportedUrlTime.restart()
            QDesktopServices.openUrl(url)
        else:
            print('WARNING: WebPage::desktopServicesOpen Url', url, 'has already been opened!\n',
                'Ignoring it to prevent infinite loop!')
示例#2
0
 def donate(self, *args):
     open_url(QUrl('http://calibre-ebook.com/donate'))
示例#3
0
    def createList(self):
        hoy = str(datetime.datetime.now().year) + str(datetime.datetime.now().month) + str(datetime.datetime.now().day) + str(datetime.datetime.now().hour) + str(datetime.datetime.now().minute) + str(datetime.datetime.now().second)

        nombrePdf = '../archivos/' + str(hoy + 'LIST') + '.pdf'
        listTable = ""
        for lista in self.listFinal:
            listTable += """
                                        <tr height="80">
                                            <td width="40%" align="center" >
                                            <br>""" + str(lista[0])  + """<br>
                                            </td>
                                            <td width="40%" >
                                                <br> &nbsp;&nbsp;""" + str(lista[1])  + """<br>
                                            </td>
                                            <td width="20%" >
                                               <br>&nbsp;&nbsp; """ + str(lista[2])  + """<br>
                                            </td>
                                        </tr>
                                   """


        subtitle = "Listado de clientes con deudas : "
        if self.type == 'PROV':
            subtitle = "Listado de deudas a proveedores : "


        fecha = str(datetime.datetime.now())
        html =  """
                     <table width="600">
                        <tr width="600" color="#000000">
                            <td width="80%">

                            </td>
                            <td width="20%" align="right">
                                <IMG SRC="kde1.png">
                            </td>
                        </tr>

                    </table>

                   <hr>
                    <br>
                    <p>
                        """+ subtitle + """
                    </p>
                    <br>
                    <table width="600" height="0" style="border-color: black; border-width: 0.5px; border-spacing: 0;">
                      <tr  style=" background-color: gray; border-style: inset;">
                        <td width="40%"  align="center" valign="middle">
                            <b>
                            APELLIDO
                            </b>
                        </td>
                        <td width="40%"  align="center" valign="middle">
                            <b>
                                NOMBRE
                            </b>
                        </td>
                        <td width="20%"  align="center" valign="middle">
                            <b>
                            DEUDA
                            </b>
                        </td>
                      </tr>
                  </table>

                  <br>
                  <br>

                  <table width="600" height="0" style="border-color: black; border-width: 0.5px; border-spacing: 0;">
                      """ + listTable + """
                  </table>
                    <br>
                    <br>

                    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                    <br>

                    <hr>
                    <br>
                    <table width="600">
                        <tr>
                            <td align="right" width="100%">
                            FECHA/HORA : """+ fecha + """
                            </td>
                        </tr>
                    </table>
                   <hr>
                """

        doc = QTextDocument()
        doc.setHtml(html)

        printer = QPrinter()
        printer.setOutputFileName(nombrePdf)

        printer.setOutputFormat(QPrinter.PdfFormat)
        doc.print(printer)
        printer.newPage()
        url = QUrl
        url = QUrl(nombrePdf)
        QDesktopServices.openUrl(url)
    def analyze(self,
                url_to_request,
                timeout=10,
                current_depth=None,
                method="GET",
                data={}):
        try:
            url_to_request = url_to_request.toString()
        except AttributeError:
            url_to_request = url_to_request

        logging.debug("Start analyzing the url {}...".format(url_to_request))
        self._timing_requests = []
        self._new_clickables = []
        self._timeming_events = []
        self._current_timeming_event = None
        self._loading_complete = False
        self._analyzing_finished = False
        self.response_code = {}
        if method == "GET":
            self.mainFrame().load(QUrl(url_to_request))
        else:
            request = self.make_request(url_to_request)
            data = self.post_data_to_array(data)
            request.setRawHeader(
                'Content-Type',
                QByteArray('application/x-www-form-urlencoded'))
            self.mainFrame().load(request, QNetworkAccessManager.PostOperation,
                                  data)
        t = 0
        while (not self._loading_complete
               and t < timeout):  # Waiting for finish processing
            self._wait(self.wait_for_processing)
            t += self.wait_for_processing

        videos = self.mainFrame().findAllElements("video")
        if len(videos) > 0:
            logging.debug("{} videos found... removing them")
            for video in videos:
                video.removeFromDocument()

        overall_waiting_time = t
        buffer = 250
        while len(
                self._timeming_events) > 0 and overall_waiting_time < timeout:
            self._current_timeming_event = self._timeming_events.pop(
                0)  # Take the first event(ordered by needed time
            self._waiting_for = self._current_timeming_event[
                'event_type']  # Setting kind of event
            waiting_time_in_milliseconds = (
                self._current_timeming_event["time"] - overall_waiting_time
            )  # Taking waiting time and convert it from milliseconds to seconds
            waiting_time_in_milliseconds = (
                (waiting_time_in_milliseconds + buffer) / 1000.0)
            if waiting_time_in_milliseconds < 0.0:
                waiting_time_in_milliseconds = 0
            self._wait(waiting_time_in_milliseconds
                       )  # Waiting for 100 millisecond before expected event
            overall_waiting_time += waiting_time_in_milliseconds
        if overall_waiting_time < 0.5:
            self._wait((0.5 - overall_waiting_time))

        # Just for debugging
        #f = open("text.txt", "w", encoding="utf-8")
        #f.write(self.mainFrame().toHtml())
        #f.close()
        base_url = self.mainFrame().findFirstElement("base")
        if base_url is not None:
            base_url = base_url.attribute("href")

        links, clickables = extract_links(self.mainFrame(), url_to_request)
        forms = extract_forms(self.mainFrame())
        elements_with_event_properties = property_helper(self.mainFrame())
        self.mainFrame().evaluateJavaScript(self._property_obs_js)
        self._wait(0.1)

        self._analyzing_finished = True
        html_after_timeouts = self.mainFrame().toHtml()
        response_url = self.mainFrame().url().toString()

        self.mainFrame().setHtml(None)
        self._new_clickables.extend(clickables)
        self._new_clickables.extend(elements_with_event_properties)
        self._new_clickables = purge_dublicates(self._new_clickables)
        response_code = None
        try:
            response_code = self.response_code[url_to_request]
        except KeyError:
            response_code = 200
        if response_code is None:
            response_code = 200
        try:
            current_page = WebPage(self.parent().get_next_page_id(),
                                   response_url, html_after_timeouts)
        except AttributeError:  #Attacker don't need this function...
            current_page = WebPage(42, response_url, html_after_timeouts)
        current_page.timing_requests = self._timing_requests
        current_page.clickables = self._new_clickables
        current_page.links = links
        current_page.forms = forms
        if base_url is not None and base_url != "":
            current_page.base_url = base_url
        return response_code, current_page
示例#5
0
    def create_actions(self):
        group = _('Global actions')

        def reg(icon,
                text,
                target,
                sid,
                keys,
                description,
                toolbar_allowed=False):
            if not isinstance(icon, QIcon):
                icon = QIcon(I(icon))
            ac = actions[sid] = QAction(icon, text, self) if icon else QAction(
                text, self)
            ac.setObjectName('action-' + sid)
            if toolbar_allowed:
                toolbar_actions[sid] = ac
            if target is not None:
                ac.triggered.connect(target)
            if isinstance(keys, unicode_type):
                keys = (keys, )
            self.keyboard.register_shortcut(sid,
                                            unicode_type(ac.text()).replace(
                                                '&', ''),
                                            default_keys=keys,
                                            description=description,
                                            action=ac,
                                            group=group)
            self.addAction(ac)
            return ac

        def treg(icon, text, target, sid, keys, description):
            return reg(icon,
                       text,
                       target,
                       sid,
                       keys,
                       description,
                       toolbar_allowed=icon is not None)

        self.action_new_file = treg('document-new.png',
                                    _('&New file (images/fonts/HTML/etc.)'),
                                    self.boss.add_file, 'new-file', (),
                                    _('Create a new file in the current book'))
        self.action_import_files = treg('document-import.png',
                                        _('&Import files into book'),
                                        self.boss.add_files, 'new-files', (),
                                        _('Import files into book'))
        self.action_open_book = treg('document_open.png', _('&Open book'),
                                     self.boss.open_book, 'open-book',
                                     'Ctrl+O', _('Open a book'))
        self.action_open_book_folder = treg(
            'mimetypes/dir.png', _('Open &folder (unzipped EPUB) as book'),
            partial(self.boss.open_book, open_folder=True),
            'open-folder-as-book', (),
            _('Open a folder (unzipped EPUB) as a book'))
        self.action_edit_next_file = treg(
            'arrow-down.png', _('Edit &next file'),
            partial(self.boss.edit_next_file, backwards=False),
            'edit-next-file', 'Ctrl+Alt+Down',
            _('Edit the next file in the spine'))
        self.action_edit_previous_file = treg(
            'arrow-up.png', _('Edit &previous file'),
            partial(self.boss.edit_next_file, backwards=True),
            'edit-previous-file', 'Ctrl+Alt+Up',
            _('Edit the previous file in the spine'))
        # Qt does not generate shortcut overrides for cmd+arrow on os x which
        # means these shortcuts interfere with editing
        self.action_global_undo = treg(
            'back.png', _('&Revert to before'), self.boss.do_global_undo,
            'global-undo', () if isosx else 'Ctrl+Left',
            _('Revert book to before the last action (Undo)'))
        self.action_global_redo = treg(
            'forward.png', _('&Revert to after'), self.boss.do_global_redo,
            'global-redo', () if isosx else 'Ctrl+Right',
            _('Revert book state to after the next action (Redo)'))
        self.action_save = treg('save.png', _('&Save'), self.boss.save_book,
                                'save-book', 'Ctrl+S', _('Save book'))
        self.action_save.setEnabled(False)
        self.action_save_copy = treg('save.png', _('Save a &copy'),
                                     self.boss.save_copy,
                                     'save-copy', 'Ctrl+Alt+S',
                                     _('Save a copy of the book'))
        self.action_quit = treg('window-close.png', _('&Quit'), self.boss.quit,
                                'quit', 'Ctrl+Q', _('Quit'))
        self.action_preferences = treg('config.png', _('&Preferences'),
                                       self.boss.preferences, 'preferences',
                                       'Ctrl+P', _('Preferences'))
        self.action_new_book = treg('plus.png', _('Create new, &empty book'),
                                    self.boss.new_book, 'new-book', (),
                                    _('Create a new, empty book'))
        self.action_import_book = treg(
            'add_book.png', _('&Import an HTML or DOCX file as a new book'),
            self.boss.import_book, 'import-book', (),
            _('Import an HTML or DOCX file as a new book'))
        self.action_quick_edit = treg(
            'modified.png', _('&Quick open a file to edit'),
            self.boss.quick_open, 'quick-open', ('Ctrl+T'),
            _('Quickly open a file from the book to edit it'))

        # Editor actions
        group = _('Editor actions')
        self.action_editor_undo = reg('edit-undo.png', _('&Undo'),
                                      self.boss.do_editor_undo, 'editor-undo',
                                      'Ctrl+Z', _('Undo typing'))
        self.action_editor_redo = reg('edit-redo.png', _('R&edo'),
                                      self.boss.do_editor_redo, 'editor-redo',
                                      'Ctrl+Y', _('Redo typing'))
        self.action_editor_cut = reg('edit-cut.png', _('Cut &text'),
                                     self.boss.do_editor_cut, 'editor-cut', (
                                         'Ctrl+X',
                                         'Shift+Delete',
                                     ), _('Cut text'))
        self.action_editor_copy = reg('edit-copy.png', _('&Copy to clipboard'),
                                      self.boss.do_editor_copy, 'editor-copy',
                                      ('Ctrl+C', 'Ctrl+Insert'),
                                      _('Copy to clipboard'))
        self.action_editor_paste = reg('edit-paste.png',
                                       _('P&aste from clipboard'),
                                       self.boss.do_editor_paste,
                                       'editor-paste', (
                                           'Ctrl+V',
                                           'Shift+Insert',
                                       ), _('Paste from clipboard'))
        self.action_editor_cut.setEnabled(False)
        self.action_editor_copy.setEnabled(False)
        self.action_editor_undo.setEnabled(False)
        self.action_editor_redo.setEnabled(False)

        # Tool actions
        group = _('Tools')
        self.action_toc = treg('toc.png', _('&Edit Table of Contents'),
                               self.boss.edit_toc, 'edit-toc', (),
                               _('Edit Table of Contents'))
        self.action_inline_toc = treg('chapters.png',
                                      _('&Insert inline Table of Contents'),
                                      self.boss.insert_inline_toc,
                                      'insert-inline-toc', (),
                                      _('Insert inline Table of Contents'))
        self.action_fix_html_current = reg('html-fix.png', _('&Fix HTML'),
                                           partial(self.boss.fix_html, True),
                                           'fix-html-current', (),
                                           _('Fix HTML in the current file'))
        self.action_fix_html_all = treg('html-fix.png',
                                        _('&Fix HTML - all files'),
                                        partial(self.boss.fix_html, False),
                                        'fix-html-all', (),
                                        _('Fix HTML in all files'))
        self.action_pretty_current = reg('beautify.png',
                                         _('&Beautify current file'),
                                         partial(self.boss.pretty_print, True),
                                         'pretty-current', (),
                                         _('Beautify current file'))
        self.action_pretty_all = treg('beautify.png', _('&Beautify all files'),
                                      partial(self.boss.pretty_print,
                                              False), 'pretty-all', (),
                                      _('Beautify all files'))
        self.action_insert_char = treg('character-set.png',
                                       _('&Insert special character'),
                                       self.boss.insert_character,
                                       'insert-character', (),
                                       _('Insert special character'))
        self.action_rationalize_folders = treg('mimetypes/dir.png',
                                               _('&Arrange into folders'),
                                               self.boss.rationalize_folders,
                                               'rationalize-folders', (),
                                               _('Arrange into folders'))
        self.action_set_semantics = treg('tags.png', _('Set &semantics'),
                                         self.boss.set_semantics,
                                         'set-semantics', (),
                                         _('Set semantics'))
        self.action_filter_css = treg('filter.png',
                                      _('&Filter style information'),
                                      self.boss.filter_css, 'filter-css', (),
                                      _('Filter style information'))
        self.action_manage_fonts = treg('font.png', _('&Manage fonts'),
                                        self.boss.manage_fonts, 'manage-fonts',
                                        (), _('Manage fonts in the book'))
        self.action_add_cover = treg('default_cover.png', _('Add &cover'),
                                     self.boss.add_cover, 'add-cover', (),
                                     _('Add a cover to the book'))
        self.action_reports = treg(
            'reports.png', _('&Reports'), self.boss.show_reports,
            'show-reports', ('Ctrl+Shift+R', ),
            _('Show a report on various aspects of the book'))
        self.action_check_external_links = treg(
            'insert-link.png', _('Check &external links'),
            self.boss.check_external_links, 'check-external-links', (),
            _('Check external links in the book'))
        self.action_compress_images = treg('compress-image.png',
                                           _('C&ompress images losslessly'),
                                           self.boss.compress_images,
                                           'compress-images', (),
                                           _('Compress images losslessly'))
        self.action_transform_styles = treg(
            'wizard.png', _('Transform &styles'), self.boss.transform_styles,
            'transform-styles', (), _('Transform styles used in the book'))
        self.action_get_ext_resources = treg(
            'download-metadata.png', _('Download external &resources'),
            self.boss.get_external_resources, 'get-external-resources', (),
            _('Download external resources in the book (images/stylesheets/etc/ that are not included in the book)'
              ))

        def ereg(icon, text, target, sid, keys, description):
            return reg(icon, text, partial(self.boss.editor_action, target),
                       sid, keys, description)

        register_text_editor_actions(ereg, self.palette())

        # Polish actions
        group = _('Polish book')
        self.action_subset_fonts = treg(
            'subset-fonts.png', _('&Subset embedded fonts'),
            partial(self.boss.polish, 'subset', _('Subset fonts')),
            'subset-fonts', (), _('Subset embedded fonts'))
        self.action_embed_fonts = treg(
            'embed-fonts.png', _('&Embed referenced fonts'),
            partial(self.boss.polish, 'embed', _('Embed fonts')),
            'embed-fonts', (), _('Embed referenced fonts'))
        self.action_smarten_punctuation = treg(
            'smarten-punctuation.png',
            _('&Smarten punctuation (works best for English)'),
            partial(self.boss.polish, 'smarten_punctuation',
                    _('Smarten punctuation')), 'smarten-punctuation', (),
            _('Smarten punctuation'))
        self.action_remove_unused_css = treg(
            'edit-clear.png', _('Remove &unused CSS rules'),
            partial(self.boss.polish, 'remove_unused_css',
                    _('Remove unused CSS rules')), 'remove-unused-css', (),
            _('Remove unused CSS rules'))
        self.action_upgrade_book_internals = treg(
            'arrow-up.png', _('&Upgrade book internals'),
            partial(self.boss.polish, 'upgrade_book',
                    _('Upgrade book internals')), 'upgrade-book', (),
            _('Upgrade book internals'))

        # Preview actions
        group = _('Preview')
        self.action_auto_reload_preview = reg('auto-reload.png',
                                              _('Auto reload preview'), None,
                                              'auto-reload-preview', (),
                                              _('Auto reload preview'))
        self.action_auto_sync_preview = reg(
            'sync-right.png', _('Sync preview position to editor position'),
            None, 'sync-preview-to-editor', (),
            _('Sync preview position to editor position'))
        self.action_reload_preview = reg('view-refresh.png',
                                         _('Refresh preview'), None,
                                         'reload-preview', ('F5', ),
                                         _('Refresh preview'))
        self.action_split_in_preview = reg(
            'document-split.png', _('Split this file'), None,
            'split-in-preview', (), _('Split file in the preview panel'))
        self.action_find_next_preview = reg('arrow-down.png', _('Find next'),
                                            None, 'find-next-preview', (),
                                            _('Find next in preview'))
        self.action_find_prev_preview = reg('arrow-up.png', _('Find previous'),
                                            None, 'find-prev-preview', (),
                                            _('Find previous in preview'))

        # Search actions
        group = _('Search')
        self.action_find = treg('search.png', _('&Find/replace'),
                                self.boss.show_find, 'find-replace',
                                ('Ctrl+F', ), _('Show the Find/replace panel'))

        def sreg(name,
                 text,
                 action,
                 overrides={},
                 keys=(),
                 description=None,
                 icon=None):
            return reg(
                icon, text,
                partial(self.boss.search_action_triggered, action, overrides),
                name, keys, description or text.replace('&', ''))

        self.action_find_next = sreg('find-next', _('Find &next'), 'find',
                                     {'direction': 'down'}, ('F3', 'Ctrl+G'),
                                     _('Find next match'))
        self.action_find_previous = sreg('find-previous', _('Find &previous'),
                                         'find', {'direction': 'up'},
                                         ('Shift+F3', 'Shift+Ctrl+G'),
                                         _('Find previous match'))
        self.action_replace = sreg('replace',
                                   _('&Replace'),
                                   'replace',
                                   keys=('Ctrl+R'),
                                   description=_('Replace current match'))
        self.action_replace_next = sreg(
            'replace-next', _('Replace and find ne&xt'), 'replace-find',
            {'direction': 'down'}, ('Ctrl+]'),
            _('Replace current match and find next'))
        self.action_replace_previous = sreg(
            'replace-previous', _('R&eplace and find previous'),
            'replace-find', {'direction': 'up'}, ('Ctrl+['),
            _('Replace current match and find previous'))
        self.action_replace_all = sreg('replace-all',
                                       _('Replace &all'),
                                       'replace-all',
                                       keys=('Ctrl+A'),
                                       description=_('Replace all matches'))
        self.action_count = sreg('count-matches',
                                 _('&Count all'),
                                 'count',
                                 keys=('Ctrl+N'),
                                 description=_('Count number of matches'))
        self.action_mark = reg(
            None, _('&Mark selected text'), self.boss.mark_selected_text,
            'mark-selected-text', ('Ctrl+Shift+M', ),
            _('Mark selected text or unmark already marked text'))
        self.action_mark.default_text = self.action_mark.text()
        self.action_go_to_line = reg(None, _('Go to &line'),
                                     self.boss.go_to_line_number,
                                     'go-to-line-number', ('Ctrl+.', ),
                                     _('Go to line number'))
        self.action_saved_searches = treg('folder_saved_search.png',
                                          _('Sa&ved searches'),
                                          self.boss.saved_searches,
                                          'saved-searches', (),
                                          _('Show the saved searches dialog'))
        self.action_text_search = treg('view.png',
                                       _('&Search ignoring HTML markup'),
                                       self.boss.show_text_search,
                                       'text-search', (),
                                       _('Show the text search panel'))

        # Check Book actions
        group = _('Check book')
        self.action_check_book = treg('debug.png', _('C&heck book'),
                                      self.boss.check_requested, 'check-book',
                                      ('F7'), _('Check book for errors'))
        self.action_spell_check_book = treg(
            'spell-check.png', _('Check &spelling'),
            self.boss.spell_check_requested, 'spell-check-book', ('Alt+F7'),
            _('Check book for spelling errors'))
        self.action_check_book_next = reg(
            'forward.png', _('&Next error'),
            partial(self.check_book.next_error, delta=1), 'check-book-next',
            ('Ctrl+F7'), _('Show next error'))
        self.action_check_book_previous = reg(
            'back.png', _('&Previous error'),
            partial(self.check_book.next_error, delta=-1),
            'check-book-previous', ('Ctrl+Shift+F7'), _('Show previous error'))
        self.action_spell_check_next = reg('forward.png',
                                           _('&Next spelling mistake'),
                                           self.boss.next_spell_error,
                                           'spell-next', ('F8'),
                                           _('Go to next spelling mistake'))

        # Miscellaneous actions
        group = _('Miscellaneous')
        self.action_create_checkpoint = treg(
            'marked.png', _('&Create checkpoint'), self.boss.create_checkpoint,
            'create-checkpoint', (),
            _('Create a checkpoint with the current state of the book'))
        self.action_close_current_tab = reg('window-close.png',
                                            _('&Close current tab'),
                                            self.central.close_current_editor,
                                            'close-current-tab', 'Ctrl+W',
                                            _('Close the currently open tab'))
        self.action_close_all_but_current_tab = reg(
            'edit-clear.png', _('C&lose other tabs'),
            self.central.close_all_but_current_editor,
            'close-all-but-current-tab', 'Ctrl+Alt+W',
            _('Close all tabs except the current tab'))
        self.action_help = treg(
            'help.png', _('User &Manual'), lambda: open_url(
                QUrl(
                    localize_user_manual_link(
                        'https://manual.calibre-ebook.com/edit.html'))),
            'user-manual', 'F1', _('Show User Manual'))
        self.action_browse_images = treg(
            'view-image.png', _('&Browse images in book'),
            self.boss.browse_images, 'browse-images', (),
            _('Browse images in the books visually'))
        self.action_multiple_split = treg(
            'document-split.png', _('&Split at multiple locations'),
            self.boss.multisplit, 'multisplit', (),
            _('Split HTML file at multiple locations'))
        self.action_compare_book = treg('diff.png',
                                        _('Compare to &another book'),
                                        self.boss.compare_book, 'compare-book',
                                        (), _('Compare to another book'))
        self.action_manage_snippets = treg('snippets.png',
                                           _('Manage &Snippets'),
                                           self.boss.manage_snippets,
                                           'manage-snippets', (),
                                           _('Manage user created snippets'))

        self.plugin_menu_actions = []

        create_plugin_actions(actions, toolbar_actions,
                              self.plugin_menu_actions)
示例#6
0
 def _forum_label_activated(self):
     if self.forum_link:
         open_url(QUrl(self.forum_link))
示例#7
0
 def donate(self, *args):
     from calibre.utils.localization import localize_website_link
     open_url(
         QUrl(localize_website_link('https://calibre-ebook.com/donate')))
示例#8
0
    def __init__(self):
        self.plugin_prefs = prefs
        self.restart_required = False
        self.inspector = None

        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        #add checkbox
        self.inspector_checkbox = QCheckBox('Show Inspector')
        self.inspector_checkbox.setChecked(
            self.plugin_prefs.get('inspector_enabled', False))
        self.inspector_checkbox.stateChanged.connect(
            self._inspector_enabled_changed)
        self.inspector_checkbox.setToolTip(
            'Enable Javascript Console for debugging WebView requests to QuietThyme API'
        )
        self.l.addWidget(self.inspector_checkbox)

        self.beta_checkbox = QCheckBox('Beta Mode')
        self.beta_checkbox.setChecked(self.plugin_prefs.get(
            'beta_mode', False))
        self.beta_checkbox.stateChanged.connect(self._set_restart_required)
        self.beta_checkbox.stateChanged.connect(self._beta_mode_changed)
        self.beta_checkbox.setToolTip(
            'Tell Calibre to communicate with the Beta version of QuietThyme')
        self.l.addWidget(self.beta_checkbox)

        self.config_url = QUrl(self.plugin_prefs.get('web_base') + '/storage')
        self.webview = QTWebView(bearer_token=self.plugin_prefs.get('token'))

        self.webview.load(self.config_url)
        self.global_settings = self.webview.page().settings(
        )  #QWebSettings.globalSettings()

        self.global_settings.setAttribute(
            QWebSettings.LocalStorageEnabled,
            True)  #required since this is where we store tokens.
        self.global_settings.setAttribute(QWebSettings.PrivateBrowsingEnabled,
                                          False)
        self.global_settings.setAttribute(QWebSettings.JavascriptEnabled, True)
        self.global_settings.setAttribute(
            QWebSettings.JavascriptCanOpenWindows, True)
        self.global_settings.setAttribute(
            QWebSettings.JavascriptCanCloseWindows, True)
        self.global_settings.setAttribute(QWebSettings.PluginsEnabled, True)
        self.global_settings.setAttribute(
            QWebSettings.LocalContentCanAccessRemoteUrls, True)
        self.global_settings.setAttribute(
            QWebSettings.LocalContentCanAccessFileUrls, True)
        self.global_settings.setAttribute(QWebSettings.XSSAuditingEnabled,
                                          False)
        self.global_settings.setAttribute(QWebSettings.DeveloperExtrasEnabled,
                                          True)

        # ensure that we get a random offline/localstorage/cache path for the brower (so that the localstorage data is not persistent across sessions)
        path = None
        while True:
            potential_path = QTemporaryDir()
            if potential_path.isValid():
                path = potential_path.path()
                break

        self.global_settings.setOfflineStoragePath(path)
        self.global_settings.setOfflineWebApplicationCachePath(path)
        self.global_settings.enablePersistentStorage(path)
        self.global_settings.setLocalStoragePath(path)

        self.webview.show()
        self.l.addWidget(self.webview)

        self.configure_webview_inspector_ui()

        self.webview.urlChanged.connect(self._url_changed)
        self.webview.loadFinished.connect(self._load_finished)
示例#9
0
 def _on_load_url(self):
     self.view.load(QUrl(self.url_le.text()))
示例#10
0
from .resources import get_data, get_icon
from .utils import safe_disconnect, open_local_file, draw_snake_spinner, icon_data_for_filename


def get_download_dir():
    if not hasattr(get_download_dir, 'ans'):
        get_download_dir.ans = os.path.expanduser(
            misc_config('download_dir', default='~/downloads'))
        try:
            os.makedirs(get_download_dir.ans)
        except FileExistsError:
            pass
    return get_download_dir.ans


DOWNLOADS_URL = QUrl(DU)
save_page_path_map = {}


def downloads_icon():
    if not hasattr(downloads_icon, 'icon'):
        downloads_icon.icon = get_icon('download.svg')
    return downloads_icon.icon


@lru_cache(maxsize=150)
def filename_icon_data(encoded_file_name):
    return QByteArray(
        icon_data_for_filename(unhexlify(encoded_file_name).decode('utf-8'),
                               size=64) or get_data('images/blank.png'))
示例#11
0
 def url(self):
     return QUrl('http://example.com/%s' % self.fname)
示例#12
0
 def load_url(self, url):
     self.dom_loaded = False
     url = QUrl(url)
     self.mainFrame().load(url)
     self.ready_state  # Without this, DOMContentLoaded does not fire for file:// URLs
示例#13
0
    def download_file(self, url_or_selector_or_qwe, timeout=60):
        '''
        Download unsupported content: i.e. files the browser cannot handle
        itself or files marked for saving as files by the website. Useful if
        you want to download something like an epub file after authentication.

        You can pass in either the url to the file to be downloaded, or a
        selector that points to an element to be clicked on the current page
        which will cause the file to be downloaded.
        '''
        ans = [False, None, []]
        loop = QEventLoop(self)
        start_time = time.time()
        end_time = start_time + timeout
        self.page.unsupportedContent.disconnect(
            self.page.on_unsupported_content)
        try:

            def download(reply):
                if ans[0]:
                    reply.abort(
                    )  # We only handle the first unsupported download
                    return
                ans[0] = True
                while not reply.isFinished() and end_time > time.time():
                    if not loop.processEvents():
                        time.sleep(0.01)
                    raw = bytes(bytearray(reply.readAll()))
                    if raw:
                        ans[-1].append(raw)
                if not reply.isFinished():
                    ans[1] = Timeout(
                        'Loading of %r took longer than %d seconds' %
                        (url_or_selector_or_qwe, timeout))
                ans[-1].append(bytes(bytearray(reply.readAll())))

            self.page.unsupportedContent.connect(download)
            if hasattr(url_or_selector_or_qwe, 'rstrip') and re.match(
                    '[a-z]+://', url_or_selector_or_qwe) is not None:
                # We have a URL
                self.page.mainFrame().load(QUrl(url_or_selector_or_qwe))
            else:
                self.click(url_or_selector_or_qwe, wait_for_load=False)
            lw = LoadWatcher(self.page)
            while not ans[0] and lw.is_loading and end_time > time.time():
                if not loop.processEvents():
                    time.sleep(0.01)
            if not ans[0]:
                raise NotAFile(
                    '%r does not point to a downloadable file. You can only'
                    ' use this method to download files that the browser cannot handle'
                    ' natively. Or files that are marked with the '
                    ' content-disposition: attachment header' %
                    url_or_selector_or_qwe)
            if ans[1] is not None:
                raise ans[1]
            return b''.join(ans[-1])
        finally:
            self.page.unsupportedContent.disconnect()
            self.page.unsupportedContent.connect(
                self.page.on_unsupported_content)
示例#14
0
文件: server.py 项目: wpxdong/calibre
 def test_server(self):
     prefix = self.advanced_tab.opt_url_prefix.text().strip()
     open_url(
         QUrl('http://127.0.0.1:' + str(self.main_tab.opt_port.value()) +
              prefix))
 def openMail(self):
     QDesktopServices.openUrl(
         QUrl("mailto:[email protected]?subject=Error&body=REPORTAR ERROR :"
              ))
示例#16
0
 def __init__(self, parent=None):
     self._host_widget = None
     self._tts_client = None
     self.callback_id_counter = count()
     self.callback_map = {}
     self.current_cfi = self.current_content_file = None
     RestartingWebEngineView.__init__(self, parent)
     self.dead_renderer_error_shown = False
     self.render_process_failed.connect(self.render_process_died)
     w = QApplication.instance().desktop().availableGeometry(self).width()
     QApplication.instance().palette_changed.connect(self.palette_changed)
     self.show_home_page_on_ready = True
     self._size_hint = QSize(int(w / 3), int(w / 2))
     self._page = WebPage(self)
     self.view_is_ready = False
     self.bridge.bridge_ready.connect(self.on_bridge_ready)
     self.bridge.view_created.connect(self.on_view_created)
     self.bridge.content_file_changed.connect(self.on_content_file_changed)
     self.bridge.set_session_data.connect(self.set_session_data)
     self.bridge.set_local_storage.connect(self.set_local_storage)
     self.bridge.reload_book.connect(self.reload_book)
     self.bridge.toggle_toc.connect(self.toggle_toc)
     self.bridge.show_search.connect(self.show_search)
     self.bridge.search_result_not_found.connect(
         self.search_result_not_found)
     self.bridge.find_next.connect(self.find_next)
     self.bridge.toggle_bookmarks.connect(self.toggle_bookmarks)
     self.bridge.toggle_highlights.connect(self.toggle_highlights)
     self.bridge.new_bookmark.connect(self.new_bookmark)
     self.bridge.toggle_inspector.connect(self.toggle_inspector)
     self.bridge.toggle_lookup.connect(self.toggle_lookup)
     self.bridge.quit.connect(self.quit)
     self.bridge.update_current_toc_nodes.connect(
         self.update_current_toc_nodes)
     self.bridge.toggle_full_screen.connect(self.toggle_full_screen)
     self.bridge.ask_for_open.connect(self.ask_for_open)
     self.bridge.selection_changed.connect(self.selection_changed)
     self.bridge.autoscroll_state_changed.connect(
         self.autoscroll_state_changed)
     self.bridge.view_image.connect(self.view_image)
     self.bridge.copy_image.connect(self.copy_image)
     self.bridge.overlay_visibility_changed.connect(
         self.overlay_visibility_changed)
     self.bridge.reference_mode_changed.connect(self.reference_mode_changed)
     self.bridge.show_loading_message.connect(self.show_loading_message)
     self.bridge.show_error.connect(self.show_error)
     self.bridge.print_book.connect(self.print_book)
     self.bridge.clear_history.connect(self.clear_history)
     self.bridge.reset_interface.connect(self.reset_interface)
     self.bridge.quit.connect(self.quit)
     self.bridge.customize_toolbar.connect(self.customize_toolbar)
     self.bridge.scrollbar_context_menu.connect(self.scrollbar_context_menu)
     self.bridge.close_prep_finished.connect(self.close_prep_finished)
     self.bridge.highlights_changed.connect(self.highlights_changed)
     self.bridge.open_url.connect(safe_open_url)
     self.bridge.speak_simple_text.connect(self.speak_simple_text)
     self.bridge.export_shortcut_map.connect(self.set_shortcut_map)
     self.shortcut_map = {}
     self.bridge.report_cfi.connect(self.call_callback)
     self.bridge.change_background_image.connect(
         self.change_background_image)
     self.pending_bridge_ready_actions = {}
     self.setPage(self._page)
     self.setAcceptDrops(False)
     self.setUrl(QUrl('{}://{}/'.format(FAKE_PROTOCOL, FAKE_HOST)))
     self.urlChanged.connect(self.url_changed)
     if parent is not None:
         self.inspector = Inspector(
             parent.inspector_dock.toggleViewAction(), self)
         parent.inspector_dock.setWidget(self.inspector)
示例#17
0
 def _donate_clicked(self):
     plugin = self._selected_display_plugin()
     if plugin and plugin.donation_link:
         open_url(QUrl(plugin.donation_link))
示例#18
0
    def accept(self):
        open_url(QUrl(get_download_url()))

        QDialog.accept(self)
示例#19
0
文件: welcome.py 项目: skeptycal/vise
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>

import base64

from PyQt5.Qt import QUrl, QByteArray

from .constants import WELCOME_URL as WU
from .resources import get_icon, get_data

WELCOME_URL = QUrl(WU)


def welcome_icon():
    if not hasattr(welcome_icon, 'icon'):
        welcome_icon.icon = get_icon('vise.svg')
    return welcome_icon.icon


def get_welcome_html():
    if not hasattr(get_welcome_html, 'html'):
        d = get_data('welcome.html').decode('utf-8')
        ic = get_data('images/vise.svg')
        d = d.replace(
            'VISE_ICON', 'data:image/svg+xml;base64,' +
            base64.standard_b64encode(ic).decode('ascii'))
        get_welcome_html.html = QByteArray(d.encode('utf-8'))
    return get_welcome_html.html
示例#20
0
 def test_server(self):
     prefix = unicode(self.opt_url_prefix.text()).strip()
     open_url(
         QUrl('http://127.0.0.1:' + str(self.opt_port.value()) + prefix))
 def open(self, parent=None, detail_item=None, external=False):
     store_link = (DETAILS_URL + detail_item) if detail_item else STORE_LINK
     open_url(QUrl(store_link))
    def __init__(self, page, pos):
        '''
        @param: page WebPage
        @param: pos QPoint
        '''
        self._isNull = True
        self._baseUrl = QUrl()
        self._alternateText = ''
        self._boundingRect = QRect()
        self._imageUrl = QUrl()
        self._isContentEditable = False
        self._isContentSelected = False
        self._linkTitle = ''
        self._linkUrl = QUrl()
        self._mediaUrl = QUrl()
        self._mediaPaused = False
        self._mediaMuted = False
        self._pos = pos
        self._viewportPos = page.mapToViewport(self._pos)
        self._tagName = ''

        source = '''
(function() {
    var e = document.elementFromPoint(%s, %s);
    if (!e)
        return;
    function isMediaElement(e) {
        return e.tagName.toLowerCase() == 'audio' || e.tagName.toLowerCase() == 'video';
    }
    function isEditableElement(e) {
        if (e.isContentEditable)
            return true;
        if (e.tagName.toLowerCase() == 'input' || e.tagName.toLowerCase() == 'textarea')
            return e.getAttribute('readonly') != 'readonly';
        return false;
    }
    function isSelected(e) {
        var selection = window.getSelection();
        if (selection.type != 'Range')
            return false;
        return window.getSelection().containsNode(e, true);
    }
    function attributeStr(e, a) {
        return e.getAttribute(a) || '';
    }
    var res = {
        baseUrl: document.baseURI,
        alternateText: e.getAttribute('alt'),
        boundingRect: '',
        imageUrl: '',
        contentEditable: isEditableElement(e),
        contentSelected: isSelected(e),
        linkTitle: '',
        linkUrl: '',
        mediaUrl: '',
        tagName: e.tagName.toLowerCase()
    };
    var r = e.getBoundingClientRect();
    res.boundingRect = [r.top, r.left, r.width, r.height];
    if (e.tagName.toLowerCase() == 'img')
        res.imageUrl = attributeStr(e, 'src').trim();
    if (e.tagName.toLowerCase() == 'a') {
        res.linkTitle = e.text;
        res.linkUrl = attributeStr(e, 'href').trim();
    }
    while (e) {
        if (res.linkTitle == '' && e.tagName.toLowerCase() == 'a')
            res.linkTitle = e.text;
        if (res.linkUrl == '' && e.tagName.toLowerCase() == 'a')
            res.linkUrl = attributeStr(e, 'href').trim();
        if (res.mediaUrl == '' && isMediaElement(e)) {
            res.mediaUrl = e.currentSrc;
            res.mediaPaused = e.paused;
            res.mediaMuted = e.muted;
        }
        e = e.parentElement;
    }
    return res;
    })()
        '''
        js = source % (self._viewportPos.x(), self._viewportPos.y())
        # TODO: block loop?
        from mc.webengine.WebPage import WebPage
        self._init(page.url(), page.execJavaScript(js, WebPage.SafeJsWorld))
示例#23
0
 def __init__(self, parent):
     self.current_img = QPixmap()
     self.current_url = QUrl()
     self.parent = parent
     self.dialogs = []
示例#24
0
 def url(self, url):
     self.setUrl(QUrl(url))
示例#25
0
def open_donate():
    open_url(QUrl(localize_website_link('https://calibre-ebook.com/donate')))
示例#26
0
文件: ui.py 项目: yuvallanger/calibre
def open_donate():
    open_url(QUrl('https://calibre-ebook.com/donate'))
示例#27
0
 def name_to_qurl(self, name=None):
     name = name or self.current_name
     qurl = QUrl()
     qurl.setScheme(FAKE_PROTOCOL), qurl.setAuthority(
         FAKE_HOST), qurl.setPath('/' + name)
     return qurl
 def openManual(self):
     url = QUrl
     url = QUrl("../Recursos/Manual.pdf")
     QDesktopServices.openUrl(url)
示例#29
0
 def browse(url):
     try:
         safe_open_url(QUrl(url, QUrl.TolerantMode))
     except Exception:
         import traceback
         traceback.print_exc()
示例#30
0
 def registerProtocolHandlerRequestUrl(self):
     '''
     @return: QUrl
     '''
     return QUrl()