class EthereumStatusButton(QToolButton): def __init__(self, parent=None): super().__init__(parent=parent) self.setEnabled(False) self.app = QApplication.instance() self.app.ethereum.ethConnected.connectTo(self.onEthStatus) self.app.ethereum.ethNewBlock.connectTo(self.onNewBlock) self.view = DWebView(parent=None) self.view.show() self.page1 = EthereumWrapperPage(self.app.ethereum, parent=self.view) self.view.p = self.page1 self.statusTab = None self.lBlockHash = None self.iconEthereum = getIcon('ethereum.png') self.setIcon(self.iconEthereum) def onToggled(self, checked): tabName = iEthStatus() if checked: if not self.statusTab: self.statusTab = WebTab(self.app.mainWindow) self.statusTab.attach(self.view) self.app.mainWindow.registerTab(self.statusTab, tabName, current=True) elif not checked and self.statusTab: tab = self.app.mainWindow.findTabWithName(tabName) if tab: self.app.mainWindow.removeTabFromWidget(tab) self.statusTab = None async def onEthStatus(self, connected): self.setEnabled(connected) if connected: self.updateToolTip() else: self.setToolTip(iEthNotConnected()) def updateToolTip(self): self.setToolTip( iEthConnected(self.app.ethereum.params.rpcUrl, self.lBlockHash if self.lBlockHash else iUnknown())) async def onNewBlock(self, blockHash): self.lBlockHash = blockHash self.updateToolTip() self.page1.handler.newBlock.emit(blockHash)
async def loadQuestService(ipfsop, parent=None): wsAddrs = await ipfsop.nodeWsAdresses() page = QuestServicePage('quest.html', url=QUrl('file:/quest')) rxscript = scriptFromQFile('rxjs', ':/share/js/rxjs.umd.min.js') script = scriptFromQFile('quest', ':/share/js/quest/quest-service.js') pScript = scriptFromQFile('quest-extension', ':/share/js/quest/quest-service-ext.js') try: # Pass the ws bootstrap addr wsAddr = wsAddrs.pop() code = pScript.sourceCode().replace("@@WS_BOOTSTRAP_ADDR@@", wsAddr) pScript.setSourceCode(code) except Exception as e: raise e return None, None page.webScripts.insert(rxscript) page.webScripts.insert(script) page.webScripts.insert(pScript) view = DWebView(page=page) return view, page
def __init__(self, parent=None): super().__init__(parent=parent) self.setEnabled(False) self.app = QApplication.instance() self.app.ethereum.ethConnected.connectTo(self.onEthStatus) self.app.ethereum.ethNewBlock.connectTo(self.onNewBlock) self.view = DWebView(parent=None) self.view.show() self.page1 = EthereumWrapperPage(self.app.ethereum, parent=self.view) self.view.p = self.page1 self.statusTab = None self.lBlockHash = None self.iconEthereum = getIcon('ethereum.png') self.setIcon(self.iconEthereum)
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)