e354d5f879e59a589743723b18fd006e6165dfb7
[motion.git] / server / api / fax_message / fax_message.controller.js
1 'use strict';
2
3 var _ = require('lodash');
4 var fs = require('fs');
5 var path = require('path');
6 var uploadFile = require('upload-file');
7 var uuidLib = require('node-uuid');
8 var pdf = require('html-pdf');
9 var spindrift = require('spindrift');
10 var formidable = require('formidable');
11 var exec = require('child_process').exec;
12 var config = require('../../config/environment');
13
14 var FaxMessage = require('../../models').FaxMessage;
15 var FaxRoom = require('../../models').FaxRoom;
16 var FaxAccount = require('../../models').FaxAccount;
17 var Contact = require('../../models').Contact;
18
19 // Get list of fax_messages
20 exports.index = function(req, res) {
21   FaxMessage
22     .findAll({
23       where: req.query,
24       order: 'createdAt DESC',
25       include: [{
26         model: Contact,
27         as: 'From'
28       }, {
29         model: Contact,
30         as: 'To'
31       }, {
32         model: FaxRoom,
33         include: [{
34           model: FaxAccount
35         }]
36       }]
37     })
38     .then(function(fax_messages) {
39       return res.status(200).send(fax_messages);
40     })
41     .catch(function(err) {
42       return handleError(res, err);
43     });
44 };
45
46 // Get a single fax_message
47 exports.show = function(req, res) {
48   FaxMessage
49     .findOne({
50       where: {
51         id: req.params.id
52       },
53       include: [{
54         model: Contact,
55         as: 'From'
56       }, {
57         model: Contact,
58         as: 'To'
59       }]
60     })
61     .then(function(fax_message) {
62       if (!fax_message) {
63         return res.sendStatus(404);
64       }
65       return res.send(fax_message);
66     })
67     .catch(function(err) {
68       return handleError(res, err);
69     });
70 };
71
72 // Creates a new fax_message in the DB.
73 exports.create = function(req, res, next) {
74   // FaxMessage
75   //   .create(req.body)
76   //   .then(function(fax_message) {
77   //     return res.status(201).send(fax_message);
78   //   })
79   //   .catch(function(err) {
80   //     return handleError(res, err);
81   //   });
82
83   var form = new formidable.IncomingForm();
84   // form.encoding = 'utf-8';
85   form.uploadDir = path.join(config.root, 'server/files/fax/outbound/original');
86   form.keepExtensions = true;
87   form.multiples = false;
88
89   if (req.body.onlyText) {
90     //There is not file, only text
91     // console.log(req.body);
92     if (req.body.html) {
93       //There is the html message -> convert
94       var uuid = uuidLib.v4()
95       var dest = path.join(config.root, 'server/files/fax/outbound/original', uuid + '.pdf');
96       pdf.create(req.body.html, {
97         "timeout": 30000
98       }).toFile(dest, function(err, result) {
99         console.log('Fax: HTML Converted');
100         convertPdfAndSendFax(req, res, uuid, req.body);
101       });
102     }
103   } else {
104     form.parse(req, function(err, fields, files) {
105       if (err) {
106         return handleError(res, err);
107       }
108
109       if (fields.html) {
110         //There is HTML with PDF
111         var uuid = uuidLib.v4();
112         var dest = path.join(config.root, 'server/files/fax/outbound/original', uuid + '.pdf');
113         pdf.create(fields.html, {
114           "timeout": 30000
115         }).toFile(dest, function(err, result) {
116           console.log('Fax: HTML Converted');
117           var pdfHTML = spindrift(result.filename);
118           var pdfUploaded = spindrift(files.file.path);
119           var uuid = uuidLib.v4();
120           spindrift.join(pdfHTML, pdfUploaded).pdfStream().pipe(fs.createWriteStream(path.join(config.root, 'server/files/fax/outbound/original', uuid + '.pdf')));
121           console.log('Fax: HTML joined with PDF uploaded');
122           convertPdfAndSendFax(req, res, uuid, fields);
123         });
124       } else {
125         //There is only PDF
126         var uuid = uuidLib.v4();
127         var dest = path.join(config.root, 'server/files/fax/outbound/original', uuid + '.pdf');
128         fs.rename(files.file.path, dest, function(err) {
129           if (err) {
130             console.error(err);
131             return handleError(res, req);
132             // return next(err);
133           }
134           console.log('Fax: PDF Rename');
135           convertPdfAndSendFax(req, res, uuid, fields);
136         });
137       }
138
139     });
140   }
141 };
142
143 function convertPdfAndSendFax(req, res, filenameInput, fields) {
144   var inputPath = path.join(config.root, 'server', 'files', 'fax', 'outbound', 'original', filenameInput + '.pdf');
145   var resultPath = path.join(config.root, 'server', 'files', 'fax', 'outbound', 'converted', filenameInput + '.tif');
146   var command = 'gs' + ' -q -dNOPAUSE -dBATCH -sDEVICE=tiffg4 ' + '-sPAPERSIZE=letter -sOutputFile=' + resultPath + ' ' + inputPath;
147   // console.log(inputPath, resultPath, command);
148
149   var uuidFax = uuidLib.v4();
150   FaxAccount
151     .findById(fields.accountId)
152     .then(function(faxAccount) {
153       // console.log('FaxAccount', faxAccount);
154
155       if (faxAccount) {
156         var faxBody = {
157           technology: 'SIP',
158           to: fields.toNum,
159           from: faxAccount.phone,
160           fax_file: resultPath,
161           fax_header: faxAccount.faxheader,
162           fax_localid: faxAccount.localid,
163           maxrate: faxAccount.maxrate,
164           minrate: faxAccount.minrate,
165           ecm: faxAccount.ecm,
166           uuid: uuidFax,
167           trunk: {
168             id: faxAccount.TrunkId
169           }
170         };
171
172         fs.exists(inputPath, function(exists) {
173           if (!exists) {
174             // console.log('File not exist');
175             handleError(res, new Error('File not exists'));
176           } else {
177             exec(command, function(err) {
178               if (err) {
179                 console.error(err);
180                 handleError(res, err);
181               } else {
182                 console.log('Fax: PDF converted to TIFF');
183                 fs.chmod(resultPath, 511, function(err) {
184                   if (fields.roomId) {
185                     // Room already exists -> create new message and associate
186                     FaxRoom
187                       .findOrCreate({
188                         where: {
189                           id: fields.roomId
190                         },
191                         defaults: {}
192                       })
193                       .spread(function(faxRoom, created) {
194                         // TODO Verify if we have to manage also the created
195                         FaxMessage
196                           .create({
197                             status: 'NOT SENT',
198                             read: true,
199                             filenamePDF: filenameInput + '.pdf',
200                             filename: filenameInput + '.tif',
201                             body: JSON.stringify(faxBody),
202                             uuid: uuidFax,
203                             FaxRoomId: faxRoom.id
204                           })
205                           .then(function(faxMessage) {
206                             // Fax message created, now association
207                             Contact
208                               .findOrCreate({
209                                 where: {
210                                   phone: faxBody.from
211                                 },
212                                 defaults: {
213                                   phone: faxBody.from,
214                                   fullname: faxBody.from
215                                 }
216                               })
217                               .spread(function(contact, created) {
218                                 // console.log('Set relationship with from', created);
219                                 faxMessage.setFrom(contact);
220                               });
221
222                             Contact
223                               .findOrCreate({
224                                 where: {
225                                   phone: faxBody.to
226                                 },
227                                 defaults: {
228                                   phone: faxBody.to,
229                                   fullname: faxBody.to
230                                 }
231                               })
232                               .spread(function(contact, created) {
233                                 // console.log('Set relationship with to', created);
234                                 faxMessage.setTo(contact);
235                               });
236
237                             return res.status(200).send(faxMessage);
238                           })
239                           .catch(function(err) {
240                             handleError(res, err);
241                             // console.error(err);
242                             // next(err);
243                           });
244                       });
245                   } else {
246                     // Room not exists -> create room, message and associate
247                     FaxRoom
248                       .create({
249                         status: 'OPEN',
250                         from: fields.toNum,
251                         FaxAccountId: fields.accountId,
252                         UserId: fields.userId
253                       })
254                       .then(function(faxRoom) {
255                         // Room created, now message
256                         FaxMessage
257                           .create({
258                             status: 'NOT SENT',
259                             read: true,
260                             filenamePDF: filenameInput + '.pdf',
261                             filename: filenameInput + '.tif',
262                             body: JSON.stringify(faxBody),
263                             uuid: uuidFax,
264                             FaxRoomId: faxRoom.id
265                           })
266                           .then(function(faxMessage) {
267                             // Fax message created, now association
268
269                             Contact
270                               .findOrCreate({
271                                 where: {
272                                   phone: faxBody.from
273                                 },
274                                 defaults: {
275                                   phone: faxBody.from,
276                                   fullname: faxBody.from
277                                 }
278                               })
279                               .spread(function(contact, created) {
280                                 faxMessage.setFrom(contact);
281                               });
282
283                             Contact
284                               .findOrCreate({
285                                 where: {
286                                   phone: faxBody.to
287                                 },
288                                 defaults: {
289                                   phone: faxBody.to,
290                                   fullname: faxBody.to
291                                 }
292                               })
293                               .spread(function(contact, created) {
294                                 faxMessage.setTo(contact);
295                               });
296
297                             return res.status(200).send(
298                               faxMessage);
299                           })
300                           .catch(function(err) {
301                             handleError(res, err);
302                           });
303                       })
304                       .catch(function(err) {
305                         handleError(res, err);
306                       });
307                   }
308                 });
309               }
310             });
311           }
312         });
313       }
314     });
315 }
316
317 // Updates an existing fax_message in the DB.
318 exports.update = function(req, res) {
319   if (req.body.id) {
320     delete req.body.id;
321   }
322   FaxMessage
323     .findOne({
324       where: {
325         id: req.params.id
326       },
327       include: [{
328         model: Contact,
329         as: 'From'
330       }, {
331         model: Contact,
332         as: 'To'
333       }]
334     })
335     .then(function(fax_message) {
336       if (!fax_message) {
337         return res.sendStatus(404);
338       }
339       var updated = _.merge(fax_message, req.body);
340       updated.save()
341         .then(function() {
342           return res.status(200).send(fax_message);
343         })
344         .catch(function(err) {
345           return handleError(res, err);
346         });
347     })
348     .catch(function(err) {
349       return handleError(res, err);
350     });
351 };
352
353 // Deletes a fax_message from the DB.
354 exports.destroy = function(req, res) {
355   FaxMessage
356     .find({
357       where: {
358         id: req.params.id
359       }
360     })
361     .then(function(fax_message) {
362       if (!fax_message) {
363         return res.sendStatus(404);
364       }
365       fax_message.destroy()
366         .then(function() {
367           return res.sendStatus(204);
368         })
369         .catch(function(err) {
370           return handleError(res, err);
371         });
372     })
373     .catch(function(err) {
374       return handleError(res, err);
375     });
376 };
377
378 exports.getContentFromMessage = function(req, res) {
379
380   FaxMessage
381     .findById(req.params.id)
382     .then(function(fax_message) {
383
384       // console.log(fax_message);
385
386       if (!fax_message) {
387         return res.sendStatus(404);
388       }
389
390       if (fax_message.filenamePDF) {
391
392         if (fax_message.status === 'RECEIVED') {
393           var pdfPath = path.join(config.root, 'server', 'files', 'fax', 'inbound', fax_message.filenamePDF);
394           fs.exists(pdfPath, function(exists) {
395             if (exists)
396               return res.sendFile(pdfPath);
397             else
398               return res.sendStatus(404);
399           });
400         } else if (fax_message.status === 'NOT SENT' || fax_message.directory ===
401           'SENT' || fax_message.status === 'FAILED') {
402           var pdfPath = path.join(config.root, 'server', 'files', 'fax', 'outbound', 'original', fax_message.filenamePDF);
403           fs.exists(pdfPath, function(exists) {
404             if (exists)
405               return res.sendFile(pdfPath);
406             else
407               return res.sendStatus(404);
408           });
409         }
410       } else {
411         res.sendStatus(404);
412       }
413
414     })
415     .catch(function(err) {
416       return handleError(res, err);
417     });
418 };
419
420 function handleError(res, err) {
421   return res.status(500).send(err);
422 }