async def downloadObject(self, ipfsop, objConfig): pBar = QProgressBar() def onProgressValue(val): if val in range(0, 50): pBar.setStyleSheet(''' QProgressBar:horizontal { border: 1px solid gray; border-radius: 5px; text-align: center; } QProgressBar::chunk:horizontal { text-align: center; background-color: #60cccf; } ''') else: pBar.setStyleSheet(''' QProgressBar:horizontal { border: 1px solid gray; border-radius: 5px; text-align: center; } QProgressBar::chunk:horizontal { text-align: center; background-color: #4b9fa2; } ''') pBar.setObjectName('downloadProgressBar') pBar.valueChanged.connect(onProgressValue) self.treeWidget().setItemWidget(self, self.COL_STATUS, pBar) baseDir = self.baseDownloadDir() chunkSize = objConfig.downloadChunkSize log.debug(f'Downloading with chunk size {chunkSize}') try: async for result in ipfsop.client.core.getgen( self.objdescr['path'], dstdir=str(baseDir), chunk_size=chunkSize, sleept=0.1): status, read, clength = result if status == 0: progress = (read * 100) / clength pBar.setValue(progress) elif status == 1: break await ipfsop.sleep(0.1) except aioipfs.APIError as e: # OK these setItemWidget() calls have got to go, this # is not middle age here. Replace by signals asap. self.treeWidget().setItemWidget(self, self.COL_STATUS, None) self.status(f'IPFS error: {e.message}') except Exception: self.treeWidget().setItemWidget(self, self.COL_STATUS, None) self.status('Error') else: pBar.setValue(100) self.status('Downloaded') self.treeWidget().setItemWidget(self, self.COL_STATUS, None) hDir = baseDir.joinpath(self.stat['Hash']) if self.objdescr['name']: nDir = baseDir.joinpath(self.objdescr['name']) else: nDir = hDir if nDir.exists(): return nDir if hDir.exists(): hDir.replace(nDir) return nDir
async def handleUserChannelsMessage(self, ipfsop, sender, piCtx, msg, dbRecord): msgConfig = self.cUserChannelsListMessage cMsg = UserChannelsListMessage(msg) if not cMsg.valid(): return pubTokensList = cMsg.pubChannels if cMsg.pubChannels else [] jwsCids = [c['sessionJwsCid'] for c in pubTokensList] for jwsCid in jwsCids: token = await self.tokManager.tokenGet(jwsCid) if token: await self.tokManager.tokenUpdate(token) else: # Fetch the JWS first jws = await ipfsop.getJson( jwsCid, timeout=msgConfig.jwsFetchTimeout) if not jws: log.debug(f'Could not fetch JWS with CID: {jwsCid}') await ipfsop.sleep() continue pubJwk = await piCtx.pubKeyJwk() if not pubJwk: log.debug(f'Peer {sender}: waiting for JWK') await ipfsop.sleep() continue payload = await ipfsop.ctx.rsaExec.jwsVerify( orjson.dumps(jws).decode(), pubJwk ) if not payload: log.debug(f'Peer {sender}: invalid JWS payload') await ipfsop.sleep() continue jwsT = verifyTokenPayload(payload) if not jwsT: log.debug(f'Peer {sender}: invalid JWS payload') await ipfsop.sleep() continue psTopic = jwsT.psTopic chan = jwsT.channel pubKeyCid = jwsT.pubKeyCid log.debug(f'Peer {sender}: valid JWS:' f'sec topic: {psTopic}') if ipfsop.ourNode(sender): await self.tokManager.reg( jwsCid, chan, psTopic, sender, pubKeyCid, encType=jwsT.encType, did=jwsT.did) else: if 0: # Disabled for now cause listing peers # on a topic is not always reliable .. # Check who's subscribed to the topic psPeers = await ipfsop.pubsubPeers( topic=psTopic, timeout=5) # There should only be one peer subscribed if psPeers and len(psPeers) == 1: await self.tokManager.reg( jwsCid, chan, psTopic, sender, pubKeyCid, encType=jwsT.encType, did=jwsT.did) else: log.debug(f'Peer {sender}: valid JWS but ' 'no one listening on sectopic') await self.tokManager.reg( jwsCid, chan, psTopic, sender, pubKeyCid, encType=jwsT.encType, did=jwsT.did) await ipfsop.sleep() piCtx._processData['chatTokensLastRev'] = cMsg.rev
def _encodeAllAppend(self, version=12): """ Generate all the QR codes and embed them all into one image by appending. We use QR version 12 by default Does basically something similar to what 'convert +append' would do, but probably less elegantly. :return: an image containing all the QR codes :rtype: PIL.Image """ baseImageWidth = 0 baseImageHeight = 0 # Base image sizes based on the QR count # The image is resized in height if needed to fit more codes unit = 172 imageSizes = { range(1, 20): (unit * 4, unit * 4), range(20, 50): (unit * 6, unit * 6), range(50, 70): (unit * 6, unit * 8), range(70, 101): (unit * 8, unit * 8) } for _range, size in imageSizes.items(): if len(self.codes) in _range: baseImageWidth, baseImageHeight = size break if baseImageWidth == 0 or baseImageHeight == 0: raise ValueError('Cannot generate image with these parameters') imgMosaic = self._newImage(baseImageWidth, baseImageHeight) lastImage = None posX = 0 posY = 0 highest = 0 for count, url in enumerate(self.codes): if len(str(url)) > 1024: log.debug('QR#{count} ({url}): too large, ignoring'.format( count=count, url=url)) continue img = self.encodeUrl(url, qrVersion=version) if not img: log.debug('QR#{count} ({url}): empty image?'.format( count=count, url=url)) continue try: # Why not ? img = img.resize((int(img.width / 4), int(img.height / 4))) except: log.debug('QR#{count} ({url}): cannot resize image'.format( count=count, url=url)) continue if img.height > highest: highest = img.height if posX + img.width > imgMosaic.width: # Sort of a carriage return posY += highest posX = 0 highest = 0 if posY + img.height > imgMosaic.height: imgNew = self._newImage(imgMosaic.width, posY + img.height) imgNew.paste(imgMosaic, (0, 0)) imgMosaic = imgNew log.debug('QR #{count} (size: {size}) at: {posx}:{posy}'.format( count=count + 1, posx=posX, posy=posY, size=len(url))) imgPosY = posY if highest > img.height: imgPosY = posY + int((highest - img.height) / 2) imgMosaic.paste( img, (posX, imgPosY, posX + img.width, imgPosY + img.height)) posX += img.width lastImage = img if lastImage is not None: # Crop it imgMosaic = imgMosaic.crop( (0, 0, posX if posY == 0 else imgMosaic.width, posY + lastImage.height)) return imgMosaic
def onSessionCidChanged(self, cid): log.debug('Session now at CID: {}'.format(cid)) self.unixDirCid = cid self.unixDirPath = IPFSPath(cid) self.unixDirLabel.path = self.unixDirPath self.unixDirClipButton.path = self.unixDirPath
def message(self, msg): log.debug(msg) for cb in self._msgCallback: cb(msg)
def debug(self, msg): log.debug('Native scheme handler: {}'.format(msg))
async def onOpenConfirmed(self, iPath, mType, dlg): log.debug('Open confirmed for: {0}'.format(iPath)) await self.openWithSystemDefault(str(iPath))
def onPureSnakeOil(self, key, message): log.debug(f'Storing new elixir: {message}') self.elixirs.appendleft(message) self.purgeExpiredElixirs()
def allowEDag(self, edag): if edag.dagMetaMfsPath not in self.__edags: log.debug(f'Allowing signing for DAG {edag.dagMetaMfsPath}') self.__edags[edag.dagMetaMfsPath] = edag
async def start(self): log.debug('Starting IPFS context services') await self.pubsub.startServices() await self.p2p.startServices()
def onDagExchangeToken(self, key, message): self._token = message['token'] log.debug(f'Switched service token: {self._token}')
async def on_stop(self) -> None: await super().on_stop() log.debug('Stopping main application service')
def message(self, msg): log.debug(msg)
async def runSearch(self, ipfsop, text): try: sRegexp = re.compile(text, re.IGNORECASE) except Exception: return await messageBoxAsync(f'Invalid search regexp: {text}') dateFrom = self.qDateToDatetime(self.ui.searchDateFrom) dateTo = self.qDateToDatetime(self.ui.searchDateTo) self.ui.cancelSearchButton.show() self.ui.seedsSearch.setEnabled(False) profile = ipfsop.ctx.currentProfile seedsDag = profile.dagSeedsAll root = self.ui.treeAllSeeds.invisibleRootItem() bfont = QFont('Montserrat', 14) bfont.setBold(True) nfont = QFont('Montserrat', 12) now = utcDatetime() try: self.ui.treeAllSeeds.setHeaderHidden(False) async for result in seedsDag.search( sRegexp, dateFrom=dateFrom, dateTo=dateTo): section, name, date, dCid = result try: seedDate = dateparser.parse(date) delta = now - seedDate seconds = delta.total_seconds() humanDelta = secondsToTimeAgo(seconds) dthuman = f'Published {humanDelta}' except Exception as err: log.debug(err) dthuman = 'No date' item = SeedTreeItem( None, [name, f'{dthuman}', ''] ) item.setDisabled(True) item.setFont(0, bfont) item.setFont(1, nfont) item.setFont(2, nfont) root.addChild(item) ensure(self.findSeed(seedsDag, item, dCid)) self.ui.seedsSearch.setEnabled(True) await ipfsop.sleep(0.1) except asyncio.CancelledError: pass self.ui.seedsSearch.setEnabled(True) self.ui.seedsSearch.setFocus(Qt.OtherFocusReason) self.ui.cancelSearchButton.hide()
def debug(self, msg): log.debug('EthDNS resolver: {}'.format(msg))
def register(self, channel): if self.channels and channel not in self.channels: log.debug('Registering channel: {}'.format(channel)) self.channels.append(channel) self.changed.emit()
def debug(self, msg): log.debug('EthDNS: {}'.format(msg))
async def registerFromObjTag(self, tag): try: await database.qaTagItemAdd(tag) except Exception: log.debug('Could not register hashmark with tag: {}'.format(tag))
async def p2pEndpointAddr(self): try: q = await self.expandEndpointLdWizard() return q.gu('DwebVideoCallServiceEndpoint', 'p2pEndpoint') except Exception as err: log.debug(err)
async def load(self): try: for item in await database.qaHashmarkItems(): ensure(self.registerHashmark(item.ithashmark)) except Exception as err: log.debug(str(err))
def debug(self, msg, **kwargs): log.debug('Pinning service: {}'.format(msg), **kwargs)
async def event_g_services_net_bitmessage(self, key, message): log.debug(f'Bitmessage service event: {message}') await self.msger.setup() self.wsSwitchButton.setEnabled(True)
def cleanup(self): if os.path.isdir(self.checkoutPath): log.debug('Cleaning up checkout directory: {}'.format( self.checkoutPath)) shutil.rmtree(self.checkoutPath)
def listenRange(self, pr): log.debug(f'{self}: Setting listen range: {pr}') self._listenRange = pr
def javaScriptConsoleMessage(self, level, message, lineNumber, sourceId): log.debug( 'JS: level: {0}, source: {1}, line: {2}, message: {3}'.format( level, sourceId, lineNumber, message))
async def ipfsImport(self, ipfsop, torrent_info): try: entry = await ipfsop.addPath(torrent_info.download_dir) glklog.debug(f'Torrent import: {entry}') except Exception as err: glklog.debug(f'Torrent import error: {err}')
def decode(self, data): """ :param bytes data: Raw image data or Pillow image :rtype: list """ if isinstance(data, bytes): image = self._getImage(data) elif isinstance(data, Image.Image): image = data else: raise Exception('Need bytes or PIL.Image') if image is None: return None try: objects = zbar_decode(image) urls = [] for obj in objects: if not isinstance(obj.data, bytes): log.debug('pyzbar decode: invalid type') continue try: decoded = obj.data.decode() except BaseException as err: log.debug(f'pyzbar decode: error decoding item: {err}') continue if len(decoded) not in range(1, 1024): log.debug('pyzbar decode: decoded value not in range') continue path = IPFSPath(decoded, autoCidConv=True) if path.valid and path not in urls: log.debug('Decoded IPFS QR: {}'.format(path)) urls.append(path) elif didRe.match(decoded): log.debug('Decoded DID QR: {}'.format(decoded)) urls.append(decoded) if len(urls) > 0: # don't return empty list return urls except Exception as err: log.debug(f'pyzbar decode error: {err}') return None
def setMimeType(self, mimeType): log.debug('Detected mime-type {type} for {path}'.format( path=self.path, type=str(mimeType))) self._mimeType = mimeType self.mimeTypeAvailable.emit(mimeType)
def _warn_pending(): running = _all_tasks(loop=loop) if running: log.debug( 'There are {tc} pending tasks, first 10: {first}', tc=len(running), first=list(running)[:10])
async def updateButton(self, ipfsop): if not isinstance(self.item, ClipboardItem): return if self.item.path is None: log.debug('Empty path') return shortened = shortPathRepr(self.item.path) self.menu.clear() action = self.menu.addSection(shortened) action.setToolTip(self.item.fullPath) self.menu.addSeparator() self.menu.addAction(self.openAction) self.menu.addAction(self.openWithAppAction) self.menu.addAction(self.openWithDefaultAction) self.menu.addSeparator() self.menu.addAction(self.setAsHomeAction) self.menu.addAction(self.hashmarkAction) self.menu.addAction(self.downloadAction) self.menu.addSeparator() self.menu.addAction(self.dagViewAction) self.menu.addAction(self.ipldExplorerAction) self.menu.addSeparator() self.menu.addAction(self.pinAction) self.exploreHashAction.setText(iClipItemExplore()) self.openAction.setText(iClipItemOpen()) self.dagViewAction.setText(iClipItemDagView()) self.hashmarkAction.setText(iClipItemHashmark()) self.downloadAction.setText(iClipItemDownload()) self.ipldExplorerAction.setText(iClipItemIpldExplorer()) self.editObjectAction.setText(iEditObject()) self.pinAction.setText(iClipItemPin()) self.copyPathToCbAction.setText(iCopyPathToClipboard()) self.copyGwPathToCbAction.setText(iCopyPubGwUrlToClipboard()) self.setToolTip(self.tooltipMessage()) if not self.item.mimeType: return self.updateIcon(getMimeIcon('unknown')) icon = None if self.item.mimeType.isDir: # It's a directory. Add the explore action and disable # the actions that don't apply to a folder self.menu.addAction(self.exploreHashAction) self.openWithAppAction.setEnabled(False) self.openWithDefaultAction.setEnabled(False) # Look for a favicon icon = await getFavIconFromDir(ipfsop, self.item.ipfsPath) if icon: return self.updateIcon(icon) self.menu.addSeparator() self.menu.addAction(self.editObjectAction) elif self.item.mimeType.isText: self.menu.addSeparator() self.menu.addAction(self.editObjectAction) elif self.item.mimeType.isImage: self.updateIcon(getMimeIcon('image/x-generic'), animate=False) ensure(self.analyzeImage()) elif self.item.mimeType.isAtomFeed: # We have an atom! self.menu.addSeparator() self.menu.addAction(self.followFeedAction) mIcon = getIconFromMimeType(self.item.mimeType) if mIcon: self.updateIcon(mIcon) self.menu.addSeparator() self.menu.addAction(self.copyPathToCbAction) self.menu.addAction(self.copyGwPathToCbAction) self.menu.addSeparator() self.mfsMenu = ipfsop.ctx.currentProfile.createMfsMenu( title=iLinkToMfsFolder(), parent=self) self.mfsMenu.triggered.connect(self.onCopyToMfs) self.menu.addSeparator() self.menu.addMenu(self.mfsMenu) if self.item.mimeType in [mimeTypeDagUnknown, mimeTypeDagPb]: self.updateIcon(getIcon('ipld.png')) self.downloadAction.setEnabled(False) self.mfsMenu.setEnabled(False)