Exemple #1
0
    def setView(self, view, inspectElement=False):
        """
        Public method to connect a view to this inspector.
        
        @param view reference to the view object
        @type WebBrowserView
        @param inspectElement flag indicating to start a web inspection
        @type bool
        """
        self.__view = view
        if not self.isEnabled():
            return

        self.__inspectElement = inspectElement

        try:
            self.page().setInspectedPage(self.__view.page())
        except AttributeError:
            # pre Qt 5.11
            port = Preferences.getWebBrowser("WebInspectorPort")
            inspectorUrl = QUrl("http://localhost:{0}".format(port))

            from WebBrowser.WebBrowserWindow import WebBrowserWindow
            self.__reply = WebBrowserWindow.networkManager().get(
                QNetworkRequest(inspectorUrl.resolved(QUrl("json/list"))))
            self.__reply.finished.connect(self.__inspectorReplyFinished)
Exemple #2
0
    def resolve_url(self, baseurl: QUrl) -> typing.Optional[QUrl]:
        """Resolve the URL in the element's src/href attribute.

        Args:
            baseurl: The URL to base relative URLs on as QUrl.

        Return:
            A QUrl with the absolute URL, or None.
        """
        if baseurl.isRelative():
            raise ValueError("Need an absolute base URL!")

        for attr in ['href', 'src']:
            if attr in self:
                text = self[attr].strip()
                break
        else:
            return None

        url = QUrl(text)
        if not url.isValid():
            return None
        if url.isRelative():
            url = baseurl.resolved(url)
        qtutils.ensure_valid(url)
        return url
Exemple #3
0
    def __inspectorReplyFinished(self):
        """
        Private slot handling the reply.
        """
        # used for pre Qt 5.11
        result = str(self.__reply.readAll(), encoding="utf8")

        self.__reply.deleteLater()
        self.__reply = None

        pageUrl = QUrl()
        try:
            index = _VIEWS.index(self.__view)
        except ValueError:
            index = -1
        try:
            clients = json.loads(result)
            if len(clients) > index:
                port = Preferences.getWebBrowser("WebInspectorPort")
                inspectorUrl = QUrl("http://localhost:{0}".format(port))

                client = clients[index]
                pageUrl = inspectorUrl.resolved(
                    QUrl(client["devtoolsFrontendUrl"]))
            self.load(pageUrl)
            pushView(self)
            self.show()
        except json.JSONDecodeError:
            # ignore silently
            pass
Exemple #4
0
    def resolve_url(self, baseurl: QUrl) -> typing.Optional[QUrl]:
        """Resolve the URL in the element's src/href attribute.

        Args:
            baseurl: The URL to base relative URLs on as QUrl.

        Return:
            A QUrl with the absolute URL, or None.
        """
        if baseurl.isRelative():
            raise ValueError("Need an absolute base URL!")

        for attr in ['href', 'src']:
            if attr in self:
                text = self[attr].strip()
                break
        else:
            return None

        url = QUrl(text)
        if not url.isValid():
            return None
        if url.isRelative():
            url = baseurl.resolved(url)
        qtutils.ensure_valid(url)
        return url
class HttpWindow(QMainWindow):
    def __init__(self, parent=None):
        super(HttpWindow, self).__init__(parent)
        self.title = "OraDocs by littleT"
        self.left = 10
        self.top = 10
        self.width = 600
        self.height = 400

        self.docRoot = "https://oradocs-corp.documents.us2.oraclecloud.com/documents/"
        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.statusBar().showMessage('Starting ...')
        # for the menu first create some actions to be added like
        # File - Exit action
        exitAction = QAction(QIcon('exit24.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit Application')
        exitAction.triggered.connect(self.close)
        # File - open
        openAction = QAction(QIcon(''), '&Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Opens a file')
        openAction.triggered.connect(self.openCall)
        # the help actions
        helpAction = QAction(QIcon(''), 'Help', self)
        helpAction.triggered.connect(self.openHelp)
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(exitAction)
        helpMenu = mainMenu.addMenu('&Help')
        helpMenu.addAction(helpAction)

        self.urlLineEdit = QLineEdit(self)
        self.urlLineEdit.setGeometry(5, 250, 590, 20)
        self.urlLineEdit.setText(self.docRoot)

        self.downloadButton = QPushButton('Click Me', self)
        self.downloadButton.move(10, 275)
        self.downloadButton.clicked.connect(self.onDownloadClick)

        self.quitButton = QPushButton("Quit", self)
        self.quitButton.setAutoDefault(False)
        self.quitButton.clicked.connect(self.close)
        self.quitButton.move(120, 275)

        self.logOutput = QTextEdit(self)
        self.logOutput.setReadOnly(True)
        # self.logOutput.setLineWrapMode(QTextEdit.NoWrap)
        self.logOutput.setGeometry(5, 320, 590, 60)
        self.logOutput.setSizePolicy(self.sizePolicy)

        self.statusBar().showMessage('waiting for click ...')

    def openCall(self):
        QMessageBox.information(self, "Info",
                                "File Open Menu, work in progress")

    def openHelp(self):
        QMessageBox.information(self, "Info",
                                "Help Menu, work in progress")

    def onDownloadClick(self):
        self.url = QUrl(self.docRoot)
        self.logOutput.insertPlainText("onclick before startReq -> url %s\n"
                                       % self.url.toString())
        # start the request
        self.startRequest(self.url)
        self.logOutput.insertPlainText("onclick after startReq -> url %s\n"
                                       % self.url.toString())
        # do we need authorization
        self.qnam.authenticationRequired.connect(
                self.slotAuthenticationRequired)
        # do we go ssl errors
        self.qnam.sslErrors.connect(self.sslErrors)

    def httpFinished(self):
        self.logOutput.insertPlainText("httpFinished ...\n")
        self.logOutput.moveCursor(QTextCursor.End)
        if self.httpRequestAborted:
            # if self.outFile is not None:
            #    self.outFile.close()
            #    self.outFile.remove()
            #    self.outFile = None
            self.logOutput.insertPlainText("httpFinished, httpReqAbr ...\n")
            self.logOutput.moveCursor(QTextCursor.End)
            self.reply.deleteLater()
            # self.outFile.flush()
            # self.outFile.close()
            return

        # maybe updating progress or so
        # self.progressDialog.hide()
        # self.outFile.flush()
        # self.outFile.close()

        # check for redirection
        redirectionTarget = self.reply.attribute(
            QNetworkRequest.RedirectionTargetAttribute)

        if self.reply.error():
            # are we got an error
            # self.outFile.remove()
            QMessageBox.information(self, "HTTP", "Download failed %s"
                                    % self.reply.errorString)
        elif redirectionTarget is not None:
            # self.logOutput.insertPlainText("httpFinished, redirect from %s\n"
            #                                % str(self.url))
            self.logOutput.moveCursor(QTextCursor.End)
            # do we got redirected
            newUrl = self.url.resolved(redirectionTarget)
            self.logOutput.insertPlainText("httpFinished, redirect \n")
            #                               % newUrl.toString())
            self.logOutput.moveCursor(QTextCursor.End)

            #ret = QMessageBox.question(self, "HTTP", "Redirect to %s." %
            #                           newUrl.toString(),
            #                           QMessageBox.Yes | QMessageBox.No)
            #if ret == QMessageBox.Yes:
            #    # if we saied yes to redirect set the new URL to redirected one
            #    self.url = newUrl
            #    # the reply needs to be nothing
            #    self.reply = None
            #    # self.outFile.open(QIODevice.WriteOnly)
            #    # self.outFile.resize(0)
            #    # and start over
            #    self.startRequest(self.url)
            #    return
            # the new url is the redirected one
            self.url = newUrl
            # the reply needs to be nothing
            self.reply = None
            # and start over
            self.startRequest(self.url)
            return
        else:
            # fileName = QFileInfo(QUrl(self.urlLineEdit.text()).path()).fileName()
            # self.statusLabel.setText("Downloaded %s to %s." % (fileName, QDir.currentPath()))
            # self.statusLabel.setText("Done")
            self.statusBar().showMessage("Done")

        self.reply.deleteLater()
        self.reply = None
        # self.outFile = None

    def startRequest(self, url):
        self.logOutput.insertPlainText("startRequest ...\n")
        self.logOutput.moveCursor(QTextCursor.End)
        # get the requested page
        self.reply = self.qnam.get(QNetworkRequest(url))
        # if we are finished
        self.reply.finished.connect(self.httpFinished)
        # are we ready to read the stuff
        # self.reply.readyRead.connect(self.httpReadyRead)
        # downloading
        # self.reply.downloadProgress.connect(self.updateDataReadProgress)

    def slotAuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic
        self.logOutput.insertPlainText("Authentication ...\n")
        self.logOutput.moveCursor(QTextCursor.End)

        self.logOutput.moveCursor(QTextCursor.End)
        self.logOutput.insertPlainText(str(authenticator))

        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        self.logOutput.moveCursor(QTextCursor.End)
        self.logOutput.insertPlainText(str(ui))

        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" % (authenticator.realm(), self.url.host()))

        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())

        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    def sslErrors(self, reply, errors):
        errorString = ", ".join([str(error.errorString()) for error in errors])

        ret = QMessageBox.warning(self, "HTTP Example",
                "One or more SSL errors has occurred: %s" % errorString,
                QMessageBox.Ignore | QMessageBox.Abort)

        if ret == QMessageBox.Ignore:
            self.reply.ignoreSslErrors()
    if context.file is None:
        print('{mode}: {msg}'.format(mode=mode, msg=message))
    else:
        print('{mode}: {msg}\t\t\t\tline: {line}, function: {func}, file: {file}'.format(
            mode=mode, line=context.line, func=context.function, file=context.file, msg=message))


