aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2019-01-26 15:02:43 -1000
committercel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2019-01-28 19:55:19 -1000
commitf002fac331c79baff7fde57899d76be0410ffe10 (patch)
tree1bed964873e117277843101c5dfaf57aca2a889d
parent05865706da36f4f3f7c2d03df4065ffdd9911a69 (diff)
downloadpatchfoo-f002fac331c79baff7fde57899d76be0410ffe10.tar.gz
patchfoo-f002fac331c79baff7fde57899d76be0410ffe10.zip
Add /script route
-rw-r--r--README.md6
-rw-r--r--lib/app.js24
-rw-r--r--lib/serve.js18
3 files changed, 47 insertions, 1 deletions
diff --git a/README.md b/README.md
index 23a40d5..9b2d27a 100644
--- a/README.md
+++ b/README.md
@@ -101,7 +101,9 @@ To make config options persistent, set them in `~/.ssb/config`, e.g.:
"emojis",
"self",
"searchbox"
- ]
+ ],
+ "dir": "patchfoo",
+ "scriptDir": "script"
}
}
```
@@ -123,6 +125,8 @@ To make config options persistent, set them in `~/.ssb/config`, e.g.:
- `ooo`: if true, use `ssb-ooo` to try to fetch missing messages in threads. also can set per-request with query string `?ooo=1`. default: `false`
`codeInTextareas`: if `true`, render markdown code blocks in textareas. if `false`, render them in `pre` tags. default: `false`
- `nav`: array of nav links. Each item may be a string, object or special value. Special values are `"searchbox"` and `"self"`, which are the search field box, and link to the current feed id's page, respectively. Any other string is interpretted to be a link to the page of that name prefixed with a forward slash. An object may have properties `name` and `url`, and that will be interpretted as a link with given name and URL (with `toUrl` conversions applied). default is the list in the readme above.
+- `dir`: name of directory in `~/.ssb/` to use for patchfoo things. default: `"patchfoo"`.
+- `scriptDir: name of directory in patchfoo's directory (as set by `patchfoo.dir` config option above) to use for user scripts. default: `"script"`.
## TODO
diff --git a/lib/app.js b/lib/app.js
index e0b4417..0b7784c 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -42,6 +42,8 @@ function App(sbot, config) {
var host1 = /:/.test(this.host) ? '[' + this.host + ']' : this.host
this.baseUrl = 'http://' + host1 + ':' + this.port
+ this.dir = path.join(config.path, conf.dir || 'patchfoo')
+ this.scriptDir = path.join(this.dir, conf.scriptDir || 'script')
var base = conf.base || '/'
this.opts = {
@@ -78,6 +80,9 @@ function App(sbot, config) {
this.about = new About(this, sbot.id, this.follows)
this.serveSsbNpmRegistry = SsbNpmRegistry.respond(this.sbot, this.config)
+ this.mtimes = {}
+ this.getScript = memo({cache: false}, this.getScript)
+
this.monitorBlobWants()
this.navLinks = conf.nav || [
'new',
@@ -1246,3 +1251,22 @@ App.prototype.verifyGitObjectSignature = function (obj, cb) {
})
}
}
+
+App.prototype.getScript = function (filepath, cb) {
+ var filename = path.join(this.scriptDir, filepath)
+ var self = this
+ fs.stat(filename, function (err, stat) {
+ if (err) return cb(err)
+ var resolved = require.resolve(filename)
+ var prevMtime = self.mtimes[resolved]
+ var mtime = stat.mtime.getTime()
+ if (mtime !== prevMtime) {
+ delete require.cache[resolved]
+ self.mtimes[filename] = mtime
+ }
+ var module
+ try { module = require(resolved) }
+ catch(e) { return cb(e) }
+ cb(null, module)
+ })
+}
diff --git a/lib/serve.js b/lib/serve.js
index e3901a0..30b529b 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -390,6 +390,7 @@ Serve.prototype.path = function (url) {
case '/shard': return this.shard(m[2])
case '/zip': return this.zip(m[2])
case '/web': return this.web(m[2])
+ case '/script': return this.script(m[2])
}
return this.respond(404, 'Not found')
}
@@ -3043,6 +3044,23 @@ Serve.prototype.web = function (url) {
})
}
+Serve.prototype.script = function (url) {
+ var self = this
+ var filepath = url.split('?')[0]
+ this.app.getScript(filepath, function (err, fn) {
+ try {
+ if (err) throw err
+ fn(self)
+ } catch(e) {
+ return pull(
+ pull.once(u.renderError(e).outerHTML),
+ self.wrapPage('local: ' + path),
+ self.respondSink(400)
+ )
+ }
+ })
+}
+
// wrap a binary source and render it or turn into an embed
Serve.prototype.wrapBinary = function (opts) {
var self = this