예제 #1
0
    def load(self, displayName: str, modname: str, uimod):
        try:
            ctrlMod = importlib.import_module(
                f'galacteek.ui.settings.{modname}')

            form = uimod.Ui_SettingsForm()

            widget = QWidget()
            widget.ui = form
            form.setupUi(widget)

            controller = ctrlMod.SettingsController(widget)

            # settingsInit() ought to be a regular function really..
            ensure(controller.settingsInit())
        except Exception:
            return
        else:
            self.ui.stack.addWidget(widget)

            item = QListWidgetItem(displayName)
            item.setData(SettingsModWidgetRole, widget)
            item.setData(SettingsModNameRole, modname)
            item.setData(SettingsModControllerRole, controller)
            item.setIcon(getIcon('settings.png'))

            self.ui.sModules.addItem(item)
            self.modules[modname] = item

            if not self.ui.sModules.currentItem():
                self.ui.sModules.setCurrentItem(
                    item,
                    QItemSelectionModel.SelectCurrent
                )
                self.ui.stack.setCurrentWidget(widget)
예제 #2
0
    def onJoinClicked(self):
        idx = self.ui.channelsView.currentIndex()
        chan = self.channelsProxyModel.data(idx, Qt.DisplayRole)
        if chan:
            ensure(self.onJoinChannel(chan))

        self.done(1)
예제 #3
0
    def __init__(self,
                 template,
                 url=None,
                 navBypassLinks=False,
                 openObjConfirm=True,
                 localCanAccessRemote=False,
                 webProfile=None,
                 parent=None):
        self.app = QApplication.instance()
        super(BasePage, self).__init__(
            webProfile if webProfile else self.app.webProfiles['ipfs'], parent)

        self.template = template
        self._handlers = {}
        self.pageCtx = {}
        self.channel = QWebChannel(self)
        self.url = url if url else QUrl('qrc:/')
        self.setUrl(self.url)
        self.setWebChannel(self.channel)
        self.webScripts = self.profile().scripts()
        self.navBypass = navBypassLinks
        self.openObjConfirm = openObjConfirm
        self.localCanAccessRemote = localCanAccessRemote

        self.settings().setAttribute(QWebEngineSettings.LocalStorageEnabled,
                                     True)
        self.settings().setAttribute(
            QWebEngineSettings.LocalContentCanAccessFileUrls, True)

        self.featurePermissionRequested.connect(self.onPermissionRequest)
        self.fullScreenRequested.connect(self.onFullScreenRequest)

        self.installScripts()
        self.setPermissions()
        ensure(self.render())
예제 #4
0
    def makeHashmarkAction(self, mark, loadIcon=True):
        tLenMax = 48

        path = mark.uri
        title = mark.title

        if title and len(title) > tLenMax:
            title = '{0} ...'.format(title[0:tLenMax])

        action = QAction(title, self)
        action.setToolTip(iHashmarkInfoToolTip(mark))

        action.setData({
            'path': path,
            'mark': mark,
            'iconpath': mark.icon.path if mark.icon else None
        })

        if not mark.icon or not loadIcon:
            # Default icon
            action.setIcon(getIcon('ipfs-logo-128-white-outline.png'))
        else:
            ensure(self.loadMarkIcon(action, mark.icon.path))

        return action
예제 #5
0
    async def stop(self):
        self.mediaRecorder.stop()
        self.ui.statusbar.showMessage('')

        if self.videoLocation and await questionBoxAsync(
                'Video import', 'Import video to your repository ?'):

            filePath = self.videoLocation.toLocalFile()

            if not os.path.isfile(filePath):
                return messageBox('Could not find captured video')

            basename = os.path.basename(filePath)

            name = inputTextCustom('Video import',
                                   'Video filename',
                                   text=basename)

            if not name:
                return

            if name != basename:
                dst = Path(os.path.dirname(filePath)).joinpath(name)
                shutil.move(filePath, str(dst))
            else:
                dst = Path(filePath)

            if name:
                ensure(self.importVideoRecord(dst, name))
예제 #6
0
    def onSendMessage(self):
        messageText = self.ui.message.text()
        if not messageText:
            return

        self.ui.message.clear()
        ensure(self.sendMessage(messageText))
예제 #7
0
    async def load(self, ipfsop,
                   did: str,
                   timeout=None,
                   localIdentifier=False,
                   initialCid=None,
                   track=True):

        if not did or not ipidFormatValid(did):
            return None

        async with self._lock:
            if did in self._managedIdentifiers:
                return self._managedIdentifiers[did]

        rTimeout = timeout if timeout else self._resolveTimeout

        ipid = IPIdentifier(
            did, localId=localIdentifier, ldCache=self._ldCache)

        if ipid.local:
            ipid.sServiceAvailable.connectTo(
                self.onLocalIpidServiceAvailable)

        if await ipid.load(resolveTimeout=rTimeout, initialCid=initialCid):
            if track:
                await self.track(ipid)

            if localIdentifier:
                log.debug('Publishing (first load) local IPID: {}'.format(did))
                ensure(ipid.publish())

            return ipid
