Exemple #1
0
    def child(self, path, normalize=False):
        if not isinstance(path, str):
            raise ValueError('Need string')

        if self.subPath is None and (path == '..' or path.startswith('../')):
            # Not crossing the /{ipfs,ipns} NS
            return self

        if normalize:
            cPath = normp(path)
            return IPFSPath(
                normp(posixIpfsPath.join(self.objPath, cPath.lstrip('/'))))
        else:
            cPath = normpPreserve(path)
            return IPFSPath(posixIpfsPath.join(self.objPath,
                                               cPath.lstrip('/')))
Exemple #2
0
 async def cat(self, op, path):
     try:
         return await op.client.cat(
             posixIpfsPath.join(self.dagCid, path))
     except aioipfs.APIError as err:
         self.debug(f'Cat error ({path}): {err.message}')
         return None
Exemple #3
0
def p2pEndpointMake(peerId: str, serviceName: str, protocolVersion=None):
    args = ['/p2p', peerId, 'x', serviceName.lstrip('/')]

    if protocolVersion:
        args.append(protocolVersion)

    return posixIpfsPath.join(*args)
Exemple #4
0
    def fullPath(self):
        parentHash = self.parentHash
        if parentHash:
            fp = joinIpfs(
                posixIpfsPath.join(parentHash, self.entry['Name']))
        else:
            fp = joinIpfs(self.entry['Hash'])

        return fp + '/' if self.isDir() else fp
Exemple #5
0
def p2pEndpointAddrExplode(addr: str):
    """
    Explode a P2P service endpoint address such as :

    /p2p/12D3KooWD3bfmNbuuuVCYwkjnFt3ukm3qaB3hDED3peHHXawvRAi/x/videocall/room1/1.0.0
    /p2p/12D3KooWD3bfmNbuuuVCYwkjnFt3ukm3qaB3hDED3peHHXawvRAi/x/test

    into its components, returning a tuple in the form

    (peerId, protoFull, protoVersion)

    protoFull can be passed to 'ipfs p2p dial'

    Example:

    ('12D3KooWD3bfmNbuuuVCYwkjnFt3ukm3qaB3hDED3peHHXawvRAi',
     '/x/videocall/room1/1.0.0',
     '1.0.0')

    protoVersion is not mandatory
    """
    parts = addr.lstrip(posixIpfsPath.sep).split(posixIpfsPath.sep)
    try:
        assert parts.pop(0) == 'p2p'
        peerId = parts.pop(0)
        prefix = parts.pop(0)
        assert peerIdRe.match(peerId)
        assert prefix == 'x'

        pVersion = None
        protoA = [prefix]
        protoPart = parts.pop(0)
        protoA.append(protoPart)

        while protoPart:
            try:
                protoPart = parts.pop(0)
            except IndexError:
                break

            protoA.append(protoPart)

            try:
                v = StrictVersion(protoPart)
            except Exception:
                pass
            else:
                # Found a version, should be last element
                pVersion = v
                assert len(parts) == 0
                break

        protoFull = posixIpfsPath.sep + posixIpfsPath.join(*protoA)
        return peerId, protoFull, pVersion
    except Exception:
        log.warning(f'Invalid P2P endpoint address: {addr}')
        return None
Exemple #6
0
    async def get(self, op, path):
        self.debug('DAG get: {}'.format(posixIpfsPath.join(self.dagCid, path)))
        try:
            dagNode = await op.dagGet(
                posixIpfsPath.join(self.dagCid, path))
        except aioipfs.APIError as err:
            log.debug('DAG get: {0}. An error occured: {1}'.format(
                path, err.message))
            return None

        if isinstance(dagNode, dict) and 'data' in dagNode and \
                'links' in dagNode:
            """ Try and decode the protobuf data """
            msg = pb.decodeUnixfsDagNode(dagNode['data'])
            if not msg:
                return
            return msg['data']
        else:
            return dagNode
Exemple #7
0
    async def walk(self, op, path='', maxObjSize=0, depth=1):
        """
        Do not use this!
        """

        data = await self.get(path)
        if data is None:
            return

        if isinstance(data, dict) and 'data' in data and 'links' in data:
            """ Try and decode the protobuf data """
            msg = pb.decodeUnixfsDagNode(data['data'])
            if not msg:
                return
            if maxObjSize == 0 or \
                    (maxObjSize > 0 and msg['size'] < maxObjSize):
                await yield_((path, DAGObj(msg['data'])))

        if not data:
            return

        if isinstance(data, dict):
            for objKey, objValue in data.items():
                if objKey == '/':
                    out = await op.client.cat(objValue)
                    await yield_((path, DAGObj(out)))
                if objKey == 'data' or objKey == 'links':
                    continue
                else:
                    await yield_from_(
                        self.walk(op, path=posixIpfsPath.join(path, objKey),
                                  maxObjSize=maxObjSize, depth=depth)
                    )

        elif isinstance(data, list):
            for idx, obj in enumerate(data):
                await yield_from_(
                    self.walk(op, path=posixIpfsPath.join(path, str(idx)),
                              maxObjSize=maxObjSize)
                )
        elif isinstance(data, str):
            await yield_((path, DAGObj(data)))
