Skip to content
This repository has been archived by the owner on Jul 16, 2019. It is now read-only.

Commit

Permalink
+source upload
Browse files Browse the repository at this point in the history
  • Loading branch information
jbdemonte committed Jan 15, 2017
1 parent f4726f9 commit f6ecd3f
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 27 deletions.
62 changes: 62 additions & 0 deletions api/sources/post.js
@@ -0,0 +1,62 @@
var tools = require('../../server/tools');
var constant = require('../../constants');
var multipart = require('connect-multiparty');

module.exports = [multipart(), function (req, res) {

if (!req.files ||!req.files.file || !req.files.file.name || !req.files.file.path) {
return res.json({error: 'Upload error'});
}

var file = req.files.file;
var sources = [];

handleFile(file.path, file.name, sources)
.then(function () {
return tools.fs.unlink(file.path);
})
.then(function () {
return tools.source.reload();
})
.then(function () {
return tools.source.list();
})
.then(function (sources) {
res.json({
sources: sources.map(function (source) {
return source.toJSON();
})
});
})
.catch(function (err) {
res.send({error: err ? err.message : 'Unknown error'});
});
}];

/**
* Try to identify an archive as a source package
* @param {string} source
* @param {string} filename - Original filename (if different from source)
* @param {array} sources output
* @return {Promise}
*/
function handleFile (source, filename, sources) {

filename = filename || path.basename(source);

if (!tools.compression.hasArchiveExtension(filename)) {
return Promise.resolve(false);
}

return tools.compression.uncompressToTmp(source, ['js', 'json', 'jpg', 'png', 'gif'])
.then(function (result) {
try {
var source = require(result.tmpPath);
if (source.guid) {
return tools.fs.rename(result.tmpPath, constant.SOURCES_PATH + '/' + source.guid);
}
} catch (err) {
return tools.fs.rmTmpDir(result.tmpPath);
}
});
}
7 changes: 7 additions & 0 deletions constants.js
@@ -0,0 +1,7 @@
var path = require('path');

var exports = module.exports = {};

exports.SOURCES_PATH = path.resolve('sources');

Object.freeze(exports);
4 changes: 2 additions & 2 deletions index.js
Expand Up @@ -4,6 +4,7 @@ var stylus = require('stylus');
var nib = require('nib');
var bodyParser = require('body-parser');
var tools = require('./server/tools');
var constants = require('./constants');