예제 #8
0
    async def updateDocument(self, ipfsop, document, publish=False):
        """
        Update the document and set the 'previous' IPLD link
        """

        now = normedUtcDate()
        self._document = document

        if self.docCid:
            self._document['previous'] = {
                '/': self.docCid
            }

        self._document['updated'] = now

        cid = await ipfsop.dagPut(document)

        if cid:
            self.docCid = cid

            if publish:
                ensure(self.publish())

            await self.sChanged.emit(cid)

            await self.rdfPush()
        else:
            self.message('Could not inject new DID document!')
예제 #9
0
    async def start(self, servicePort=None):
        if self.connected:
            return True

        port = servicePort if servicePort else self.servicePort

        self.commandsQ = asyncio.Queue()
        self.servicePort = servicePort
        self.process = NodeOrbitProcess(port=port,
                                        orbitDataPath=self.orbitDataPath)
        self.baseUrl = URL.build(scheme='http', host='localhost',
                                 port=port)
        await self.process.start()

        try:
            await asyncio.wait_for(
                self.process.proto.evStarted.wait(),
                60)
        except asyncio.TimeoutError:
            log.debug('Time out while waiting for connector to rise')
            return False

        await asyncio.sleep(0.5)

        ensure(self.readEventsTask(self.process.proto))

        self._connected = True
        return True
예제 #10
0
    async def onSeedAdded(self, seed):
        item = SeedingTreeItem(
            seed, [seed.name]
        )
        ensure(item.lazyLoad())

        self.root.addChild(item)
예제 #11
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.app = QApplication.instance()

        self.destTags = []

        self.allTagsModel = UneditableStringListModel(self)
        self.destTagsModel = UneditableStringListModel(self)
        self.allTagsProxyModel = QSortFilterProxyModel(self)
        self.allTagsProxyModel.setSourceModel(self.allTagsModel)

        self.ui = ui_iptagsmanager.Ui_IPTagsDialog()
        self.ui.setupUi(self)

        self.ui.destTagsView.setModel(self.destTagsModel)
        self.ui.destTagsView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.ui.destTagsView.doubleClicked.connect(self.onTagDoubleClicked)

        self.ui.addTagButton.clicked.connect(lambda: ensure(self.addTag()))
        self.ui.lineEditTag.textChanged.connect(self.onTagEditChanged)
        self.ui.lineEditTag.setValidator(
            QRegExpValidator(QRegExp(r'[A-Za-z0-9-_@#]+')))
        self.ui.lineEditTag.setMaxLength(128)

        self.ui.tagItButton.clicked.connect(self.onTagObject)
        self.ui.untagItButton.clicked.connect(self.untagObject)
        self.ui.okButton.clicked.connect(lambda: ensure(self.validate()))
        self.ui.noTagsButton.clicked.connect(self.reject)

        self.setMinimumSize(self.app.desktopGeometry.width() / 2,
                            (2 * self.app.desktopGeometry.height()) / 3)
예제 #12
0
    def __init__(self, profile, parent=None):
        super().__init__(parent)

        self.setObjectName('profileEditDialog')
        self.app = QApplication.instance()
        self.profile = profile

        self.ui = ui_profileeditdialog.Ui_ProfileEditDialog()
        self.ui.setupUi(self)
        self.ui.pEditTabWidget.setCurrentIndex(0)

        self.loadPlanets()
        self.updateProfile()

        self.ui.labelWarning.setStyleSheet('QLabel { font-weight: bold; }')
        self.ui.labelInfo.setStyleSheet('QLabel { font-weight: bold; }')
        self.ui.labelWarning.linkActivated.connect(self.onLabelAnchorClicked)

        self.ui.profileDid.setText('<b>{0}</b>'.format(
            self.profile.userInfo.personDid))

        self.ui.lockButton.toggled.connect(self.onLockChange)
        self.ui.lockButton.setChecked(True)
        self.ui.changeIconButton.clicked.connect(self.changeIcon)
        self.ui.updateButton.clicked.connect(lambda: ensure(self.save()))
        self.ui.updateButton.setEnabled(False)
        self.ui.closeButton.clicked.connect(self.close)

        self.ui.username.textEdited.connect(self.onEdited)
        self.ui.vPlanet.currentTextChanged.connect(self.onEdited)
        self.ui.vPlanet.setIconSize(QSize(32, 32))

        self.reloadIcon()

        ensure(self.loadIpHandlesContract())