Exemple #8
0
    async def followPeerFeed(self, op, piCtx):
        identMsg = piCtx.ident

        path = posixIpfsPath.join(joinIpns(identMsg.dagIpns), DWEB_ATOM_FEEDFN)
        ipfsPath = IPFSPath(path)

        try:
            await self.app.sqliteDb.feeds.follow(ipfsPath.ipfsUrl)
        except Exception:
            # TODO
            pass
Exemple #9
0
    def feedAddPinRequests(self, requests, feed):
        for id, reqobj in enumerate(requests):
            req = reqobj['pinrequest']
            rpath = self.sitePath.child(
                posixIpfsPath.join(PINREQS_NODEKEY, str(id), 'view'))

            fEntry = feed.add_entry()
            fEntry.title('Pin request: {}'.format(req['title']))
            fEntry.id(rpath.ipfsUrl)
            fEntry.link(href=rpath.ipfsUrl, rel='alternate')
            fEntry.published(req['date_published'])
            fEntry.author({'name': self.profile.userInfo.iphandle})
Exemple #10
0
    def data(self, column, role):
        if column == 0:
            handle = self.peerItem.ctx.spaceHandle
            exploded = didExplode(self.service.id)

            if exploded['path']:
                return posixIpfsPath.join(handle.human,
                                          exploded['path'].lstrip('/'))
        if column == 1:
            return str(self.service.id)

        return QVariant(None)
Exemple #11
0
    def data(self, column, role):
        if column == 0:
            handle = self.peerItem.ctx.spaceHandle
            exploded = didExplode(self.sObject['id'])

            if exploded and exploded['path']:
                return posixIpfsPath.join(handle.short,
                                          exploded['path'].lstrip('/'))
        if column == 1:
            return self.sObject['id']

        return QVariant(None)
Exemple #12
0
    def getFullPath(self):
        """
        Returns the full IPFS path of the entry associated with this item
        (preserving file names) if we have the parent's hash, or the IPFS path
        with the entry's hash otherwise
        """

        if self._parentCid:
            return joinIpfs(
                posixIpfsPath.join(cidConvertBase32(self._parentCid),
                                   self.filename))
        else:
            return joinIpfs(cidConvertBase32(self.entry['Hash']))
Exemple #13
0
async def getTitleDirectory(client, path):
    indexPath = posixIpfsPath.join(path, 'index.html')

    try:
        data = await client.cat(indexPath)
    except aioipfs.APIError as exc:
        if exc.code == 0 and exc.message.startswith('no link named'):
            return None
        if exc.code == 0 and exc.message == 'this dag node is a directory':
            # Wicked!
            return None
    else:
        return runTitleParser(data)
Exemple #14
0
    async def savePlaylist(self, ipfsop, obj, name):
        objPath = posixIpfsPath.join(self.profile.pathPlaylists, name)
        exists = await ipfsop.filesStat(objPath)

        if exists:
            await ipfsop.filesRm(objPath)

        ent = await ipfsop.client.core.add_json(obj.root)

        if ent:
            await ipfsop.filesLinkFp(ent, objPath)
            self.playlistIpfsPath = joinIpfs(ent['Hash'])
            self.copyPathAction.setEnabled(True)

        self.update()
Exemple #15
0
    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)
Exemple #16
0
    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()
Exemple #17
0
    def feedAddPosts(self, blogPosts, feed, ftype='ipfs'):
        for post in blogPosts:
            ppath = self.sitePath.child(
                posixIpfsPath.join('blog', post['postname'], 'view'))

            fEntry = feed.add_entry()
            fEntry.title(post['title'])

            if ftype == 'ipfs':
                url = ppath.ipfsUrl
            elif ftype == 'publicgw':
                url = ppath.publicGwUrl

            fEntry.id(url)
            fEntry.link(href=url, rel='alternate')
            fEntry.updated(post['date_modified'])
            fEntry.published(post['date_published'])
            fEntry.content(content=markitdown(post['body']), type='html')

            fEntry.author({'name': self.profile.userInfo.iphandle})

            for tag in post['tags']:
                fEntry.category(term=tag)
Exemple #18
0
 def pathOrbitalConfig(self):
     return posixIpfsPath.join(self.pathOrbital, 'config')
Exemple #19
0
def joinIpns(path):
    if isinstance(path, str):
        return posixIpfsPath.join('/ipns/', path)
Exemple #20
0
 def pathjoin(self, path1, path2):
     return posixIpfsPath.join(path1, path2.lstrip('/'))
