Skip to content

Commit

Permalink
Merge branch 'upload'
Browse files Browse the repository at this point in the history
Conflicts:
	views/listview.html
  • Loading branch information
simov committed Dec 5, 2013
2 parents 7a589d4 + acdc658 commit f09f416
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ results

npm-debug.log
node_modules
public/upload
6 changes: 5 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ function initSettings (args) {
args.config.app.root = '';
}

var upload = args.config.app.upload || path.join(__dirname, 'public/upload');
args.config.app.upload = upload;
if (!fs.existsSync(upload)) fs.mkdirSync(upload);

args.langs = (function () {
var dpath = path.join(__dirname, 'config/lang'),
files = fs.readdirSync(dpath),
Expand Down Expand Up @@ -201,7 +205,7 @@ function initServer (args) {

// editview
app.get(routes.editview, r.auth.restrict, r.editview.get, r.render.admin);
app.post(routes.editview, r.auth.restrict, r.editview.post, r.render.admin);
app.post(routes.editview, r.auth.restrict, r.upload.files, r.editview.post, r.render.admin);

// listview
app.get(routes.listview, r.auth.restrict, r.listview.get, r.render.admin);
Expand Down
1 change: 1 addition & 0 deletions public/express-admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

/*editview*/
.btn-today { line-height: 240%; }
[type=file] { margin-top: 4px; }

/*fix for all fields*/
.ex-table .form-group { margin-bottom: 0; }
Expand Down
9 changes: 9 additions & 0 deletions public/express-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Date.prototype.toJSONLocal = function() {
if ($('.form-group .form-control', self).length)
return $('.form-group .form-control', self);
}
function getFileControl (self) {
if ($('.form-group [type=file]', self).length)
return $('.form-group [type=file]', self);
}
return {
inlines: function () {
$('.add-another').on('click', function (e) {
Expand All @@ -55,6 +59,11 @@ Date.prototype.toJSONLocal = function() {
name = control.attr('name') || '';
control.attr('name',
name.replace('blank', 'records').replace('index', index));

var fileControl = getFileControl(this);
if (fileControl)
fileControl.attr('name',
name.replace('blank', 'records').replace('index', index));
});
// set keys for insert
(function () {
Expand Down
10 changes: 5 additions & 5 deletions routes/editview.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ exports.post = function (req, res, next) {
action = req.body.action,
table = Object.keys(view)[0];

if (action.hasOwnProperty('remove')) {
if ({}.hasOwnProperty.call(action, 'remove')) {
// should be based on constraints
args.action = 'remove';

Expand Down Expand Up @@ -70,20 +70,20 @@ exports.post = function (req, res, next) {

// based on clicked button
switch (true) {
case action.hasOwnProperty('remove'):
case {}.hasOwnProperty.call(action, 'remove'):
// the message should be different for delete
req.session.success = true;
res.redirect(res.locals.root+'/'+args.slug);
break;
case action.hasOwnProperty('save'):
case {}.hasOwnProperty.call(action, 'save'):
req.session.success = true;
res.redirect(res.locals.root+'/'+args.slug);
break;
case action.hasOwnProperty('another'):
case {}.hasOwnProperty.call(action, 'another'):
req.session.success = true;
res.redirect(res.locals.root+'/'+args.slug+'/add');
break;
case action.hasOwnProperty('continue'):
case {}.hasOwnProperty.call(action, 'continue'):
req.session.success = true;
if (args.debug) return render(req, res, next, data, args);
res.redirect(res.locals.root+'/'+args.slug+'/'+args.id);
Expand Down
1 change: 1 addition & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ exports.notfound = require('./404');
exports.mainview = require('./mainview');
exports.listview = require('./listview');
exports.editview = require('./editview');
exports.upload = require('./upload');

exports.render = require('./render');
77 changes: 77 additions & 0 deletions routes/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

var fs = require('fs'),
path = require('path');


// prevent overriding of existing files
function getName (target, cb) {
var ext = path.extname(target),
fname = path.basename(target, ext),
dpath = path.dirname(target);
fs.exists(target, function (exists) {
return exists ? loop(1) : cb(target, fname+ext);
});
function loop (i) {
var name = fname+'-'+i,
fpath = path.join(dpath, name+ext);
fs.exists(fpath, function (exists) {
return exists ? loop(++i) : cb(fpath, name+ext);
});
}
}

function processFile (file, dpath, cb) {
if (!file.name) return cb(null, file.name);
// file.name; // file-name.jpg
// file.path; // /tmp/9c9b10b72fe71be752bd3895f1185bc8

var source = file.path,
target = path.join(dpath, file.name);

fs.readFile(source, function (err, data) {
if (err) return cb(err);
getName(target, function (target, fname) {
fs.writeFile(target, data, function (err) {
if (err) return cb(err);
cb(null, fname);
});
});
});
}

function setName (req, file, fname) {
var m = file.fieldName.match(/(.+)\[(.+)\]\[records\]\[(\d+)\]\[columns\]\[(.+)\]/);
req.body[m[1]][m[2]].records[parseInt(m[3])].columns[m[4]] = fname;
}

function getFiles (req) {
var files = [];
for (var key in req.files) {
var view = req.files[key];
for (var key in view) {
var table = view[key];
if (!table.records) continue;
for (var i=0; i < table.records.length; i++) {
var record = table.records[i];
for (var key in record.columns) {
files.push(record.columns[key]);
}
}
}
}
return files;
}

exports.files = function (req, res, next) {
var files = getFiles(req),
dpath = res.locals._admin.config.app.upload;

(function loop (index) {
if (index == files.length) return next();
var file = files[index];
processFile(file, dpath, function (err, fname) {
if (fname != '') setName(req, file, fname);
loop(++index);
});
}(0));
}
2 changes: 1 addition & 1 deletion views/editview.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h2>{{view.name}}</h2>
</div>
{{/show.error}}

<form class="form-horizontal" action="{{root}}{{view.action}}" method="post" accept-charset="utf-8">
<form class="form-horizontal" action="{{root}}{{view.action}}" method="post" accept-charset="utf-8" enctype="multipart/form-data">
{{>view}}
{{>inline}}

Expand Down
11 changes: 10 additions & 1 deletion views/editview/column.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{{#control}}
<!-- data-type-name={{type.name}} data-type-range="{{type.range}}" data-allow-null="{{allowNull}}" data-default-value="{{defaultValue}}" -->

<div class="{{#text}}col-sm-5 col-md-4 col-lg-3{{/text}}{{#date}}col-sm-5 col-md-4 col-lg-3{{/date}}{{#select}}col-sm-5 col-md-4 col-lg-3{{/select}}{{#textarea}}{{#editor}}col-sm-9 col-md-9 col-lg-10{{/editor}}{{/textarea}}{{#textarea}}{{^editor}}col-sm-7 col-md-6 col-lg-5{{/editor}}{{/textarea}}">
<div class="{{#text}}col-sm-5 col-md-4 col-lg-3{{/text}}{{#file}}col-sm-5 col-md-4 col-lg-3{{/file}}{{#date}}col-sm-5 col-md-4 col-lg-3{{/date}}{{#select}}col-sm-5 col-md-4 col-lg-3{{/select}}{{#textarea}}{{#editor}}col-sm-9 col-md-9 col-lg-10{{/editor}}{{/textarea}}{{#textarea}}{{^editor}}col-sm-7 col-md-6 col-lg-5{{/editor}}{{/textarea}}">

{{#text}}
<input type="text" name="{{key}}" value="{{value}}" class="form-control" />
Expand All @@ -32,6 +32,10 @@
<input type="text" name="{{key}}" value="{{value}}" class="datepicker form-control" autocomplete="off" />
{{/date}}

{{#file}}
<input type="text" name="{{key}}" value="{{value}}" class="form-control" />
{{/file}}

{{#error}}
<strong class="help-block" data-error="{{type}}">{{message}}</strong>
{{/error}}
Expand All @@ -46,6 +50,11 @@
<a href="#" class="btn-today">{{string.today}}</a>
</div>
{{/date}}
{{#file}}
<div class="col-sm-4 col-md-4 col-lg-4">
<input type="file" name="{{key}}" value="{{value}}" />
</div>
{{/file}}

{{/control}}
</div>
Expand Down
4 changes: 2 additions & 2 deletions views/listview.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<h2>
{{string.select}} {{view.name}} {{string.to-change}}.
<a href="{{view.slug}}/add" class="btn btn-default">{{string.add}} {{view.name}}</a>
<a href="{{root}}/{{view.slug}}/add" class="btn btn-default">{{string.add}} {{view.name}}</a>
</h2>

{{#show.success}}
Expand Down Expand Up @@ -30,7 +30,7 @@ <h2>
{{#records}}
<tr>
{{#pk}}
<td><a href="/{{view.slug}}/{{id}}">{{text}}</a></td>
<td><a href="{{root}}/{{view.slug}}/{{id}}">{{text}}</a></td>
{{/pk}}
{{#values}}
<td>{{.}}</td>
Expand Down
10 changes: 5 additions & 5 deletions views/pagination.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
{{#pagination}}

{{#first}}
<li><a href="/{{view.slug}}">«</a></li>
<li><a href="{{root}}/{{view.slug}}">«</a></li>
{{/first}}

{{#prev}}
<li><a href="/{{view.slug}}/?p={{index}}"></a></li>
<li><a href="{{root}}/{{view.slug}}/?p={{index}}"></a></li>
{{/prev}}

{{#page}}
<li><a href="/{{view.slug}}/?p={{index}}">{{index}}</a></li>
<li><a href="{{root}}/{{view.slug}}/?p={{index}}">{{index}}</a></li>
{{/page}}

{{#active}}
<li class="active"><a href="">{{index}}</a></li>
{{/active}}

{{#next}}
<li><a href="/{{view.slug}}/?p={{index}}"></a></li>
<li><a href="{{root}}/{{view.slug}}/?p={{index}}"></a></li>
{{/next}}

{{#last}}
<li><a href="/{{view.slug}}/?p={{index}}">»</a></li>
<li><a href="{{root}}/{{view.slug}}/?p={{index}}">»</a></li>
{{/last}}

{{/pagination}}
Expand Down

0 comments on commit f09f416

Please sign in to comment.