From 1d1fec3ee0328c998989aaa35aabc20e300b7042 Mon Sep 17 00:00:00 2001 From: cipres Date: Thu, 30 Apr 2020 00:07:20 +0200 Subject: [PATCH] Play nicely with go-ipfs 0.5.0 * deps: use latest py-multicodec * Embed go-ipfs 0.5.0 and the latest fs-repo-migrations in the AppImage. Automatic repo migration is on by default. * Add galacteek.ipfs.cidhelpers.ipnsKeyCidV1(), which converts an IPNS key into a CIDv1 with the right multicodec, that is usable with /ipns/ with go-ipfs 0.5.0 * Make the ipns:// scheme work natively with such CIDs. All across the browser any IPNS object opened should go through this scheme (and not dweb:/). --- AppImage/galacteek-appimage-build | 3 +- Pipfile | 4 +- galacteek/application.py | 8 +-- galacteek/core/models/mfs.py | 6 +- galacteek/core/profile.py | 8 +++ galacteek/core/userdag.py | 14 ++--- galacteek/core/webprofiles.py | 3 - galacteek/database/models/core.py | 3 +- galacteek/guientrypoint.py | 1 + .../hashmarks/default/hashmarks.ipfs.yaml | 4 +- galacteek/ipfs/cidhelpers.py | 60 +++++++++++++++++-- galacteek/ipfs/distipfsfetch.py | 15 +++-- galacteek/ipfs/ipfsops.py | 10 +++- galacteek/ui/browser.py | 22 ++++--- galacteek/ui/iprofile.py | 10 ++-- galacteek/ui/peers.py | 2 +- galacteek/ui/pyramids.py | 19 +++++- galacteek/ui/resource.py | 2 - requirements.txt | 4 +- travis/install.sh | 10 ++-- 20 files changed, 150 insertions(+), 58 deletions(-) diff --git a/AppImage/galacteek-appimage-build b/AppImage/galacteek-appimage-build index 1a89243f..58de4dc1 100755 --- a/AppImage/galacteek-appimage-build +++ b/AppImage/galacteek-appimage-build @@ -89,8 +89,9 @@ cp ../share/icons/galacteek.png $APPDIR/usr/share/icons/hicolor/512x512/apps find /usr/lib -iname 'libzbar.so*' -exec cp -av {} $APPDIR/usr/lib \; find /usr/lib -iname 'libjpeg.so*' -exec cp -av {} $APPDIR/usr/lib \; -# Copy go-ipfs +# Copy go-ipfs and fs-repo-migrations cp /tmp/go-ipfs/ipfs $APPDIR/usr/bin +cp $HOME/bin/fs-repo-migrations $APPDIR/usr/bin # Remove unnecessary stuff pushd "$APPDIR"/usr diff --git a/Pipfile b/Pipfile index d2d1d6f1..304dc4cd 100644 --- a/Pipfile +++ b/Pipfile @@ -10,7 +10,7 @@ jinja2 = ">=2.10.1" base58 = ">=1.0.2,<2.0" gitpython = ">=2.1.11" py-multibase = "==1.0.1" -py-multicodec = "==0.1.3" +py-multicodec = "==0.2.1" py-multihash = ">=0.2.3" aiofiles = ">=0.4.0" aiohttp = ">=3.4.4" @@ -34,7 +34,7 @@ async-timeout = ">=3.0.1" aiosqlite = ">=0.10.0" aiodns = ">=2.0.0" pyld = ">=1.0.5" -aioipfs = ">=0.4.4" +aioipfs = ">=0.4.5" cachetools = ">=3.1.1" tortoise-orm = "==0.16.5" pyyaml = ">=5.3.0" diff --git a/galacteek/application.py b/galacteek/application.py index 88b15e49..b5e554e4 100644 --- a/galacteek/application.py +++ b/galacteek/application.py @@ -59,7 +59,6 @@ from galacteek.core.analyzer import ResourceAnalyzer from galacteek.core.schemes import SCHEME_MANUAL -from galacteek.core.schemes import DWebSchemeHandlerNative from galacteek.core.schemes import DWebSchemeHandlerGateway from galacteek.core.schemes import EthDNSSchemeHandler from galacteek.core.schemes import EthDNSProxySchemeHandler @@ -155,7 +154,7 @@ def ipfsVersion(): async def fetchGoIpfsWrapper(app, timeout=60 * 10): try: await asyncio.wait_for(fetchIpfsSoft( - app, 'go-ipfs', 'ipfs', '0.4.23'), timeout) + app, 'go-ipfs', 'ipfs', '0.5.0'), timeout) except asyncio.TimeoutError: app.mainWindow.statusMessage(iGoIpfsFetchTimeout()) return None @@ -787,7 +786,7 @@ async def fetchGoIpfs(self): ipfsPath = self.which('ipfs') fsMigratePath = self.which('fs-repo-migrations') - if fsMigratePath is None and self.cmdArgs.forcegoipfsdl: + if fsMigratePath is None or self.cmdArgs.forcegoipfsdl: await fetchFsMigrateWrapper(self) if ipfsPath is None or self.cmdArgs.forcegoipfsdl: @@ -1050,8 +1049,7 @@ def initDapps(self): self.dappsRegistry = DappsRegistry(self.ethereum, parent=self) def setupSchemeHandlers(self): - self.dwebGwSchemeHandler = DWebSchemeHandlerGateway(self) - self.dwebSchemeHandler = DWebSchemeHandlerNative(self) + self.dwebSchemeHandler = DWebSchemeHandlerGateway(self) self.ensSchemeHandler = EthDNSSchemeHandler(self) self.ensProxySchemeHandler = EthDNSProxySchemeHandler(self) self.nativeIpfsSchemeHandler = NativeIPFSSchemeHandler( diff --git a/galacteek/core/models/mfs.py b/galacteek/core/models/mfs.py index 3df6c4ad..d356bd4f 100644 --- a/galacteek/core/models/mfs.py +++ b/galacteek/core/models/mfs.py @@ -106,8 +106,8 @@ def ipfsPath(self): return IPFSPath(self.fullPath) @property - def dwebUrl(self): - return QUrl('dweb:{}'.format(self.fullPath)) + def qIpfsUrl(self): + return QUrl(self.ipfsPath.ipfsUrl) @property def mimeType(self): @@ -279,7 +279,7 @@ def mimeData(self, indexes): nameItem = self.getNameItemFromIdx(idx) if nameItem: - mimedata.setUrls([nameItem.dwebUrl]) + mimedata.setUrls([nameItem.qIpfsUrl]) break return mimedata diff --git a/galacteek/core/profile.py b/galacteek/core/profile.py index e6b8d225..1ba6190a 100644 --- a/galacteek/core/profile.py +++ b/galacteek/core/profile.py @@ -155,6 +155,14 @@ async def identityDagGet(self, ipfsop, path, identityUid=None): path) ) + @ipfsOp + async def identityGetRaw(self, ipfsop, path, identityUid=None): + return await self.cat(os.path.join( + 'identities', + identityUid if identityUid else self.root['currentIdentityUid'], + path) + ) + @ipfsOp async def getAvatar(self, ipfsop): return await self.get('avatar') diff --git a/galacteek/core/userdag.py b/galacteek/core/userdag.py index 4a03b9dc..4970c889 100644 --- a/galacteek/core/userdag.py +++ b/galacteek/core/userdag.py @@ -108,7 +108,7 @@ def ipnsKey(self): @property def siteUrl(self): - return self.sitePath.dwebUrl + return self.sitePath.ipfsUrl @property def sitePath(self): @@ -274,7 +274,7 @@ def createFeed(self): feed.author({ 'name': self.profile.userInfo.iphandle }) - feed.link(href=self.atomFeedPath.dwebUrl, rel='self') + feed.link(href=self.atomFeedPath.ipfsUrl, rel='self') feed.language('en') return feed @@ -409,8 +409,8 @@ def feedAddPinRequests(self, requests, feed): fEntry = feed.add_entry() fEntry.title('Pin request: {}'.format(req['title'])) - fEntry.id(rpath.dwebUrl) - fEntry.link(href=rpath.dwebUrl, rel='alternate') + fEntry.id(rpath.ipfsUrl) + fEntry.link(href=rpath.ipfsUrl, rel='alternate') fEntry.published(req['date_published']) fEntry.author({'name': self.profile.userInfo.iphandle}) @@ -421,8 +421,8 @@ def feedAddPosts(self, blogPosts, feed): fEntry = feed.add_entry() fEntry.title(post['title']) - fEntry.id(ppath.dwebUrl) - fEntry.link(href=ppath.dwebUrl, rel='alternate') + fEntry.id(ppath.ipfsUrl) + fEntry.link(href=ppath.ipfsUrl, rel='alternate') fEntry.updated(post['date_modified']) fEntry.published(post['date_published']) fEntry.author({'name': self.profile.userInfo.iphandle}) @@ -439,7 +439,7 @@ async def tmplRender(self, tmpl, contained=False, **kw): profile=self.profile, dag=self.edag.dagRoot, siteIpns=self.ipnsKey, - atomFeedrUrl=self.atomFeedPath.dwebUrl, + atomFeedrUrl=self.atomFeedPath.ipfsUrl, **kw) async def renderLink(self, tmpl, contained=False, **kw): diff --git a/galacteek/core/webprofiles.py b/galacteek/core/webprofiles.py index 059785d7..8e86a4ff 100644 --- a/galacteek/core/webprofiles.py +++ b/galacteek/core/webprofiles.py @@ -8,7 +8,6 @@ from galacteek.dweb.webscripts import ethereumClientScripts from galacteek.core.schemes import SCHEME_DWEB -from galacteek.core.schemes import SCHEME_DWEBGW from galacteek.core.schemes import SCHEME_ENS from galacteek.core.schemes import SCHEME_ENSR from galacteek.core.schemes import SCHEME_FS @@ -64,8 +63,6 @@ def installIpfsSchemeHandlers(self): for scheme in [SCHEME_DWEB, SCHEME_FS]: self.installHandler(scheme, self.app.dwebSchemeHandler) - self.installHandler(SCHEME_DWEBGW, self.app.dwebGwSchemeHandler) - for scheme in [SCHEME_IPFS, SCHEME_IPNS]: self.installHandler(scheme, self.app.nativeIpfsSchemeHandler) diff --git a/galacteek/database/models/core.py b/galacteek/database/models/core.py index d476b92b..b44b3112 100644 --- a/galacteek/database/models/core.py +++ b/galacteek/database/models/core.py @@ -121,7 +121,8 @@ def preferredUrl(self): iPath = IPFSPath(self.path, autoCidConv=True) if self.schemepreferred == 'dweb': return iPath.dwebUrl - elif not self.schemepreferred or self.schemepreferred == 'ipfs': + elif not self.schemepreferred or self.schemepreferred in \ + ['ipfs', 'ipns']: return iPath.ipfsUrl else: return self.url diff --git a/galacteek/guientrypoint.py b/galacteek/guientrypoint.py index 053268b5..b0ccf513 100644 --- a/galacteek/guientrypoint.py +++ b/galacteek/guientrypoint.py @@ -131,6 +131,7 @@ def start(): '--migrate', action='store_true', dest='migrate', + default=True, help='Activate automatic repository migration') parser.add_argument( '--no-release-check', diff --git a/galacteek/hashmarks/default/hashmarks.ipfs.yaml b/galacteek/hashmarks/default/hashmarks.ipfs.yaml index a6794e89..da09b438 100644 --- a/galacteek/hashmarks/default/hashmarks.ipfs.yaml +++ b/galacteek/hashmarks/default/hashmarks.ipfs.yaml @@ -54,7 +54,7 @@ hashmarks: description: Hardbin is an encrypted pastebin for IPFS category: ipfs/apps icon: /ipfs/QmQZ1PLTZKekXbcLErY2bSnHiqB9vXxkLtPtbqhEPbDHgg - schemepreferred: dwebgw + schemepreferred: dweb tags: - '#pastebin' - '#dapp' @@ -75,7 +75,7 @@ hashmarks: date: "2019-07-04T12:00:00-00:00" category: ipfs/apps icon: /ipfs/bafybeihbmylhr5aplden7ijet4m6izxn6svq27eykqyiq5tik6mjxsoxjy/mstile-144x144.png - schemepreferred: dwebgw + schemepreferred: dweb tags: - '#ipfs' - '#essays' diff --git a/galacteek/ipfs/cidhelpers.py b/galacteek/ipfs/cidhelpers.py index 5e74eeea..b77d0c93 100644 --- a/galacteek/ipfs/cidhelpers.py +++ b/galacteek/ipfs/cidhelpers.py @@ -6,6 +6,7 @@ from PyQt5.QtCore import QUrl from galacteek import log +from galacteek.ipfs.cid import CIDv1 from galacteek.ipfs.cid import make_cid from galacteek.ipfs.cid import BaseCID from galacteek.ipfs.stat import StatInfo @@ -167,6 +168,21 @@ def cidConvertBase32(cid): return cid.encode('base32').decode() +def ipnsKeyCidV1(ipnsKey): + """ + Converts a base58 IPNS key to a CIDv1 with the + 'libp2p-key' multicodec. + """ + + cid = getCID(ipnsKey) + if not cid: + return None + + # Need to use the libp2p-key multicodec + cidV1 = CIDv1('libp2p-key', cid.multihash) + return cidV1.encode('base32').decode() + + def cidValid(cid): """ Check if the passed argument is a valid IPFS CID @@ -209,6 +225,10 @@ def domainValid(domain): r'^(\s*)?(?:fs:|dweb:|dwebgw:|https?://[\w:.-]+)?(?P(/ipfs/)?(?P[a-zA-Z0-9]{46,113})/?(?P[\w<>":;,?!\*%&=@\$~/\s\.\-_\\\'()\+]{1,1024})?)#?(?P[\w_\.\-\+,=/]{1,256})?$', # noqa flags=re.UNICODE) +ipfsDomainPathRe = re.compile( + r'^(\s*)?(?:http)://(?P[a-z2-7]{59,113})\.ipfs\.(?:[\w]+):(?:[\d]+)/(?P[\w<>"\/:;,?!\*%&=@\$~/\s\.\-_\\\'()\+]{0,1024})#?(?P[\w_\.\-\+,=/]{1,256})?$', # noqa + flags=re.UNICODE) + # For ipfs:// ipfsPathDedRe = re.compile( r'^(\s*)?(?:ipfs://)(?P(?P[a-z2-7]{59,113})/?(?P[\w<>"*:;,?!%&=@\$~/\s\.\-_\\\'\+()]{1,1024})?)#?(?P[\w_\+\.\-,=/]{1,256})?$', # noqa @@ -393,7 +413,10 @@ def ipfsUrl(self): path=stripIpns(self.fullPath) ) else: - return self.dwebUrl + return '{scheme}://{path}'.format( + scheme=self.scheme, + path=stripIpns(self.fullPath) + ) else: return self.dwebUrl @@ -416,6 +439,28 @@ def __analyze(self): if len(self.input) > self.maxLength: return False + ma = ipfsRegSearchDomainPath(self.input) + if ma: + gdict = ma.groupdict() + cidStr = gdict.get('rootcid') + subpath = gdict.get('subpath') + + if not self.parseCid(cidStr): + return False + + if subpath: + self._rscPath = os.path.join( + joinIpfs(cidStr), + subpath + ) + else: + self._rscPath = joinIpfs(self.rootCidRepr) + '/' + + self._subPath = subpath + self._scheme = 'ipfs' + self._fragment = gdict.get('fragment') + return True + ma = ipfsDedSearchPath(self.input) if ma: gdict = ma.groupdict() @@ -472,15 +517,18 @@ def __analyze(self): gdict = ma.groupdict() subpath = gdict.get('subpath') + ipnsId32 = ipnsKeyCidV1(gdict.get('fqdn')) + _id = ipnsId32 if ipnsId32 else gdict.get('fqdn') + if subpath: self._rscPath = os.path.join( - joinIpns(gdict.get('fqdn')), + joinIpns(_id), subpath ) else: - self._rscPath = joinIpns(gdict.get('fqdn')) + self._rscPath = joinIpns(_id) - self._ipnsId = gdict.get('fqdn') + self._ipnsId = _id self._fragment = gdict.get('fragment') self._subPath = gdict.get('subpath') self._scheme = 'ipns' @@ -624,6 +672,10 @@ def ipfsDedSearchPath(text): return ipfsPathDedRe.match(text) +def ipfsRegSearchDomainPath(text): + return ipfsDomainPathRe.match(text) + + def ipfsDedSearchPath58(text): # Like ipfsDedSearchPath() but allows any type of CID (including # CIDv0) as root CID. Only used to be able to extract the root CID diff --git a/galacteek/ipfs/distipfsfetch.py b/galacteek/ipfs/distipfsfetch.py index e31c0298..86231241 100644 --- a/galacteek/ipfs/distipfsfetch.py +++ b/galacteek/ipfs/distipfsfetch.py @@ -15,7 +15,7 @@ @async_generator async def distIpfsExtract(dstdir='.', software='go-ipfs', executable='ipfs', - site='dist.ipfs.io', version='0.4.23', loop=None, + site='dist.ipfs.io', version='0.5.0', loop=None, sslverify=True): """ Fetch a distribution archive from dist.ipfs.io and extracts the @@ -79,14 +79,21 @@ def statusMessage(code, msg): return False else: await yield_(statusMessage(0, 'File found!')) + + csize = 524288 + ccount = 0 while True: - data = await resp.content.read(262144) + data = await resp.content.read(csize) if not data: break + + ccount += 1 await fd.write(data) bytesRead += len(data) - await yield_(statusMessage( - 0, 'received {} bytes'.format(bytesRead))) + + if divmod(ccount, 32)[1] == 0: + await yield_(statusMessage( + 0, 'received {} bytes'.format(bytesRead))) await asyncio.sleep(0) def extract(path, dest): diff --git a/galacteek/ipfs/ipfsops.py b/galacteek/ipfs/ipfsops.py index 8645a16b..ff9a76d9 100644 --- a/galacteek/ipfs/ipfsops.py +++ b/galacteek/ipfs/ipfsops.py @@ -188,11 +188,13 @@ class IPFSOperator(object): """ def __init__(self, client, ctx=None, rsaAgent=None, debug=False, - offline=False, nsCachePath=None): + offline=False, nsCachePath=None, + objectMapping=False): self._lock = asyncio.Lock() self._id = uuid.uuid1() self._cache = {} self._offline = offline + self._objectMapping = objectMapping self._rsaAgent = rsaAgent self._nsCache = {} self._nsCachePath = nsCachePath @@ -529,7 +531,7 @@ async def keysRemove(self, name): return False return True - async def publish(self, path, key='self', timeout=60 * 4, + async def publish(self, path, key='self', timeout=60 * 6, allow_offline=None, lifetime='24h', resolve=True, ttl=None, cache=None, cacheOrigin='unknown'): @@ -1067,6 +1069,10 @@ def ipld(self, cid): return {"/": cid['Hash']} def objectPathMap(self, path): + if self._objectMapping is False and 0: + # No object mapping (don't use any cache) + return path + ipfsPath = path if isinstance(path, IPFSPath) else \ IPFSPath(path, autoCidConv=True) diff --git a/galacteek/ui/browser.py b/galacteek/ui/browser.py index cf5830d5..3c1acf22 100644 --- a/galacteek/ui/browser.py +++ b/galacteek/ui/browser.py @@ -1342,6 +1342,10 @@ def pinAll(self): def currentIpfsObject(self): return self._currentIpfsObject + def fromGateway(self, authority): + return authority.endswith(self.gatewayAuthority) or \ + authority.endswith('ipfs.' + self.gatewayAuthority) + def createPageOpsButton(self): icon = getMimeIcon('text/html') iconPrinter = getIcon('printer.png') @@ -1383,7 +1387,7 @@ def onMoveToMfsMenuTriggered(self, action): cTitle = self.currentPageTitle if self.currentPageTitle else '' - ensure(runDialogASync( + ensure(runDialogAsync( TitleInputDialog, cTitle, accepted=functools.partial( self.onMoveToMfsWithTitle, @@ -1866,6 +1870,8 @@ async def onUrlChanged(self, url): sHandler = self.webEngineView.webProfile.urlSchemeHandler( url.scheme().encode()) + urlAuthority = url.authority() + if url.scheme() in [SCHEME_IPFS, SCHEME_IPNS, SCHEME_DWEB]: self.urlZone.setStyleSheet(''' QLineEdit { @@ -1883,20 +1889,22 @@ async def onUrlChanged(self, url): self.followIpnsAction.setEnabled( self.currentIpfsObject.isIpns) self.curObjectCtrl.show() - elif url.authority() == self.gatewayAuthority: + elif self.fromGateway(urlAuthority): # dweb:/ with IPFS gateway's authority # Content loaded from IPFS gateway, this is IPFS content - urlString = url.toDisplayString( - QUrl.RemoveAuthority | QUrl.RemoveScheme) + if 0: + urlString = url.toDisplayString( + QUrl.RemoveAuthority | QUrl.RemoveScheme) - self._currentIpfsObject = IPFSPath(urlString) + self._currentIpfsObject = IPFSPath( + url.toString(), autoCidConv=True) if self.currentIpfsObject.valid: log.debug('Current IPFS object: {0}'.format( repr(self.currentIpfsObject))) - url = QUrl(self.currentIpfsObject.dwebGwUrl) + url = QUrl(self.currentIpfsObject.dwebUrl) self.urlZone.clear() self.urlZone.insert(url.toString()) @@ -1996,7 +2004,7 @@ def onLoadProgress(self, progress): def browseFsPath(self, path, schemePreferred='ipfs'): def _handle(iPath): if iPath.valid and not schemePreferred or \ - schemePreferred == 'ipfs': + schemePreferred in [SCHEME_IPFS, SCHEME_IPNS]: self.enterUrl(QUrl(iPath.ipfsUrl)) elif iPath.valid and schemePreferred == 'dweb': self.enterUrl(QUrl(iPath.dwebUrl)) diff --git a/galacteek/ui/iprofile.py b/galacteek/ui/iprofile.py index e70c2b36..309eb25f 100644 --- a/galacteek/ui/iprofile.py +++ b/galacteek/ui/iprofile.py @@ -16,7 +16,6 @@ from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QImage -from galacteek import asyncify from galacteek import ensure from galacteek import log from galacteek.ipfs.wrappers import ipfsOp @@ -252,18 +251,17 @@ def loadPlanets(self, planetsList=None): self.ui.vPlanet.setEnabled(False) - @asyncify async def loadIcon(self): - avatar = await self.profile.userInfo.identityDagGet('avatar') + avatar = await self.profile.userInfo.identityGetRaw('avatar') if isinstance(avatar, bytes): try: img1 = QImage() img1.loadFromData(avatar) - img = img1.scaledToWidth(256) + img = img1.scaledToWidth(128) self.ui.iconPixmap.setPixmap(QPixmap.fromImage(img)) - except Exception: - pass + except Exception as err: + log.debug(str(err)) def changeIcon(self): fps = filesSelectImages() diff --git a/galacteek/ui/peers.py b/galacteek/ui/peers.py index 68a40c73..080175b7 100644 --- a/galacteek/ui/peers.py +++ b/galacteek/ui/peers.py @@ -658,7 +658,7 @@ async def followPeerFeed(self, op, peerCtx): ipfsPath = IPFSPath(path) try: - await self.app.sqliteDb.feeds.follow(ipfsPath.dwebUrl) + await self.app.sqliteDb.feeds.follow(ipfsPath.ipfsUrl) except Exception: # TODO pass diff --git a/galacteek/ui/pyramids.py b/galacteek/ui/pyramids.py index ffbf4c1b..3442b746 100644 --- a/galacteek/ui/pyramids.py +++ b/galacteek/ui/pyramids.py @@ -26,6 +26,7 @@ from galacteek.ipfs.cidhelpers import IPFSPath from galacteek.ipfs.cidhelpers import joinIpns +from galacteek.ipfs.cidhelpers import ipnsKeyCidV1 from galacteek.ipfs import ipfsOp from galacteek.ipfs.stat import StatInfo from galacteek.ipfs.dag import EvolvingDAG @@ -55,6 +56,7 @@ from .i18n import iRemove from .i18n import iHelp from .i18n import iHashmark +from .i18n import iOpen def iCreateRawPyramid(): @@ -368,6 +370,10 @@ def __init__(self, pyramid, icon=None, parent=None): self, triggered=self.onOpenLatest) self.openLatestAction.setEnabled(False) + self.openAction = QAction(getIcon('pyramid-aqua.png'), + iOpen(), + self, + triggered=self.onOpen) self.publishCurrentClipAction = QAction( getIcon('clipboard.png'), @@ -496,6 +502,8 @@ def createExtraActions(self): pass def buildMenu(self): + self.menu.addAction(self.openAction) + self.menu.addSeparator() self.menu.addAction(self.openLatestAction) self.menu.addSeparator() self.menu.addAction(self.publishCurrentClipAction) @@ -557,6 +565,7 @@ def updateToolTip(self):