var app = express();
var server = require('http').createServer(app);
Expand All @@ -28,8 +29,7 @@ app.get('/partials/*.html', function (req, res) {

app.get('/images/sources/:sourceId/:image', function (req, res) {
res.sendFile(
'web/' + req.params.sourceId + '/' + req.params.image,
{root: __dirname},
constants.SOURCES_PATH + '/' + req.params.sourceId + '/' + req.params.image,
function (err) {
if (err) {
return res.status(err.status).end();
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -30,6 +30,7 @@
"md5-file": "^3.1.1",
"mkdirp": "^0.5.1",
"nib": "^1.1.2",
"node-uuid": "^1.4.7",
"p7zip": "^2.2.0",
"request": "^2.79.0",
"request-progress": "^3.0.0",
Expand Down
13 changes: 11 additions & 2 deletions partials/sources.jade
@@ -1,13 +1,22 @@
#sources
#sources.dropable(ng-class="{uploading: uploading.length}", ngf-drop, ngf-select, ng-model='files', ngf-drag-over-class="'dragover'", ngf-multiple='true', ngf-select-disabled='true', ngf-allow-dir='true')

#pictures
i.fa.fa-cloud

h1 {{system.name}}

uploading-list(list="uploading")

.no-entry(ng-if="!sources.length")
span No source found

.channel(ng-repeat="source in sources", ui-sref="source({sourceId: source.id})")
.box
span.helper
img(ng-if="source.picture", ng-src="{{'images/sources/' + source.id + '/' + source.picture}}")
.footer
span {{source.name}}
span {{source.name}}

.drop-label
i.fa.fa-download
span Drop your SOURCEs files here
52 changes: 51 additions & 1 deletion public/app.js
Expand Up @@ -377,8 +377,58 @@ app.controller('SystemsCtrl', ['$scope', '$state', function ($scope, $state) {
});
}]);

app.controller('SourcesCtrl', ['$scope', 'sources', function ($scope, sources) {
app.controller('SourcesCtrl', ['$scope', 'Upload', 'sources', function ($scope, Upload, sources) {
$scope.sources = sources;
$scope.uploading = [];

function sort() {
$scope.sources.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
}

$scope.$watch('files', function (files) {
(files || []).forEach(function (file) {
if (file.$error) {
return ;
}
var item = {
name: file.name,
progress: {}
};
$scope.uploading.push(item);
function hide() {
$scope.uploading.splice($scope.uploading.indexOf(item), 1);
}
Upload
.upload({
url: 'api/sources',
data: {
file: file
}
})
.then(
function (response) {
if (response.data && response.data.sources) {
$scope.sources = response.data.sources;
sort();
}
hide();
},
function () {
hide();
},
function (evt) {
item.progress = Math.floor(100.0 * evt.loaded / evt.total);
}
)
.catch(function () {
hide();
});
});
});

sort();
}]);

app.controller('SourceCtrl', ['$scope', 'source', function ($scope, source) {
Expand Down
2 changes: 1 addition & 1 deletion server/classes/lib/Source.js
Expand Up @@ -302,7 +302,7 @@ Source.prototype._loadGameList = function (systemConfig) {
var self = this;
var crawled = {}; // URL HashMap to avoid infinity loop
var engine = this.engine;
var url = engine.completeURL(systemConfig.path);
var url = engine.completeURL(systemConfig.url);

if (!tools.object.isObject(systemConfig.pg_games)) {
return Promise.reject('Manifest error: pages.games mismatch');
Expand Down
5 changes: 3 additions & 2 deletions server/tools/lib/compression.js
Expand Up @@ -74,13 +74,14 @@ function uncompress(source, destination, extensions) {
/**
* Uncompress an archive and return its tmpPath path and files
* @param {string} source
* @param {string[]} [extensions]
* @return {Promise.<{tmpPath: string, files: string[]}>}
*/
function uncompressToTmp(source) {
function uncompressToTmp(source, extensions) {
return tools.fs
.mkTmpDir()
.then(function (tmpPath) {
return uncompress(source, tmpPath)
return uncompress(source, tmpPath, extensions)
.then(function (files) {
return {
tmpPath: tmpPath,
Expand Down
12 changes: 6 additions & 6 deletions server/tools/lib/source.js
@@ -1,6 +1,5 @@
var path = require('path');
var classes = require('../../classes');
var WEB_PATH = path.resolve('web');
var constants = require('../../../constants');

var sourceById;

Expand All @@ -10,17 +9,18 @@ var tools = {
};

module.exports = {
get: get,
list: list,
get: get
reload: reload
};

/**
* LOAD ALL SOURCES IN GLOBAL SOURCES
* @return {Promise}
*/
function loadSources() {
function reload() {
return tools.fs
.glob(WEB_PATH + '/*')
.glob(constants.SOURCES_PATH + '/*')
.then(function (items) {
return tools.fs.filterDirs(items);
})
Expand All @@ -45,7 +45,7 @@ function list(system) {
.resolve()
.then(function () {
if (!sourceById) {
return loadSources();
return reload();
}
})
.then(function () {
Expand Down
22 changes: 9 additions & 13 deletions server/tools/lib/string.js
@@ -1,3 +1,7 @@
var uuid = require('node-uuid');

var guidRE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;

module.exports = {
rand: rand,
guid: guid,
Expand All @@ -20,24 +24,16 @@ function rand(length) {
return text;
}

/**
* Return an hexa string of 4 digit
* @return {string}
*/
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}

/**
* Return a guid
* @return {string}
*/
function guid() {
return s4() + s4() + '-' +
s4() + '-' +
s4() + '-' +
s4() + '-' +
s4() + s4() + s4();
return uuid.v1();
}

function guidValid(str) {
return str && typeof str === 'string' && str.match(guidRE);
}

/**
Expand Down

0 comments on commit f6ecd3f

Please sign in to comment.