Merge pull request #925 from ethereum/extendFileprovider

Extend file providers
pull/3094/head
yann300 7 years ago committed by GitHub
commit 70fba49da8
  1. 12
      src/app.js
  2. 18
      src/app/compiler/compiler-imports.js
  3. 11
      src/app/contract/publishOnSwarm.js
  4. 102
      src/app/files/basicReadOnlyExplorer.js
  5. 3
      src/app/files/file-explorer.js
  6. 21
      src/app/panels/file-panel.js
  7. 3
      src/app/tabs/compile-tab.js
  8. 8
      src/config.js

@ -36,6 +36,7 @@ var handleImports = require('./app/compiler/compiler-imports')
var FileManager = require('./app/files/fileManager')
var ContextualListener = require('./app/editor/contextualListener')
var ContextView = require('./app/editor/contextView')
var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer')
var styleGuide = remixLib.ui.styleGuide
var styles = styleGuide()
@ -111,6 +112,10 @@ class App {
self._api.filesProviders = {}
self._api.filesProviders['browser'] = new Browserfiles(fileStorage)
self._api.filesProviders['localhost'] = new SharedFolder(new Remixd())
self._api.filesProviders['swarm'] = new BasicReadOnlyExplorer('swarm')
self._api.filesProviders['github'] = new BasicReadOnlyExplorer('github')
self._api.filesProviders['gist'] = new BasicReadOnlyExplorer('gist')
self._api.filesProviders['ipfs'] = new BasicReadOnlyExplorer('ipfs')
self._view = {}
self._components = {}
self.data = {
@ -195,10 +200,10 @@ function run () {
if (provider && provider.exists(url)) {
return provider.get(url, cb)
}
handleImports.import(url, (error, content) => {
handleImports.import(url, (error, content, cleanUrl, type) => {
if (!error) {
// FIXME: at some point we should invalidate the browser cache
filesProviders['browser'].addReadOnly(url, content)
filesProviders[type].addReadOnly(cleanUrl, content)
cb(null, content)
} else {
cb(error)
@ -548,6 +553,9 @@ function run () {
fileProviderOf: (path) => {
return fileManager.fileProviderOf(path)
},
fileProvider: (name) => {
return self._api.filesProviders[name]
},
getBalance: (address, callback) => {
udapp.getBalance(address, (error, balance) => {
if (error) {

@ -8,7 +8,7 @@ module.exports = {
return $.getJSON('https://api.github.com/repos/' + root + '/contents/' + path)
.done(function (data) {
if ('content' in data) {
cb(null, base64.decode(data.content))
cb(null, base64.decode(data.content), root + '/' + path)
} else {
cb('Content not received')
}
@ -21,7 +21,7 @@ module.exports = {
handleSwarmImport: function (url, cb) {
swarmgw.get(url, function (err, content) {
cb(err, content)
cb(err, content, url)
})
},
@ -31,7 +31,7 @@ module.exports = {
return $.ajax({ type: 'GET', url: 'https://gateway.ipfs.io/' + url })
.done(function (data) {
cb(null, data)
cb(null, data, url)
})
.fail(function (xhr, text, err) {
// NOTE: on some browsers, err equals to '' for certain errors (such as offline browser)
@ -41,9 +41,9 @@ module.exports = {
import: function (url, cb) {
var handlers = [
{ match: /^(https?:\/\/)?(www.)?github.com\/([^/]*\/[^/]*)\/(.*)/, handler: (match, cb) => { this.handleGithubCall(match[3], match[4], cb) } },
{ match: /^(bzz[ri]?:\/\/?.*)$/, handler: (match, cb) => { this.handleSwarmImport(match[1], cb) } },
{ match: /^(ipfs:\/\/?.+)/, handler: (match, cb) => { this.handleIPFS(match[1], cb) } }
{ type: 'github', match: /^(https?:\/\/)?(www.)?github.com\/([^/]*\/[^/]*)\/(.*)/, handler: (match, cb) => { this.handleGithubCall(match[3], match[4], cb) } },
{ type: 'swarm', match: /^(bzz[ri]?:\/\/?.*)$/, handler: (match, cb) => { this.handleSwarmImport(match[1], cb) } },
{ type: 'ipfs', match: /^(ipfs:\/\/?.+)/, handler: (match, cb) => { this.handleIPFS(match[1], cb) } }
]
var found = false
@ -57,13 +57,13 @@ module.exports = {
found = true
$('#output').append($('<div/>').append($('<pre/>').text('Loading ' + url + ' ...')))
handler.handler(match, function (err, content) {
handler.handler(match, function (err, content, cleanUrl) {
if (err) {
cb('Unable to import "' + url + '": ' + err)
cb('Unable to import "' + cleanUrl + '": ' + err)
return
}
cb(null, content)
cb(null, content, cleanUrl, handler.type)
})
}
})

@ -3,10 +3,14 @@
var async = require('async')
var swarmgw = require('swarmgw')
module.exports = (contract, appAPI, cb) => {
module.exports = (contract, appAPI, cb, swarmVerifiedPublishCallBack) => {
// gather list of files to publish
var sources = []
try {
contract.metadata = JSON.stringify(JSON.parse(contract.metadata), null, '\t')
} catch (e) {}
sources.push({
content: contract.metadata,
hash: contract.metadataHash
@ -49,7 +53,10 @@ module.exports = (contract, appAPI, cb) => {
} else {
// publish the list of sources in order, fail if any failed
async.eachSeries(sources, function (item, cb) {
swarmVerifiedPublish(item.content, item.hash, cb)
swarmVerifiedPublish(item.content, item.hash, (error) => {
if (!error && swarmVerifiedPublishCallBack) swarmVerifiedPublishCallBack(item)
cb(error)
})
}, cb)
}
})

@ -0,0 +1,102 @@
'use strict'
var EventManager = require('remix-lib').EventManager
class SwarmExplorer {
constructor (type) {
this.event = new EventManager()
this.files = {}
this.type = type
}
close (cb) {
this.files = {}
cb()
}
init (cb) {
this.files = {}
}
exists (path) {
if (!this.files) return false
return this.files[path] !== undefined
}
get (path, cb) {
var content = this.files[path]
if (cb) {
cb(null, content)
}
return content
}
set (path, content, cb) {
return true
}
addReadOnly (path, content) {
this.files[this.type + '/' + path] = content
this.event.trigger('fileAdded', [this.type + '/' + path, true])
return true
}
isReadOnly (path) {
return true
}
remove (path) {
delete this.files[path]
}
rename (oldPath, newPath, isFolder) {
return true
}
list () {
return this.files
}
//
// Tree model for files
// {
// 'a': { }, // empty directory 'a'
// 'b': {
// 'c': {}, // empty directory 'b/c'
// 'd': { '/readonly': true, '/content': 'Hello World' } // files 'b/c/d'
// 'e': { '/readonly': false, '/path': 'b/c/d' } // symlink to 'b/c/d'
// 'f': { '/readonly': false, '/content': '<executable>', '/mode': 0755 }
// }
// }
//
listAsTree () {
function hashmapize (obj, path, val) {
var nodes = path.split('/')
var i = 0
for (; i < nodes.length - 1; i++) {
var node = nodes[i]
if (obj[node] === undefined) {
obj[node] = {}
}
obj = obj[node]
}
obj[nodes[i]] = val
}
var tree = {}
var self = this
// This does not include '.remix.config', because it is filtered
// inside list().
Object.keys(this.list()).forEach(function (path) {
hashmapize(tree, path, {
'/readonly': self.isReadOnly(path),
'/content': self.get(path)
})
})
return tree
}
}
module.exports = SwarmExplorer

@ -410,9 +410,6 @@ function expandPathTo (li) {
fileExplorer.prototype.init = function () {
var files = this.files.listAsTree()
if (!Object.keys(files).length) {
files[this.files.type] = {} // default
}
var element = this.treeView.render(files)
element.className = css.fileexplorer
element.events = this.events

@ -128,6 +128,10 @@ function filepanel (appAPI, filesProvider) {
var self = this
var fileExplorer = new FileExplorer(appAPI, filesProvider['browser'])
var fileSystemExplorer = new FileExplorer(appAPI, filesProvider['localhost'])
var swarmExplorer = new FileExplorer(appAPI, filesProvider['swarm'])
var githubExplorer = new FileExplorer(appAPI, filesProvider['github'])
var gistExplorer = new FileExplorer(appAPI, filesProvider['gist'])
var dragbar = yo`<div onmousedown=${mousedown} class=${css.dragbar}></div>`
function remixdDialog () {
@ -174,6 +178,9 @@ function filepanel (appAPI, filesProvider) {
<div class=${css.treeviews}>
<div class=${css.treeview}>${fileExplorer.init()}</div>
<div class="filesystemexplorer ${css.treeview}"></div>
<div class="swarmexplorer ${css.treeview}">${swarmExplorer.init()}</div>
<div class="githubexplorer ${css.treeview}">${githubExplorer.init()}</div>
<div class="gistexplorer ${css.treeview}">${gistExplorer.init()}</div>
</div>
</div>
${dragbar}
@ -221,6 +228,18 @@ function filepanel (appAPI, filesProvider) {
appAPI.switchFile(path)
})
swarmExplorer.events.register('focus', function (path) {
appAPI.switchFile(path)
})
githubExplorer.events.register('focus', function (path) {
appAPI.switchFile(path)
})
gistExplorer.events.register('focus', function (path) {
appAPI.switchFile(path)
})
self.render = function render () { return element }
function uploadFile (event) {
@ -326,7 +345,7 @@ function filepanel (appAPI, filesProvider) {
}
function toGist () {
packageFiles(filesProvider['browser'], (error, packaged) => {
packageFiles(filesProvider['gist'], (error, packaged) => {
if (error) {
console.log(error)
} else {

@ -436,6 +436,9 @@ function compileTab (container, appAPI, appEvents, opts) {
} else {
modalDialogCustom.alert(yo`<span>Metadata published successfully.<br />The Swarm address of the metadata file is available in the contract details.</span>`)
}
}, function (item) {
// triggered each time there's a new verified publish (means hash correspond)
appAPI.fileProvider('swarm').addReadOnly(item.hash, item.content)
})
}
}

@ -33,7 +33,13 @@ function Config (storage) {
this.ensureStorageUpdated = function (key) {
if (key === 'currentFile') {
if (this.items[key] && this.items[key] !== '' && this.items[key].indexOf('browser/') !== 0 && this.items[key].indexOf('localhost/') !== 0) {
if (this.items[key] && this.items[key] !== '' &&
this.items[key].indexOf('browser/') !== 0 &&
this.items[key].indexOf('localhost/') !== 0 &&
this.items[key].indexOf('swarm/') !== 0 &&
this.items[key].indexOf('gist/') !== 0 &&
this.items[key].indexOf('github/') !== 0 &&
this.items[key].indexOf('ipfs/') !== 0) {
this.items[key] = 'browser/' + this.items[key]
}
}

Loading…
Cancel
Save