Description: {descr}

IPNS key: {ipns}

+

IPNS key (CIDv1): {ipnsv1}

Description: {descr}

IPNS key: {ipns}

+

IPNS key (CIDv1): {ipnsv1}

=2.0.0 aiofiles>=0.4.0 aiohttp>=3.4.4 -aioipfs>=0.4.4 +aioipfs>=0.4.5 aiojobs>=0.2.2 aiosqlite>=0.10.0 async-generator>=1.10 @@ -20,7 +20,7 @@ multiaddr>=0.0.8 pillow>=6.0.0 protobuf>=3.6.1 py-multibase==1.0.1 -py-multicodec==0.1.3 +py-multicodec==0.2.1 py-multihash>=0.2.3 pycryptodomex>=3.6.6 pygments>=2.3.1 diff --git a/travis/install.sh b/travis/install.sh index 532b7cb4..e40c7804 100644 --- a/travis/install.sh +++ b/travis/install.sh @@ -17,8 +17,8 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then wget https://dist.ipfs.io/go-ipfs/v${GO_IPFS_VERSION}/go-ipfs_v${GO_IPFS_VERSION}_linux-amd64.tar.gz tar -C $HOME -xzvf go-ipfs_v${GO_IPFS_VERSION}_linux-amd64.tar.gz - #wget https://dist.ipfs.io/fs-repo-migrations/v${FS_MIGRATE_VERSION}/fs-repo-migrations_v${FS_MIGRATE_VERSION}_linux-amd64.tar.gz - #tar -C $HOME -xzvf fs-repo-migrations_v${FS_MIGRATE_VERSION}_linux-amd64.tar.gz + wget https://dist.ipfs.io/fs-repo-migrations/v${FS_MIGRATE_VERSION}/fs-repo-migrations_v${FS_MIGRATE_VERSION}_linux-amd64.tar.gz + tar -C $HOME -xzvf fs-repo-migrations_v${FS_MIGRATE_VERSION}_linux-amd64.tar.gz wget https://github.com/wasmerio/wasmer/releases/download/0.12.0/wasmer-linux-amd64.tar.gz tar -C $HOME -xzvf wasmer-linux-amd64.tar.gz @@ -34,11 +34,13 @@ if [ "$TRAVIS_OS_NAME" = "osx" ]; then wget https://dist.ipfs.io/go-ipfs/v${GO_IPFS_VERSION}/go-ipfs_v${GO_IPFS_VERSION}_darwin-amd64.tar.gz tar -C $HOME -xzvf go-ipfs_v${GO_IPFS_VERSION}_darwin-amd64.tar.gz - #wget https://dist.ipfs.io/fs-repo-migrations/v${FS_MIGRATE_VERSION}/fs-repo-migrations_v${FS_MIGRATE_VERSION}_darwin-amd64.tar.gz - #tar -C $HOME -xzvf fs-repo-migrations_v${FS_MIGRATE_VERSION}_darwin-amd64.tar.gz + wget https://dist.ipfs.io/fs-repo-migrations/v${FS_MIGRATE_VERSION}/fs-repo-migrations_v${FS_MIGRATE_VERSION}_darwin-amd64.tar.gz + tar -C $HOME -xzvf fs-repo-migrations_v${FS_MIGRATE_VERSION}_darwin-amd64.tar.gz fi mv $HOME/go-ipfs/ipfs $HOME/bin +mv $HOME/fs-repo-migrations/fs-repo-migrations $HOME/bin + $HOME/bin/ipfs init export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.7/dist-packages