Beispiel #1
0
    def load(self, url=None, encoding=None, keepUndo=False):
        """Load the specified or current url (if None was specified).

        Currently only local files are supported. An IOError is raised
        when trying to load a nonlocal URL.

        If loading succeeds and an url was specified, the url is made the
        current url (by calling setUrl() internally).

        If keepUndo is True, the loading can be undone (with Ctrl-Z).

        """
        if url is None:
            url = QUrl()
        u = url if not url.isEmpty() else self.url()
        text = self.load_data(u, encoding or self._encoding)
        if keepUndo:
            c = QTextCursor(self)
            c.select(QTextCursor.Document)
            c.insertText(text)
        else:
            self.setPlainText(text)
        self.setModified(False)
        if not url.isEmpty():
            self.setUrl(url)
Beispiel #2
0
 def save(self, url=None, encoding=None):
     """Saves the document to the specified or current url.
     
     Currently only local files are supported. An IOError is raised
     when trying to save a nonlocal URL.
     
     If saving succeeds and an url was specified, the url is made the
     current url (by calling setUrl() internally).
     
     """
     if url is None:
         url = QUrl()
     u = url if not url.isEmpty() else self.url()
     filename = u.toLocalFile()
     # currently, we do not support non-local files
     if not filename:
         raise IOError("not a local file")
     # keep the url if specified when we didn't have one, even if saving
     # would fail
     if self.url().isEmpty() and not url.isEmpty():
         self.setUrl(url)
     with self.saving(), app.documentSaving(self):
         with open(filename, "wb") as f:
             f.write(self.encodedText())
             f.flush()
             os.fsync(f.fileno())
         self.setModified(False)
         if not url.isEmpty():
             self.setUrl(url)
     self.saved()
     app.documentSaved(self)
Beispiel #3
0
 def save(self, url=None, encoding=None):
     """Saves the document to the specified or current url.
     
     Currently only local files are supported. An IOError is raised
     when trying to save a nonlocal URL.
     
     If saving succeeds and an url was specified, the url is made the
     current url (by calling setUrl() internally).
     
     """
     if url is None:
         url = QUrl()
     u = url if not url.isEmpty() else self.url()
     filename = u.toLocalFile()
     # currently, we do not support non-local files
     if not filename:
         raise IOError("not a local file")
     # keep the url if specified when we didn't have one, even if saving
     # would fail
     if self.url().isEmpty() and not url.isEmpty():
         self.setUrl(url)
     with self.saving(), app.documentSaving(self):
         with open(filename, "wb") as f:
             f.write(self.encodedText())
             f.flush()
             os.fsync(f.fileno())
         self.setModified(False)
         if not url.isEmpty():
             self.setUrl(url)
     self.saved()
     app.documentSaved(self)
Beispiel #4
0
    def load(self, url=None, encoding=None, keepUndo=False):
        """Load the specified or current url (if None was specified).

        Currently only local files are supported. An IOError is raised
        when trying to load a nonlocal URL.

        If loading succeeds and an url was specified, the url is made the
        current url (by calling setUrl() internally).

        If keepUndo is True, the loading can be undone (with Ctrl-Z).

        """
        if url is None:
            url = QUrl()
        u = url if not url.isEmpty() else self.url()
        text = self.load_data(u, encoding or self._encoding)
        if keepUndo:
            c = QTextCursor(self)
            c.select(QTextCursor.Document)
            c.insertText(text)
        else:
            self.setPlainText(text)
        self.setModified(False)
        if not url.isEmpty():
            self.setUrl(url)
Beispiel #5
0
    def save(self, url=None, encoding=None):
        """Saves the document to the specified or current url.

        Currently only local files are supported. An IOError is raised
        when trying to save a nonlocal URL.

        If saving succeeds and an url was specified, the url is made the
        current url (by calling setUrl() internally).

        This method is never called directly but only from the overriding
        subclass methods that make further specific use of the modified results.

        """
        if url is None:
            url = QUrl()
        u = url if not url.isEmpty() else self.url()
        filename = u.toLocalFile()
        # currently, we do not support non-local files
        if not filename:
            raise IOError("not a local file")
        # keep the url if specified when we didn't have one, even if saving
        # would fail
        if self.url().isEmpty() and not url.isEmpty():
            self.setUrl(url)
        return url, filename
Beispiel #6
0
    def save(self, url=None, encoding=None):
        """Saves the document to the specified or current url.

        Currently only local files are supported. An IOError is raised
        when trying to save a nonlocal URL.

        If saving succeeds and an url was specified, the url is made the
        current url (by calling setUrl() internally).

        This method is never called directly but only from the overriding
        subclass methods that make further specific use of the modified results.

        """
        if url is None:
            url = QUrl()
        u = url if not url.isEmpty() else self.url()
        filename = u.toLocalFile()
        # currently, we do not support non-local files
        if not filename:
            raise IOError("not a local file")
        # keep the url if specified when we didn't have one, even if saving
        # would fail
        if self.url().isEmpty() and not url.isEmpty():
            self.setUrl(url)
        return url, filename
Beispiel #7
0
    def contextMenuEvent(self, evt):
        """
        Protected method handling context menu events.
        
        @param evt reference to the context menu event (QContextMenuEvent)
        """
        point = evt.globalPos()

        if self.__browser:
            point = self.__browser.mapFromGlobal(point)
            if not self.__browser.rect().contains(point, True):
                return
            link = QUrl(self.__browser.anchorAt(point))
        else:
            point = self.__result.mapFromGlobal(point)
            link = self.__result.linkAt(point)

        if link.isEmpty() or not link.isValid():
            return

        menu = QMenu()
        curTab = menu.addAction(self.tr("Open Link"))
        newTab = menu.addAction(self.tr("Open Link in New Tab"))
        menu.move(evt.globalPos())
        act = menu.exec_()
        if act == curTab:
            self.linkActivated.emit(link)
        elif act == newTab:
            self.__mw.newTab(link)
    def __testWebBrowserView(self, view, url):
        """
        Private method to test a web browser view against an URL.
        
        @param view reference to the web browser view to be tested
        @type WebBrowserView
        @param url URL to test against
        @type QUrl
        @return flag indicating, that the view is the one for the URL
        @rtype bool
        """
        if view.tabWidget().count() < 2:
            return False

        page = view.page()
        if page.history().count() != 0:
            return False

        if (not page.url().isEmpty() and page.url().host() == url.host()):
            return True

        requestedUrl = page.requestedUrl()
        if requestedUrl.isEmpty():
            requestedUrl = QUrl(view.tabWidget().urlBarForView(view).text())
        return requestedUrl.isEmpty() or requestedUrl.host() == url.host()
