Esempio n. 1
0
    def peerActive(self):
        delay = self.cfgPeers.liveness.inactiveNoIdent

        if not self.identLast:
            return False

        return (loopTime() - self.identLast) < delay
Esempio n. 2
0
    async def refresh(self):
        staleValue = cGet('resolve.staleAfterDelay')
        last = self._lastResolve

        if self.local or not last or (loopTime() - last) > staleValue:
            self.message('Reloading')

            return await self.load()
Esempio n. 3
0
    def pingedRecently(self):
        pDelay = self.cfgPeers.liveness.didPingEvery

        if self.ipid.local:
            return True

        try:
            prec = self.pinghist[-1]
            return int(loopTime()) - prec[1] < pDelay
        except:
            return False
Esempio n. 4
0
    async def watchOldStyle(self, ipfsop):
        if self.ipid.local:
            self.pinghist.append((
                0,
                int(loopTime())
            ))
            return

        pingAvg = await ipfsop.waitFor(
            ipfsop.pingAvg(self.peerId, count=2), 10)

        if pingAvg and pingAvg > 0:
            self.pinghist.append((
                int(pingAvg),
                int(loopTime())
            ))

            await self.sStatusChanged.emit()
        else:
            self.debug('Could not ping peer')

            await self.sStatusChanged.emit()
Esempio n. 5
0
    async def watch(self, ipfsop):
        if self.ipid.local:
            self.pinghist.append((
                0,
                int(loopTime())
            ))
            return

        if self.ident is None:
            return

        if isinstance(self.ident, PeerIdentMessageV4):
            idToken = self.ident.identToken

            pongReply = await ipfsop.waitFor(ipfsop.didPing(
                self.peerId, self.ipid.did,
                idToken), self.cfgPeers.liveness.didPingCallTimeout
            )

            if pongReply:
                ms, pong = pongReply
                if not pong:
                    # Retry later
                    return

                self._didPongLast = pong['didpong'][self.ipid.did]

                self.pinghist.append((
                    ms,
                    int(loopTime())
                ))

                await self.sStatusChanged.emit()
            else:
                self.debug('Could not ping DID {self.ipid.did}')

                await self.sStatusChanged.emit()
        else:
            return await self.watchOldStyle(ipfsop)
Esempio n. 6
0
    async def load(self, ipfsop, pin=True, initialCid=None,
                   resolveTimeout=30):
        if not initialCid:
            resolved = await self.resolve()

            if not resolved:
                self.message('Failed to resolve ?')
                return False

            dagCid = stripIpfs(resolved['Path'])
        else:
            self.message('Loading from initial CID: {}'.format(initialCid))
            dagCid = initialCid

        self.message('DID resolves to {}'.format(dagCid))

        if self.docCid == dagCid:
            # We already have this one

            self.message('DID document already at latest iteration')
            return False

        self._lastResolve = loopTime()

        if pin is True:
            await ipfsop.ctx.pin(dagCid, qname='ipid')

        self.message('Load: IPNS key resolved to {}'.format(dagCid))

        doc = await ipfsop.dagGet(dagCid)

        if doc:
            self._document = doc
            self._latestModified = doc.get('modified')
            self.docCid = dagCid
            await self.sChanged.emit(dagCid)

            if self.local:
                # Local IPID: propagate did services
                async for service in self.discoverServices():
                    await self.sServiceAvailable.emit(self, service)

            # Graph it
            await self.rdfPush()

            return True

        return False
Esempio n. 7
0
 def failedAuthAttempt(self):
     self._authFailedAttemptsCn += 1
     self._authFailedLtLast = loopTime()
Esempio n. 8
0
 def ident(self, v):
     self._identMsg = v
     self._identLast = loopTime()
Esempio n. 9
0
 def authFailedRecently(self):
     if self.authFailedLtLast:
         return (loopTime() - self.authFailedLtLast) < 10