qInstallMessageHandler(qt_message_handler)

app = QApplication(sys.argv)

base_url = QUrl("{}{}/".format(FILE_PREFIX[system()], str(path.abspath(path.dirname(__file__))).replace('\\', '/')))

icon = QIcon()
for size in ICON_SIZES:
    path = FileIO.removeFilePrefix(base_url.resolved(QUrl("assets/icons/{}x{}.png".format(size, size))).url())
    icon.addFile(path, QSize(size, size))
app.setWindowIcon(icon)

qmlRegisterSingletonType(base_url.resolved(QUrl("assets/styles/UIStyles.qml")), "StyleSettings", 1, 0, "StyleSettings")
qmlRegisterSingletonType(CodeAnalyzer, "CodeAnalyzer", 1, 0, "CodeAnalyzer", CodeAnalyzer.singletonProvider)
qmlRegisterType(ExpSyntaxHighlighter, "ExpSyntaxHighlighter", 1, 0, "ExpSyntaxHighlighter")
qmlRegisterType(DiffCodeAnalyzer, "DiffCodeAnalyzer", 1, 0, "DiffCodeAnalyzer")
qmlRegisterType(ExpAnalyzer, "ExpAnalyzer", 1, 0, "ExpAnalyzer")
qmlRegisterType(TreeViewModel, "TreeViewModel", 1, 0, "TreeViewModel")
qmlRegisterType(DebuggerWrapper, "Debugger", 1, 0, "Debugger")
qmlRegisterType(IOWrapper, "IOWrapper", 1, 0, "IOWrapper")
qmlRegisterType(FileIO, "FileIO", 1, 0, "FileIO")
qmlRegisterType(FormattedTextWriter, "FormattedTextWriter", 1, 0, "FormattedTextWriter")