Beispiel #9
0
 def contextMenuEvent(self, evt):
     """
     Protected method handling context menu events.
     
     @param evt reference to the context menu event (QContextMenuEvent)
     """
     point = evt.globalPos()
     
     if self.__browser:
         point = self.__browser.mapFromGlobal(point)
         if not self.__browser.rect().contains(point, True):
             return
         link = QUrl(self.__browser.anchorAt(point))
     else:
         point = self.__result.mapFromGlobal(point)
         link = self.__result.linkAt(point)
     
     if link.isEmpty() or not link.isValid():
         return
     
     menu = QMenu()
     curTab = menu.addAction(self.tr("Open Link"))
     newTab = menu.addAction(self.tr("Open Link in New Tab"))
     menu.move(evt.globalPos())
     act = menu.exec_()
     if act == curTab:
         self.linkActivated.emit(link)
     elif act == newTab:
         self.__mw.newTab(link)
Beispiel #10
0
    def __showContextMenu(self, pos):
        """
        Private slot showing the context menu.
        
        @param pos position to show the menu at (QPoint)
        """
        idx = self.__index.indexAt(pos)
        if idx.isValid():
            menu = QMenu()
            curTab = menu.addAction(self.tr("Open Link"))
            newTab = menu.addAction(self.tr("Open Link in New Tab"))
            newBackgroundTab = menu.addAction(
                self.tr("Open Link in Background Tab"))
            newWindow = menu.addAction(self.tr("Open Link in New Window"))
            menu.move(self.__index.mapToGlobal(pos))

            act = menu.exec_()
            model = self.__index.model()
            if model is not None:
                keyword = model.data(idx, Qt.DisplayRole)
                links = model.linksForKeyword(keyword)
                if len(links) == 1:
                    link = QUrl(links[list(links.keys())[0]])
                else:
                    link = self.__selectLink(links, keyword)

                if not link.isEmpty() and link.isValid():
                    if act == curTab:
                        self.openUrl.emit(link)
                    elif act == newTab:
                        self.newTab.emit(link)
                    elif act == newBackgroundTab:
                        self.newBackgroundTab.emit(link)
                    elif act == newWindow:
                        self.newWindow.emit(link)
Beispiel #11
0
 def __showEnginesMenu(self):
     """
     Private slot to handle the display of the engines menu.
     """
     self.__enginesMenu.clear()
     
     from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction
     engineNames = self.__openSearchManager.allEnginesNames()
     for engineName in engineNames:
         engine = self.__openSearchManager.engine(engineName)
         action = OpenSearchEngineAction(engine, self.__enginesMenu)
         action.setData(engineName)
         action.triggered.connect(self.__changeCurrentEngine)
         self.__enginesMenu.addAction(action)
         
         if self.__openSearchManager.currentEngineName() == engineName:
             action.setCheckable(True)
             action.setChecked(True)
     
     ct = self.__mw.currentBrowser()
     linkedResources = ct.linkedResources("search")
     
     if len(linkedResources) > 0:
         self.__enginesMenu.addSeparator()
     
     for linkedResource in linkedResources:
         url = QUrl(linkedResource.href)
         title = linkedResource.title
         mimetype = linkedResource.type_
         
         if mimetype != "application/opensearchdescription+xml":
             continue
         if url.isEmpty():
             continue
         
         if url.isRelative():
             url = ct.url().resolved(url)
         
         if not title:
             if not ct.title():
                 title = url.host()
             else:
                 title = ct.title()
         
         action = self.__enginesMenu.addAction(
             self.tr("Add '{0}'").format(title),
             self.__addEngineFromUrl)
         action.setData(url)
         action.setIcon(ct.icon())
     
     self.__enginesMenu.addSeparator()
     self.__enginesMenu.addAction(self.__mw.searchEnginesAction())
     
     if self.__recentSearches:
         self.__enginesMenu.addAction(self.tr("Clear Recent Searches"),
                                      self.clear)
    def __showEnginesMenu(self):
        """
        Private slot to handle the display of the engines menu.
        """
        self.__enginesMenu.clear()

        from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction
        engineNames = self.__openSearchManager.allEnginesNames()
        for engineName in engineNames:
            engine = self.__openSearchManager.engine(engineName)
            action = OpenSearchEngineAction(engine, self.__enginesMenu)
            action.setData(engineName)
            action.triggered.connect(self.__changeCurrentEngine)
            self.__enginesMenu.addAction(action)

            if self.__openSearchManager.currentEngineName() == engineName:
                action.setCheckable(True)
                action.setChecked(True)

        ct = self.__mw.currentBrowser()
        linkedResources = ct.linkedResources("search")

        if len(linkedResources) > 0:
            self.__enginesMenu.addSeparator()

        for linkedResource in linkedResources:
            url = QUrl(linkedResource.href)
            title = linkedResource.title
            mimetype = linkedResource.type_

            if mimetype != "application/opensearchdescription+xml":
                continue
            if url.isEmpty():
                continue

            if url.isRelative():
                url = ct.url().resolved(url)

            if not title:
                if not ct.title():
                    title = url.host()
                else:
                    title = ct.title()

            action = self.__enginesMenu.addAction(
                self.tr("Add '{0}'").format(title), self.__addEngineFromUrl)
            action.setData(url)
            action.setIcon(ct.icon())

        self.__enginesMenu.addSeparator()
        self.__enginesMenu.addAction(self.__mw.searchEnginesAction())

        if self.__recentSearches:
            self.__enginesMenu.addAction(self.tr("Clear Recent Searches"),
                                         self.clear)
Beispiel #13
0
class NetArchitecture(QObject):
    def __init__(self, parent=None):
        # TODO should know its name
        super(NetArchitecture, self).__init__()
        self.renderer = QSvgRenderer()
        self.source_url = QUrl("")
        self.settings = QSettings('dt', 'DeepThought')
        self.graph = None
        self.update_source()

    def source_setting_changed(self):
        return not self.settings.value('protofile') == self.source_url

    def update_source(self):
        if self.settings.contains('protofile'):
            source_url = QUrl(self.settings.value('protofile'))
            source = source_url.toDisplayString(QUrl.RemoveScheme)
            if os.path.isfile(source):
                self.source_url = source_url
                self.set_source(source)
        return not self.source_url.isEmpty()

    def set_source(self, caffeproto_file):
        net = caffe_pb2.NetParameter()
        text_format.Merge(open(caffeproto_file).read(), net)
        self.graph = caffe.draw.draw_net(net, 'LR', 'svg')
        # self.sourceChanged.emit('network_architecture')

    def get_image(self, size):
        if self.source_setting_changed():
            self.update_source()

        image = QImage(size.width(), size.height(), QImage.Format_ARGB32)
        painter = QPainter(image)
        if self.graph is None:
            if self.settings.contains('protofile'):
                url = QUrl(self.settings.value('protofile'))
                self.set_source(url.toDisplayString(QUrl.RemoveScheme))
            else:
                image.fill(QColor(200, 200, 200))
            return image
        self.renderer.load(QByteArray(self.graph))
        self.renderer.render(painter)
        return image