예제 #13
0
    async def loadFeedEntries(self, ipfsop, feedSql, atomFeed):
        entries = await self.searchEntries(atomFeed.id)
        existingIds = [ent['entry_id'] for ent in entries]

        self._handled_by_id[atomFeed.id] = atomFeed

        for entry in atomFeed.entries:
            await asyncio.sleep(0.2)
            if not isinstance(entry.id, str):
                continue

            if entry.id not in existingIds:
                _rid = await self.addEntry(feedSql['id'], entry.id)

                entry.status = IPFSAtomFeedEntry.ENTRY_STATUS_NEW
                entry.srow_id = _rid
                self.processedFeedEntry.emit(atomFeed, entry)

                if feedSql['autopin_entries'] == 1 and \
                        feedSql['scheme'] in ['ipns', 'ipfs', 'dweb']:
                    path = IPFSPath(entry.id)
                    if path.valid:
                        log.debug('Atom: autopinning {id}'.format(id=entry.id))
                        ensure(ipfsop.ctx.pin(path.objPath, qname='atom'))
            else:
                for exent in entries:
                    if exent['entry_id'] == entry.id:
                        entry.status = exent['status']
                        entry.srow_id = exent['id']
                        self.processedFeedEntry.emit(atomFeed, entry)
예제 #14
0
 def injectIconFromIndex(self, idx):
     iconPath = self.itemData(idx)
     if iconPath:
         if iconPath.startswith('qta:'):
             ensure(self.injectQaIcon(idx, iconPath))
         else:
             ensure(self.injectQrcIcon(iconPath))
예제 #15
0
    def openFile(self, entryInfo):
        # if item.mimeType is None:
        #    return self.browse(fileHash)

        if self.autoOpenFiles:
            ensure(self.openWithRscOpener(entryInfo))
        else:
            self.fileOpenRequest.emit(entryInfo.ipfsPath)
예제 #16
0
    def onSearch(self, text):
        for action in self.menu.actions():
            if self.isProtectedAction(action):
                continue
            if action.text() == text:
                self.menu.removeAction(action)

        ensure(self.searchInCatalog(text))
예제 #17
0
 async def onClicked(self):
     hashmark = await self.hashmark()
     if hashmark:
         ensure(
             self.app.resourceOpener.open(
                 hashmark.path,
                 openingFrom='qa',
                 schemePreferred=hashmark.schemepreferred))
예제 #18
0
 def __init__(self, connector, database, parent):
     super().__init__(parent)
     self.posts = []
     self.connector = connector
     self.database = database
     self.connector.registerEventListener(self.onEvent)
     self.destroyed.connect(self.onDestroyed)
     ensure(self.isUserRegistered())
예제 #19
0
    def openFile(self, item, fileHash):
        if item.mimeType is None:
            return self.browse(fileHash)

        if self.autoOpenFiles:
            ensure(self.openWithRscOpener(item, fileHash))
        else:
            self.fileOpenRequest.emit(item.ipfsPath)
예제 #20
0
 def onTextEdit(self):
     if self.item:
         ensure(self.rscOpener.open(
             self.item.ipfsPath,
             mimeType=self.item.mimeType,
             editObject=True,
             openingFrom='clipboardmgr'
         ))
예제 #21
0
    def onAccepted(self):
        channel = self.ui.channelName.text().strip()

        if not channel.startswith('#'):
            return messageBox('Channel name should start with a #')

        ensure(self.chans.createChannel(channel))
        self.done(1)
예제 #22
0
    def onPathEntered(self):
        text = self.pathEdit.text()
        self.pathEdit.clear()

        path = IPFSPath(text)
        if path.valid:
            ensure(self.app.ipfsCtx.pinner.queue(path.objPath, True, None))
        else:
            messageBox(iInvalidInput())
예제 #23
0
    async def seedAppImage(self, ipfsop):
        # Automatic AppImage seeding

        if os.path.isfile(self.cmdArgs.binarypath):
            log.info(
                'AppImage seeding: {img}'.format(img=self.cmdArgs.binarypath))

            ensure(ipfsop.addPath(self.cmdArgs.binarypath, wrap=True),
                   futcallback=self.onAppSeed)
예제 #24
0
    async def updateIcons(self):
        for mName, menu in self.cMenus.items():
            await asyncio.sleep(0)

            for action in menu.actions():
                data = action.data()

                if 'iconloaded' not in data and data['iconpath']:
                    ensure(self.loadMarkIcon(action, data['iconpath']))