core = Core()
Exemple #7
0
class Hrobot(QObject):

    asyncFinished = pyqtSignal()

    def __init__(self,
                 base_url=None,
                 private=True,
                 profile_name=None,
                 gui=False):
        super().__init__()
        self.base_url = QUrl(base_url)
        self.__interceptor = Interceptor(self)
        if private:
            self.__profile = QWebEngineProfile()
        elif profile_name:
            self.__profile = QWebEngineProfile(profile_name)
        else:
            raise Exception(
                'please pass `profile_name` in case of `private` flag set to False'
            )
        self.__profile.setRequestInterceptor(self.__interceptor)
        self.__page = Page(self.__profile, None)
        self.__cookie_store = self.__profile.cookieStore()
        self.__cookie_store.cookieAdded.connect(self.__on_cookie_added)
        self.__cookies = []
        self.__async_result = None
        self.__loading = False

        self.__view = QWebEngineView()

        self.__page.setView(self.__view)
        self._qt_invocation = QtInvocation(self.__page)
        self.__channel = QWebChannel(self)
        self.__channel.registerObject("QtInvocation", self._qt_invocation)
        self.__page.setWebChannel(self.__channel)

        self.__page.loadStarted.connect(self.__load_started)
        self.__page.loadFinished.connect(self.__load_finished)
        self.__view.loadProgress.connect(self.__prg)
        self.__page.navigationRequested.connect(self.__navigation_requested)
        # self._qt_invocation.js_navigation_requested.connect(self.__page._js_gap_eventloop)
        self.__page.settings().setAttribute(
            self.__page.settings().LocalContentCanAccessRemoteUrls, True)
        self.__page.setUrl(QUrl('about:blank'))

        self.__view.setWindowState(Qt.WindowMaximized)
        if gui:
            self.__view.show()

    def __prg(self, p):
        print('progress: ', p)

    def __load_started(self):
        print('load started')

    def __load_finished(self, ok):
        print('load finished', ok)

    def __node(self, node_id):
        return Node(self, self.__page, node_id)

    def __navigation_requested(self):
        print('navvvvvvvvvvvvv', self.__loading)
        if not self.__loading:
            self.__loading = True
            print('navigation event loop started')
            loop = QEventLoop()
            self.__page.loadFinished.connect(loop.quit)
            loop.exec()
            print('navigation event loop ended')
            loop_js = QEventLoop()
            self._qt_invocation.js_ready.connect(loop_js.quit)
            self.__register_js()
            loop_js.exec()
            self.__loading = False
            print('js register event loop ended')

    def __register_js(self):
        channel_file = QFile(":/qtwebchannel/qwebchannel.js")
        if channel_file.open(QIODevice.ReadOnly):
            content = channel_file.readAll()
            channel_file.close()
            print('runjssssssssssssssssssssssssssssssssssssssss 1')
            self.__run_js(content.data().decode())
            print('runjssssssssssssssssssssssssssssssssssssssss 2',
                  BASE_APP_PATH)
        qt_file = QFile(
            '{0}/extensions/hrobot/v_2_0/qt.js'.format(BASE_APP_PATH))
        if qt_file.open(QIODevice.ReadOnly):
            content = qt_file.readAll()
            qt_file.close()
            print('runjssssssssssssssssssssssssssssssssssssssss 3')
            self.__run_js(content.data().decode())
            print('runjssssssssssssssssssssssssssssssssssssssss 4')

    def __async_callback(self, result):
        self.__async_result = result
        self.asyncFinished.emit()
        print('async js emit')

    def __run_js(self, script):
        loop = QEventLoop()
        self.asyncFinished.connect(loop.quit)
        self.__page.runJavaScript(script, self.__async_callback)
        loop.exec()
        print('run js finished')
        return self.__async_result

    def __on_cookie_added(self, cookie):
        print('on add cookie', cookie.toRawForm(1))
        for c in self.__cookies:
            if c.hasSameIdentifier(cookie):
                return
        print('coocke', cookie)
        print('net cookie', QNetworkCookie(cookie))
        self.__cookies.append(QNetworkCookie(cookie))

    def set_cookie(self, cookie):
        self.__cookie_store.setCookie(cookie)

    def __set_browser_attribute(self, attr, value):
        self.__page.settings().setAttribute(attr, value)

    def go_to(self, url: Union[QUrl, str]) -> bool:
        """ Goes to a given URL. """
        url = QUrl(url)
        if self.base_url:
            url = self.base_url.resolved(url)
        loop = QEventLoop()
        self.__page.loadFinished.connect(loop.exit)
        self.__page.load(url)
        return True if loop.exec() else False

    def go_back(self):
        self.__view.back()

    def get_body(self):
        """ Return the current DOM as HTML. """
        loop = QEventLoop()
        self.asyncFinished.connect(loop.quit)
        self.__page.toHtml(self.__async_callback)
        loop.exec()
        return self.__async_result

    def get_cookies(self, as_json=False):
        if as_json:
            return self.__cookie_to_json()
        return self.__cookies

    def __cookie_to_json(self):
        cookies_list_info = []
        for c in self.__cookies:
            c = QNetworkCookie(c)
            data = {
                "name": bytearray(c.name()).decode(),
                "domain": c.domain(),
                "value": bytearray(c.value()).decode(),
                "path": c.path(),
                "expirationDate": c.expirationDate().toString(Qt.ISODate),
                "secure": c.isSecure(),
                "httponly": c.isHttpOnly()
            }
            cookies_list_info.append(data)
        return cookies_list_info

    def json_to_cookie(self, json_cookie_list):
        cookies_list_info = []
        for json_cookie in json_cookie_list:
            c = QNetworkCookie()
            print(json_cookie, '** json_cookie')
            for k, v in json_cookie.items():
                if k == 'path':
                    c.setPath(v)
                elif k == 'domain':
                    c.setPath(v)
                elif k == 'expirationDate':
                    print(v, type(v))
                    qdate = QDateTime(2019, 12, 20, 11, 59, 59)
                    print(qdate)
                    c.setExpirationDate(qdate)
                elif k == 'httponly':
                    c.setHttpOnly(v)
                elif k == 'secure':
                    c.setSecure(v)
                elif k == 'value':
                    c.setValue(v.encode())
                elif k == 'name':
                    c.setName(v.encode())
            print('c', c.expirationDate())
            cookies_list_info.append(c)
        return cookies_list_info

    def eval_script(self, script):
        """ Evaluates a piece of Javascript in the context of the current page and returns its value. """
        return self.__run_js(script)

    def exec_script(self, script):
        """ Executes a piece of Javascript in the context of the current page. """
        self.__run_js(script)

    def block_url(self, url):
        raise NotImplementedError

    def allow_url(self, url):
        raise NotImplementedError

    def get_url(self):
        """ Returns the current location. """
        return self.__page.url()

    def reload(self):
        self.go_to(self.current_url())

    def is_private(self):
        return self.__page.profile().isOffTheRecord()

    def set_skip_image_loading(self, value):
        """ Specifies whether images are automatically loaded in web pages. This is disabled by default."""
        # self.browser.set_attribute('auto_load_images', value)
        self.__set_browser_attribute(self.__page.settings().AutoLoadImages,
                                     not value)

    def save_as_pdf(self, name):
        loop = QEventLoop()
        self.__page.pdfPrintingFinished.connect(loop.quit)
        self.__page.printToPdf(name)
        loop.exec()

    def scroll_to_end(self, lazy_load=True):
        loop = QEventLoop()
        self._qt_invocation.async_js_finished.connect(loop.quit)
        self.__run_js(
            'Qt.scrollToEnd({0})'.format('true' if lazy_load else 'false'))
        loop.exec()

    def find_by_css(self, selector):
        """ Return the first node matching the given CSSv3 expression or None. """
        nodes = self.find_all_by_css(selector)
        return None if not nodes else nodes[0]

    def find_by_xpath(self, xpath):
        """ Return the first node matching the given XPath 2.0 expression or None. """
        nodes = self.find_all_by_xpath(xpath)
        return None if not nodes else nodes[0]

    def find_all_by_css(self, selector):
        """ Return all nodes matching the given CSSv3 expression. """
        try:
            return [
                self.__node(node_id) for node_id in self.__run_js(
                    Utils.qt_js_prepare('Qt.findCss("{0}")'.format(
                        Utils.normalize_quotes(selector)))).split(",")
                if node_id
            ]
        except AttributeError:
            return None

    def find_all_by_xpath(self, xpath):
        """ Return all nodes matching the given XPath 2.0 expression. """
        try:
            return [
                self.__node(node_id) for node_id in self.__run_js(
                    Utils.qt_js_prepare('Qt.findXpath("{0}")'.format(
                        Utils.normalize_quotes(xpath)))).split(",") if node_id
            ]
        except AttributeError:
            return None

    def wait_until_css(self, selector, timeout=30):
        node = self.find_by_css(selector)
        elapsed = 0
        while not node:
            if elapsed > timeout:
                return None
            Utils.wait(1000)
            elapsed += 1
            node = self.find_by_css(selector)
        return node

    def wait_until_xpath(self, xpath, timeout=30):
        node = self.find_by_xpath(xpath)
        elapsed = 0
        while not node:
            if elapsed > timeout:
                return None
            Utils.wait(1000)
            elapsed += 1
            node = self.find_by_xpath(xpath)
        return node

    def find_by_following_sibling(self, tag, sibling):
        """ Return first sibling node after the current node """
        return self.find_by_xpath("//%s/following-sibling::%s" %
                                  (tag, sibling))

    def find_all_by_following_sibling(self, tag, sibling):
        """ Return all sibling nodes after the current node """
        return self.find_all_by_xpath("//%s/following-sibling::%s" %
                                      (tag, sibling))

    def find_by_preceding_sibling(self, tag, sibling):
        """ Return first sibling node before the current node """
        return self.find_by_xpath("//%s/preceding-sibling::%s" %
                                  (tag, sibling))

    def find_all_by_preceding_sibling(self, tag, sibling):
        """ Return all sibling nodes before the current node """
        return self.find_all_by_xpath("//%s/preceding-sibling::%s" %
                                      (tag, sibling))

    def find_element_has_attribute(self, tag, attr):
        """ Return the first node has attr in its attribute or none """
        return self.find_by_xpath("//%s[@%s]" % (tag, attr))

    def find_elements_has_attribute(self, tag, attr):
        """ Return all nodes has attr in their attribute or none """
        return self.find_all_by_xpath("//%s[@%s]" % (tag, attr))

    def find_elements_has_any_attribute(self, tag):
        """ Return all nodes that has any attribute or none"""
        return self.find_by_xpath("//%s[@*]" % tag)

    def find_elements_has_not_attribute(self, tag):
        """ Return all nodes that has not any attribute or none"""
        return self.find_by_xpath("//%s[not(@*)]" % tag)

    def find_by_attribute_value(self, tag, attr, value, normalize_space=True):
        """ Return first node has attr in its attribute and the value of attr is equal to value."""
        if normalize_space:
            return self.find_by_xpath("//%s[normalize-space(@%s = %s)]" %
                                      (tag, attr, value))
        else:
            return self.find_by_xpath("//%s[@%s = %s]" % (tag, attr, value))

    def find_all_by_attribute_value(self,
                                    tag,
                                    attr,
                                    value,
                                    normalize_space=True):
        """ Return all nodes has attr in their attribute and the value of attr is equal to value."""
        if normalize_space:
            return self.find_all_by_xpath("//%s[normalize-space(@%s = %s)]" %
                                          (tag, attr, value))
        else:
            return self.find_all_by_xpath("//%s[@%s = %s]" %
                                          (tag, attr, value))

    def find_by_children_number(self, tag, children_number):
        """ Return first node that number of its children is equal to children_number  """
        return self.find_all_by_xpath("//*[count(%s)= %s]" %
                                      (tag, children_number))

    def find_all_by_children_number(self, children_number):
        """ Return all nodes that number of their children is equal to children_number  """
        return self.find_all_by_xpath("//*[count(*)= %s]" % children_number)

    def find_by_name(self, tag_name):
        """ Return node that name of it is equal to tag_name """
        return self.find_all_by_xpath("//*[name()=%s]" % tag_name)

    def find_by_name_starts_with(self, letter):
        """ Return node that name of it starts with to letter """
        return self.find_all_by_xpath("//*[starts-with(name(), %s)]" % letter)

    def find_by_name_contains(self, letter):
        """ Return node that name of it contains letter """
        return self.find_all_by_xpath("//*[contains(name(),%s)]" % letter)

    # this finds excludes any descendants and  attribute nodes and namespace nodes.
    def find_by_following(self, node):
        """ Return nodes that exist in following of node """
        return self.find_all_by_xpath("//%s/following::*" % node)

    # this finds excludes any descendants and  attribute nodes and namespace nodes.
    def find_by_preceding(self, node):
        """ Return nodes that exist in preceding of node """
        return self.find_all_by_xpath("//%s/preceding::*" % node)

    def find_element_descendant(self, tag, child_tag='*'):
        return self.find_by_xpath("%s/descendant::%s" % (tag, child_tag))

    def find_elements_descendant(self, tag, child_tag='*'):
        return self.find_all_by_xpath("%s/descendant::%s" % (tag, child_tag))

    def find_all_elements_descendant(self, tag):
        return self.find_all_by_xpath("//%s/descendant::*" % tag)

    def find_by_contain_text(self, tag, text):
        """ Return node that contains text in their text value"""
        return self.find_by_xpath("//%s[contains(text(), '%s')]" % (tag, text))

    def find_all_by_contain_text(self, tag, text):
        """ Return all nodes that contains text in their text value"""
        return self.find_all_by_xpath("//%s[contains(text(), '%s')]" %
                                      (tag, text))
