async def handleRequest(self, request): rUrl = request.requestUrl() if not rUrl.isValid(): return self.urlInvalid(request) domain = rUrl.host() uPath = rUrl.path() if not domain or len(domain) > 512 or not domainValid(domain): log.info('EthDNS: invalid domain request') return self.urlInvalid(request) pathRaw = await self.ethResolver.resolveEnsDomain(domain) path = IPFSPath(pathRaw, autoCidConv=True) if path and path.valid: await ensDomainResolved.emit(domain, path) sPath = path.child(uPath) if uPath else path log.debug('EthDNS: {domain} resolved to {res}'.format( domain=domain, res=sPath.ipfsUrl)) return request.redirect(QUrl(sPath.dwebUrl)) else: log.info('EthDNS: {domain} resolve failed'.format(domain=domain)) return self.urlNotFound(request)
async def openWithExternal(self, ipfsop, rscPath, progArgs): filePath = os.path.join(self.app.tempDir.path(), os.path.basename(rscPath)) if not os.path.exists(filePath): try: await ipfsop.client.get(rscPath, dstdir=self.app.tempDir.path()) except aioipfs.APIError as err: log.debug(err.message) return if not os.path.isfile(filePath): # Bummer return if not self.app.windowsSystem: filePathEsc = filePath.replace('"', r'\"') args = progArgs.replace('%f', filePathEsc) else: args = progArgs.replace('%f', filePath) log.info('Object opener: executing: {}'.format(args)) try: proc = await asyncio.create_subprocess_shell( args, stdout=asyncio.subprocess.PIPE) stdout, stderr = await proc.communicate() except BaseException as err: os.unlink(filePath) log.debug(str(err)) else: os.unlink(filePath)
async def sync(self): _count, _scount = 0, 0 await self.syncing.emit(True) log.info('Synchronizing hashmarks database ...') sources = await database.hashmarkSourceAll() for source in sources: if source.type == HashmarkSource.TYPE_PYMODULE: loader = ModuleCatalogLoader() elif source.type == HashmarkSource.TYPE_GITREPOS: loader = GitCatalogLoader() elif source.type == HashmarkSource.TYPE_IPFSMARKS_LEGACY: loader = IPFSMarksCatalogLoader() else: continue log.info('Synchronizing: {}'.format(source)) _count += await loader.load(source) if _count >= 0: _scount += 1 source.syncedlast = datetime.now() await source.save() shistory = database.HashmarkSyncHistory( hashmarkstotal=await database.hashmarksCount(), hashmarksadded=_count, srcsynccount=_scount ) await shistory.save() await self.syncing.emit(False)
async def _accept(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter): addr_repr = ':'.join(map(str, writer.get_extra_info('peername'))) logger.info('accepted connection from %s', addr_repr) try: writer.write(ControlServer.HANDSHAKE_MESSAGE) while True: # FIXME: maybe do not allow to execute arbitrary object action = cast(Callable[[ControlManager], Any], await ControlServer.receive_object(reader)) try: result = action(self._control) if asyncio.iscoroutine(result): result = await result except asyncio.CancelledError: raise except Exception as e: result = e ControlServer.send_object(result, writer) if isinstance(result, DaemonExit): logger.info('stop command received') if self._daemon_stop_handler is not None: self._daemon_stop_handler(self) return except asyncio.IncompleteReadError: pass except asyncio.CancelledError: raise except Exception as e: logger.warning('%s disconnected because of %r', addr_repr, e) finally: writer.close()
async def browseIpService(self, ipfsop, serviceId, serviceCtx=None): """ Browse/open an IP service registered on an IPID """ log.info('Accessing IP service {}'.format(serviceId)) pService = await ipfsop.ipidManager.getServiceById(serviceId) if not pService: return endpoint = pService.endpoint if pService.type == IPService.SRV_TYPE_ATOMFEED: await self.app.mainWindow.atomButton.atomFeedSubscribe( str(endpoint)) elif pService.type == IPService.SRV_TYPE_VIDEOCALL: from galacteek.ui.videocall import VideoCallInitiator vc = VideoCallInitiator(pService) await vc.start() elif isinstance(endpoint, str): path = IPFSPath(endpoint, autoCidConv=True) await self.open(path)
async def sendIdent(self, op, profile): if not profile.initialized: logger.debug('Profile not initialized, ident message not sent') return nodeId = op.ctx.node.id uInfo = profile.userInfo ipid = await op.ipidManager.load(profile.userInfo.personDid, localIdentifier=True) if not ipid: logger.info('Failed to load local DID') return else: logger.debug('Local IPID ({did}) load: OK, dagCID is {cid}'.format( did=profile.userInfo.personDid, cid=ipid.docCid)) msg = await PeerIdentMessageV3.make(nodeId, profile.dagUser.dagCid, profile.keyRootId, uInfo, profile.userInfo.personDid, ipid.docCid) logger.debug('Sending ident message') await self.send(str(msg))
async def onJoinChannel(self, ipfsop, channel): log.info(f'Joining channel: {channel}') widget = await self.chans.joinChannel(channel) self.app.mainWindow.registerTab(widget, name=channel, icon=getIcon('qta:mdi.chat-outline'), current=True)
async def onJoinChannel(self, ipfsop, channel): log.info(f'Joining channel: {channel}') widget = await self.chans.joinChannel(channel) self.app.mainWindow.registerTab(widget, name=channel, icon=getIcon('chat.png'), current=True, workspace=WS_PEERS)
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)
def dappsRegisterSchemes(): # Called early (register dapps schemes before app creation) for dappName, dappPath in availableDapps(): mod = dappGetModule(dappName) if mod: log.debug(f'Registering ipdapp schemes for {dappName}') mod.declareUrlSchemes() else: log.info(f'Cannot load dapp {dappName}')
def onAppSeed(self, future): try: replResult = future.result() except Exception as err: log.debug('AppImage seed: failed', exc_info=err) else: if isinstance(replResult, dict): cid = replResult.get('Hash') self.appImageImported.emit(cid) log.info('AppImage seed OK: CID {cid}'.format(cid=cid))
async def profileNew(self, pName, emitavail=False): profile = UserProfile(self, pName, os.path.join( GFILES_ROOT_PATH, 'profile.{}'.format(pName))) try: await profile.init() except Exception as e: log.info('Could not initialize profile: {}'.format( str(e)), exc_info=True) return None self.profiles[pName] = profile if emitavail is True: self.profileEmitAvail() return profile
async def start(self): for port in ControlServer.PORT_RANGE: try: self._server = await asyncio.start_server( self._accept, host=ControlServer.HOST, port=port) except asyncio.CancelledError: raise except Exception as e: logger.debug(f'exception on starting server on port {port}: {e}') else: logger.info(f'server started on port {port}') return else: raise RuntimeError('Failed to start a control server')
def mimeTypeProcess(mTypeText, buff, info=None): if mTypeText == 'text/xml': # If it's an XML, check if it's an Atom feed from the buffer # Can't call feedparser here cause we only got a partial buffer atomized = re.search('<feed xmlns="http://www.w3.org/[0-9]+/Atom".*>', buff.decode()) if atomized: return MIMEType('application/atom+xml') elif mTypeText == 'application/octet-stream': # Check for WASM magic number wasmMagic = binascii.unhexlify(b'0061736d') if buff[0:4] == wasmMagic: version = struct.unpack('<I', buff[4:8])[0] log.info('Detected WASM binary, version {}'.format(version)) return mimeTypeWasm return MIMEType(mTypeText)
async def profileLoad(self, ipfsop, pName): if await self.profileExists(pName): profile = UserProfile(self, pName, posixIpfsPath.join( GFILES_ROOT_PATH, 'profile.{}'.format(pName)) ) if pName not in self.profiles: self.profiles[pName] = profile self.currentProfile = profile try: async for msg in profile.init(ipfsop): yield msg except Exception as e: log.info('Could not initialize profile: {}'.format( str(e)), exc_info=True) raise e self.profileEmitAvail() self.profileChange(pName)
async def sendIdent(self, op, profile): if not profile.initialized: logger.debug('Profile not initialized, ident message not sent') return await self.gHubPublish(keyTokensIdent, {'token': self.__identToken}) nodeId = op.ctx.node.id uInfo = profile.userInfo ipid = await op.ipidManager.load( profile.userInfo.personDid, localIdentifier=True ) if not ipid: logger.info('Failed to load local DID') return else: logger.debug('Local IPID ({did}) load: OK, dagCID is {cid}'.format( did=profile.userInfo.personDid, cid=ipid.docCid)) pssSigCurDid = await self.didSigCache( op, profile.userInfo.personDid) msg = await PeerIdentMessageV4.make( nodeId, self.__identToken, profile.dagUser.dagCid, profile.keyRootId, uInfo, profile.userInfo.personDid, ipid.docCid, await op.rsaAgent.pubKeyCid(), await op.curve25519Agent.pubKeyCid(), pssSigCurDid, profile.dagNetwork.dagCid ) logger.debug('Sending ident message') await self.send(str(msg))
async def profileNew(self, ipfsop, pName, initOptions=None, emitavail=True): profile = UserProfile(self, pName, posixIpfsPath.join( GFILES_ROOT_PATH, 'profile.{}'.format(pName)), initOptions=initOptions ) if not self.currentProfile: self.currentProfile = profile try: async for msg in profile.init(ipfsop): yield msg except Exception as e: log.info('Could not initialize profile: {}'.format( str(e)), exc_info=True) raise e self.profiles[pName] = profile self.profileChange(pName) self.profileEmitAvail()
async def openIpServiceObject(self, ipfsop, serviceId, objectId): log.info('Accessing IP service object {}'.format(objectId)) pService = await ipfsop.ipidManager.getServiceById(serviceId) if not pService: log.info('Cannot find service {}'.format(serviceId)) return obj = await pService.getObjectWithId(objectId) if obj: path = IPFSPath(obj['path'], autoCidConv=True) await self.open(path) else: log.info('Cannot find object {}'.format(objectId))
def info(self, msg): logger.info('PS[{0}]: {1}'.format(self.topic, msg))
async def start(self): # Set the IPFS_PATH environment variable os.environ['IPFS_PATH'] = self.repopath log.debug('Using go-ipfs binary: {}'.format(self.goIpfsPath)) if not os.path.isdir(self.repopath): os.mkdir(self.repopath) if not os.path.exists(os.path.join(self.repopath, 'config')) or \ not os.path.isdir(os.path.join(self.repopath, 'datastore')): # Pretty sure this is an empty repository path log.info('Initializing IPFS repository: {repo}'.format( repo=self.repopath)) await shell('ipfs init') apifile = os.path.join(self.repopath, 'api') if os.path.exists(apifile): os.unlink(apifile) # API & gateway multiaddrs await self.ipfsConfig('Addresses.API', '/ip4/127.0.0.1/tcp/{0}'.format(self.apiport)) await self.ipfsConfig( 'Addresses.Gateway', '/ip4/127.0.0.1/tcp/{0}'.format(self.gatewayport)) # Swarm multiaddrs (ipv4 and ipv6), TCP and quic swarmAddrs = [] if 'quic' in self.swarmProtos: swarmAddrs += [ '/ip4/0.0.0.0/udp/{swarmport}/quic'.format( swarmport=self.swarmportQuic), '/ip6/::/udp/{swarmport}/quic'.format( swarmport=self.swarmportQuic) ] if 'tcp' in self.swarmProtos or not swarmAddrs: swarmAddrs += [ '/ip4/0.0.0.0/tcp/{swarmport}'.format( swarmport=self.swarmport), '/ip6/::/tcp/{swarmport}'.format(swarmport=self.swarmport) ] await self.ipfsConfigJson('Addresses.Swarm', json.dumps(swarmAddrs)) # Swarm connection manager parameters await self.ipfsConfigJson('Swarm.ConnMgr.LowWater', self.swarmLowWater) await self.ipfsConfigJson('Swarm.ConnMgr.HighWater', self.swarmHighWater) await self.ipfsConfig('Swarm.ConnMgr.GracePeriod', '60s') await self.ipfsConfig('Routing.Type', self.routingMode) if self.pubsubRouter in ['floodsub', 'gossipsub']: await self.ipfsConfig('Pubsub.Router', self.pubsubRouter) await self.ipfsConfigJson('Pubsub.DisableSigning', boolarg(not self.pubsubSigning)) await self.ipfsConfigJson('Swarm.DisableBandwidthMetrics', 'false') # Maximum storage await self.ipfsConfig('Datastore.StorageMax', '{0}GB'.format(self.storageMax)) # P2P streams await self.ipfsConfigJson('Experimental.Libp2pStreamMounting', boolarg(self.p2pStreams)) await self.ipfsConfigJson('Experimental.FilestoreEnabled', boolarg(self.fileStore)) # CORS if self.corsEnable: await self.ipfsConfigJson( 'API.HTTPHeaders.Access-Control-Allow-Credentials', '["true"]') await self.ipfsConfigJson( 'API.HTTPHeaders.Access-Control-Allow-Methods', '["GET", "POST"]') await self.ipfsConfigJson( 'API.HTTPHeaders.Access-Control-Allow-Origin', '["*"]') if self.noBootstrap: await self.ipfsConfigJson('Bootstrap', '[]') await self.ipfsConfigJson('Gateway.Writable', self.gwWritable) args = [self.goIpfsPath, 'daemon'] if self.pubsubEnable: args.append('--enable-pubsub-experiment') if self.namesysPubsub: args.append('--enable-namesys-pubsub') if self.migrateRepo: args.append('--migrate') if self.offline: args.append('--offline') f = self.loop.subprocess_exec(lambda: IPFSDProtocol( self.loop, self.exitFuture, self.startedFuture, debug=self.debug), *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) self.transport, self.proto = await f self._procPid = self.transport.get_pid() self.setProcLimits(self.pid, nice=self.nice) return True
async def stop(self): if self._server is not None: self._server.close() await self._server.wait_closed() logger.info('server stopped')