Beispiel #14
0
class LoginForm(object):
    """
    Class implementing a data structure for login forms.
    """
    def __init__(self):
        """
        Constructor
        """
        self.url = QUrl()
        self.name = ""
        self.postData = ""

    def isValid(self):
        """
        Public method to test for validity.
        
        @return flag indicating a valid form (boolean)
        """
        return (not self.url.isEmpty() and bool(self.postData))
Beispiel #15
0
 def dropEvent(self, evt):
     """
     Protected method to handle drop events.
     
     @param evt reference to the drop event (QDropEvent)
     """
     mimeData = evt.mimeData()
     
     url = QUrl()
     if mimeData.hasUrls():
         url = mimeData.urls()[0]
     elif mimeData.hasText():
         url = QUrl.fromEncoded(mimeData.text().encode(), QUrl.TolerantMode)
     
     if url.isEmpty() or not url.isValid():
         E5LineEdit.dropEvent(self, evt)
         return
     
     self.setText(str(url.toEncoded(), encoding="utf-8"))
     self.selectAll()
     
     evt.acceptProposedAction()
Beispiel #16
0
    def dropEvent(self, evt):
        """
        Protected method to handle drop events.
        
        @param evt reference to the drop event (QDropEvent)
        """
        mimeData = evt.mimeData()

        url = QUrl()
        if mimeData.hasUrls():
            url = mimeData.urls()[0]
        elif mimeData.hasText():
            url = QUrl.fromEncoded(mimeData.text().encode("utf-8"),
                                   QUrl.TolerantMode)

        if url.isEmpty() or not url.isValid():
            E5LineEdit.dropEvent(self, evt)
            return

        self.setText(str(url.toEncoded(), encoding="utf-8"))
        self.selectAll()

        evt.acceptProposedAction()
 def lookupUrl(self, url):
     """
     Public method to lookup an URL.
     
     @param url URL to be checked
     @type str or QUrl
     @return tuple containing the list of threat lists the URL was found in
         and an error message
     @rtype tuple of (list of ThreatList, str)
     @exception ValueError raised for an invalid URL
     """
     if self.isEnabled():
         if self.__useLookupApi:
             if isinstance(url, str):
                 url = QUrl(url.strip())
             
             if url.isEmpty():
                 raise ValueError("Empty URL given.")
             
             listNames, error = self.__apiClient.lookupUrl(
                 url, self.__platforms)
             return listNames, error
         else:
             if isinstance(url, QUrl):
                 urlStr = url.toString().strip()
             else:
                 urlStr = url.strip()
             
             if not urlStr:
                 raise ValueError("Empty URL given.")
             
             urlHashes = SafeBrowsingUrl(urlStr).hashes()
             listNames = self.__lookupHashes(urlHashes)
             
             return listNames, ""
     
     return None, ""
    def contextMenuEvent(self, event):
        self.img_url = ''
        menu = self.page().createStandardContextMenu()
        hit = self.page().currentFrame().hitTestContent(event.pos())
        hit_m = self.page().mainFrame()
        hit_n = hit_m.hitTestContent(event.pos())
        url = hit.linkUrl()
        arr = ['Download As Fanart', 'Download As Cover']
        arr_extra_tvdb = ['Series Link', 'Season Episode Link']
        arr_extra_tmdb = ['Series/Movie Link']
        arr_last = ['Artist Link']
        action = []
        self.img_url = hit.imageUrl()
        self.title_page = hit.linkText()
        yt = False
        title_found = False
        self.ui.logger.info('elm: {}; text:{};'.format(
            hit.element(),
            hit.element().toPlainText()))
        try:
            if self.title_page:
                if 'youtube.com' in self.url().toString():
                    self.title_page = hit_n.linkElement().toPlainText()
                    self.ui.logger.info(self.title_page)
                if not self.title_page:
                    self.title_page = hit.linkText()
                self.title_page = self.title_page.strip()
                self.title_page = self.title_page.replace('\n', ' - ')
                self.ui.logger.info(self.title_page)
            elif hit.element():
                self.title_page = hit.element().toPlainText()
                self.ui.logger.info(self.title_page)
                title_found = True
            else:
                self.title_page = hit.title()
        except Exception as err:
            self.ui.logger.error(err)
            self.title_page = hit.title()

        if (url.isEmpty()
                or not url.toString().startswith('http')) and self.img_url:
            url = self.img_url
        if url.isEmpty():
            url = self.url()
            if not title_found:
                self.title_page = hit_m.title()
            if 'reload' in self.url().toString():
                url = self.url().toString()
                n_url = re.sub('\?reload[^\/]*\/|&mode=NORMAL|&params[^&]*',
                               '', url)
                url = QUrl(n_url)
        if not url.isEmpty() or self.img_url:
            if 'tvdb' in url.toString():
                arr = arr + arr_extra_tvdb
            elif 'themoviedb' in url.toString():
                arr = arr_extra_tmdb
            elif 'last.fm' in url.toString():
                arr = arr + arr_last
            elif 'youtube.com' in url.toString(
            ) or 'ytimg.com' in url.toString() or url.toString().startswith(
                    'http'):
                yt = True
                arr.append('Play with Kawaii-Player')
                arr.append('Queue Item')
                arr.append('Download')
                if self.ui.pc_to_pc_casting == "master":
                    arr.append("Cast This Item")
                    arr.append("Cast Queue")
                if 'ytimg.com' in url.toString():
                    yt_id = url.toString().split('/')[-2]
                    url = QUrl('https://m.youtube.com/watch?v=' + yt_id)
                    try:
                        self.title_page = self.playlist_dict[yt_id]
                    except Exception as err:
                        self.ui.logger.error(err)
                        self.title_page = ''
                    arr.append('Add as Local Playlist')
                    self.playlist_name = self.epn_name_in_list

                menu.addSeparator()
                submenuR = QtWidgets.QMenu(menu)
                submenuR.setTitle("Add To Playlist")
                menu.addMenu(submenuR)
                pls = os.listdir(os.path.join(self.home, 'Playlists'))
                home1 = os.path.join(self.home, 'Playlists')
                pls = sorted(
                    pls,
                    key=lambda x: os.path.getmtime(os.path.join(home1, x)),
                    reverse=True)
                item_m = []
                for i in pls:
                    item_m.append(submenuR.addAction(i))

                submenuR.addSeparator()
                new_pls = submenuR.addAction("Create New Playlist")

            for nmenu in arr:
                action.append(menu.addAction(nmenu))

            act = menu.exec_(event.globalPos())
            for i, acts in enumerate(action):
                if act == acts:
                    self.download(url, arr[i])
            if yt:
                for i, acts in enumerate(item_m):
                    if act == acts:
                        if 'views' in self.title_page:
                            self.title_page = re.sub('[0-9][^ ]* ', '',
                                                     self.title_page, 1)
                            self.title_page = re.sub('[0-9][^ ]* views', '',
                                                     self.title_page, 1)
                            self.title_page = self.title_page.replace('/', '-')
                        if not self.title_page:
                            content = ccurl(url.toString())
                            soup = BeautifulSoup(content, 'lxml')
                            self.title_page = soup.title.text.strip().replace(
                                '/', '-')
                        self.triggerPlaylist(pls[i], url.toString(),
                                             self.title_page)

                if act == new_pls:
                    MainWindow = QtWidgets.QWidget()
                    item, ok = QtWidgets.QInputDialog.getText(
                        MainWindow, 'Input Dialog', 'Enter Playlist Name')
                    if ok and item:
                        file_path = os.path.join(self.home, 'Playlists', item)
                        if not os.path.exists(file_path):
                            f = open(file_path, 'w')
                            f.close()
        super(Browser, self).contextMenuEvent(event)
 def importedBookmarks(self):
     """
     Public method to get the imported bookmarks.
     
     @return imported bookmarks (BookmarkNode)
     """
     from ..BookmarkNode import BookmarkNode
     importRootNode = BookmarkNode(BookmarkNode.Root)
     
     # step 1: build the hierarchy of bookmark folders
     folders = {}
     
     try:
         cursor = self.__db.cursor()
         cursor.execute(
             "SELECT id, parent, title FROM moz_bookmarks "
             "WHERE type = 2 and title !=''")
         for row in cursor:
             id_ = row[0]
             parent = row[1]
             title = row[2]
             if parent in folders:
                 folder = BookmarkNode(BookmarkNode.Folder, folders[parent])
             else:
                 folder = BookmarkNode(BookmarkNode.Folder, importRootNode)
             folder.title = title.replace("&", "&&")
             folders[id_] = folder
     except sqlite3.DatabaseError as err:
         self._error = True
         self._errorString = self.tr(
             "Unable to open database.\nReason: {0}").format(str(err))
         return None
     
     try:
         cursor = self.__db.cursor()
         cursor.execute(
             "SELECT parent, title, fk, position FROM moz_bookmarks"
             " WHERE type = 1 and title != '' ORDER BY position")
         for row in cursor:
             parent = row[0]
             title = row[1]
             placesId = row[2]
             
             cursor2 = self.__db.cursor()
             cursor2.execute(
                 "SELECT url FROM moz_places WHERE id = {0}"
                 .format(placesId))
             row2 = cursor2.fetchone()
             if row2:
                 url = QUrl(row2[0])
                 if not title or url.isEmpty() or \
                         url.scheme() in ["place", "about"]:
                     continue
                 
                 if parent in folders:
                     bookmark = BookmarkNode(BookmarkNode.Bookmark,
                                             folders[parent])
                 else:
                     bookmark = BookmarkNode(BookmarkNode.Bookmark,
                                             importRootNode)
                 bookmark.url = url.toString()
                 bookmark.title = title.replace("&", "&&")
     except sqlite3.DatabaseError as err:
         self._error = True
         self._errorString = self.tr(
             "Unable to open database.\nReason: {0}").format(str(err))
         return None
     
     importRootNode.setType(BookmarkNode.Folder)
     if self._id == "firefox":
         importRootNode.title = self.tr("Mozilla Firefox Import")
     else:
         importRootNode.title = self.tr("Imported {0}")\
             .format(QDate.currentDate().toString(Qt.SystemLocaleShortDate))
     return importRootNode
