|  | 
|  | 1 | +const router = module.exports = require('express').Router(); | 
|  | 2 | +const git = require('../git-tool'); | 
|  | 3 | +const store = require('../store').mods.editor; | 
|  | 4 | +const path = require('path'); | 
|  | 5 | +const promisify = require('../helpers').promisify; | 
|  | 6 | +const fs = require('fs'); | 
|  | 7 | +const formidable = require('formidable'); | 
|  | 8 | + | 
|  | 9 | +const safePath = val => decodeURI(val).replace(/|\.\.|\/\//g, ''); | 
|  | 10 | +const getRoot = req => Promise.resolve(store.root(req)) | 
|  | 11 | + | 
|  | 12 | +//create | 
|  | 13 | +router.post('/file/*', (req, res) => { | 
|  | 14 | +  const f = req.query.type == 'file'; | 
|  | 15 | +  const p = safePath(req.url.slice(5)); | 
|  | 16 | +  return getRoot(req) | 
|  | 17 | +  .then(root => promisify(f && fs.writeFile || fs.mkdir)(path.join(root, p), f ? '' : 0o777)) //TODO: check if exists | 
|  | 18 | +  .then(a => ({id: p})) | 
|  | 19 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 20 | +  .then(data => res.send(data)) | 
|  | 21 | +}) | 
|  | 22 | + | 
|  | 23 | +//remove | 
|  | 24 | +router.delete('/file/*', (req, res) => { | 
|  | 25 | +  const p = safePath(req.url.slice(5)); | 
|  | 26 | +  return getRoot(req) | 
|  | 27 | +  .then(root => promisify(fs.stat)(path.join(root, p)).then(stats => promisify(stats.isDirectory() ? fs.rmdir : fs.unlink)(path.join(root, p)) )) | 
|  | 28 | +  .then(a => ({id: p})) | 
|  | 29 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 30 | +  .then(data => res.send(data)) | 
|  | 31 | +}) | 
|  | 32 | + | 
|  | 33 | +//move //TODO check if destenation not exists ? | 
|  | 34 | +router.put('/file/*', (req, res) => { | 
|  | 35 | +  const p = safePath(req.url.slice(5)); | 
|  | 36 | +  const t = safePath(req.body.to); | 
|  | 37 | +  return getRoot(req) | 
|  | 38 | +  .then(root => promisify(fs.rename)(path.join(root, p), path.join(root, t))) | 
|  | 39 | +  .then(a => ({id: t})) | 
|  | 40 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 41 | +  .then(data => res.send(data)) | 
|  | 42 | +}) | 
|  | 43 | + | 
|  | 44 | +//TODO:copy | 
|  | 45 | + | 
|  | 46 | +//list | 
|  | 47 | +router.get('/tree', function(req, res) { | 
|  | 48 | +  var dir = req.query.id == '#' && '/' || req.query.id || ''; | 
|  | 49 | +  dir = dir.replace(/\.\./g, ''); | 
|  | 50 | +  return getRoot(req) | 
|  | 51 | +  .then(root => promisify(fs.readdir)(path.join(root, dir)) | 
|  | 52 | +    .then(list => list.filter(name => name && (name != '.' || name != '..'))) | 
|  | 53 | +    .then(list => Promise.all(list.map(name => promisify(fs.stat)(path.join(root, dir, name)) | 
|  | 54 | +      .then(stats => ({ | 
|  | 55 | +        children: stats.isDirectory(), | 
|  | 56 | +        type: stats.isDirectory() ? 'default' : "file", | 
|  | 57 | +        text: name, | 
|  | 58 | +        id: path.join(dir, name), | 
|  | 59 | +//        icon: stats.isDirectory() ? 'jstree-folder' : "jstree-file", | 
|  | 60 | +      })))) | 
|  | 61 | +    ) | 
|  | 62 | +  ) | 
|  | 63 | +  .then(list => dir != '/' && list || {text: store.name(req), children: list, id: '/', type: 'default', state: {opened: true, disabled: true}}) | 
|  | 64 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 65 | +  .then(data => res.send(data)) | 
|  | 66 | +}) | 
|  | 67 | + | 
|  | 68 | +//content | 
|  | 69 | +router.get('/file/*', function(req, res) { | 
|  | 70 | +  const p = safePath(req.url.slice(5)); | 
|  | 71 | +  return getRoot(req) | 
|  | 72 | +  .then(root => promisify(fs.stat)(path.join(root, p)).then(stats => !stats.isDirectory() && promisify(fs.readFile)(path.join(root, p)) || '' )) | 
|  | 73 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 74 | +  .then(data => res.send(data)) | 
|  | 75 | +}) | 
|  | 76 | + | 
|  | 77 | +const parseForm = req => new Promise((resolve, reject) => { | 
|  | 78 | +    var form = new formidable.IncomingForm(); | 
|  | 79 | +    form.parse(req, function (err, fields, files) { | 
|  | 80 | +      return err && reject(err) || resolve([fields, files]); | 
|  | 81 | +    }) | 
|  | 82 | +  }) | 
|  | 83 | + | 
|  | 84 | +router.post('/upload/*', function(req, res) { | 
|  | 85 | +  const p = safePath(req.url.slice(7)); | 
|  | 86 | +  return getRoot(req) | 
|  | 87 | +  .then(root => parseForm(req).then(ff => promisify(fs.rename)(ff[1].data.path, path.join(root, p)).then(a => p) )) | 
|  | 88 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 89 | +  .then(data => res.send(data)) | 
|  | 90 | + }); | 
|  | 91 | + | 
|  | 92 | + | 
|  | 93 | +//git file TODO: git for multiproject | 
|  | 94 | +router.get('/git/*', function(req, res) { | 
|  | 95 | +  git.Tag() | 
|  | 96 | +  .then(tag => git.Show(tag, req.originalUrl.replace(/.*git\//, ''))) | 
|  | 97 | +  .catch(e => res.status(501).send(e.message)) | 
|  | 98 | +  .then(data => res.send(data)) | 
|  | 99 | +}) | 
0 commit comments