Exemple #8
0
class HttpWindow(QDialog):
    def __init__(self, parent=None):
        super(HttpWindow, self).__init__(parent)

        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False

        self.urlLineEdit = QLineEdit('https://www.qt.io')

        urlLabel = QLabel("&URL:")
        urlLabel.setBuddy(self.urlLineEdit)
        self.statusLabel = QLabel(
                "Please enter the URL of a file you want to download.")
        self.statusLabel.setWordWrap(True)

        self.downloadButton = QPushButton("Download")
        self.downloadButton.setDefault(True)
        self.quitButton = QPushButton("Quit")
        self.quitButton.setAutoDefault(False)

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.downloadButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)

        self.progressDialog = QProgressDialog(self)

        self.urlLineEdit.textChanged.connect(self.enableDownloadButton)
        self.qnam.authenticationRequired.connect(
                self.slotAuthenticationRequired)
        self.qnam.sslErrors.connect(self.sslErrors)
        self.progressDialog.canceled.connect(self.cancelDownload)
        self.downloadButton.clicked.connect(self.downloadFile)
        self.quitButton.clicked.connect(self.close)

        topLayout = QHBoxLayout()
        topLayout.addWidget(urlLabel)
        topLayout.addWidget(self.urlLineEdit)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("HTTP")
        self.urlLineEdit.setFocus()

    def startRequest(self, url):
        self.reply = self.qnam.get(QNetworkRequest(url))
        self.reply.finished.connect(self.httpFinished)
        self.reply.readyRead.connect(self.httpReadyRead)
        self.reply.downloadProgress.connect(self.updateDataReadProgress)

    def downloadFile(self):
        self.url = QUrl(self.urlLineEdit.text())
        fileInfo = QFileInfo(self.url.path())
        fileName = fileInfo.fileName()

        if not fileName:
            fileName = 'index.html'

        if QFile.exists(fileName):
            ret = QMessageBox.question(self, "HTTP",
                    "There already exists a file called %s in the current "
                    "directory. Overwrite?" % fileName,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if ret == QMessageBox.No:
                return

            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, "HTTP",
                    "Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.progressDialog.setWindowTitle("HTTP")
        self.progressDialog.setLabelText("Downloading %s." % fileName)
        self.downloadButton.setEnabled(False)

        self.httpRequestAborted = False
        self.startRequest(self.url)

    def cancelDownload(self):
        self.statusLabel.setText("Download canceled.")
        self.httpRequestAborted = True
        if self.reply is not None:
            self.reply.abort()
        self.downloadButton.setEnabled(True)

    def httpFinished(self):
        if self.httpRequestAborted:
            if self.outFile is not None:
                self.outFile.close()
                self.outFile.remove()
                self.outFile = None

            self.reply.deleteLater()
            self.reply = None
            self.progressDialog.hide()
            return

        self.progressDialog.hide()
        self.outFile.flush()
        self.outFile.close()

        redirectionTarget = self.reply.attribute(QNetworkRequest.RedirectionTargetAttribute)

        if self.reply.error():
            self.outFile.remove()
            QMessageBox.information(self, "HTTP",
                    "Download failed: %s." % self.reply.errorString())
            self.downloadButton.setEnabled(True)
        elif redirectionTarget is not None:
            newUrl = self.url.resolved(redirectionTarget)

            ret = QMessageBox.question(self, "HTTP",
                    "Redirect to %s?" % newUrl.toString(),
                    QMessageBox.Yes | QMessageBox.No)

            if ret == QMessageBox.Yes:
                self.url = newUrl
                self.reply.deleteLater()
                self.reply = None
                self.outFile.open(QIODevice.WriteOnly)
                self.outFile.resize(0)
                self.startRequest(self.url)
                return
        else:
            fileName = QFileInfo(QUrl(self.urlLineEdit.text()).path()).fileName()
            self.statusLabel.setText("Downloaded %s to %s." % (fileName, QDir.currentPath()))

            self.downloadButton.setEnabled(True)

        self.reply.deleteLater()
        self.reply = None
        self.outFile = None

    def httpReadyRead(self):
        if self.outFile is not None:
            self.outFile.write(self.reply.readAll())

    def updateDataReadProgress(self, bytesRead, totalBytes):
        if self.httpRequestAborted:
            return

        self.progressDialog.setMaximum(totalBytes)
        self.progressDialog.setValue(bytesRead)

    def enableDownloadButton(self):
        self.downloadButton.setEnabled(self.urlLineEdit.text() != '')

    def slotAuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic

        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" % (authenticator.realm(), self.url.host()))

        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())

        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    def sslErrors(self, reply, errors):
        errorString = ", ".join([str(error.errorString()) for error in errors])

        ret = QMessageBox.warning(self, "HTTP Example",
                "One or more SSL errors has occurred: %s" % errorString,
                QMessageBox.Ignore | QMessageBox.Abort)

        if ret == QMessageBox.Ignore:
            self.reply.ignoreSslErrors()
                    file=context.file,
                    msg=message))