class SlippyMap(QObject):

    updated = pyqtSignal(QRect)

    def __init__(self, parent=None):
        super(SlippyMap, self).__init__(parent)

        self._offset = QPoint()
        self._tilesRect = QRect()
        self._tilePixmaps = {}  # Point(x, y) to QPixmap mapping
        self._manager = QNetworkAccessManager()
        self._url = QUrl()
        # public vars
        self.width = 400
        self.height = 300
        self.zoom = 15
        self.latitude = 59.9138204
        self.longitude = 10.7387413

        self._emptyTile = QPixmap(TDIM, TDIM)
        self._emptyTile.fill(Qt.lightGray)

        cache = QNetworkDiskCache()
        cache.setCacheDirectory(
            QStandardPaths.writableLocation(QStandardPaths.CacheLocation))
        self._manager.setCache(cache)
        self._manager.finished.connect(self.handleNetworkData)

    def invalidate(self):
        if self.width <= 0 or self.height <= 0:
            return

        ct = tileForCoordinate(self.latitude, self.longitude, self.zoom)
        tx = ct.x()
        ty = ct.y()

        # top-left corner of the center tile
        xp = int(self.width / 2 - (tx - math.floor(tx)) * TDIM)
        yp = int(self.height / 2 - (ty - math.floor(ty)) * TDIM)

        # first tile vertical and horizontal
        xa = (xp + TDIM - 1) / TDIM
        ya = (yp + TDIM - 1) / TDIM
        xs = int(tx) - xa
        ys = int(ty) - ya

        # offset for top-left tile
        self._offset = QPoint(xp - xa * TDIM, yp - ya * TDIM)

        # last tile vertical and horizontal
        xe = int(tx) + (self.width - xp - 1) / TDIM
        ye = int(ty) + (self.height - yp - 1) / TDIM

        # build a rect
        self._tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1)

        if self._url.isEmpty():
            self.download()

        self.updated.emit(QRect(0, 0, self.width, self.height))

    def render(self, p, rect):
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(x + self._tilesRect.left(),
                           y + self._tilesRect.top())
                box = self.tileRect(tp)
                if rect.intersects(box):
                    p.drawPixmap(box,
                                 self._tilePixmaps.get(tp, self._emptyTile))

    def pan(self, delta):
        dx = QPointF(delta) / float(TDIM)
        center = tileForCoordinate(self.latitude, self.longitude,
                                   self.zoom) - dx
        self.latitude = latitudeFromTile(center.y(), self.zoom)
        self.longitude = longitudeFromTile(center.x(), self.zoom)
        self.invalidate()

    # slots
    def handleNetworkData(self, reply):
        img = QImage()
        tp = Point(reply.request().attribute(QNetworkRequest.User))
        url = reply.url()
        if not reply.error():
            if img.load(reply, None):
                self._tilePixmaps[tp] = QPixmap.fromImage(img)
        reply.deleteLater()
        self.updated.emit(self.tileRect(tp))

        # purge unused tiles
        bound = self._tilesRect.adjusted(-2, -2, 2, 2)
        for tp in list(self._tilePixmaps.keys()):
            if not bound.contains(tp):
                del self._tilePixmaps[tp]
        self.download()

    def download(self):
        grab = None
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(self._tilesRect.topLeft() + QPoint(x, y))
                if tp not in self._tilePixmaps:
                    grab = QPoint(tp)
                    break

        if grab is None:
            self._url = QUrl()
            return

        path = 'http://tile.openstreetmap.org/%d/%d/%d.png' % (
            self.zoom, grab.x(), grab.y())
        self._url = QUrl(path)
        request = QNetworkRequest()
        request.setUrl(self._url)
        request.setRawHeader(b'User-Agent', b'Nokia (PyQt) Graphics Dojo 1.0')
        request.setAttribute(QNetworkRequest.User, grab)
        self._manager.get(request)

    def tileRect(self, tp):
        t = tp - self._tilesRect.topLeft()
        x = t.x() * TDIM + self._offset.x()
        y = t.y() * TDIM + self._offset.y()

        return QRect(x, y, TDIM, TDIM)
