def peerActive(self): delay = self.cfgPeers.liveness.inactiveNoIdent if not self.identLast: return False return (loopTime() - self.identLast) < delay
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()
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
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()
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)
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
def failedAuthAttempt(self): self._authFailedAttemptsCn += 1 self._authFailedLtLast = loopTime()
def ident(self, v): self._identMsg = v self._identLast = loopTime()
def authFailedRecently(self): if self.authFailedLtLast: return (loopTime() - self.authFailedLtLast) < 10
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)