Exemple #21
0
 def pathHMarksLibrary(self):
     return posixIpfsPath.join(self.pathData, 'hmarks_library')
Exemple #22
0
 async def peerNode(self, peerId):
     if peerId in self.nodes:
         return await self.get(posixIpfsPath.join('nodes', peerId))
Exemple #23
0
 def pathOrbital(self):
     return posixIpfsPath.join(self.pathData, 'orbital')
Exemple #24
0
 def pathEdagSeedsAll(self):
     return posixIpfsPath.join(self.pathEDagsSeeds,
                               'ipseeds_main_mega.enc.edag')
Exemple #25
0
    async def init(self, ipfsop):
        """
        Initialize the profile's filesystem
        """

        yield 10, 'Initializing filesystem'

        await ipfsop.filesMkdir(self.root)

        for directory in self.tree:
            await ipfsop.filesMkdir(directory)

        wPath = posixIpfsPath.join(self.pathHome, 'welcome')
        welcomeEnt = await ipfsop.filesList(wPath)

        if not welcomeEnt:
            try:
                welcome = readQrcTextFile(':/share/static/misc/welcome.md')
                tmpPath = self.ctx.app.tempDir.filePath('welcome.html')

                await asyncWriteFile(tmpPath, markitdown(welcome), mode='w+t')

                await ipfsop.filesLink(await ipfsop.addPath(tmpPath,
                                                            wrap=True),
                                       self.pathHome,
                                       name='welcome')
            except Exception:
                pass

        self.filesModel = createMFSModel()
        self.filesModel.setupItemsFromProfile(self)

        yield 20, 'Generating IPNS keys'

        key = await ipfsop.keyFind(self.keyRoot)
        if key is not None:
            self.keyRootId = key.get('Id', None)
        else:
            self.userLogInfo('Generating main IPNS key')
            result = await ipfsop.keyGen(self.keyRoot)
            self.keyRootId = result.get('Id', None)

        self.debug('IPNS key({0}): {1}'.format(self.keyRoot, self.keyRootId))

        yield 30, 'Initializing crypto'

        if not await self.cryptoInit():
            self.userLogInfo('Error while initializing crypto')
            raise ProfileError('Crypto init failed')

        if not await ipfsop.hasDagCommand():
            self.userLogInfo('No DAG API! ..')
            raise ProfileError('No DAG API')

        yield 40, 'Initializing EDAGs ..'
        self._dagUser = UserDAG(self.pathUserDagMeta, loop=self.ctx.loop)

        self._dagChatChannels = ChannelsDAG(self.pathChatChannelsDagMeta,
                                            loop=self.ctx.loop)

        self._dagNetwork = PeersGraphDAG(self.pathEDagNetwork,
                                         loop=self.ctx.loop,
                                         autoUpdateDates=True)

        # Seeds
        self.dagSeedsMain = SeedsEDag(self.pathEdagSeedsMain,
                                      loop=self.ctx.loop,
                                      cipheredMeta=True)
        self.dagSeedsAll = MegaSeedsEDag(self.pathEdagSeedsAll,
                                         loop=self.ctx.loop,
                                         cipheredMeta=True)

        yield 50, 'Loading EDAGs ..'
        ensure(self.dagUser.load())
        await self.dagUser.loaded

        # Chat channels
        await self.dagChatChannels.load()

        # Network EDAG
        await self.dagNetwork.load()

        # Seeds EDAGs
        await self.dagSeedsMain.load()
        await self.dagSeedsAll.load()
        await self.dagSeedsAll.associate(self.dagSeedsMain)

        self.dagUser.dagCidChanged.connect(self.onDagChange)
        ensure(self.publishDag(allowOffline=True, reschedule=True))

        yield 60, 'Loading user blog ..'
        self.userWebsite = UserWebsite(self.dagUser,
                                       self,
                                       self.keyRootId,
                                       self.ctx.app.jinjaEnv,
                                       parent=self)

        await self.userWebsite.init()

        ensure(self.update())

        self._initialized = True

        yield 70, 'Importing manual ..'
        ensure(self.ctx.app.manuals.importManuals(self))

        self._initOptions = {}
        yield 100, 'Profile ready'
Exemple #26
0
 def pathEDagNetwork(self):
     return posixIpfsPath.join(self.pathEDags, 'network.edag')
Exemple #27
0
 def pathChatChannelsDagMeta(self):
     return posixIpfsPath.join(self.pathEDags, 'chatchannels.edag')
Exemple #28
0
 def pathUserDagMeta(self):
     return posixIpfsPath.join(self.pathData, 'dag.main')
Exemple #29
0
 def pathUserInfo(self):
     return posixIpfsPath.join(self.pathData, 'userinfo.json.enc')
Exemple #30
0
 def pathPlaylists(self):
     return posixIpfsPath.join(self.pathData, 'playlists')