Beispiel #21
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)
	def contextMenuEvent(self, event):
		self.img_url = ''
		menu = self.page().createStandardContextMenu()
		hit = self.page().currentFrame().hitTestContent(event.pos())
		hit_m = self.page().mainFrame()
		hit_n = hit_m.hitTestContent(event.pos())
		url = hit.linkUrl()
		arr = ['Download As Fanart','Download As Cover']
		arr_extra_tvdb = ['Series Link','Season Episode Link']
		arr_last = ['Artist Link']
		action = []
		self.img_url = hit.imageUrl()
		self.title_page = hit.linkText()
		yt = False
		try:
			if self.title_page:
				print('self.title_page=',self.title_page)
				#self.title_page = self.title_page.strip()
				if 'youtube.com' in self.url().toString(): 
					self.title_page = hit_n.linkElement().toPlainText()
				if not self.title_page:
					self.title_page = hit.linkText()
				self.title_page = self.title_page.strip()
				tmp = self.title_page.replace('\n','#')
				print(tmp)
				tmp1 = re.search('#[^#]*',tmp)
				print(tmp1)
				self.title_page = tmp1.group()
				self.title_page = self.title_page.replace('#','')
				
			else:
				self.title_page = hit.title()
		except:
			self.title_page = hit.title()
			
		print('url--info\n',self.img_url.toString(),'=img_url\n',url,'=url',
				hit.title(),'=title\n',hit.linkText(),'=linktext\n',hit_m.title(),
				'--p_title--',hit_n.linkElement().toPlainText(),'--link-element')
				
		if (url.isEmpty() or not url.toString().startswith('http')) and self.img_url:
			url = self.img_url
		if url.isEmpty():
			url = self.url()
			print('--next--url=',self.url().toString())
			self.title_page = hit_m.title()
			if 'reload' in self.url().toString():
				print('reload # in url')
				url = self.url().toString()
				n_url = re.sub('\?reload[^\/]*\/|&mode=NORMAL|&params[^&]*','',url)
				url = QUrl(n_url)
			print('--next--url=',url.toString())
		if not url.isEmpty() or self.img_url:
			if 'tvdb' in url.toString():
				arr = arr + arr_extra_tvdb
			if 'last.fm' in url.toString():
				arr = arr + arr_last
			if 'youtube.com' in url.toString() or 'ytimg.com' in url.toString():
				yt = True
				arr[:]=[]
				arr.append('Play with AnimeWatch')
				arr.append('Queue Item')
				arr.append('Download')
				arr.append('Get Subtitle (If Available)')
				if 'ytimg.com' in url.toString():
						print(self.playlist_dict)
						yt_id = url.toString().split('/')[-2]
						url = QUrl('https://m.youtube.com/watch?v='+yt_id)
						print('url=',url)
						try:
							self.title_page = self.playlist_dict[yt_id]
						except:
							self.title_page = ''
						arr.append('Add as Local Playlist')
						self.playlist_name = self.epn_name_in_list
				
				menu.addSeparator()
				submenuR = QtWidgets.QMenu(menu)
				submenuR.setTitle("Add To Playlist")
				menu.addMenu(submenuR)
				pls = os.listdir(os.path.join(self.home,'Playlists'))
				home1 = os.path.join(self.home,'Playlists')
				pls = sorted(pls,
							key = lambda x:os.path.getmtime(os.path.join(home1,x)),
							reverse=True)
				item_m = []
				for i in pls:
					item_m.append(submenuR.addAction(i))
				
				submenuR.addSeparator()
				new_pls = submenuR.addAction("Create New Playlist")
				
			for i in range(len(arr)):
				action.append(menu.addAction(arr[i]))
				
			act = menu.exec_(event.globalPos())
			for i in range(len(action)):
				if act == action[i]:
					self.download(url,arr[i])
			if yt:
				for i in range(len(item_m)):
					#print(hit.title(),self.title_page)
					if act == item_m[i]:
						if 'views' in self.title_page:
							#content = ccurl(url.toString())
							#soup = BeautifulSoup(content,'lxml')
							self.title_page = re.sub('[0-9][^ ]* ','',self.title_page,1)
							self.title_page = re.sub('[0-9][^ ]* views','',self.title_page,1)
							self.title_page = self.title_page.replace('/','-')
							print('self.title_page=',self.title_page)
						if not self.title_page:
							content = ccurl(url.toString())
							soup = BeautifulSoup(content,'lxml')
							self.title_page = soup.title.text.strip().replace('/','-')
							##self.title_page = hit_m.title().strip().replace('/','-')
							##print(hit.title(),self.title_page)
							#thr = downloadThread(url.toString(),self,pls[i])
							#thr.start()
						self.triggerPlaylist(pls[i],url.toString(),self.title_page)
				
				if act == new_pls:
					print ("creating")
					MainWindow = QtWidgets.QWidget()
					item, ok = QtWidgets.QInputDialog.getText(
								MainWindow, 'Input Dialog', 
								'Enter Playlist Name')
					if ok and item:
						file_path = os.path.join(self.home,'Playlists',item)
						if not os.path.exists(file_path):
							f = open(file_path,'w')
							f.close()
		
		super(Browser, self).contextMenuEvent(event)