Esempio n. 10
0
    async def open(self,
                   ipfsop,
                   pathRef,
                   mimeType=None,
                   openingFrom=None,
                   pyramidOrigin=None,
                   minWebProfile='ipfs',
                   schemePreferred=None,
                   tryDecrypt=False,
                   fromEncrypted=False,
                   editObject=False,
                   pin=False,
                   burnAfterReading=False,
                   useWorkspace=None):
        """
        Open the resource referenced by rscPath according
        to its MIME type

        :param pathRef: IPFS object's path (can be str or IPFSPath)
        :param openingFrom str: UI component making the open request
        :param minWebProfile str: Minimum Web profile to use
        :param tryDecrypt bool: Try to decrypt the object or not
        :param editObject bool: Set Text Editor in edit mode for text files
        :param MIMEType mimeType: MIME type
        """

        ipfsPath = None
        statInfo = None

        if isinstance(pathRef, IPFSPath):
            ipfsPath = pathRef
        elif isinstance(pathRef, str):
            url = QUrl(pathRef)

            if isEnsUrl(url):
                return self.openEnsUrl(url, pin=pin)
            if isUrlSupported(url):
                return self.openUrl(url)

            ipfsPath = IPFSPath(pathRef, autoCidConv=True)
        else:
            raise ValueError(f'Invalid input value: {pathRef}')

        if not ipfsPath.valid:
            return False

        rscPath = ipfsPath.objPath

        if self.app.mainWindow.pinAllGlobalChecked:
            ensure(
                ipfsop.ctx.pinner.queue(rscPath, False, None, qname='default'))

        rscShortName = ipfsPath.shortRepr()

        if ipfsPath.isIpfs:
            # Try to reuse metadata from the multihash store
            rscMeta = await self.app.multihashDb.get(rscPath)
            if rscMeta:
                cachedMime = rscMeta.get('mimetype')
                cachedStat = rscMeta.get('stat')
                if cachedMime:
                    mimeType = MIMEType(cachedMime)
                if cachedStat:
                    statInfo = StatInfo(cachedStat)

        wsSwitch = True
        mtConfig = self.cObjectOpener.mimeTypes.default

        if mimeType is None:
            ltBefore = loopTime()
            mimeType = await detectMimeType(rscPath)
            spent = loopTime() - ltBefore

            if spent > mtConfig.slowObjectTimer:
                # We won't switch workspaces
                wsSwitch = False

        if mimeType and mimeType.valid:
            logUser.info('{path} ({type}): opening'.format(path=rscPath,
                                                           type=str(mimeType)))
        else:
            logUser.info(iResourceCannotOpen(rscPath))
            return

        hashmark = await hashmarksByPath(rscPath)
        if hashmark and not useWorkspace:
            await hashmark._fetch_all()
            useWorkspace = self.app.mainWindow.stack.wsHashmarkTagRulesRun(
                hashmark)

        if mimeType == mimeTypeDagUnknown:
            indexPath = ipfsPath.child('index.html')
            stat = await ipfsop.objStat(indexPath.objPath, timeout=8)

            if stat:
                # Browse the index
                return self.app.mainWindow.addBrowserTab(
                    minProfile=minWebProfile, pinBrowsed=pin).browseFsPath(
                        indexPath, schemePreferred=schemePreferred)

            # Otherwise view the DAG
            view = DAGViewer(rscPath, self.app.mainWindow)
            self.app.mainWindow.registerTab(view,
                                            iDagViewer(),
                                            current=True,
                                            icon=getIcon('ipld.png'),
                                            tooltip=rscPath)
            return

        if mimeType.type == 'application/octet-stream' and not fromEncrypted:
            # Try to decode it with our key if it's a small file
            if statInfo is None:
                statInfo = StatInfo(await ipfsop.objStat(rscPath, timeout=5))

            profile = ipfsop.ctx.currentProfile
            if profile and statInfo.valid and \
                    (statInfo.dataSmallerThan(megabytes(8)) or tryDecrypt):
                data = await ipfsop.catObject(ipfsPath.objPath, timeout=30)
                if not data:
                    # XXX
                    return

                decrypted = await profile.rsaAgent.decrypt(data)

                if decrypted:
                    #
                    # "Good evening, 007"
                    #
                    # Create a short-lived IPFS offline file (not announced)
                    # with the decrypted content and open it
                    #

                    logUser.info('{path}: RSA OK'.format(path=rscPath))

                    # This one won't be announced or pinned
                    entry = await ipfsop.addBytes(decrypted,
                                                  offline=True,
                                                  pin=False)
                    if not entry:
                        logUser.info(
                            '{path}: cannot import decrypted file'.format(
                                path=rscPath))
                        return

                    # Open the decrypted file
                    return ensure(
                        self.open(entry['Hash'],
                                  fromEncrypted=True,
                                  burnAfterReading=True))
                else:
                    logUser.debug(
                        '{path}: decryption impossible'.format(path=rscPath))

        if mimeType.isText or editObject:
            tab = TextEditorTab(parent=self.app.mainWindow,
                                editing=editObject,
                                pyramidOrigin=pyramidOrigin)
            tab.editor.display(ipfsPath)
            self.objectOpened.emit(ipfsPath)
            return self.app.mainWindow.registerTab(
                tab,
                rscShortName,
                icon=getMimeIcon('text/x-generic'),
                tooltip=rscPath,
                current=True,
                workspace=WS_EDIT)

        if mimeType.isImage or mimeType.isAnimation:
            tab = ImageViewerTab(self.app.mainWindow)
            ensure(tab.view.showImage(rscPath))
            self.objectOpened.emit(ipfsPath)

            return self.app.mainWindow.registerTab(
                tab,
                rscShortName,
                icon=getMimeIcon('image/x-generic'),
                tooltip=rscPath,
                current=True)

        if mimeType.isVideo or mimeType.isAudio:
            tab = self.app.mainWindow.getMediaPlayer()
            if tab:
                tab.playFromPath(rscPath)
            return

        if mimeType == 'application/pdf' and 0:  # not usable yet
            tab = WebTab(self.app.mainWindow)
            tab.attach(DWebView(page=PDFViewerPage(rscPath)))
            self.objectOpened.emit(ipfsPath)
            return self.app.mainWindow.registerTab(
                tab,
                rscShortName,
                icon=getMimeIcon('application/pdf'),
                tooltip=rscPath,
                current=True)

        if mimeType.isHtml:
            self.objectOpened.emit(ipfsPath)
            return self.app.mainWindow.addBrowserTab(
                minProfile=minWebProfile,
                pinBrowsed=pin,
                workspace=useWorkspace,
                wsSwitch=wsSwitch).browseFsPath(
                    ipfsPath, schemePreferred=schemePreferred)

        if mimeType.isDir:
            indexPath = ipfsPath.child('index.html')
            stat = await ipfsop.objStat(indexPath.objPath, timeout=8)

            if stat:
                self.objectOpened.emit(ipfsPath)
                return self.app.mainWindow.addBrowserTab(
                    minProfile=minWebProfile,
                    pinBrowsed=pin,
                    workspace=useWorkspace,
                    wsSwitch=wsSwitch).browseFsPath(
                        ipfsPath, schemePreferred=schemePreferred)
            else:
                return await self.app.mainWindow.exploreIpfsPath(ipfsPath)

        if mimeType.isBitTorrent:
            wStack = self.app.mainWindow.stack

            with wStack.workspaceCtx(WS_FILES, show=True) as ws:
                btClient = await ws.getTorrentClient()
                return await btClient.addTorrentFromIpfs(ipfsPath)

        if openingFrom in ['filemanager', 'qa', 'didlocal']:
            await self.needUserConfirm.emit(ipfsPath, mimeType, True)
        else:
            await self.needUserConfirm.emit(ipfsPath, mimeType, False)