Commit e628921a by Johannes Zellner

Add rename functionality

This also break backwardscompat since PUT is now POST
and PUT is used for renaming
1 parent 4b6cf0ad
......@@ -118,7 +118,7 @@ function put(filePath, otherFilePaths, options) {
var destinationPath = (destination ? '/' + destination : '') + '/' + relativeFilePath;
console.log('Uploading file %s -> %s', relativeFilePath.cyan, destinationPath.cyan);
superagent.put(config.server() + API + destinationPath).query(gQuery).attach('file', file).end(function (error, result) {
superagent.post(config.server() + API + destinationPath).query(gQuery).attach('file', file).end(function (error, result) {
if (result && result.statusCode === 403) return callback(new Error('Upload destination ' + destinationPath + ' not allowed'));
if (result && result.statusCode !== 201) return callback(new Error('Error uploading file: ' + result.statusCode));
if (error) return callback(error);
......
......@@ -41,7 +41,7 @@
</div>
<div class="modal-body">
<h5 v-show="deleteData.isFile">Really delete <span style="font-weight: bold;">{{ deleteData.filePath }}</span>?</h5>
<h5 v-show="deleteData.isDirectory">Really delete directory <span style="font-weight: bold;">{{ deleteData.filePath }}</span> and all its content?</h5>
<h5 v-show="deleteData.isDirectory">Really delete folder <span style="font-weight: bold;">{{ deleteData.filePath }}</span> and all its content?</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
......@@ -51,12 +51,36 @@
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="modalRename" v-cloak>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Rename {{ renameData.entry.filePath }}</h4>
</div>
<div class="modal-body">
<form v-on:submit.prevent="rename(renameData)">
<div class="form-group" v-bind:class="{ 'has-error': renameData.error }">
<input type="text" class="form-control" v-model="renameData.newFilePath" placeholder="Name" autofocus="true">
<label class="control-label">{{ renameData.error }}</label>
</div>
<button type="submit" style="display: none;"></button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-success" v-on:click="rename(renameData)">Yes</button>
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="modalcreateDirectory" v-cloak>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">New Directory Name</h4>
<h4 class="modal-title">New directory name</h4>
</div>
<div class="modal-body">
<form v-on:submit.prevent="createDirectory(createDirectoryData)">
......@@ -135,7 +159,7 @@
<a href="{{ part.link }}">{{ part.name }}</a>
</li>
<li>{{ pathParts.slice(-1)[0].name }}</li>
<button class="btn btn-default btn-sm pull-right" v-on:click="createDirectoryAsk()">Create Directory</button>
<button class="btn btn-default btn-sm pull-right" v-on:click="createDirectoryAsk()">Create Folder</button>
</ol>
</div>
<div class="col-lg-12">
......@@ -150,6 +174,9 @@
</tr>
</thead>
<tbody>
<tr v-show="entries.length === 0">
<th><i>Empty folder</i></th>
</tr>
<tr v-for="entry in entries" v-on:click="open(entry)" class="hand">
<th>
<img v-bind:src="entry.previewUrl" height="48px" width="48px"/>
......@@ -159,7 +186,7 @@
<th><span v-my-tooltip="foobar" data-toggle="tooltip" title="{{ entry.mtime }}">{{ entry.mtime | prettyDate }}</span></th>
<th style="text-align: right;">
<span class="entry-toolbar">
<!-- <button class="btn btn-sm btn-default" v-on:click.stop="renameAsk(entry)" title="Rename"><i class="fa fa-pencil"></i></button> -->
<button class="btn btn-sm btn-default" v-on:click.stop="renameAsk(entry)" title="Rename"><i class="fa fa-pencil"></i></button>
<button class="btn btn-sm btn-danger" v-on:click.stop="delAsk(entry)" title="Delete"><i class="fa fa-trash"></i></button>
</span>
</th>
......
......@@ -141,7 +141,7 @@ function upload() {
var formData = new FormData();
formData.append('file', file);
superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send(formData).end(function (error, result) {
superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send(formData).end(function (error, result) {
if (result && result.statusCode === 401) return logout();
if (result && result.statusCode !== 201) console.error('Error uploading file: ', result.statusCode);
if (error) console.error(error);
......@@ -149,8 +149,6 @@ function upload() {
app.uploadStatus.done += 1;
app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100);
console.log(Math.round(app.uploadStatus.done / app.uploadStatus.count * 100))
if (app.uploadStatus.done >= app.uploadStatus.count) {
app.uploadStatus = {
busy: false,
......@@ -198,6 +196,33 @@ function del(entry) {
});
}
function renameAsk(entry) {
app.renameData.entry = entry;
app.renameData.error = null;
app.renameData.newFilePath = entry.filePath;
$('#modalRename').modal('show');
}
function rename(data) {
app.busy = true;
var path = encode(sanitize(app.path + '/' + data.entry.filePath));
var newFilePath = sanitize(app.path + '/' + data.newFilePath);
superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send({ newFilePath: newFilePath }).end(function (error, result) {
app.busy = false;
if (result && result.statusCode === 401) return logout();
if (result && result.statusCode !== 200) return console.error('Error renaming file: ', result.statusCode);
if (error) return console.error(error);
refresh();
$('#modalRename').modal('hide');
});
}
function createDirectoryAsk() {
$('#modalcreateDirectory').modal('show');
app.createDirectoryData = '';
......@@ -210,7 +235,7 @@ function createDirectory(name) {
var path = encode(sanitize(app.path + '/' + name));
superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
app.busy = false;
if (result && result.statusCode === 401) return logout();
......@@ -258,6 +283,11 @@ var app = new Vue({
},
loginData: {},
deleteData: {},
renameData: {
entry: {},
error: null,
newFilePath: ''
},
createDirectoryData: '',
createDirectoryError: null,
entries: []
......@@ -271,6 +301,8 @@ var app = new Vue({
upload: upload,
delAsk: delAsk,
del: del,
renameAsk: renameAsk,
rename: rename,
createDirectoryAsk: createDirectoryAsk,
createDirectory: createDirectory
}
......
......@@ -24,7 +24,8 @@ var router = new express.Router();
var multipart = multipart({ maxFieldsSize: 2 * 1024, limit: '512mb', timeout: 3 * 60 * 1000 });
router.get ('/api/files/*', auth.verify, files.get);
router.put ('/api/files/*', auth.verify, multipart, files.put);
router.post ('/api/files/*', auth.verify, multipart, files.post);
router.put ('/api/files/*', auth.verify, files.put);
router.delete('/api/files/*', auth.verify, files.del);
router.get ('/api/healthcheck', function (req, res) { res.status(200).send(); });
......
......@@ -17,6 +17,7 @@ exports = module.exports = function (basePath) {
return {
get: get,
put: put,
post: post,
del: del
};
};
......@@ -111,22 +112,22 @@ function get(req, res, next) {
});
}
function put(req, res, next) {
function post(req, res, next) {
var filePath = decodeURIComponent(req.params[0]);
if (!(req.files && req.files.file) && !req.query.directory) return next(new HttpError(400, 'missing file or directory'));
if ((req.files && req.files.file) && req.query.directory) return next(new HttpError(400, 'either file or directory'));
debug('post:', filePath);
var absoluteFilePath = getAbsolutePath(filePath);
if (!absoluteFilePath || isProtected(absoluteFilePath)) return next(new HttpError(403, 'Path not allowed'));
fs.stat(absoluteFilePath, function (error, result) {
if (error && error.code !== 'ENOENT') return next(new HttpError(500, error));
debug('put', absoluteFilePath);
if (result && req.query.directory) return next(new HttpError(409, 'name already exists'));
if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories'));
if (result && result.isDirectory()) return next(new HttpError(409, 'cannot post on directories'));
if (req.query.directory) {
return createDirectory(absoluteFilePath, function (error) {
......@@ -144,6 +145,30 @@ function put(req, res, next) {
});
}
function put(req, res, next) {
var oldFilePath = decodeURIComponent(req.params[0]);
if (!req.body || !req.body.newFilePath) return next(new HttpError(400, 'missing newFilePath'));
var newFilePath = decodeURIComponent(req.body.newFilePath);
debug('put: %s -> %s', oldFilePath, newFilePath);
var absoluteOldFilePath = getAbsolutePath(oldFilePath);
if (!absoluteOldFilePath || isProtected(absoluteOldFilePath)) return next(new HttpError(403, 'Path not allowed'));
var absoluteNewFilePath = getAbsolutePath(newFilePath);
if (!absoluteNewFilePath || isProtected(absoluteNewFilePath)) return next(new HttpError(403, 'Path not allowed'));
fs.rename(absoluteOldFilePath, absoluteNewFilePath, function (error) {
if (error) return next (new HttpError(500, error));
debug('put: successful');
return next(new HttpSuccess(200, {}));
});
}
function del(req, res, next) {
var filePath = decodeURIComponent(req.params[0]);
var recursive = !!req.query.recursive;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!