Beispiel #23
0
	def contextMenuEvent(self, event):
		self.img_url = ''
		menu = self.page().createStandardContextMenu()
		hit = self.page().currentFrame().hitTestContent(event.pos())
		hit_m = self.page().mainFrame()
		hit_n = hit_m.hitTestContent(event.pos())
		url = hit.linkUrl()
		arr = ['Download As Fanart','Download As Cover']
		arr_extra_tvdb = ['Series Link','Season Episode Link']
		arr_last = ['Artist Link']
		action = []
		self.img_url = hit.imageUrl()
		self.title_page = hit.linkText()
		yt = False
		try:
			if self.title_page:
				print('self.title_page=',self.title_page)
				#self.title_page = self.title_page.strip()
				if 'youtube.com' in self.url().toString(): 
					self.title_page = hit_n.linkElement().toPlainText()
				if not self.title_page:
					self.title_page = hit.linkText()
				self.title_page = self.title_page.strip()
				tmp = self.title_page.replace('\n','#')
				print(tmp)
				tmp1 = re.search('#[^#]*',tmp)
				print(tmp1)
				self.title_page = tmp1.group()
				self.title_page = self.title_page.replace('#','')
				
			else:
				self.title_page = hit.title()
		except:
			self.title_page = hit.title()
			
		print('url--info\n',self.img_url.toString(),'=img_url\n',url,'=url',
				hit.title(),'=title\n',hit.linkText(),'=linktext\n',hit_m.title(),
				'--p_title--',hit_n.linkElement().toPlainText(),'--link-element')
				
		if (url.isEmpty() or not url.toString().startswith('http')) and self.img_url:
			url = self.img_url
		if url.isEmpty():
			url = self.url()
			print('--next--url=',self.url().toString())
			self.title_page = hit_m.title()
			if 'reload' in self.url().toString():
				print('reload # in url')
				url = self.url().toString()
				n_url = re.sub('\?reload[^\/]*\/|&mode=NORMAL|&params[^&]*','',url)
				url = QUrl(n_url)
			print('--next--url=',url.toString())
		if not url.isEmpty() or self.img_url:
			if 'tvdb' in url.toString():
				arr = arr + arr_extra_tvdb
			if 'last.fm' in url.toString():
				arr = arr + arr_last
			if 'youtube.com' in url.toString() or 'ytimg.com' in url.toString():
				yt = True
				arr[:]=[]
				arr.append('Play with Kawaii-Player')
				arr.append('Queue Item')
				arr.append('Download')
				arr.append('Get Subtitle (If Available)')
				if 'ytimg.com' in url.toString():
						print(self.playlist_dict)
						yt_id = url.toString().split('/')[-2]
						url = QUrl('https://m.youtube.com/watch?v='+yt_id)
						print('url=',url)
						try:
							self.title_page = self.playlist_dict[yt_id]
						except:
							self.title_page = ''
						arr.append('Add as Local Playlist')
						self.playlist_name = self.epn_name_in_list
				
				menu.addSeparator()
				submenuR = QtWidgets.QMenu(menu)
				submenuR.setTitle("Add To Playlist")
				menu.addMenu(submenuR)
				pls = os.listdir(os.path.join(self.home,'Playlists'))
				home1 = os.path.join(self.home,'Playlists')
				pls = sorted(pls,
							key = lambda x:os.path.getmtime(os.path.join(home1,x)),
							reverse=True)
				item_m = []
				for i in pls:
					item_m.append(submenuR.addAction(i))
				
				submenuR.addSeparator()
				new_pls = submenuR.addAction("Create New Playlist")
				
			for i in range(len(arr)):
				action.append(menu.addAction(arr[i]))
				
			act = menu.exec_(event.globalPos())
			for i in range(len(action)):
				if act == action[i]:
					self.download(url,arr[i])
			if yt:
				for i in range(len(item_m)):
					#print(hit.title(),self.title_page)
					if act == item_m[i]:
						if 'views' in self.title_page:
							#content = ccurl(url.toString())
							#soup = BeautifulSoup(content,'lxml')
							self.title_page = re.sub('[0-9][^ ]* ','',self.title_page,1)
							self.title_page = re.sub('[0-9][^ ]* views','',self.title_page,1)
							self.title_page = self.title_page.replace('/','-')
							print('self.title_page=',self.title_page)
						if not self.title_page:
							content = ccurl(url.toString())
							soup = BeautifulSoup(content,'lxml')
							self.title_page = soup.title.text.strip().replace('/','-')
							##self.title_page = hit_m.title().strip().replace('/','-')
							##print(hit.title(),self.title_page)
							#thr = downloadThread(url.toString(),self,pls[i])
							#thr.start()
						self.triggerPlaylist(pls[i],url.toString(),self.title_page)
				
				if act == new_pls:
					print ("creating")
					MainWindow = QtWidgets.QWidget()
					item, ok = QtWidgets.QInputDialog.getText(
								MainWindow, 'Input Dialog', 
								'Enter Playlist Name')
					if ok and item:
						file_path = os.path.join(self.home,'Playlists',item)
						if not os.path.exists(file_path):
							f = open(file_path,'w')
							f.close()
		
		super(Browser, self).contextMenuEvent(event)