qInstallMessageHandler(qt_message_handler)

app = QApplication(sys.argv)

base_url = QUrl("{}{}/".format(
    FILE_PREFIX[system()],
    str(path.abspath(path.dirname(__file__))).replace('\\', '/')))

icon = QIcon()
for size in ICON_SIZES:
    path = FileIO.removeFilePrefix(
        base_url.resolved(QUrl("assets/icons/{}x{}.png".format(size,
                                                               size))).url())
    icon.addFile(path, QSize(size, size))
app.setWindowIcon(icon)

qmlRegisterSingletonType(base_url.resolved(QUrl("assets/styles/UIStyles.qml")),
                         "StyleSettings", 1, 0, "StyleSettings")
qmlRegisterSingletonType(CodeAnalyzer, "CodeAnalyzer", 1, 0, "CodeAnalyzer",
                         CodeAnalyzer.singletonProvider)
qmlRegisterType(ExpSyntaxHighlighter, "ExpSyntaxHighlighter", 1, 0,
                "ExpSyntaxHighlighter")
qmlRegisterType(DiffCodeAnalyzer, "DiffCodeAnalyzer", 1, 0, "DiffCodeAnalyzer")
qmlRegisterType(ExpAnalyzer, "ExpAnalyzer", 1, 0, "ExpAnalyzer")
qmlRegisterType(TreeViewModel, "TreeViewModel", 1, 0, "TreeViewModel")
qmlRegisterType(DebuggerWrapper, "Debugger", 1, 0, "Debugger")
qmlRegisterType(IOWrapper, "IOWrapper", 1, 0, "IOWrapper")
qmlRegisterType(FileIO, "FileIO", 1, 0, "FileIO")
Exemple #10
0
class AppWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.docRoot = "https://oradocs-corp.documents.us2.oraclecloud.com/documents/"
        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False
        self.gotToken = False

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        # self.ui.setupUi.MainWindow.setTitle("OraDocs")
        self._connections()

    def _connections(self):
        self.ui.logOutput.insertPlainText(
            "Setting up actions for all menus and such .")
        self.ui.action_Exit.triggered.connect(self.close)
        self.ui.action_Open.triggered.connect(self.action_open)
        self.ui.action_Save.triggered.connect(self.action_save)
        self.ui.action_SyncAll.triggered.connect(self.action_syncAll)
        self.ui.action_SyncConnect.triggered.connect(self.action_syncConnect)
        self.ui.logOutput.insertPlainText(".. done\n")

    def startRequest(self, url):
        # just some debugging to see were we are
        self.ui.logOutput.insertPlainText("startRequest ...\n")
        # get the URL
        self.ui.logOutput.insertPlainText("get page ...\n")
        self.reply = self.qnam.get(QNetworkRequest(url))

        # not sure if here correct or better somwhere else
        # do we need authorization
        self.qnam.authenticationRequired.connect(
            self.slotAuthenticationRequired)
        # do we got ssl errors
        self.qnam.sslErrors.connect(self.sslErrors)

        # after loading the page do some hadling of the output via the pyslot
        self.reply.finished.connect(self.httpFinished)
        # we should be able to read the stuff
        self.ui.logOutput.insertPlainText("before httpReady ...\n")
        self.reply.readyRead.connect(self.httpReadyRead)
        # not sure if the return is needed
        return

    def httpFinished(self):
        # just some debugging
        self.ui.logOutput.insertPlainText("httpFinished start ...\n")

        # check for redirection
        redirectionTarget = self.reply.attribute(
            QNetworkRequest.RedirectionTargetAttribute)
        # check for reply results
        if self.reply.error():
            # looks like we got an error
            # self.outFile.remove()
            QMessageBox.information(
                self, "HTTP", "Download failed %s" % self.reply.errorString)
        elif redirectionTarget is not None:
            # we got redirected
            # output where we are going to
            self.ui.logOutput.insertPlainText("redirect -> %s\n" %
                                              str(redirectionTarget))
            self.ui.logOutput.moveCursor(QTextCursor.End)
            # our new URL is that one
            newUrl = self.url.resolved(redirectionTarget)
            # debug
            self.ui.logOutput.insertPlainText("new URL -> %s\n" %
                                              newUrl.toString())
            self.ui.logOutput.moveCursor(QTextCursor.End)

            # the new url is the redirected one
            self.url = newUrl
            # the reply needs to be nothing
            self.reply = None
            # and start over
            self.startRequest(self.url)
            return
        else:
            # do normal processing
            self.ui.logOutput.insertPlainText("no-redirect -> %s \n" %
                                              self.url.toString())
            self.ui.logOutput.moveCursor(QTextCursor.End)
            self.ui.logOutput.insertPlainText(
                str(self.reply.header(QNetworkRequest.rawHeader)))
            # as the last actions in here

        self.reply.deleteLater()
        self.reply = None

    def httpReadyRead(self):
        # if self.outFile is not None:
        #    self.outFile.write(self.reply.readAll())
        self.ui.logOutput.insertPlainText("http Ready\n")
        self.ui.logOutput.moveCursor(QTextCursor.End)
        myData = self.reply.readAll()
        # self.ui.logOutput.insertPlainText(str(myData, 'utf-8'))

    def AuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic
        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" %
                                    (authenticator.realm(), self.url.host()))
        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())
        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    @pyqtSlot()
    def action_close(self):
        # print("closing")
        self.quit()

    @pyqtSlot()
    def action_open(self):
        # print("open")
        QMessageBox.information(self, "File Open", "work in progress")

    @pyqtSlot()
    def action_save(self):
        # print("open")
        QMessageBox.information(self, "File Save", "work in progress")

    @pyqtSlot()
    def action_syncAll(self):
        QMessageBox.information(self, "Sync ALl", "work in progress")

    @pyqtSlot()
    # we are starting the the connection actions
    def action_syncConnect(self):
        # just some debugging
        self.ui.logOutput.insertPlainText("syncConnect ...\n")
        # we start with the root URL
        self.url = QUrl(self.docRoot)
        # start the request
        self.startRequest(self.url)
        # not sure if here correct or better in httpFinished
        # do we need authorization
        self.qnam.authenticationRequired.connect(
            self.slotAuthenticationRequired)
        # do we got ssl errors
        self.qnam.sslErrors.connect(self.sslErrors)

        # just some debugging
        self.ui.logOutput.insertPlainText(
            "syncConnect - after start Request\n")

        # QMessageBox.information(self, "Sync Connect", "work in progress")

    @pyqtSlot()
    def slotAuthenticationRequired(self, authenticator):
        # import os
        QMessageBox.information(self, "Authentication", "work in progress")

    def sslErrors(self, reply, errors):
        QMessageBox.information(self, "SSL error", "work in progress")
