diff options
author | Johannes Zellner <johannes@nebulon.de> | 2016-03-01 16:37:05 +0100 |
---|---|---|
committer | Johannes Zellner <johannes@nebulon.de> | 2016-03-01 16:37:05 +0100 |
commit | 403359cf6986b9c0f8c69f144cd36974d61a2370 (patch) | |
tree | 89ba9b26ff89afc617c89603b40f7b2cbf552c61 | |
parent | 61e0b8e4910051d0dfb4d454817b9f0511ba96ad (diff) | |
download | Surfer-403359cf6986b9c0f8c69f144cd36974d61a2370.tar.gz Surfer-403359cf6986b9c0f8c69f144cd36974d61a2370.tar.zst Surfer-403359cf6986b9c0f8c69f144cd36974d61a2370.zip |
Add ui to create directories
-rw-r--r-- | app/index.html | 25 | ||||
-rw-r--r-- | app/js/app.js | 33 | ||||
-rw-r--r-- | src/files.js | 21 | ||||
-rw-r--r-- | src/multipart.js | 2 |
4 files changed, 74 insertions, 7 deletions
diff --git a/app/index.html b/app/index.html index cf1f399..ea14bc1 100644 --- a/app/index.html +++ b/app/index.html | |||
@@ -49,6 +49,29 @@ | |||
49 | </div> | 49 | </div> |
50 | </div> | 50 | </div> |
51 | 51 | ||
52 | <div class="modal fade" tabindex="-1" role="dialog" id="modalcreateDirectory"> | ||
53 | <div class="modal-dialog"> | ||
54 | <div class="modal-content"> | ||
55 | <div class="modal-header"> | ||
56 | <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | ||
57 | <h4 class="modal-title">New Directory Name</h4> | ||
58 | </div> | ||
59 | <div class="modal-body"> | ||
60 | <form v-on:submit.prevent="createDirectory(createDirectoryData)"> | ||
61 | <div class="form-group"> | ||
62 | <input type="text" class="form-control" v-model="createDirectoryData" placeholder="Name"> | ||
63 | </div> | ||
64 | <button type="submit" style="display: none;"></button> | ||
65 | </form> | ||
66 | </div> | ||
67 | <div class="modal-footer"> | ||
68 | <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> | ||
69 | <button type="button" class="btn btn-primary" v-on:click="createDirectory(createDirectoryData)">Create</button> | ||
70 | </div> | ||
71 | </div> | ||
72 | </div> | ||
73 | </div> | ||
74 | |||
52 | <div class="container" v-show="busy" v-cloak> | 75 | <div class="container" v-show="busy" v-cloak> |
53 | <div class="row"> | 76 | <div class="row"> |
54 | <div class="col-lg-12"> | 77 | <div class="col-lg-12"> |
@@ -126,7 +149,7 @@ | |||
126 | </table> | 149 | </table> |
127 | </div> | 150 | </div> |
128 | <div class="col-lg-12" style="text-align: right;"> | 151 | <div class="col-lg-12" style="text-align: right;"> |
129 | <button class="btn btn-default btn-sm" v-on:click="">Create Directory</button> | 152 | <button class="btn btn-default btn-sm" v-on:click="createDirectoryAsk()">Create Directory</button> |
130 | </div> | 153 | </div> |
131 | </div> | 154 | </div> |
132 | </div> | 155 | </div> |
diff --git a/app/js/app.js b/app/js/app.js index 823e4f7..c0ed616 100644 --- a/app/js/app.js +++ b/app/js/app.js | |||
@@ -79,9 +79,12 @@ function up() { | |||
79 | } | 79 | } |
80 | 80 | ||
81 | function upload() { | 81 | function upload() { |
82 | $(app.$els.upload).change(function () { | 82 | $(app.$els.upload).on('change', function () { |
83 | app.busy = true; | 83 | app.busy = true; |
84 | 84 | ||
85 | // detach event handler | ||
86 | $(app.$els.upload).off('change'); | ||
87 | |||
85 | var file = app.$els.upload.files[0]; | 88 | var file = app.$els.upload.files[0]; |
86 | var path = encode(sanitize(app.path + '/' + file.name)); | 89 | var path = encode(sanitize(app.path + '/' + file.name)); |
87 | 90 | ||
@@ -123,6 +126,29 @@ function del(entry) { | |||
123 | }); | 126 | }); |
124 | } | 127 | } |
125 | 128 | ||
129 | function createDirectoryAsk() { | ||
130 | $('#modalcreateDirectory').modal('show'); | ||
131 | app.createDirectoryData = ''; | ||
132 | } | ||
133 | |||
134 | function createDirectory(name) { | ||
135 | app.busy = true; | ||
136 | |||
137 | var path = encode(sanitize(app.path + '/' + name)); | ||
138 | |||
139 | superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) { | ||
140 | app.busy = false; | ||
141 | |||
142 | if (error) return console.error(error); | ||
143 | if (result.statusCode !== 201) return console.error('Error creating directory: ', result.statusCode); | ||
144 | |||
145 | app.createDirectoryData = ''; | ||
146 | refresh(); | ||
147 | |||
148 | $('#modalcreateDirectory').modal('hide'); | ||
149 | }); | ||
150 | } | ||
151 | |||
126 | var app = new Vue({ | 152 | var app = new Vue({ |
127 | el: '#app', | 153 | el: '#app', |
128 | data: { | 154 | data: { |
@@ -134,6 +160,7 @@ var app = new Vue({ | |||
134 | }, | 160 | }, |
135 | loginData: {}, | 161 | loginData: {}, |
136 | deleteData: {}, | 162 | deleteData: {}, |
163 | createDirectoryData: '', | ||
137 | entries: [] | 164 | entries: [] |
138 | }, | 165 | }, |
139 | methods: { | 166 | methods: { |
@@ -144,7 +171,9 @@ var app = new Vue({ | |||
144 | up: up, | 171 | up: up, |
145 | upload: upload, | 172 | upload: upload, |
146 | delAsk: delAsk, | 173 | delAsk: delAsk, |
147 | del: del | 174 | del: del, |
175 | createDirectoryAsk: createDirectoryAsk, | ||
176 | createDirectory: createDirectory | ||
148 | } | 177 | } |
149 | }); | 178 | }); |
150 | 179 | ||
diff --git a/src/files.js b/src/files.js index 520127d..68dfea3 100644 --- a/src/files.js +++ b/src/files.js | |||
@@ -54,6 +54,13 @@ function copyFile(source, target, cb) { | |||
54 | }); | 54 | }); |
55 | } | 55 | } |
56 | 56 | ||
57 | function createDirectory(targetPath, callback) { | ||
58 | mkdirp(targetPath, function (error) { | ||
59 | if (error) return callback(error); | ||
60 | callback(null); | ||
61 | }); | ||
62 | } | ||
63 | |||
57 | function getAbsolutePath(filePath) { | 64 | function getAbsolutePath(filePath) { |
58 | var absoluteFilePath = path.resolve(path.join(gBasePath, filePath)); | 65 | var absoluteFilePath = path.resolve(path.join(gBasePath, filePath)); |
59 | 66 | ||
@@ -103,7 +110,8 @@ function get(req, res, next) { | |||
103 | function put(req, res, next) { | 110 | function put(req, res, next) { |
104 | var filePath = req.params[0]; | 111 | var filePath = req.params[0]; |
105 | 112 | ||
106 | if (!req.files.file) return next(new HttpError(400, 'missing file')); | 113 | if (!(req.files && req.files.file) && !req.query.directory) return next(new HttpError(400, 'missing file or directory')); |
114 | if ((req.files && req.files.file) && req.query.directory) return next(new HttpError(400, 'either file or directory')); | ||
107 | 115 | ||
108 | var absoluteFilePath = getAbsolutePath(filePath); | 116 | var absoluteFilePath = getAbsolutePath(filePath); |
109 | if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); | 117 | if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); |
@@ -111,10 +119,17 @@ function put(req, res, next) { | |||
111 | fs.stat(absoluteFilePath, function (error, result) { | 119 | fs.stat(absoluteFilePath, function (error, result) { |
112 | if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); | 120 | if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); |
113 | 121 | ||
114 | debug('put', absoluteFilePath, req.files.file); | 122 | debug('put', absoluteFilePath); |
115 | 123 | ||
124 | if (result && req.query.directory) return next(new HttpError(409, 'name already exists')); | ||
116 | if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); | 125 | if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); |
117 | if (!result || result.isFile()) { | 126 | |
127 | if (req.query.directory) { | ||
128 | return createDirectory(absoluteFilePath, function (error) { | ||
129 | if (error) return next(new HttpError(500, error)); | ||
130 | next(new HttpSuccess(201, {})); | ||
131 | }); | ||
132 | } else if (!result || result.isFile()) { | ||
118 | return copyFile(req.files.file.path, absoluteFilePath, function (error) { | 133 | return copyFile(req.files.file.path, absoluteFilePath, function (error) { |
119 | if (error) return next(new HttpError(500, error)); | 134 | if (error) return next(new HttpError(500, error)); |
120 | next(new HttpSuccess(201, {})); | 135 | next(new HttpSuccess(201, {})); |
diff --git a/src/multipart.js b/src/multipart.js index 7b994cc..ec72506 100644 --- a/src/multipart.js +++ b/src/multipart.js | |||
@@ -12,7 +12,7 @@ function _mime(req) { | |||
12 | 12 | ||
13 | module.exports = function multipart(options) { | 13 | module.exports = function multipart(options) { |
14 | return function (req, res, next) { | 14 | return function (req, res, next) { |
15 | if (_mime(req) !== 'multipart/form-data') return res.status(400).send('Invalid content-type. Expecting multipart'); | 15 | if (_mime(req) !== 'multipart/form-data') return next(null); |
16 | 16 | ||
17 | var form = new multiparty.Form({ | 17 | var form = new multiparty.Form({ |
18 | uploadDir: '/tmp', | 18 | uploadDir: '/tmp', |