Beispiel #24
0
class SlippyMap(QObject):

    updated = pyqtSignal(QRect)

    def __init__(self, parent=None):
        super(SlippyMap, self).__init__(parent)

        self._offset = QPoint()
        self._tilesRect = QRect()
        self._tilePixmaps = {} # Point(x, y) to QPixmap mapping
        self._manager = QNetworkAccessManager()
        self._url = QUrl()
        # public vars
        self.width = 400
        self.height = 300
        self.zoom = 15
        self.latitude = 59.9138204
        self.longitude = 10.7387413

        self._emptyTile = QPixmap(TDIM, TDIM)
        self._emptyTile.fill(Qt.lightGray)

        cache = QNetworkDiskCache()
        cache.setCacheDirectory(
            QStandardPaths.writableLocation(QStandardPaths.CacheLocation))
        self._manager.setCache(cache)
        self._manager.finished.connect(self.handleNetworkData)

    def invalidate(self):
        if self.width <= 0 or self.height <= 0:
            return

        ct = tileForCoordinate(self.latitude, self.longitude, self.zoom)
        tx = ct.x()
        ty = ct.y()

        # top-left corner of the center tile
        xp = int(self.width / 2 - (tx - math.floor(tx)) * TDIM)
        yp = int(self.height / 2 - (ty - math.floor(ty)) * TDIM)

        # first tile vertical and horizontal
        xa = (xp + TDIM - 1) / TDIM
        ya = (yp + TDIM - 1) / TDIM
        xs = int(tx) - xa
        ys = int(ty) - ya

        # offset for top-left tile
        self._offset = QPoint(xp - xa * TDIM, yp - ya * TDIM)

        # last tile vertical and horizontal
        xe = int(tx) + (self.width - xp - 1) / TDIM
        ye = int(ty) + (self.height - yp - 1) / TDIM

        # build a rect
        self._tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1)

        if self._url.isEmpty():
            self.download()

        self.updated.emit(QRect(0, 0, self.width, self.height))

    def render(self, p, rect):
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(x + self._tilesRect.left(), y + self._tilesRect.top())
                box = self.tileRect(tp)
                if rect.intersects(box):
                    p.drawPixmap(box, self._tilePixmaps.get(tp, self._emptyTile))
   
    def pan(self, delta):
        dx = QPointF(delta) / float(TDIM)
        center = tileForCoordinate(self.latitude, self.longitude, self.zoom) - dx
        self.latitude = latitudeFromTile(center.y(), self.zoom)
        self.longitude = longitudeFromTile(center.x(), self.zoom)
        self.invalidate()

    # slots
    def handleNetworkData(self, reply):
        img = QImage()
        tp = Point(reply.request().attribute(QNetworkRequest.User))
        url = reply.url()
        if not reply.error():
            if img.load(reply, None):
                self._tilePixmaps[tp] = QPixmap.fromImage(img)
        reply.deleteLater()
        self.updated.emit(self.tileRect(tp))

        # purge unused tiles
        bound = self._tilesRect.adjusted(-2, -2, 2, 2)
        for tp in list(self._tilePixmaps.keys()):
            if not bound.contains(tp):
                del self._tilePixmaps[tp]
        self.download()

    def download(self):
        grab = None
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(self._tilesRect.topLeft() + QPoint(x, y))
                if tp not in self._tilePixmaps:
                    grab = QPoint(tp)
                    break

        if grab is None:
            self._url = QUrl()
            return

        path = 'http://tile.openstreetmap.org/%d/%d/%d.png' % (self.zoom, grab.x(), grab.y())
        self._url = QUrl(path)
        request = QNetworkRequest()
        request.setUrl(self._url)
        request.setRawHeader(b'User-Agent', b'Nokia (PyQt) Graphics Dojo 1.0')
        request.setAttribute(QNetworkRequest.User, grab)
        self._manager.get(request)

    def tileRect(self, tp):
        t = tp - self._tilesRect.topLeft()
        x = t.x() * TDIM + self._offset.x()
        y = t.y() * TDIM + self._offset.y()

        return QRect(x, y, TDIM, TDIM)
Beispiel #25
0
 def _on_link_click(self, url: QUrl) -> None:
     """ If the graph is enabled, send the fragment string of the clicked URL and set focus on it.
         When we click something that isn't a link, this will be sent with an empty string. """
     if self._mouse_enabled:
         self._has_focus = not url.isEmpty()
         self._send_action(url)