class GreaseMonkeyScript(QObject):
    """
    Class implementing the GreaseMonkey script.
    
    @signal scriptChanged() emitted to indicate a script change
    @signal updatingChanged(bool) emitted to indicate a change of the
        updating state
    """
    DocumentStart = 0
    DocumentEnd = 1
    DocumentIdle = 2

    scriptChanged = pyqtSignal()
    updatingChanged = pyqtSignal(bool)

    def __init__(self, manager, path):
        """
        Constructor
        
        @param manager reference to the manager object (GreaseMonkeyManager)
        @param path path of the Javascript file (string)
        """
        super(GreaseMonkeyScript, self).__init__(manager)

        self.__manager = manager
        self.__fileWatcher = DelayedFileWatcher(parent=None)

        self.__name = ""
        self.__namespace = "GreaseMonkeyNS"
        self.__description = ""
        self.__version = ""

        self.__include = []
        self.__exclude = []
        self.__require = []

        self.__icon = QIcon()
        self.__iconUrl = QUrl()
        self.__downloadUrl = QUrl()
        self.__updateUrl = QUrl()
        self.__startAt = GreaseMonkeyScript.DocumentEnd

        self.__script = ""
        self.__fileName = path
        self.__enabled = True
        self.__valid = False
        self.__noFrames = False

        self.__updating = False

        self.__downloaders = []
        self.__iconReplies = []

        self.__parseScript()

        self.__fileWatcher.delayedFileChanged.connect(
            self.__watchedFileChanged)

    def isValid(self):
        """
        Public method to check the validity of the script.
        
        @return flag indicating a valid script (boolean)
        """
        return self.__valid

    def name(self):
        """
        Public method to get the name of the script.
        
        @return name of the script (string)
        """
        return self.__name

    def nameSpace(self):
        """
        Public method to get the name space of the script.
        
        @return name space of the script (string)
        """
        return self.__namespace

    def fullName(self):
        """
        Public method to get the full name of the script.
        
        @return full name of the script (string)
        """
        return "{0}/{1}".format(self.__namespace, self.__name)

    def description(self):
        """
        Public method to get the description of the script.
        
        @return description of the script (string)
        """
        return self.__description

    def version(self):
        """
        Public method to get the version of the script.
        
        @return version of the script (string)
        """
        return self.__version

    def icon(self):
        """
        Public method to get the icon of the script.
        
        @return script icon
        @rtype QIcon
        """
        return self.__icon

    def iconUrl(self):
        """
        Public method to get the icon URL of the script.
        
        @return icon URL of the script (QUrl)
        """
        return QUrl(self.__iconUrl)

    def downloadUrl(self):
        """
        Public method to get the download URL of the script.
        
        @return download URL of the script (QUrl)
        """
        return QUrl(self.__downloadUrl)

    def updateUrl(self):
        """
        Public method to get the update URL of the script.
        
        @return update URL of the script (QUrl)
        """
        return QUrl(self.__updateUrl)

    def startAt(self):
        """
        Public method to get the start point of the script.
        
        @return start point of the script (DocumentStart or DocumentEnd)
        """
        return self.__startAt

    def noFrames(self):
        """
        Public method to get the noFrames flag.
        
        @return flag indicating to not run on sub frames
        @rtype bool
        """
        return self.__noFrames

    def isEnabled(self):
        """
        Public method to check, if the script is enabled.
        
        @return flag indicating an enabled state (boolean)
        """
        return self.__enabled and self.__valid

    def setEnabled(self, enable):
        """
        Public method to enable a script.
        
        @param enable flag indicating the new enabled state (boolean)
        """
        self.__enabled = enable

    def include(self):
        """
        Public method to get the list of included URLs.
        
        @return list of included URLs (list of strings)
        """
        return self.__include[:]

    def exclude(self):
        """
        Public method to get the list of excluded URLs.
        
        @return list of excluded URLs (list of strings)
        """
        return self.__exclude[:]

    def require(self):
        """
        Public method to get the list of required scripts.
        
        @return list of required scripts (list of strings)
        """
        return self.__require[:]

    def fileName(self):
        """
        Public method to get the path of the Javascript file.
        
        @return path of the Javascript file (string)
        """
        return self.__fileName

    def isUpdating(self):
        """
        Public method to get the updating flag.
        
        @return updating flag
        @rtype bool
        """
        return self.__updating

    @pyqtSlot(str)
    def __watchedFileChanged(self, fileName):
        """
        Private slot handling changes of the script file.
        
        @param fileName path of the script file
        @type str
        """
        if self.__fileName == fileName:
            self.__reloadScript()

    def __parseScript(self):
        """
        Private method to parse the given script and populate the data
        structure.
        """
        self.__name = ""
        self.__namespace = "GreaseMonkeyNS"
        self.__description = ""
        self.__version = ""

        self.__include = []
        self.__exclude = []
        self.__require = []

        self.__icon = QIcon()
        self.__iconUrl = QUrl()
        self.__downloadUrl = QUrl()
        self.__updateUrl = QUrl()
        self.__startAt = GreaseMonkeyScript.DocumentEnd

        self.__script = ""
        self.__enabled = True
        self.__valid = False
        self.__noFrames = False

        try:
            f = open(self.__fileName, "r", encoding="utf-8")
            fileData = f.read()
            f.close()
        except (IOError, OSError):
            # silently ignore because it shouldn't happen
            return

        if self.__fileName not in self.__fileWatcher.files():
            self.__fileWatcher.addPath(self.__fileName)

        rx = QRegExp("// ==UserScript==(.*)// ==/UserScript==")
        rx.indexIn(fileData)
        metaDataBlock = rx.cap(1).strip()

        if metaDataBlock == "":
            # invalid script file
            return

        for line in metaDataBlock.splitlines():
            if not line.strip():
                continue

            if not line.startswith("// @"):
                continue

            line = line[3:].replace("\t", " ")
            index = line.find(" ")

            key = line[:index].strip()
            if index > 0:
                value = line[index + 1:].strip()
            else:
                value = ""

            if not key:
                continue

            if key == "@name":
                self.__name = value

            elif key == "@namespace":
                self.__namespace = value

            elif key == "@description":
                self.__description = value

            elif key == "@version":
                self.__version = value

            elif key in ["@include", "@match"]:
                self.__include.append(value)

            elif key in ["@exclude", "@exclude_match"]:
                self.__exclude.append(value)

            elif key == "@require":
                self.__require.append(value)

            elif key == "@run-at":
                if value == "document-end":
                    self.__startAt = GreaseMonkeyScript.DocumentEnd
                elif value == "document-start":
                    self.__startAt = GreaseMonkeyScript.DocumentStart
                elif value == "document-idle":
                    self.__startAt = GreaseMonkeyScript.DocumentIdle

            elif key == "@downloadURL" and self.__downloadUrl.isEmpty():
                self.__downloadUrl = QUrl(value)

            elif key == "@updateURL" and self.__updateUrl.isEmpty():
                self.__updateUrl = QUrl(value)

            elif key == "@icon":
                self.__iconUrl = QUrl(value)

            elif key == "@noframes":
                self.__noFrames = True

        self.__iconUrl = self.__downloadUrl.resolved(self.__iconUrl)

        if not self.__include:
            self.__include.append("*")

        nspace = bytes(
            QCryptographicHash.hash(
                QByteArray(self.fullName().encode("utf-8")),
                QCryptographicHash.Md4).toHex()).decode("ascii")
        valuesScript = values_js.format(nspace)
        self.__script = "(function(){{{0}\n{1}\n{2}\n}})();".format(
            valuesScript, self.__manager.requireScripts(self.__require),
            fileData)
        self.__valid = True

        self.__downloadIcon()
        self.__downloadRequires()

    def webScript(self):
        """
        Public method to create a script object.
        
        @return prepared script object
        @rtype QWebEngineScript
        """
        script = QWebEngineScript()
        script.setSourceCode("{0}\n{1}".format(bootstrap_js, self.__script))
        script.setName(self.fullName())
        script.setWorldId(WebBrowserPage.SafeJsWorld)
        script.setRunsOnSubFrames(not self.__noFrames)
        return script

    def updateScript(self):
        """
        Public method to updated the script.
        """
        if not self.__downloadUrl.isValid() or self.__updating:
            return

        self.__updating = True
        self.updatingChanged.emit(self.__updating)

        downloader = GreaseMonkeyDownloader(
            self.__downloadUrl, self.__manager,
            GreaseMonkeyDownloader.DownloadMainScript)
        downloader.updateScript(self.__fileName)
        downloader.finished.connect(
            lambda: self.__downloaderFinished(downloader))
        downloader.error.connect(lambda: self.__downloaderError(downloader))
        self.__downloaders.append(downloader)

        self.__downloadRequires()

    def __downloaderFinished(self, downloader):
        """
        Private slot to handle a finished download.
        
        @param downloader reference to the downloader object
        @type GreaseMonkeyDownloader
        """
        if downloader in self.__downloaders:
            self.__downloaders.remove(downloader)
        self.__updating = False
        self.updatingChanged.emit(self.__updating)

    def __downloaderError(self, downloader):
        """
        Private slot to handle a downloader error.
        
        @param downloader reference to the downloader object
        @type GreaseMonkeyDownloader
        """
        if downloader in self.__downloaders:
            self.__downloaders.remove(downloader)
        self.__updating = False
        self.updatingChanged.emit(self.__updating)

    def __reloadScript(self):
        """
        Private method to reload the script.
        """
        self.__parseScript()

        self.__manager.removeScript(self, False)
        self.__manager.addScript(self)

        self.scriptChanged.emit()

    def __downloadRequires(self):
        """
        Private method to download the required scripts.
        """
        for urlStr in self.__require:
            if not self.__manager.requireScripts([urlStr]):
                downloader = GreaseMonkeyDownloader(
                    QUrl(urlStr), self.__manager,
                    GreaseMonkeyDownloader.DownloadRequireScript)
                downloader.finished.connect(
                    lambda: self.__requireDownloaded(downloader))
                downloader.error.connect(
                    lambda: self.__requireDownloadError(downloader))
                self.__downloaders.append(downloader)

    def __requireDownloaded(self, downloader):
        """
        Private slot to handle a finished download of a required script.
        
        @param downloader reference to the downloader object
        @type GreaseMonkeyDownloader
        """
        if downloader in self.__downloaders:
            self.__downloaders.remove(downloader)

        self.__reloadScript()

    def __requireDownloadError(self, downloader):
        """
        Private slot to handle a downloader error.
        
        @param downloader reference to the downloader object
        @type GreaseMonkeyDownloader
        """
        if downloader in self.__downloaders:
            self.__downloaders.remove(downloader)

    def __downloadIcon(self):
        """
        Private slot to download the script icon.
        """
        if self.__iconUrl.isValid():
            request = QNetworkRequest(self.__iconUrl)
            reply = WebBrowserWindow.networkManager().get(request)
            reply.finished.connect(lambda: self.__iconDownloaded(reply))
            self.__iconReplies.append(reply)

    def __iconDownloaded(self, reply):
        """
        Private slot to handle a finished download of a script icon.
        
        @param reply reference to the network reply
        @type QNetworkReply
        """
        if reply in self.__iconReplies:
            self.__iconReplies.remove(reply)

        reply.deleteLater()
        if reply.error() == QNetworkReply.NoError:
            self.__icon = QPixmap.fromImage(QImage.fromData(reply.readAll()))