예제 #25
0
    def onDappPkgChanged(self, dappName):
        dapp = self._dapps.get(dappName)
        if dapp:
            dapp.pkgContentsChanged.disconnect(self.onDappPkgChanged)
            dapp.reimportModule()
            dapp.stop()
            del self._dapps[dappName]

            ensure(self.loadDapp(dappName))
예제 #26
0
    async def registerHashmark(self,
                               ipfsop,
                               mark,
                               button=None,
                               maxIconSize=512 * 1024):
        """
        Register an object in the toolbar with an associated hashmark
        """

        await mark._fetch_all()

        ipfsPath = IPFSPath(mark.path)
        if not ipfsPath.valid:
            return

        result = await self.analyzer(ipfsPath)
        if result is None:
            return

        mimeType, rscStat = result

        mIcon = mark.icon.path if mark.icon else None
        icon = None

        if mIcon and IPFSPath(mIcon).valid:
            stat = await ipfsop.objStat(mIcon)

            statInfo = StatInfo(stat)

            # Check filesize from the stat on the object
            if statInfo.valid and statInfo.dataSmallerThan(maxIconSize):
                icon = await getIconFromIpfs(ipfsop, mIcon)

                if icon is None:
                    icon = getIcon('unknown-file.png')
                else:
                    if not await ipfsop.isPinned(mIcon):
                        log.debug('Pinning icon {0}'.format(mIcon))
                        await ipfsop.ctx.pin(mIcon)
        elif mimeType:
            icon = await self.findIcon(ipfsop, ipfsPath, rscStat, mimeType)
        else:
            icon = getIcon('unknown-file.png')

        if not button:
            button = HashmarkToolButton(mark, parent=self, icon=icon)
            action = self.addWidget(button)
            button.setToolTip(iHashmarkInfoToolTipShort(mark))
            button.clicked.connect(lambda: ensure(
                self.app.resourceOpener.open(str(ipfsPath), openingFrom='qa')))
            button.deleteRequest.connect(
                lambda: ensure(self.onDelete(button, action)))
        else:
            if icon:
                button.setIcon(icon)

            button.setToolTip(iHashmarkInfoToolTipShort(mark))
예제 #27
0
    def onValidPath(self, ipfsPath):
        existing = self.getByPath(ipfsPath)

        if not existing:
            item = ClipboardItem(ipfsPath, parent=self)
            self.itemRegister.emit(item, True)
            ensure(self.scanItem(item))
        else:
            # Set existing item as current item
            self.current = existing
예제 #28
0
    async def runSearch(self, ipfsop, searchQuery, timeout=30):
        pageStart = self.vPageCurrent * self.pagesPerVpage
        statusEmitted = False
        gotResults = False

        proxy = self.app.networkProxy()

        try:
            with async_timeout.timeout(timeout):
                async for pageCount, result in multiSearch(
                        searchQuery,
                        page=pageStart,
                        filters=self.filters,
                        proxyUrl=proxy.url() if proxy else None,
                        sslverify=self.app.sslverify):
                    await asyncio.sleep(0)
                    gotResults = True

                    if not statusEmitted:
                        self.vPageStatus.emit(
                            self.vPageCurrent + 1,
                            pageCount if pageCount > 0 else 1)
                        statusEmitted = True

                    hit = result['hit']
                    engine = result['engine']

                    self._cResults.append(result)
                    self.searchRunning.emit(searchQuery)

                    if engine == 'ipfs-search':
                        self.sendHit(hit)
                        self._tasks.append(
                            ensure(self.fetchObjectStat(ipfsop, hit['hash'])))
                    else:
                        self._tasks.append(ensure(self.sendCyberHit(hit)))
        except asyncio.TimeoutError:
            log.debug('Search timeout')
            self.searchTimeout.emit(timeout)
            return False
        except asyncio.CancelledError:
            log.debug('Search cancelled')
            return False
        except Exception as e:
            log.debug(
                'IPFSSearch: unknown exception while searching: {}'.format(
                    str(e)))
            return False

        if gotResults:
            self.searchComplete.emit()
            return True
        else:
            self.searchError.emit()
            return False
예제 #29
0
    def _add_magnet_triggered(self, *a):
        if self.magnetConverter.available:
            clipText = self.app.getClipboardText()
            magnetLink = inputTextCustom(
                label=iBtAddFromMagnetLink(),
                text=clipText if isMagnetLink(clipText) else '')

            if isMagnetLink(magnetLink):
                ensure(self.add_from_magnet(magnetLink))
            else:
                messageBox('Invalid magnet link')
예제 #30
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.app = QApplication.instance()
        self.lock = asyncio.Lock()
        self.channelWidgets = weakref.WeakValueDictionary()
        self.userListRev = uid4()

        self.pubTokensManager = PubChatTokensManager()

        ensure(self.sendChannelsStatus())