710b3a0911530e85b9b55b35f89dd25d1e664f4c
[motion.git] / server / api / upload / upload.controller.js
1 'use strict';
2
3 var _ = require('lodash');
4 var Upload = require('../../models').Upload;
5 var uploadFile = require('upload-file');
6 var sr = require('simple-random');
7 var sox = require('sox');
8 var path = require('path');
9 var config = require('../../config/environment');
10 var fs = require('fs');
11 var sequelize = require('../../models').sequelize;
12 var base64 = require('file-base64');
13
14 // Get list of uploads
15 exports.index = function(req, res) {
16   Upload
17     .findAll()
18     .then(function(uploads) {
19       return res.status(200).send(uploads);
20     })
21     .catch(function(err) {
22       return handleError(res, err);
23     });
24 };
25
26 // Get a single upload
27 exports.show = function(req, res) {
28   Upload
29     .findById(req.params.id)
30     .then(function(upload) {
31       if (!upload) {
32         return res.sendStatus(404);
33       }
34       return res.send(upload);
35     })
36     .catch(function(err) {
37       return handleError(res, err);
38     });
39 };
40
41 // Creates a new upload in the DB.
42 exports.create = function(req, res) {
43   var upload = new uploadFile({
44     dest: path.join(config.root, 'server/files/sounds/original'),
45     maxFileSize: 15 * 1000000,
46     maxNumberOfFiles: 10,
47     minNumberOfFiles: 0,
48     acceptFileTypes: /(\.|\/)(wav|mp3|gsm|ogg)$/i,
49     rename: function(name, file) {
50       return sr() + path.extname(file.filename);
51     },
52     messages: {
53       maxNumberOfFiles: "Max number of files upload exceeded",
54       acceptFileTypes: "Only wav,mp3,gsm, and ogg format accepted",
55       maxFileSize: "The maximum file size is 15 Mb",
56       invalidRequest: "Invalid request"
57     }
58   });
59
60   upload.on('end', function(fields, files) {
61     var job_details = {};
62     job_details.description = "";
63     job_details.name = job_details.display_name = path.basename(files.file.path, path.extname(files.file.filename));
64     job_details.save_name = path.basename(files.file.filename, path.extname(files.file.filename));
65     job_details.original_path = path.join(config.root, 'server/files/sounds/original');
66     job_details.converted_path = path.join(config.root, 'server/files/sounds/converted');
67
68     if (!files.file.filename) {
69       return res.status(500).send(upload);
70     }
71
72     var filepath = path.join(job_details.original_path, job_details.save_name + path.extname(files.file.filename));
73     var destination = path.join(job_details.converted_path, job_details.save_name + '.wav');
74     //
75
76     fs.chmodSync(filepath, parseInt('0777', 8));
77     sox.identify(filepath, function(err, result) {
78       console.log('************** Result: ', result);
79     });
80
81     var job = sox.transcode(filepath, destination, {
82       sampleRate: 8000,
83       format: 'wav',
84       channelCount: 1,
85       bitRate: 192 * 1024,
86       compressionQuality: 5,
87     });
88
89
90
91     job.on('error', function(err) {
92       console.error('********** Conversion Error: ', err);
93       fs.unlink(filepath, function(err) {
94         if (err)
95           return handleError(res, err);
96       });
97       return handleError(res, err);
98     });
99
100     job.on('progress', function(amountDone, amountTotal) {
101       // console.log("*********** Progress", amountDone, amountTotal);
102     });
103
104     job.on('src', function(info) {
105       // console.log('********** src: ', info);
106       /* info looks like:
107       {
108         format: 'wav',
109         duration: 1.5,
110         sampleCount: 66150,
111         channelCount: 1,
112         bitRate: 722944,
113         sampleRate: 44100,
114       }
115       */
116       job_details.original_format = info.format;
117       job_details.original_duration = info.duration * 1000;
118       job_details.original_sampleCount = info.sampleCount;
119       job_details.original_channelCount = info.channelCount;
120       job_details.original_bitRate = info.bitRate;
121       job_details.original_sampleRate = info.sampleRate;
122     });
123
124     job.on('dest', function(info) {
125       // console.log('********** dest: ', info);
126       /* info looks like:
127       {
128         sampleRate: 44100,
129         format: 'mp3',
130         channelCount: 2,
131         sampleCount: 67958,
132         duration: 1.540998,
133         bitRate: 196608,
134       }
135       */
136       job_details.converted_format = info.format;
137       job_details.converted_duration = info.duration * 1000;
138       job_details.converted_sampleCount = info.sampleCount;
139       job_details.converted_channelCount = info.channelCount;
140       job_details.converted_bitRate = info.bitRate;
141       job_details.converted_sampleRate = info.sampleRate;
142     });
143
144     job.on('end', function() {
145       console.log("Conversion completed");
146       fs.chmodSync(destination, parseInt('0777', 8));
147       Upload
148         .create(job_details)
149         .then(function(upload) {
150           return res.status(201).send(upload);
151         })
152         .catch(function(err) {
153           return handleError(res, err);
154         });
155     });
156
157     job.start();
158
159   });
160
161   upload.on('error', function(err) {
162     console.log('********** Upload error :', err)
163     return handleError(res, err);
164   });
165
166   upload.parse(req);
167 };
168
169 // Updates an existing upload in the DB.
170 exports.update = function(req, res) {
171   if (req.body.id) {
172     delete req.body.id;
173   }
174   Upload
175     .findById(req.params.id)
176     .then(function(upload) {
177       if (!upload) {
178         return res.sendStatus(404);
179       }
180       var updated = _.merge(upload, req.body);
181       updated.save()
182         .then(function() {
183           return res.status(200).send(upload);
184         })
185         .catch(function(err) {
186           return handleError(res, err);
187         });
188     })
189     .catch(function(err) {
190       return handleError(res, err);
191     });
192 };
193
194 // Deletes a upload from the DB.
195 exports.destroy = function(req, res) {
196   Upload
197     .findById(req.params.id)
198     .then(function(upload) {
199       if (!upload) {
200         return res.status(404).send(upload);
201       }
202       var original_filepath = path.join(upload.original_path, upload.save_name + '.' + upload.original_format);
203       var converted_filepath = path.join(upload.converted_path, upload.save_name + '.' + upload.converted_format);
204       return sequelize.transaction(function(t) {
205           return upload.destroy({
206               transaction: t
207             })
208             .then(function() {
209               fs.unlink(original_filepath, function(err) {
210                 if (err)
211                   return handleError(res, err);
212               });
213               fs.unlink(converted_filepath, function(err) {
214                 if (err)
215                   return handleError(res, err);
216               });
217               return res.status(200).send(upload);
218             })
219         })
220         .catch(function(err) {
221           return handleError(res, err);
222         });
223     })
224     .catch(function(err) {
225       return handleError(res, err);
226     });
227 };
228 //Download an uploaded file
229 exports.download = function(req, res) {
230   Upload
231     .findById(req.params.id)
232     .then(function(upload) {
233       if (!upload) {
234         return res.status(404).send(upload);
235       }
236       var original_filepath = path.join(upload.original_path, upload.save_name + '.' + upload.original_format);
237       res.status(200).download(original_filepath, upload.display_name + '.' + upload.original_format, function(err) {
238         if (err) {
239           return handleError(res, err);
240         } else {
241           console.log("Sent file under :", original_filepath);
242         }
243       });
244     })
245 };
246
247 //Stream an uploaded file
248 exports.stream = function(req, res) {
249   Upload
250     .findById(req.params.id)
251     .then(function(upload) {
252       if (!upload) {
253         return res.status(404).send(upload);
254       }
255       var original_filepath = path.join(upload.converted_path, upload.save_name + '.' + upload.original_format);
256       base64.encode(original_filepath, function(err, base64String) {
257         if (err) {
258           console.log(err);
259           return handleError(res, err);
260         } else {
261           return res.status(200).send(base64String);
262         }
263       });
264     })
265 };
266
267 function handleError(res, err) {
268   return res.status(500).send(err);
269 }