Exemple #12
0
def getFullPath(path):
    currentPath = QUrl(QFileInfo(__file__).absolutePath()+'/')
    return currentPath.resolved(QUrl(path)).toString()
Exemple #13
0
class WebHitTestResult(object):
    """
    Class implementing an object for testing certain aspects of a web page.
    """
    def __init__(self, page, pos):
        """
        Constructor
        
        @param page reference to the web page
        @type WebBrowserPage
        @param pos position to be tested
        @type QPoint
        """
        self.__isNull = True
        self.__isContentEditable = False
        self.__isContentSelected = False
        self.__isMediaPaused = False
        self.__isMediaMuted = False
        self.__pos = QPoint(pos)
        self.__baseUrl = QUrl()
        self.__alternateText = ""
        self.__boundingRect = QRect()
        self.__imageUrl = QUrl()
        self.__linkTitle = ""
        self.__linkUrl = QUrl()
        self.__mediaUrl = QUrl()
        self.__tagName = ""
        self.__viewportPos = page.mapToViewport(pos)

        script = """
            (function() {{
                var e = document.elementFromPoint({0}, {1});
                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: '',
                    mediaPaused: false,
                    mediaMuted: false,
                    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;
            }})()
        """.format(self.__viewportPos.x(), self.__viewportPos.y())
        self.__populate(page.url(), page.execJavaScript(script))

    def updateWithContextMenuData(self, data):
        """
        Public method to update the hit test data with data from the context
        menu event.
        
        @param data context menu data
        @type QWebEngineContextMenuData
        """
        from PyQt5.QtWebEngineWidgets import QWebEngineContextMenuData
        if not data.isValid() or data.position() != self.__pos:
            return

        self.__linkTitle = data.linkText()
        self.__linkUrl = data.linkUrl()
        self.__isContentEditable = data.isContentEditable()
        self.__isContentSelected = bool(data.selectedText())

        if data.mediaType() == QWebEngineContextMenuData.MediaTypeImage:
            self.__imageUrl = data.mediaUrl()
        elif data.mediaType() in [
                QWebEngineContextMenuData.MediaTypeAudio,
                QWebEngineContextMenuData.MediaTypeVideo
        ]:
            self.__mediaUrl = data.mediaUrl()

    def baseUrl(self):
        """
        Public method to get the base URL of the page.
        
        @return base URL
        @rtype QUrl
        """
        return self.__baseUrl

    def alternateText(self):
        """
        Public method to get the alternate text.
        
        @return alternate text
        @rtype str
        """
        return self.__alternateText

    def boundingRect(self):
        """
        Public method to get the bounding rectangle.
        
        @return bounding rectangle
        @rtype QRect
        """
        return QRect(self.__boundingRect)

    def imageUrl(self):
        """
        Public method to get the URL of an image.
        
        @return image URL
        @rtype QUrl
        """
        return self.__imageUrl

    def isContentEditable(self):
        """
        Public method to check for editable content.
        
        @return flag indicating editable content
        @rtype bool
        """
        return self.__isContentEditable

    def isContentSelected(self):
        """
        Public method to check for selected content.
        
        @return flag indicating selected content
        @rtype bool
        """
        return self.__isContentSelected

    def isNull(self):
        """
        Public method to test, if the hit test is empty.
        
        @return flag indicating an empty object
        @rtype bool
        """
        return self.__isNull

    def linkTitle(self):
        """
        Public method to get the title for a link element.
        
        @return title for a link element
        @rtype str
        """
        return self.__linkTitle

    def linkUrl(self):
        """
        Public method to get the URL for a link element.
        
        @return URL for a link element
        @rtype QUrl
        """
        return self.__linkUrl

    def mediaUrl(self):
        """
        Public method to get the URL for a media element.
        
        @return URL for a media element
        @rtype QUrl
        """
        return self.__mediaUrl

    def mediaPaused(self):
        """
        Public method to check, if a media element is paused.
        
        @return flag indicating a paused media element
        @rtype bool
        """
        return self.__isMediaPaused

    def mediaMuted(self):
        """
        Public method to check, if a media element is muted.
        
        @return flag indicating a muted media element
        @rtype bool
        """
        return self.__isMediaMuted

    def pos(self):
        """
        Public method to get the position of the hit test.
        
        @return position of hit test
        @rtype QPoint
        """
        return QPoint(self.__pos)

    def viewportPos(self):
        """
        Public method to get the viewport position.
        
        @return viewport position
        @rtype QPoint
        """
        return QPoint(self.__viewportPos)

    def tagName(self):
        """
        Public method to get the name of the tested tag.
        
        @return name of the tested tag
        @rtype str
        """
        return self.__tagName

    def __populate(self, url, res):
        """
        Private method to populate the object.
        
        @param url URL of the tested page
        @type QUrl
        @param res dictionary with result data from JavaScript
        @type dict
        """
        if not res:
            return

        self.__baseUrl = QUrl(res["baseUrl"])
        self.__alternateText = res["alternateText"]
        self.__imageUrl = QUrl(res["imageUrl"])
        self.__isContentEditable = res["contentEditable"]
        self.__isContentSelected = res["contentSelected"]
        self.__linkTitle = res["linkTitle"]
        self.__linkUrl = QUrl(res["linkUrl"])
        self.__mediaUrl = QUrl(res["mediaUrl"])
        self.__isMediaPaused = res["mediaPaused"]
        self.__isMediaMuted = res["mediaMuted"]
        self.__tagName = res["tagName"]

        rect = res["boundingRect"]
        if len(rect) == 4:
            self.__boundingRect = QRect(int(rect[0]), int(rect[1]),
                                        int(rect[2]), int(rect[3]))

        if not self.__imageUrl.isEmpty():
            self.__imageUrl = url.resolved(self.__imageUrl)
        if not self.__linkUrl.isEmpty():
            self.__linkUrl = self.__baseUrl.resolved(self.__linkUrl)
        if not self.__mediaUrl.isEmpty():
            self.__mediaUrl = url.resolved(self.__mediaUrl)
