aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcel <cel@lOUVT+Phkvai9a/cCS/RKo+S9hnPAQdVixms/7ldpPA=.ed25519>2020-06-26 07:23:22 -0400
committercel <cel@lOUVT+Phkvai9a/cCS/RKo+S9hnPAQdVixms/7ldpPA=.ed25519>2020-06-26 07:23:22 -0400
commit4e6e5fcf95f5b07e6d6017ab14f755a34c03e12e (patch)
tree8c696fdd53678018e4abc893652240c13238bba4
parentdba98ce1cf2df6aaa92315ee830b45ae5e414cb0 (diff)
downloadpatchfoo-4e6e5fcf95f5b07e6d6017ab14f755a34c03e12e.tar.gz
patchfoo-4e6e5fcf95f5b07e6d6017ab14f755a34c03e12e.zip
Allow subdirectories in drafts
-rw-r--r--lib/app.js12
-rw-r--r--lib/serve.js53
2 files changed, 50 insertions, 15 deletions
diff --git a/lib/app.js b/lib/app.js
index 814bfb6..15aa796 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -1572,7 +1572,6 @@ App.prototype.saveDraft = function (id, url, form, content, cb) {
mkdirp.sync(self.draftsDir)
self.madeDraftsDir = true
}
- if (/[\/:\\]/.test(id)) return cb(new Error('draft id cannot contain path seperators'))
var draft = {
url: url,
form: form,
@@ -1587,6 +1586,7 @@ App.prototype.getDraft = function (id, cb) {
var self = this
var filename = path.join(self.draftsDir, id)
fs.readFile(filename, 'utf8', function (err, data) {
+ if (err && err.code === 'EISDIR') return cb(null, {id: id, isDir: true})
if (err) return cb(err)
var draft
try { draft = JSON.parse(data) }
@@ -1621,19 +1621,21 @@ function statAll(files, dir, cb) {
)
}
-App.prototype.listDrafts = function () {
+App.prototype.listDrafts = function (dir) {
var self = this
+ var draftsDir = dir ? path.join(self.draftsDir, dir) : self.draftsDir
return u.readNext(function (cb) {
- fs.readdir(self.draftsDir, function (err, files) {
+ fs.readdir(draftsDir, function (err, files) {
if (err && err.code === 'ENOENT') return cb(null, pull.empty())
if (err) return cb(err)
- statAll(files, self.draftsDir, function (err, stats) {
+ statAll(files, draftsDir, function (err, stats) {
if (err) return cb(err)
stats.sort(compareMtime)
cb(null, pull(
pull.values(stats),
paramap(function (stat, cb) {
- self.getDraft(stat.name, cb)
+ var name = dir ? path.join(dir, stat.name) : stat.name
+ self.getDraft(name, cb)
}, 4)
))
})
diff --git a/lib/serve.js b/lib/serve.js
index c7065bc..397a148 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -1781,7 +1781,7 @@ Serve.prototype.block = function (path) {
function renderDraftLink(draftId) {
return pull.values([
- ph('a', {href: self.app.render.toUrl('/drafts/' + encodeURIComponent(draftId)),
+ ph('a', {href: self.app.render.toUrl('/drafts/' + encodeURI(draftId)),
title: 'draft link'}, u.escapeHTML(draftId)),
ph('input', {type: 'hidden', name: 'draft_id', value: u.escapeHTML(draftId)}), ' ',
])
@@ -4364,7 +4364,7 @@ Serve.prototype.composer = function (opts, cb) {
var draftLinkContainer
function renderDraftLink(draftId) {
if (!draftId) return []
- var draftHref = self.app.render.toUrl('/drafts/' + encodeURIComponent(draftId))
+ var draftHref = self.app.render.toUrl('/drafts/' + encodeURI(draftId))
return [
h('a', {href: draftHref, title: 'draft link'}, u.escapeHTML(draftId)),
h('input', {type: 'hidden', name: 'draft_id', value: u.escapeHTML(draftId)})
@@ -4834,7 +4834,7 @@ Serve.prototype.phMsgActions = function (content) {
function renderDraftLink(draftId) {
return pull.values([
- ph('a', {href: self.app.render.toUrl('/drafts/' + encodeURIComponent(draftId)),
+ ph('a', {href: self.app.render.toUrl('/drafts/' + encodeURI(draftId)),
title: 'draft link'}, u.escapeHTML(draftId)),
ph('input', {type: 'hidden', name: 'draft_id', value: u.escapeHTML(draftId)}), ' ',
])
@@ -5135,18 +5135,37 @@ function hiddenInput(key, value) {
}) : ph('input', {type: 'hidden', name: key, value: u.escapeHTML(value)})
}
-Serve.prototype.drafts = function (path) {
+Serve.prototype.drafts = function (filepath) {
var self = this
- var id = path && String(path).substr(1)
+ var id = filepath && String(filepath).substr(1)
if (id) try { id = decodeURIComponent(id) }
catch(e) {}
+ var dir
+ if (id) try {
+ var draftFile = path.join(self.app.draftsDir, id)
+ var stat = fs.statSync(draftFile)
+ if (stat.isDirectory()) {
+ dir = id
+ id = null
+ }
+ } catch(e) {
+ return this.respond(404, 'Not found')
+ }
if (id) {
+ var idHref = '/drafts'
return pull(
ph('section', [
ph('h3', [
- ph('a', {href: self.app.render.toUrl('/drafts')}, 'Drafts'), ': ',
- ph('a', {href: ''}, u.escapeHTML(id))
+ ph('a', {href: self.app.render.toUrl('/drafts')}, 'Drafts'),
+ id.split(/\/+/).map(function (part, i) {
+ idHref += '/' + part
+ var href = self.app.render.toUrl(idHref)
+ return [
+ ': ',
+ ph('a', {href: href}, u.escapeHTML(part))
+ ]
+ })
]),
u.readNext(function (cb) {
if (self.data.draft_discard) {
@@ -5187,11 +5206,22 @@ Serve.prototype.drafts = function (path) {
)
}
+ var render = self.app.render
+ var idHref = '/drafts'
return pull(
ph('section', [
- ph('h3', 'Drafts'),
+ ph('h3', [
+ ph('a', {href: render.toUrl('/drafts')}, 'Drafts'),
+ dir ? dir.split(/\/+/).map(function (part, i) {
+ idHref += '/' + part
+ return [
+ ': ',
+ ph('a', {href: render.toUrl(idHref)}, u.escapeHTML(part))
+ ]
+ }) : ''
+ ]),
ph('ul', pull(
- self.app.listDrafts(),
+ self.app.listDrafts(dir),
pull.asyncMap(function (draft, cb) {
var form = draft.form || {}
var msg = {
@@ -5199,7 +5229,10 @@ Serve.prototype.drafts = function (path) {
value: {
author: self.app.sbot.id,
timestamp: Date.now(),
- content: draft.content || {type: 'post'}
+ content: draft.content || (
+ draft.isDir ? {type: draft.id + '/'}
+ : {type: 'post'}
+ )
}
}
cb(null, ph('li', self.app.render.phMsgLink(msg)))