Beispiel #26
0
class SlippyMap(QObject):
    def __init__(self, parent: QObject = None) -> None:
        super().__init__(parent)

        self.width: int = 400
        self.height: int = 300
        self.zoom: int = 15
        self.latitude: float = 59.9138204
        self.longitude: float = 10.7387413

        self.m_offset = QPoint()
        self.m_tilesRect = QRect()

        self.m_emptyTile = QPixmap(tdim, tdim)
        self.m_emptyTile.fill(Qt.lightGray)

        self.m_tilePixmaps: typing.Dict[QPointH, QPixmap] = dict()
        self.m_manager = QNetworkAccessManager()
        self.m_url = QUrl()

        cache = QNetworkDiskCache()
        cache.setCacheDirectory(
            QStandardPaths.writableLocation(QStandardPaths.CacheLocation)
        )
        self.m_manager.setCache(cache)
        self.m_manager.finished.connect(self.handleNetworkData)

    def invalidate(self) -> None:
        if self.width <= 0 or self.height <= 0:
            return

        ct = tileForCoordinate(self.latitude, self.longitude, self.zoom)
        tx = ct.x()
        ty = ct.y()

        # top-left corner of the center tile
        xp = self.width / 2 - (tx - math.floor(tx)) * tdim
        yp = self.height / 2 - (ty - math.floor(ty)) * tdim

        xa = (xp + tdim - 1) / tdim
        ya = (yp + tdim - 1) / tdim
        xs = int(tx) - xa
        ys = int(ty) - ya

        # offset for top-left tile
        self.m_offset = QPoint(xp - xa * tdim, yp - ya * tdim)

        # last tile vertical and horizontal
        xe = int(tx) + (self.width - xp - 1) / tdim
        ye = int(ty) + (self.height - yp - 1) / tdim

        # build a rect
        self.m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1)

        if self.m_url.isEmpty():
            self.download()

        self.updated.emit(QRect(0, 0, self.width, self.height))

    def render(self, painter: QPainter, rect: QRect) -> None:
        for x in range(self.m_tilesRect.width() + 1):
            for y in range(self.m_tilesRect.height() + 1):
                tp = QPoint(x + self.m_tilesRect.left(), y + self.m_tilesRect.top())
                box = self.tileRect(tp)
                if rect.intersects(box):
                    painter.drawPixmap(
                        box, self.m_tilePixmaps.get(QPointH(tp), self.m_emptyTile)
                    )

    def pan(self, delta: QPoint) -> None:
        dx = QPointF(delta) / float(tdim)
        center = tileForCoordinate(self.latitude, self.longitude, self.zoom) - dx
        self.latitude = latitudeFromTile(center.y(), self.zoom)
        self.longitude = longitudeFromTile(center.x(), self.zoom)
        self.invalidate()

    updated = pyqtSignal(QRect)

    @pyqtSlot(QNetworkReply)
    def handleNetworkData(self, reply: QNetworkReply) -> None:
        img = QImage()
        tp = reply.request().attribute(QNetworkRequest.User)
        if not reply.error():
            if not img.load(reply, ""):
                img = QImage()
        reply.deleteLater()
        self.m_tilePixmaps[QPointH(tp)] = (
            self.m_emptyTile if img.isNull() else QPixmap.fromImage(img)
        )
        self.updated.emit(self.tileRect(tp))

        # purge unused spaces
        bound = self.m_tilesRect.adjusted(-2, -2, 2, 2)
        self.m_tilePixmaps = {
            tp: pixmap
            for tp, pixmap in self.m_tilePixmaps.items()
            if bound.contains(tp)
        }

        self.download()

    @pyqtSlot()
    def download(self):
        grab = QPoint(0, 0)
        for x in range(self.m_tilesRect.width() + 1):
            for y in range(self.m_tilesRect.height() + 1):
                tp = self.m_tilesRect.topLeft() + QPoint(x, y)
                if QPointH(tp) not in self.m_tilePixmaps:
                    grab = tp
                    break

        if grab == QPoint(0, 0):
            self.m_url = QUrl()
            return
        path = "http://tile.openstreetmap.org/%d/%d/%d.png"
        self.m_url = QUrl(path % (self.zoom, grab.x(), grab.y()))
        request = QNetworkRequest()
        request.setUrl(self.m_url)
        request.setRawHeader(b"User-Agent", b"The Qt Company (Qt) Graphics Dojo 1.0")
        request.setAttribute(QNetworkRequest.User, grab)
        self.m_manager.get(request)

    def tileRect(self, tp: QPoint):
        t = tp - self.m_tilesRect.topLeft()
        x = t.x() * tdim + self.m_offset.x()
        y = t.y() * tdim + self.m_offset.y()
        return QRect(x, y, tdim, tdim)
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()))
Beispiel #28
0
class GreaseMonkeyScript(object):
    """
    Class implementing the GreaseMonkey script.
    """
    DocumentStart = 0
    DocumentEnd = 1
    
    def __init__(self, manager, path):
        """
        Constructor
        
        @param manager reference to the manager object (GreaseMonkeyManager)
        @param path path of the Javascript file (string)
        """
        self.__manager = manager
        
        self.__name = ""
        self.__namespace = "GreaseMonkeyNS"
        self.__description = ""
        self.__version = ""
        
        self.__include = []
        self.__exclude = []
        
        self.__downloadUrl = QUrl()
        self.__startAt = GreaseMonkeyScript.DocumentEnd
        
        self.__script = ""
        self.__fileName = path
        self.__enabled = True
        self.__valid = False
        
        self.__parseScript(path)
    
    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 downloadUrl(self):
        """
        Public method to get the download URL of the script.
        
        @return download URL of the script (QUrl)
        """
        return QUrl(self.__downloadUrl)
    
    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 isEnabled(self):
        """
        Public method to check, if the script is enabled.
        
        @return flag indicating an enabled state (boolean)
        """
        return self.__enabled
    
    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)
        """
        list = []
        for matcher in self.__include:
            list.append(matcher.pattern())
        return list
    
    def exclude(self):
        """
        Public method to get the list of excluded URLs.
        
        @return list of excluded URLs (list of strings)
        """
        list = []
        for matcher in self.__exclude:
            list.append(matcher.pattern())
        return list
    
    def script(self):
        """
        Public method to get the Javascript source.
        
        @return Javascript source (string)
        """
        return self.__script
    
    def fileName(self):
        """
        Public method to get the path of the Javascript file.
        
        @return path path of the Javascript file (string)
        """
        return self.__fileName
    
    def match(self, urlString):
        """
        Public method to check, if the script matches the given URL.
        
        @param urlString URL (string)
        @return flag indicating a match (boolean)
        """
        if not self.__enabled:
            return False
        
        for matcher in self.__exclude:
            if matcher.match(urlString):
                return False
        
        for matcher in self.__include:
            if matcher.match(urlString):
                return True
        
        return False
    
    def __parseScript(self, path):
        """
        Private method to parse the given script and populate the data
        structure.
        
        @param path path of the Javascript file (string)
        """
        try:
            f = open(path, "r", encoding="utf-8")
            fileData = f.read()
            f.close()
        except (IOError, OSError):
            # silently ignore because it shouldn't happen
            return
        
        rx = QRegExp("// ==UserScript==(.*)// ==/UserScript==")
        rx.indexIn(fileData)
        metaDataBlock = rx.cap(1).strip()
        
        if metaDataBlock == "":
            # invalid script file
            return
        
        requireList = []
        for line in metaDataBlock.splitlines():
            if not line.startswith("// @"):
                continue
            
            line = line[3:].replace("\t", " ")
            index = line.find(" ")
            if index < 0:
                continue
            
            key = line[:index].strip()
            value = line[index + 1:].strip()
            
            # Ignored values: @resource, @unwrap
            
            if not key or not value:
                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 == "@updateURL":
                self.__downloadUrl = QUrl(value)
            
            elif key in ["@include", "@match"]:
                self.__include.append(GreaseMonkeyUrlMatcher(value))
            
            elif key in ["@exclude", "@exclude_match"]:
                self.__exclude.append(GreaseMonkeyUrlMatcher(value))
            
            elif key == "@require":
                requireList.append(value)
            
            elif key == "@run-at":
                if value == "document-end":
                    self.__startAt = GreaseMonkeyScript.DocumentEnd
                elif value == "document-start":
                    self.__startAt = GreaseMonkeyScript.DocumentStart
            
            elif key == "@downloadURL" and self.__downloadUrl.isEmpty():
                self.__downloadUrl = QUrl(value)
        
        if not self.__include:
            self.__include.append(GreaseMonkeyUrlMatcher("*"))
        
        marker = "// ==/UserScript=="
        index = fileData.find(marker) + len(marker)
        script = fileData[index:].strip()
        script = "{0}{1}".format(
            self.__manager.requireScripts(requireList),
            script)
        self.__script = "(function(){{{0}}})();".format(script)
        self.__valid = len(script) > 0
Beispiel #29
0
 def handleWebViewUrlChanged(self, url: QUrl):
     self.m_urlLineEdit.setUrl(url)
     if url.isEmpty():
         self.m_urlLineEdit.setFocus()