Exemple #14
0
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "OraDocs by littleT"
        self.left = 10
        self.top = 10
        self.width = 600
        self.height = 400
        self.initUI()

        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.statusBar().showMessage('Starting ...')
        # for the menu first create some actions to be added like
        # File - Exit action
        exitAction = QAction(QIcon('exit24.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit Application')
        exitAction.triggered.connect(self.close)
        # File - open
        openAction = QAction(QIcon(''), '&Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Opens a file')
        openAction.triggered.connect(self.openCall())
        # the help actions
        helpAction = QAction(QIcon(''), 'Help', self)
        helpAction.triggered.connect(self.openHelp)
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(exitAction)
        helpMenu = mainMenu.addMenu('&Help')
        helpMenu.addAction(helpAction)

        self.logOutput = QTextEdit(self)
        self.logOutput.setReadOnly(True)
        # self.logOutput.setLineWrapMode(QTextEdit.NoWrap)
        self.logOutput.setGeometry(5, 200, 590, 60)

        self.statusBar().showMessage('waiting for click ...')
        self.urlLineEdit = QLineEdit(self)
        # self.textbox.move(5, 300)
        # self.textbox.resize(590, 20)
        self.urlLineEdit.setGeometry(5, 325, 590, 20)

        self.button = QPushButton('Click Me', self)
        self.button.move(10, 350)
        self.button.clicked.connect(self.doRequest)


    def doRequest(self):
        self.root = "https://oradocs-corp.documents.us2.oraclecloud.com/documents/"
        # url = "https://www.google.com"
        self.url = QUrl(self.root)

        self.httpRequestAborted = False
        self.startRequest(self.url)
        self.downloadFile()


        self.qnam.authenticationRequired.connect(
                self.slotAuthenticationRequired)

    def startRequest(self, url):
        self.reply = self.qnam.get(QNetworkRequest(url))
        self.reply.finished.connect(self.httpFinished)
        self.reply.readyRead.connect(self.httpReadyRead)

    def downloadFile(self):
        self.url = QUrl(self.urlLineEdit.text())
        fileInfo = QFileInfo(self.url.path())
        fileName = fileInfo.fileName()

        if not fileName:
            fileName = 'index.html'

        if QFile.exists(fileName):
            ret = QMessageBox.question(self, "HTTP",
                    "There already exists a file called %s in the current "
                    "directory. Overwrite?" % fileName,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if ret == QMessageBox.No:
                return

            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, "HTTP",
                    "Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.progressDialog.setWindowTitle("HTTP")
        self.progressDialog.setLabelText("Downloading %s." % fileName)
        self.downloadButton.setEnabled(False)

        self.httpRequestAborted = False
        self.startRequest(self.url)

    def cancelDownload(self):
        self.statusLabel.setText("Download canceled.")
        self.httpRequestAborted = True
        if self.reply is not None:
            self.reply.abort()
        self.downloadButton.setEnabled(True)

    def httpFinished(self):
        if self.httpRequestAborted:
            if self.outFile is not None:
                self.outFile.close()
                self.outFile.remove()
                self.outFile = None

            self.reply.deleteLater()
            self.reply = None
            # self.progressDialog.hide()
            return

        # self.progressDialog.hide()
        self.outFile.flush()
        self.outFile.close()

        redirectionTarget = self.reply.attribute(QNetworkRequest.RedirectionTargetAttribute)

        if self.reply.error():
            self.outFile.remove()
            QMessageBox.information(self, "HTTP",
                    "Download failed: %s." % self.reply.errorString())
            self.downloadButton.setEnabled(True)
        elif redirectionTarget is not None:
            newUrl = self.url.resolved(redirectionTarget)

            ret = QMessageBox.question(self, "HTTP",
                    "Redirect to %s?" % newUrl.toString(),
                    QMessageBox.Yes | QMessageBox.No)

            if ret == QMessageBox.Yes:
                self.url = newUrl
                self.reply.deleteLater()
                self.reply = None
                self.outFile.open(QIODevice.WriteOnly)
                self.outFile.resize(0)
                self.startRequest(self.url)
                return
        else:
            fileName = QFileInfo(QUrl(self.urlLineEdit.text()).path()).fileName()
            self.statusLabel.setText("Downloaded %s to %s." % (fileName, QDir.currentPath()))

            self.downloadButton.setEnabled(True)

        self.reply.deleteLater()
        self.reply = None
        self.outFile = None

    def httpReadyRead(self):
        if self.outFile is not None:
            self.outFile.write(self.reply.readAll())

    def updateDataReadProgress(self, bytesRead, totalBytes):
        if self.httpRequestAborted:
            return

        self.progressDialog.setMaximum(totalBytes)
        self.progressDialog.setValue(bytesRead)

    def slotAuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic

        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" % (authenticator.realm(), self.url.host()))

        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())

        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    def sslErrors(self, reply, errors):
        errorString = ", ".join([str(error.errorString()) for error in errors])

        ret = QMessageBox.warning(self, "HTTP Example",
                "One or more SSL errors has occurred: %s" % errorString,
                QMessageBox.Ignore | QMessageBox.Abort)

        if ret == QMessageBox.Ignore:
            self.reply.ignoreSslErrors()

    def openCall(self):
        print("Open Call")

    def openHelp(self):
        print("Open Help")

    @pyqtSlot()
    def onClick(self):
        # textboxValue = self.textbox.text()
        # QMessageBox.question(self, 'Hello World!', "Confirm: " + textboxValue,
        #                     QMessageBox.Ok, QMessageBox.Ok)
        # self.textbox.setText("...")
        myRet = self.myDocs.doRequest("https://www.google.com")
        self.logOutput.moveCursor(QTextCursor.End)
        print(myRet)
        self.logOutput.insertPlainText(myRet)

    @pyqtSlot()
    def processReq(self):
        if self.nam.bytesAvailable():
            self.logOutput.moveCursor(QTextCursor.End)
            self.logOutput.insertPlainText('We are connected\n')
            bytes_string = self.nam.readAll()

        self.nam.deleteLater()

    @pyqtSlot(QNetworkReply.NetworkError)
    def processErr(self, code):
        self.msg.critical(None, "Info", "You are not connected to the Internet.")
        print(code)