Commit bf34bf1e43a19651d5d75d9177066a161fa73338
1 parent
feb33337
Exists in
master
First code
Showing
17 changed files
with
1387 additions
and
1 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | +SCRIPT_NAME := wikilibras-db-api | |
| 2 | +SCRIPT_PATH := $(CURDIR)/${SCRIPT_NAME} | |
| 3 | +SCRIPT_PATH_TMP := /tmp/${SCRIPT_NAME} | |
| 4 | +SCRIPT_PATH_ETC := /etc/init.d/${SCRIPT_NAME} | |
| 5 | +NPM := $(shell which npm) | |
| 6 | + | |
| 7 | +install: | |
| 8 | + @ npm install | |
| 9 | + @ sudo npm install -g supervisor | |
| 10 | + | |
| 11 | +autostart-enable: | |
| 12 | + @ install -m 777 -p ${SCRIPT_PATH} ${SCRIPT_PATH_TMP} | |
| 13 | + @ sed -i "s#<CURDIR>#$(CURDIR)#" ${SCRIPT_PATH_TMP} | |
| 14 | + @ sed -i "s#<SCRIPT_NAME>#${SCRIPT_NAME}#" ${SCRIPT_PATH_TMP} | |
| 15 | + @ sed -i "s#<NPM>#${NPM}#" ${SCRIPT_PATH_TMP} | |
| 16 | + @ sudo install -m 755 -p ${SCRIPT_PATH_TMP} ${SCRIPT_PATH_ETC} | |
| 17 | + @ sudo update-rc.d -f ${SCRIPT_NAME} remove | |
| 18 | + @ sudo update-rc.d -f ${SCRIPT_NAME} defaults | |
| 19 | + | |
| 20 | +autostart-disable: | |
| 21 | + @ sudo update-rc.d -f ${SCRIPT_NAME} remove | |
| 22 | + @ sudo rm -f ${SCRIPT_PATH_ETC} | |
| 23 | + | |
| 24 | +clean: | |
| 25 | + @ sudo chmod -R 777 ./public/users/ ./uploads/ | |
| 26 | + @ find ./public/users/ -type d -empty -delete | |
| 27 | + | |
| 28 | +distclean: | |
| 29 | + @ sudo rm -rf ./public/users/ ./uploads/ | |
| 30 | + | |
| 31 | +run: | |
| 32 | + @ sudo ${NPM} start | |
| 33 | + | |
| 34 | +unistall: distclean | |
| 35 | + @ rm -rf ./node_modules/ | |
| 36 | + | |
| 37 | +ROLENAME := wikilibras | |
| 38 | +DATABASE := wikilibras | |
| 39 | +PASSWORD := wikilibras123 | |
| 40 | +DBFILEIN := wikilibras-db-api.sql | |
| 41 | +DBOUTBAK := wikilibras-db-api-dump.sql | |
| 42 | +VERBOSE := #-v | |
| 43 | + | |
| 44 | +create-db: .create-role .create-db .restore-db | |
| 45 | +drop-db: .restart-db .drop-db .drop-role | |
| 46 | + | |
| 47 | +dump-db: | |
| 48 | + @ sudo su postgres -c "PGPASSWORD='${PASSWORD}' pg_dump ${VERBOSE} -b --inserts ${ROLENAME};" > ${DBOUTBAK} | |
| 49 | + | |
| 50 | +.create-db: | |
| 51 | + @ sudo su postgres -c "psql -c \"CREATE DATABASE ${DATABASE} OWNER ${ROLENAME};\"" | |
| 52 | + | |
| 53 | +.create-role: | |
| 54 | + @ sudo su postgres -c "psql -c \"CREATE USER ${ROLENAME} WITH PASSWORD '${PASSWORD}';\"" | |
| 55 | + | |
| 56 | +.drop-db: | |
| 57 | + @ sudo su postgres -c "psql -c \"DROP DATABASE ${DATABASE};\"" | |
| 58 | + | |
| 59 | +.drop-role: | |
| 60 | + @ sudo su postgres -c "psql -c \"DROP USER ${ROLENAME};\"" | |
| 61 | + | |
| 62 | +populate-db: | |
| 63 | + @ sudo su postgres -c "psql --set ON_ERROR_STOP=off -f ${DBOUTBAK} ${ROLENAME}" | |
| 64 | + | |
| 65 | +.restart-db: | |
| 66 | + @ sudo service postgresql restart | |
| 67 | + | |
| 68 | +.restore-db: | |
| 69 | + @ sudo su postgres -c "psql --set ON_ERROR_STOP=off -f ${DBFILEIN} ${ROLENAME}" | |
| 70 | + | |
| 71 | +.PHONY: autostart-enable autostart-disable clean distclean install run uninstall | |
| 0 | 72 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,94 @@ |
| 1 | +var _ = require("lodash"); | |
| 2 | +var async = require("async"); | |
| 3 | +var bodyParser = require("body-parser"); | |
| 4 | +var cookieParser = require("cookie-parser"); | |
| 5 | +var express = require("express"); | |
| 6 | +var favicon = require("serve-favicon"); | |
| 7 | +var http = require("http"); | |
| 8 | +var logger = require("morgan"); | |
| 9 | +var multer = require("multer"); | |
| 10 | +var path = require("path"); | |
| 11 | +var util = require("util"); | |
| 12 | +var files = require(path.join(__dirname, "helpers/files")); | |
| 13 | +var routes = require(path.join(__dirname, "routes/index")); | |
| 14 | +var users = require(path.join(__dirname, "routes/users")); | |
| 15 | +var app = express(); | |
| 16 | +var server = http.createServer(app); | |
| 17 | + | |
| 18 | +var upload = multer( | |
| 19 | +{ | |
| 20 | + dest: "uploads/" | |
| 21 | +}); | |
| 22 | + | |
| 23 | +server.maxConnections = 5000; | |
| 24 | + | |
| 25 | +// static path | |
| 26 | +app.use("/sinais", express.static(path.join(__dirname, "sinais"))); | |
| 27 | +app.use("/avatar", express.static(path.join(__dirname, "avatar"))); | |
| 28 | +app.use("/blender", express.static(path.join(__dirname, "blender"))); | |
| 29 | +app.use("/public", express.static(path.join(__dirname, "public"))); | |
| 30 | + | |
| 31 | +// view engine setup | |
| 32 | +app.set("views", path.join(__dirname, "views")); | |
| 33 | +app.set("view engine", "pug"); | |
| 34 | + | |
| 35 | +// uncomment after placing your favicon in /public | |
| 36 | +app.use(favicon(path.join(__dirname, "public", "img", "favicon.ico"))); | |
| 37 | +app.use(logger("dev")); | |
| 38 | +app.use(bodyParser.json({limit: "50mb"})); | |
| 39 | +app.use(bodyParser.urlencoded( | |
| 40 | +{ | |
| 41 | + extended: true | |
| 42 | +})); | |
| 43 | + | |
| 44 | +app.use(cookieParser()); | |
| 45 | +app.use(function(req, res, next) | |
| 46 | +{ | |
| 47 | + res.header("Access-Control-Allow-Origin", "*"); | |
| 48 | + res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE"); | |
| 49 | + res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type"); | |
| 50 | + next(); | |
| 51 | +}); | |
| 52 | + | |
| 53 | +app.use("/", routes); | |
| 54 | +app.use("/users", users); | |
| 55 | + | |
| 56 | +// catch 404 and forward to error handler | |
| 57 | +app.use(function(req, res, next) | |
| 58 | +{ | |
| 59 | + var err = new Error("Not Found"); | |
| 60 | + err.status = 404; | |
| 61 | + next(err); | |
| 62 | +}); | |
| 63 | + | |
| 64 | +// error handlers | |
| 65 | + | |
| 66 | +// development error handler | |
| 67 | +// will print stacktrace | |
| 68 | +if (app.get("env") === "development") | |
| 69 | +{ | |
| 70 | + app.use(function(err, req, res, next) | |
| 71 | + { | |
| 72 | + res.status(err.status || 500); | |
| 73 | + res.render("error" | |
| 74 | + , { | |
| 75 | + message: err.message | |
| 76 | + , error: err | |
| 77 | + }); | |
| 78 | + }); | |
| 79 | +} | |
| 80 | + | |
| 81 | +// production error handler | |
| 82 | +// no stacktraces leaked to user | |
| 83 | +app.use(function(err, req, res, next) | |
| 84 | +{ | |
| 85 | + res.status(err.status || 500); | |
| 86 | + res.render("error" | |
| 87 | + , { | |
| 88 | + message: err.message | |
| 89 | + , error: | |
| 90 | + {} | |
| 91 | + }); | |
| 92 | +}); | |
| 93 | + | |
| 94 | +module.exports = app; | ... | ... |
| ... | ... | @@ -0,0 +1,90 @@ |
| 1 | +#!/usr/bin/env node | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Module dependencies. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +var app = require('../app'); | |
| 8 | +var debug = require('debug')('wikilibrasdbapi:server'); | |
| 9 | +var http = require('http'); | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * Get port from environment and store in Express. | |
| 13 | + */ | |
| 14 | + | |
| 15 | +var port = normalizePort(process.env.PORT || '200'); | |
| 16 | +app.set('port', port); | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * Create HTTP server. | |
| 20 | + */ | |
| 21 | + | |
| 22 | +var server = http.createServer(app); | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * Listen on provided port, on all network interfaces. | |
| 26 | + */ | |
| 27 | + | |
| 28 | +server.listen(port); | |
| 29 | +server.on('error', onError); | |
| 30 | +server.on('listening', onListening); | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Normalize a port into a number, string, or false. | |
| 34 | + */ | |
| 35 | + | |
| 36 | +function normalizePort(val) { | |
| 37 | + var port = parseInt(val, 10); | |
| 38 | + | |
| 39 | + if (isNaN(port)) { | |
| 40 | + // named pipe | |
| 41 | + return val; | |
| 42 | + } | |
| 43 | + | |
| 44 | + if (port >= 0) { | |
| 45 | + // port number | |
| 46 | + return port; | |
| 47 | + } | |
| 48 | + | |
| 49 | + return false; | |
| 50 | +} | |
| 51 | + | |
| 52 | +/** | |
| 53 | + * Event listener for HTTP server "error" event. | |
| 54 | + */ | |
| 55 | + | |
| 56 | +function onError(error) { | |
| 57 | + if (error.syscall !== 'listen') { | |
| 58 | + throw error; | |
| 59 | + } | |
| 60 | + | |
| 61 | + var bind = typeof port === 'string' | |
| 62 | + ? 'Pipe ' + port | |
| 63 | + : 'Port ' + port; | |
| 64 | + | |
| 65 | + // handle specific listen errors with friendly messages | |
| 66 | + switch (error.code) { | |
| 67 | + case 'EACCES': | |
| 68 | + console.error(bind + ' requires elevated privileges'); | |
| 69 | + process.exit(1); | |
| 70 | + break; | |
| 71 | + case 'EADDRINUSE': | |
| 72 | + console.error(bind + ' is already in use'); | |
| 73 | + process.exit(1); | |
| 74 | + break; | |
| 75 | + default: | |
| 76 | + throw error; | |
| 77 | + } | |
| 78 | +} | |
| 79 | + | |
| 80 | +/** | |
| 81 | + * Event listener for HTTP server "listening" event. | |
| 82 | + */ | |
| 83 | + | |
| 84 | +function onListening() { | |
| 85 | + var addr = server.address(); | |
| 86 | + var bind = typeof addr === 'string' | |
| 87 | + ? 'pipe ' + addr | |
| 88 | + : 'port ' + addr.port; | |
| 89 | + debug('Listening on ' + bind); | |
| 90 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,104 @@ |
| 1 | +var parameters = require('../helpers/parameters'); | |
| 2 | +var http = require('http'); | |
| 3 | +var fs = require('fs'); | |
| 4 | +var _ = require('lodash'); | |
| 5 | + | |
| 6 | +/* | |
| 7 | +* Função que processa o vídeo (seja baixando, seja pegando o vídeo enviado) | |
| 8 | +* Deve retornar um objeto contendo o nome e o caminho | |
| 9 | +*/ | |
| 10 | +function downloadAndMoveVideo(req, folder, callback) | |
| 11 | +{ | |
| 12 | + console.log(req.files[0].path + " " + req.files[0].originalname); | |
| 13 | + // Se enviou o arquivo na requisição | |
| 14 | + if (req.files[0].fieldname !== undefined) | |
| 15 | + { | |
| 16 | + // Se a validação falhar | |
| 17 | + if (parameters.checkVideo(req.files[0].originalname) === false) | |
| 18 | + { | |
| 19 | + var error = 'Vídeo enviado com extensão inválida'; | |
| 20 | + return callback(error); | |
| 21 | + } | |
| 22 | + /* Move o vídeo submetido para a pasta com o seu ID correspondente */ | |
| 23 | + try | |
| 24 | + { | |
| 25 | + if (!_.isEmpty(req.body.wikilibras)) | |
| 26 | + { | |
| 27 | + fs.renameSync(req.files[0].path, 'avatar/' + req.files[0].originalname); | |
| 28 | + fs.renameSync(req.files[1].path, 'blender/' + req.files[1].originalname); | |
| 29 | + } | |
| 30 | + else | |
| 31 | + { | |
| 32 | + fs.renameSync(req.files[0].path, 'uploads/' + req.files[0].originalname); | |
| 33 | + } | |
| 34 | + } | |
| 35 | + catch (err) | |
| 36 | + { | |
| 37 | + console.log("Erro ao mover o vídeo submetido: " + err); | |
| 38 | + callback("Erro ao mover o vídeo submetido: " + err); | |
| 39 | + } | |
| 40 | + return callback(); | |
| 41 | + } // Se o arquivo não foi enviado, mas um video_url foi | |
| 42 | + else if (req.body.video_url !== undefined) | |
| 43 | + { | |
| 44 | + // Requisição para baixar o vídeo | |
| 45 | + http.get(req.body.video_url, function(response) | |
| 46 | + { | |
| 47 | + | |
| 48 | + // Se o vídeo não foi baixado com sucesso | |
| 49 | + if (response.statusCode !== 200) | |
| 50 | + { | |
| 51 | + var error = 'Problema ao carregar video_url: status ' + response.statusCode; | |
| 52 | + return callback(error); | |
| 53 | + } | |
| 54 | + | |
| 55 | + // Nome do arquivo | |
| 56 | + var filename = req.body.video_url.substring(req.body.video_url.lastIndexOf('/') + 1); | |
| 57 | + | |
| 58 | + // Tira os parâmetros HTTP | |
| 59 | + if (filename.lastIndexOf("?") !== -1) | |
| 60 | + { | |
| 61 | + filename = filename.substring(0, filename.lastIndexOf("?")); | |
| 62 | + } | |
| 63 | + | |
| 64 | + var path = folder + '/' + filename; | |
| 65 | + | |
| 66 | + // Cria o stream para escrita | |
| 67 | + var file = fs.createWriteStream(path); | |
| 68 | + | |
| 69 | + // Salva o arquivo em disco | |
| 70 | + response.pipe(file); | |
| 71 | + | |
| 72 | + // Quando a escrita acabar | |
| 73 | + file.on('finish', function() | |
| 74 | + { | |
| 75 | + // Fecha o arquivo | |
| 76 | + file.close(function() | |
| 77 | + { | |
| 78 | + | |
| 79 | + // Retorna o vídeo baixado | |
| 80 | + locals.video = { | |
| 81 | + 'path': path | |
| 82 | + }; | |
| 83 | + | |
| 84 | + // Chama o callback para prosseguir execução | |
| 85 | + callback(); | |
| 86 | + }); | |
| 87 | + }); | |
| 88 | + | |
| 89 | + // Se deu erro na requisição de baixar o vídeo | |
| 90 | + }).on('error', function(e) { | |
| 91 | + var error = 'Problema ao carregar video_url: ' + e.message; | |
| 92 | + return callback(error); | |
| 93 | + }); | |
| 94 | + | |
| 95 | + // Se nem o vídeo foi enviado e nem o video_url foi preenchido | |
| 96 | + } | |
| 97 | + else | |
| 98 | + { | |
| 99 | + var error = "Video deve ser enviado como parâmetro 'video' ou como 'video_url'"; | |
| 100 | + return callback(error); | |
| 101 | + } | |
| 102 | +} | |
| 103 | + | |
| 104 | +module.exports.downloadAndMoveVideo = downloadAndMoveVideo; | ... | ... |
| ... | ... | @@ -0,0 +1,182 @@ |
| 1 | +function getServiceType(service_type) | |
| 2 | +{ | |
| 3 | + switch(service_type) | |
| 4 | + { | |
| 5 | + case 'video-legenda': return 2; break; | |
| 6 | + case 'video': return 3; break; | |
| 7 | + case 'texto': return 4; break; | |
| 8 | + case 'ios': return 4; break; | |
| 9 | + case 'legenda': return 5; break; | |
| 10 | + case 'audio': return 6; break; | |
| 11 | + } | |
| 12 | +}; | |
| 13 | + | |
| 14 | +function getLanguage(language) | |
| 15 | +{ | |
| 16 | + switch(language) | |
| 17 | + { | |
| 18 | + case 'portugues': return 'portugues'; break; | |
| 19 | + case 'glosa': return 'glosa'; break; | |
| 20 | + } | |
| 21 | +}; | |
| 22 | + | |
| 23 | +function getPosition(position) | |
| 24 | +{ | |
| 25 | + switch(position) | |
| 26 | + { | |
| 27 | + case 'superior-esquerdo': return 'top_left'; break; | |
| 28 | + case 'superior-direito': return 'top_right'; break; | |
| 29 | + case 'inferior-direito': return 'bottom_right'; break; | |
| 30 | + case 'inferior-esquerdo': return 'bottom_left'; break; | |
| 31 | + } | |
| 32 | +}; | |
| 33 | + | |
| 34 | +function getSize(size) | |
| 35 | +{ | |
| 36 | + switch(size) | |
| 37 | + { | |
| 38 | + case 'pequeno': return 1; break; | |
| 39 | + case 'medio': return 2; break; | |
| 40 | + case 'grande': return 3; break; | |
| 41 | + } | |
| 42 | +}; | |
| 43 | + | |
| 44 | +function getTransparency(transparency) | |
| 45 | +{ | |
| 46 | + switch(transparency) | |
| 47 | + { | |
| 48 | + case 'opaco': return 'opaque'; break; | |
| 49 | + case 'transparente': return 'transp'; break; | |
| 50 | + } | |
| 51 | +}; | |
| 52 | + | |
| 53 | +function getSize(size) | |
| 54 | +{ | |
| 55 | + switch(size) | |
| 56 | + { | |
| 57 | + case 'pequeno': return 'small'; break; | |
| 58 | + case 'medio': return 'medium'; break; | |
| 59 | + case 'grande': return 'large'; break; | |
| 60 | + } | |
| 61 | +}; | |
| 62 | + | |
| 63 | +function checkServiceType(service_type) | |
| 64 | +{ | |
| 65 | + var t_types = ['video', 'texto']; | |
| 66 | + for (var i = 0; i < t_types.length; i++) | |
| 67 | + { | |
| 68 | + if (service_type === t_types[i]) | |
| 69 | + { | |
| 70 | + return true; | |
| 71 | + } | |
| 72 | + } | |
| 73 | + return false; | |
| 74 | +}; | |
| 75 | + | |
| 76 | +function checkLanguage(language) | |
| 77 | +{ | |
| 78 | + var t_types = ['portugues', 'glosa']; | |
| 79 | + for (var i = 0; i < t_types.length; i++) | |
| 80 | + { | |
| 81 | + if (language === t_types[i]) | |
| 82 | + { | |
| 83 | + return true; | |
| 84 | + } | |
| 85 | + } | |
| 86 | + return false; | |
| 87 | +}; | |
| 88 | + | |
| 89 | +function checkPosition(position) | |
| 90 | +{ | |
| 91 | + var t_types = ['superior-esquerdo', 'superior-direito', 'inferior-esquerdo', 'inferior-direito']; | |
| 92 | + for (var i = 0; i < t_types.length; i++) | |
| 93 | + { | |
| 94 | + if (position === t_types[i]) | |
| 95 | + { | |
| 96 | + return true; | |
| 97 | + } | |
| 98 | + } | |
| 99 | + return false; | |
| 100 | +}; | |
| 101 | + | |
| 102 | +function checkSize(size) | |
| 103 | +{ | |
| 104 | + var t_types = ['pequeno', 'medio', 'grande']; | |
| 105 | + for (var i = 0; i < t_types.length; i++) | |
| 106 | + { | |
| 107 | + if (size === t_types[i]) | |
| 108 | + { | |
| 109 | + return true; | |
| 110 | + } | |
| 111 | + } | |
| 112 | + return false; | |
| 113 | +}; | |
| 114 | + | |
| 115 | +function checkTransparency(transparency) | |
| 116 | +{ | |
| 117 | + var t_types = ['opaco', 'transparente']; | |
| 118 | + for (var i = 0; i < t_types.length; i++) | |
| 119 | + { | |
| 120 | + if (transparency === t_types[i]) | |
| 121 | + { | |
| 122 | + return true; | |
| 123 | + } | |
| 124 | + } | |
| 125 | + return false; | |
| 126 | +}; | |
| 127 | + | |
| 128 | +function checkVideo(file) { | |
| 129 | + var accepted_file_types = ['flv', 'ts', 'avi', 'mp4', 'mov', 'webm', 'wmv', 'mkv', 'srt']; | |
| 130 | + return check_type(file, accepted_file_types); | |
| 131 | +}; | |
| 132 | + | |
| 133 | +function checkSubtitle(file) | |
| 134 | +{ | |
| 135 | + var accepted_file_types = ['srt']; | |
| 136 | + return check_type(file, accepted_file_types); | |
| 137 | +}; | |
| 138 | + | |
| 139 | +function checkAudio(file) | |
| 140 | +{ | |
| 141 | + var accepted_file_types = ['mp3', 'wav', 'aac', 'flac', 'ogg', 'wma']; | |
| 142 | + return check_type(file, accepted_file_types); | |
| 143 | +}; | |
| 144 | + | |
| 145 | +function check_type(file, accepted_file_types) | |
| 146 | +{ | |
| 147 | + var ext = file.substring(file.lastIndexOf('.') + 1).toLowerCase(); | |
| 148 | + var isValidFile = false; | |
| 149 | + for (var i = 0; i < accepted_file_types.length; i++) | |
| 150 | + { | |
| 151 | + if (ext == accepted_file_types[i]) | |
| 152 | + { | |
| 153 | + isValidFile = true; | |
| 154 | + break; | |
| 155 | + } | |
| 156 | + } | |
| 157 | + if (!isValidFile) | |
| 158 | + { | |
| 159 | + file.value = null; | |
| 160 | + } | |
| 161 | + return isValidFile; | |
| 162 | +}; | |
| 163 | + | |
| 164 | +function errorMessage(message) | |
| 165 | +{ | |
| 166 | + return JSON.stringify({ 'error': message }) | |
| 167 | +}; | |
| 168 | + | |
| 169 | +module.exports.getServiceType = getServiceType; | |
| 170 | +module.exports.getLanguage = getLanguage; | |
| 171 | +module.exports.getPosition = getPosition; | |
| 172 | +module.exports.getSize = getSize; | |
| 173 | +module.exports.getTransparency = getTransparency; | |
| 174 | +module.exports.checkServiceType = checkServiceType; | |
| 175 | +module.exports.checkLanguage = checkLanguage; | |
| 176 | +module.exports.checkPosition = checkPosition; | |
| 177 | +module.exports.checkSize = checkSize; | |
| 178 | +module.exports.checkTransparency = checkTransparency; | |
| 179 | +module.exports.checkVideo = checkVideo; | |
| 180 | +module.exports.checkSubtitle = checkSubtitle; | |
| 181 | +module.exports.checkAudio = checkAudio; | |
| 182 | +module.exports.errorMessage = errorMessage; | ... | ... |
inicial.txt
| ... | ... | @@ -1 +0,0 @@ |
| 1 | -Repositorio wikilibrasdbapi Criado |
| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | +{ | |
| 2 | + "name": "Wikilibras-DBAPI", | |
| 3 | + "description": "", | |
| 4 | + "version": "1.0.0", | |
| 5 | + "private": true, | |
| 6 | + "scripts": | |
| 7 | + { | |
| 8 | + "start": "supervisor ./bin/www" | |
| 9 | + }, | |
| 10 | + "dependencies": | |
| 11 | + { | |
| 12 | + "bluebird": "~3.4.6", | |
| 13 | + "body-parser": "~1.13.2", | |
| 14 | + "cookie-parser": "~1.3.5", | |
| 15 | + "debug": "~2.2.0", | |
| 16 | + "express": "~4.13.1", | |
| 17 | + "lodash": "~4.15.0", | |
| 18 | + "mkdirp": "~0.5.1", | |
| 19 | + "morgan": "~1.6.1", | |
| 20 | + "multer": "~1.2.0", | |
| 21 | + "pg": "^4.4.6", | |
| 22 | + "pg-promise": "~5.3.3", | |
| 23 | + "pug": "~2.0.0-beta6", | |
| 24 | + "serve-favicon": "~2.3.0" | |
| 25 | + } | |
| 26 | +} | ... | ... |
No preview for this file type
| ... | ... | @@ -0,0 +1,645 @@ |
| 1 | +var express = require("express"); | |
| 2 | +var promise = require("bluebird"); // or any other Promise/A+ compatible library; | |
| 3 | +var _ = require("lodash"); | |
| 4 | +var pgp = require("pg-promise")({promiseLib: promise}); // overriding the default (ES6 Promise); | |
| 5 | +var db = pgp("postgres://wikilibras:wikilibras123@localhost:5432/wikilibras"); | |
| 6 | +var parameters = require("../helpers/parameters"); | |
| 7 | +var async = require("async"); | |
| 8 | +var files = require("../helpers/files.js"); | |
| 9 | +var fs = require('fs'); | |
| 10 | +var path = require("path"); | |
| 11 | +var util = require("util"); | |
| 12 | +var mkdirp = require("mkdirp"); | |
| 13 | +var multer = require("multer"); | |
| 14 | +var upload = multer({dest: "uploads/"}); | |
| 15 | +var users = path.join(__dirname, "../public/users"); | |
| 16 | +var sys = require("util"); | |
| 17 | +var exec = require("child_process").exec; | |
| 18 | +var child = null; | |
| 19 | +var router = express.Router(); | |
| 20 | + | |
| 21 | +// GET home page | |
| 22 | +router.get("/", function(req, res, next) | |
| 23 | +{ | |
| 24 | + res.render("index" | |
| 25 | + , { | |
| 26 | + title: "Wikilibras-DB API", | |
| 27 | + version: "1.0.0" | |
| 28 | + }); | |
| 29 | +}); | |
| 30 | + | |
| 31 | +router.get("/countvideo", function(req, res, next) | |
| 32 | +{ | |
| 33 | + var response = {}; | |
| 34 | + db.query('SELECT COUNT(*) FROM sinal;') | |
| 35 | + .then(function(result) | |
| 36 | + { | |
| 37 | + // response.status = true; | |
| 38 | + // response.message = ""; | |
| 39 | + // response.data = result; | |
| 40 | + // TODO uncomment lines above, remove the line below and | |
| 41 | + response = [parseInt(result[0].count)]; | |
| 42 | + res.status(203); | |
| 43 | + }) | |
| 44 | + .catch(function(error) | |
| 45 | + { | |
| 46 | + response.status = false; | |
| 47 | + response.message = ""; | |
| 48 | + response.data = error; | |
| 49 | + res.status(500); | |
| 50 | + }) | |
| 51 | + .finally(function() | |
| 52 | + { | |
| 53 | + res.send(response); | |
| 54 | + pgp.end(); | |
| 55 | + }); | |
| 56 | +}); | |
| 57 | + | |
| 58 | +router.get("/listselos", function(req, res, next) | |
| 59 | +{ | |
| 60 | + var response = {}; | |
| 61 | + db.query('SELECT "nomeSelo", "idSelo" FROM "tipoSelo";') | |
| 62 | + .then(function(result) | |
| 63 | + { | |
| 64 | + // response.status = true; | |
| 65 | + // response.data = result; | |
| 66 | + response = result; | |
| 67 | + res.status(203); | |
| 68 | + }) | |
| 69 | + .catch(function(error) | |
| 70 | + { | |
| 71 | + response.status = false; | |
| 72 | + response.error = error; | |
| 73 | + res.status(500); | |
| 74 | + }) | |
| 75 | + .finally(function() | |
| 76 | + { | |
| 77 | + res.send(response); | |
| 78 | + pgp.end(); | |
| 79 | + }); | |
| 80 | +}); | |
| 81 | + | |
| 82 | +router.get("/countuservideos", function(req, res, next) | |
| 83 | +{ | |
| 84 | + var response = {}; | |
| 85 | + var limit = 10; | |
| 86 | + if (!_.isEmpty(req.query.limit)) | |
| 87 | + { | |
| 88 | + var _limit = parseInt(req.query.limit); | |
| 89 | + if ((0 <= _limit) && (_limit <= 1000)) | |
| 90 | + { | |
| 91 | + limit = _limit; | |
| 92 | + } | |
| 93 | + } | |
| 94 | + var query = 'SELECT DISTINCT' + | |
| 95 | + ' usuario as username,' + | |
| 96 | + ' "idUsuario" as email,' + | |
| 97 | + ' CAST(COUNT(*) as INTEGER) as videos' + | |
| 98 | + ' FROM sinal' + | |
| 99 | + ' GROUP BY usuario, "idUsuario"' + | |
| 100 | + ' ORDER BY videos DESC, usuario' + | |
| 101 | + ' LIMIT ' + limit + ';'; | |
| 102 | + db.query(query) | |
| 103 | + .then(function(result) | |
| 104 | + { | |
| 105 | + // response.status = true; | |
| 106 | + // response.data = result; | |
| 107 | + response = result; | |
| 108 | + res.status(203); | |
| 109 | + }) | |
| 110 | + .catch(function(error) | |
| 111 | + { | |
| 112 | + response.status = false; | |
| 113 | + response.error = error; | |
| 114 | + console.log(error); | |
| 115 | + res.status(500); | |
| 116 | + }) | |
| 117 | + .finally(function() | |
| 118 | + { | |
| 119 | + res.send(response); | |
| 120 | + pgp.end(); | |
| 121 | + }); | |
| 122 | +}); | |
| 123 | + | |
| 124 | +router.get("/listall", function(req, res, next) | |
| 125 | +{ | |
| 126 | + var response = {}; | |
| 127 | + // db.query('SELECT s."nome", s."data", s.cidade, s.estado, s.file, s.avatar, s.blender, ts."nomeSelo", s."version" FROM "sinal" s, "tipoSelo" ts WHERE s."idSelo" = ts."idSelo"') | |
| 128 | + db.query('SELECT s."data", s."usuario", s."idSinal", s."idSelo", s."nome", s."classe", s."frase", s."estado", s."cidade", s."file" FROM "sinal" s, "tipoSelo" ts WHERE s."idSelo" = ts."idSelo"') | |
| 129 | + .then(function(result) | |
| 130 | + { | |
| 131 | + response = result; | |
| 132 | + res.status(203); | |
| 133 | + }) | |
| 134 | + .catch(function(error) | |
| 135 | + { | |
| 136 | + response = error; | |
| 137 | + res.status(500); | |
| 138 | + }) | |
| 139 | + .finally(function() | |
| 140 | + { | |
| 141 | + res.send(response); | |
| 142 | + pgp.end(); | |
| 143 | + }); | |
| 144 | +}); | |
| 145 | + | |
| 146 | +/* | |
| 147 | +// only for test | |
| 148 | +router.get("/populate", function(req, res, next) | |
| 149 | +{ | |
| 150 | + var response = {}; | |
| 151 | + exec("sudo su postgres -c 'psql --set ON_ERROR_STOP=off -f ../wikilibras-db-api-dump.sql wikilibras'", | |
| 152 | + function(error, stdout, stderr) | |
| 153 | + { | |
| 154 | + if (error) | |
| 155 | + { | |
| 156 | + response.status = false; | |
| 157 | + response.message = "Error while populate"; | |
| 158 | + console.log(stdout); | |
| 159 | + res.status = 500; | |
| 160 | + } | |
| 161 | + else if (stderr.length > 0) | |
| 162 | + { | |
| 163 | + response.status = false; | |
| 164 | + response.message = "The Database already been populated"; | |
| 165 | + console.log(stderr); | |
| 166 | + res.status = 304; | |
| 167 | + } | |
| 168 | + else | |
| 169 | + { | |
| 170 | + response.status = true; | |
| 171 | + response.message = "The Database has been populated"; | |
| 172 | + res.status = 201; | |
| 173 | + } | |
| 174 | + res.send(response); | |
| 175 | + }); | |
| 176 | +}); | |
| 177 | +*/ | |
| 178 | + | |
| 179 | +router.get("/reset", function(req, res, next) | |
| 180 | +{ | |
| 181 | + var response = {}; | |
| 182 | + db.query('TRUNCATE TABLE sinal, selo; ALTER SEQUENCE sequence RESTART WITH 1;') | |
| 183 | + .then(function(result) | |
| 184 | + { | |
| 185 | + response.status = true; | |
| 186 | + response.message = "The database has been truncated"; | |
| 187 | + res.status(203); | |
| 188 | + }) | |
| 189 | + .catch(function(error) | |
| 190 | + { | |
| 191 | + response.status = false; | |
| 192 | + response.message = "The database cannot be truncated"; | |
| 193 | + response.error = error; | |
| 194 | + res.status(500); | |
| 195 | + }) | |
| 196 | + .finally(function() | |
| 197 | + { | |
| 198 | + res.send(response); | |
| 199 | + pgp.end(); | |
| 200 | + // console.log(JSON.stringify(response, null, 4)); | |
| 201 | + }); | |
| 202 | +}); | |
| 203 | + | |
| 204 | +router.get("/version", function(req, res, next) | |
| 205 | +{ | |
| 206 | + var response = []; | |
| 207 | + db.query('SELECT MAX(version) FROM sinal;') | |
| 208 | + .then(function(result) | |
| 209 | + { | |
| 210 | + response = { "version": result[0].max }; | |
| 211 | + }) | |
| 212 | + .catch(function(error) | |
| 213 | + { | |
| 214 | + response = error; | |
| 215 | + }) | |
| 216 | + .finally(function() | |
| 217 | + { | |
| 218 | + pgp.end(); | |
| 219 | + res.status(203).send(response); | |
| 220 | + }); | |
| 221 | +}); | |
| 222 | + | |
| 223 | +router.get("/sinais", function(req, res, next) | |
| 224 | +{ | |
| 225 | + var results = []; | |
| 226 | + if ((!_.isEmpty(req.param("selo"))) && (!_.isEmpty(req.param("version")))) | |
| 227 | + { | |
| 228 | + db.query('SELECT s."nome", s."data", s.cidade, s."version", s.estado, s.file, s.avatar, s.blender, ts."nomeSelo" FROM "sinal" s, "tipoSelo" ts WHERE s."idSelo" = ts."idSelo" AND ts."nomeSelo" = $1 AND s."version" = $2', [req.param("selo"), req.param("version")]) | |
| 229 | + .then(function(result) | |
| 230 | + { | |
| 231 | + res.status(203).send(result); | |
| 232 | + }) | |
| 233 | + .catch(function(error) | |
| 234 | + { | |
| 235 | + // error; | |
| 236 | + }) | |
| 237 | + .finally(function() | |
| 238 | + { | |
| 239 | + pgp.end(); | |
| 240 | + }); | |
| 241 | + } | |
| 242 | + else | |
| 243 | + { | |
| 244 | + if (!_.isEmpty(req.param("version"))) | |
| 245 | + { | |
| 246 | + db.query("select nome, data, file, avatar, blender version FROM sinal WHERE version = $1", req.param("version")) | |
| 247 | + .then(function(result) | |
| 248 | + { | |
| 249 | + res.status(203).send(result); | |
| 250 | + }) | |
| 251 | + .catch(function(error) | |
| 252 | + { | |
| 253 | + // error; | |
| 254 | + }) | |
| 255 | + .finally(function() | |
| 256 | + { | |
| 257 | + pgp.end(); | |
| 258 | + }); | |
| 259 | + } | |
| 260 | + if (!_.isEmpty(req.param("selo"))) | |
| 261 | + { | |
| 262 | + db.query('SELECT s."nome", s."data", s.cidade, s.estado, s.file, s.avatar, s.blender, ts."nomeSelo", s.version FROM "sinal" s, "tipoSelo" ts WHERE s."idSelo" = ts."idSelo" AND ts."nomeSelo" = $1', req.param("selo")) | |
| 263 | + | |
| 264 | + .then(function(result) | |
| 265 | + { | |
| 266 | + res.status(203).send(result); | |
| 267 | + }) | |
| 268 | + .catch(function(error) | |
| 269 | + { | |
| 270 | + // error; | |
| 271 | + }) | |
| 272 | + .finally(function() | |
| 273 | + { | |
| 274 | + pgp.end(); | |
| 275 | + }); | |
| 276 | + } | |
| 277 | + } | |
| 278 | +}); | |
| 279 | + | |
| 280 | +router.post('/gsinal', function(req, res, next) | |
| 281 | +{ | |
| 282 | + console.log("\n\n\n============================================="); | |
| 283 | + console.log("[" + new Date().toISOString() + "] Requisição do IP: " + req.ip); | |
| 284 | + console.log("== Parametros: " + util.inspect(req.body)); | |
| 285 | + console.log("== Body: " + JSON.stringify(req.headers)); | |
| 286 | + db.query('UPDATE sinal SET "idSelo" = ($1), version = version + 1 WHERE nome = ($2)', [req.body.selo, req.body.nome]) | |
| 287 | + .then(function(data) | |
| 288 | + { | |
| 289 | + res.status(203).send('Sinal ' + req.body.nome + ' atualizado com sucesso [without archive]'); | |
| 290 | + }) | |
| 291 | + .catch(function(error) | |
| 292 | + { | |
| 293 | + console.log("Erro " + error); | |
| 294 | + }); | |
| 295 | +}); | |
| 296 | + | |
| 297 | +/* | |
| 298 | +router.post('/addsinal', upload.array('video', 2), function(req, res, next) | |
| 299 | +{ | |
| 300 | + console.log("\n\n\n============================================="); | |
| 301 | + console.log("[" + new Date().toISOString() + "]"); | |
| 302 | + console.log("From: " + req.ip); | |
| 303 | + // console.log("Files: " + req.files[0]); | |
| 304 | + // console.log("headers: " + JSON.stringify(req.headers)); | |
| 305 | + console.log("body: " + JSON.stringify(req.body)); | |
| 306 | + | |
| 307 | + if (req.method === "OPTIONS") | |
| 308 | + { | |
| 309 | + res.header('Access-Control-Allow-Origin', req.headers.origin); | |
| 310 | + } | |
| 311 | + else | |
| 312 | + { | |
| 313 | + res.header('Access-Control-Allow-Origin', '*'); | |
| 314 | + } | |
| 315 | + | |
| 316 | + if (_.isEmpty(req.body.nome)) | |
| 317 | + { | |
| 318 | + res.send(500, 'O valor do parâmetro nome está vazio'); | |
| 319 | + return; | |
| 320 | + } | |
| 321 | + async.series([ | |
| 322 | + function(callback) | |
| 323 | + { | |
| 324 | + console.log("\t >> ORDEM 1"); | |
| 325 | + if (_.isEmpty(req.body.wikilibras)) | |
| 326 | + { | |
| 327 | + console.log("Movendo arquivo para conversão..."); | |
| 328 | + files.downloadAndMoveVideo(req, 'sinais', callback); | |
| 329 | + } | |
| 330 | + else | |
| 331 | + { | |
| 332 | + files.downloadAndMoveVideo(req, 'wikilibras', callback); | |
| 333 | + } | |
| 334 | + }, | |
| 335 | + function(callback) | |
| 336 | + { | |
| 337 | + console.log("\t >> ORDEM 2"); | |
| 338 | + if (_.isEmpty(req.body.wikilibras)) | |
| 339 | + { | |
| 340 | + console.log("Convertendo para .webm..."); | |
| 341 | + child = exec('avconv -v error -i uploads/' + req.files[0].originalname + ' -acodec libvorbis -vcodec libvpx -an sinais/' + req.files[0].originalname.slice(0, -4) + '.webm -y', function(error, stdout, stderr) | |
| 342 | + { | |
| 343 | + console.log('stdout: ' + stdout); | |
| 344 | + console.log('stderr: ' + stderr); | |
| 345 | + if (error !== null) | |
| 346 | + { | |
| 347 | + console.log('exec error: ' + error); | |
| 348 | + } | |
| 349 | + }); | |
| 350 | + | |
| 351 | + child.on('exit', function() | |
| 352 | + { | |
| 353 | + setTimeout(function() | |
| 354 | + { | |
| 355 | + console.log("Conversão para webm concluída."); | |
| 356 | + callback(null, 1); | |
| 357 | + }, 500); | |
| 358 | + }); | |
| 359 | + } | |
| 360 | + else | |
| 361 | + { | |
| 362 | + callback(); | |
| 363 | + } | |
| 364 | + }, | |
| 365 | + function(callback) | |
| 366 | + { | |
| 367 | + console.log("== Alterando o db"); | |
| 368 | + db.query('SELECT "idSelo" FROM "sinal" WHERE nome = $1', req.body.nome) | |
| 369 | + .then(function(result) | |
| 370 | + { | |
| 371 | + var d = new Date(); | |
| 372 | + if (Object.keys(result).length > 0) | |
| 373 | + { | |
| 374 | + if (!_.isEmpty(req.body.overwrite)) | |
| 375 | + { | |
| 376 | + if (!_.isEmpty(req.body.wikilibras)) | |
| 377 | + { | |
| 378 | + db.query('UPDATE sinal SET avatar = ($1), blender = ($2) WHERE nome = ($3)', [req.files[0].originalname, req.files[1].originalname, req.body.nome]) | |
| 379 | + .then(function(data) | |
| 380 | + { | |
| 381 | + res.send(200, 'Sinal ' + req.body.nome + ' atualizado com sucesso [with avatar/blender].'); | |
| 382 | + }) | |
| 383 | + .catch(function(error) | |
| 384 | + { | |
| 385 | + console.log("Erro " + error); | |
| 386 | + }); | |
| 387 | + } | |
| 388 | + if (!_.isEmpty(req.files)) | |
| 389 | + { | |
| 390 | + db.query('UPDATE sinal SET "idSelo" = ($1), version = version + 1, file = ($2) WHERE nome = ($3)', [req.body.selo, req.files[0].originalname, req.body.nome]) | |
| 391 | + .then(function(data) | |
| 392 | + { | |
| 393 | + res.status(200).send('Sinal ' + req.body.nome + ' atualizado com sucesso [with archive].'); | |
| 394 | + }) | |
| 395 | + .catch(function(error) | |
| 396 | + { | |
| 397 | + console.log("Erro " + error); | |
| 398 | + }); | |
| 399 | + } | |
| 400 | + else | |
| 401 | + { | |
| 402 | + db.query('UPDATE sinal SET "idSelo" = ($1) WHERE nome = ($2)', [req.body.selo, req.body.nome]) | |
| 403 | + .then(function(data) | |
| 404 | + { | |
| 405 | + res.status(200).send('Sinal ' + req.body.nome + ' atualizado com sucesso [without archive].'); | |
| 406 | + }) | |
| 407 | + .catch(function(error) | |
| 408 | + { | |
| 409 | + console.log("Erro " + error); | |
| 410 | + }); | |
| 411 | + } | |
| 412 | + } | |
| 413 | + else | |
| 414 | + { | |
| 415 | + res.status(500).send('Sinal já cadastrado no sistema'); | |
| 416 | + } | |
| 417 | + } | |
| 418 | + else | |
| 419 | + { | |
| 420 | + if (_.isEmpty(req.body.selo)) | |
| 421 | + { | |
| 422 | + req.body.selo = 7; | |
| 423 | + } | |
| 424 | + db.one('insert into sinal (usuario, nome, "idSelo", data, version, estado, cidade, file) values ($1, $2, $3, $4, $5, $6, $7, $8) returning "idSinal"', [req.body.login, req.body.nome, req.body.selo, d.getFullYear() + "/" + d.getMonth() + "/" + d.getDate(), 1, req.body.estado, req.body.cidade, req.files[0].originalname.slice(0, -4) + '.webm']) | |
| 425 | + .then(function(data) | |
| 426 | + { | |
| 427 | + res.status(200).send('Sinal ' + req.body.nome + ' adicionado com sucesso.'); | |
| 428 | + }) | |
| 429 | + .catch(function(error) | |
| 430 | + { | |
| 431 | + console.log("Erro " + error); | |
| 432 | + }); | |
| 433 | + } | |
| 434 | + }) | |
| 435 | + .catch(function(error) | |
| 436 | + { | |
| 437 | + console.log(error); | |
| 438 | + }) | |
| 439 | + .finally(function() | |
| 440 | + { | |
| 441 | + pgp.end(); | |
| 442 | + }); | |
| 443 | + } | |
| 444 | + , ], function(err) | |
| 445 | + { | |
| 446 | + if (err) | |
| 447 | + { | |
| 448 | + res.send(500, "Error"); | |
| 449 | + return; | |
| 450 | + } | |
| 451 | + }); | |
| 452 | +}); | |
| 453 | +*/ | |
| 454 | + | |
| 455 | +router.post('/addsinal', upload.array('video', 2), function(req, res, next) | |
| 456 | +{ | |
| 457 | + // console.log("[" + new Date().toISOString() + "]"); | |
| 458 | + // console.log("From: " + req.ip); | |
| 459 | + // console.log("Files: " + JSON.stringify(req.files[0], null, 4)); | |
| 460 | + // console.log("headers: " + JSON.stringify(req.headers, null, 4)); | |
| 461 | + // console.log("body: " + JSON.stringify(req.body, null, 4)); | |
| 462 | + if (req.method === "OPTIONS") | |
| 463 | + { | |
| 464 | + res.header('Access-Control-Allow-Origin', req.headers.origin); | |
| 465 | + } | |
| 466 | + else | |
| 467 | + { | |
| 468 | + res.header('Access-Control-Allow-Origin', '*'); | |
| 469 | + } | |
| 470 | + if (req.files.length < 1) | |
| 471 | + { | |
| 472 | + res.status(500).send("ERROR: O campo 'video' não contém nenhum arquivo do sinal"); | |
| 473 | + return; | |
| 474 | + } | |
| 475 | + var directory = users; | |
| 476 | + var login = req.body["login"]; | |
| 477 | + var estado = req.body["estado"]; | |
| 478 | + var classe = req.body["classe-gramatical"]; | |
| 479 | + var nome = req.body["nome"]; | |
| 480 | + var cidade = req.body["cidade"]; | |
| 481 | + var frase = req.body["frases"]; | |
| 482 | + var selo = req.body["selo"]; | |
| 483 | + var filesize = req.files[0].size; | |
| 484 | + var input = req.files[0].path; | |
| 485 | + var videoref = ""; | |
| 486 | + var output = ""; | |
| 487 | + var maxfilesize = 25; // MB | |
| 488 | + if (filesize > (maxfilesize * 1048576)) | |
| 489 | + { | |
| 490 | + res.status(500).send("O tamanho do arquivo deve ter no máximo " + maxfilesize + " MB"); | |
| 491 | + return; | |
| 492 | + } | |
| 493 | + if (_.isEmpty(nome)) | |
| 494 | + { | |
| 495 | + res.status(500).send("ERROR: O campo 'nome' não foi encontrado"); | |
| 496 | + return; | |
| 497 | + } | |
| 498 | + else | |
| 499 | + { | |
| 500 | + nome = nome.trim().toUpperCase(); | |
| 501 | + videoref = nome + "_REF.webm"; | |
| 502 | + } | |
| 503 | + if (_.isEmpty(selo)) | |
| 504 | + { | |
| 505 | + selo = 7; | |
| 506 | + } | |
| 507 | + if (_.isEmpty(login)) | |
| 508 | + { | |
| 509 | + console.log("WARNING: O campo 'login' não foi encontrado"); | |
| 510 | + } | |
| 511 | + else | |
| 512 | + { | |
| 513 | + directory = path.join(directory, login); | |
| 514 | + } | |
| 515 | + if (_.isEmpty(estado)) | |
| 516 | + { | |
| 517 | + console.log("WARNING: O campo 'estado' não foi encontrado"); | |
| 518 | + } | |
| 519 | + else | |
| 520 | + { | |
| 521 | + directory = path.join(directory, estado); | |
| 522 | + } | |
| 523 | + if (_.isEmpty(classe)) | |
| 524 | + { | |
| 525 | + console.log("WARNING: O campo 'classe' não foi encontrado"); | |
| 526 | + } | |
| 527 | + else | |
| 528 | + { | |
| 529 | + directory = path.join(directory, classe); | |
| 530 | + } | |
| 531 | + if (!fs.existsSync(directory)) | |
| 532 | + { | |
| 533 | + console.log("Criando diretorio: " + directory); | |
| 534 | + mkdirp(directory, function (err) | |
| 535 | + { | |
| 536 | + if (err) | |
| 537 | + { | |
| 538 | + console.error(err); | |
| 539 | + res.status(500).send(err); | |
| 540 | + return; | |
| 541 | + } | |
| 542 | + else | |
| 543 | + { | |
| 544 | + console.log("Diretório criado com sucesso!"); | |
| 545 | + } | |
| 546 | + }); | |
| 547 | + } | |
| 548 | + output = path.join(directory, videoref); | |
| 549 | + async.series([ | |
| 550 | + // Converter para formato webm | |
| 551 | + function(callback) | |
| 552 | + { | |
| 553 | + console.log("Convertendo para webm..."); | |
| 554 | + child = exec("avconv -y -v error -i \"" + input + "\" -acodec libvorbis -vcodec libvpx -an \"" + output + "\"", | |
| 555 | + function(error, stdout, stderr) | |
| 556 | + { | |
| 557 | + if (error || (stderr.length > 0)) | |
| 558 | + { | |
| 559 | + var log = "O arquivo de vídeo é inválido, ou ocorreu um erro durante a conversão\nDetalhes: " + stdout + stderr; | |
| 560 | + log = log.trim(); | |
| 561 | + res.status(500).send(log.trim()); | |
| 562 | + callback(true, log); | |
| 563 | + } | |
| 564 | + else | |
| 565 | + { | |
| 566 | + res.status(200); | |
| 567 | + return 0; | |
| 568 | + } | |
| 569 | + }); | |
| 570 | + child.on("exit", function(code) | |
| 571 | + { | |
| 572 | + setTimeout(function() | |
| 573 | + { | |
| 574 | + if (code === 0) | |
| 575 | + { | |
| 576 | + console.log("Conversão concluída"); | |
| 577 | + callback(null, 1); | |
| 578 | + } | |
| 579 | + else | |
| 580 | + { | |
| 581 | + callback(true, new Error("Erro durante conversão")); | |
| 582 | + } | |
| 583 | + }, 500); | |
| 584 | + }); | |
| 585 | + }, | |
| 586 | + function(callback) | |
| 587 | + { | |
| 588 | + console.log("Verificando se este sinal já existe"); | |
| 589 | + db.query('SELECT "idSinal" FROM "sinal" WHERE usuario = ($1) AND estado = ($2) AND classe = ($3) AND nome = ($4)', [login, estado, classe, nome]) | |
| 590 | + .then(function(result) | |
| 591 | + { | |
| 592 | + var d = new Date(); | |
| 593 | + var date = d.getFullYear() + "/" + d.getMonth() + "/" + d.getDate(); | |
| 594 | + if (Object.keys(result).length > 0) | |
| 595 | + { | |
| 596 | + var idSinal = result[0].idSinal; | |
| 597 | + console.log("Existe, atualizando o sinal[" + idSinal + "]: '" + nome + "'"); | |
| 598 | + db.query('UPDATE sinal SET "idSelo" = ($1), version = ($2), data = ($3), cidade = ($4), frase = ($5), file = ($6) WHERE "idSinal" = ($7)', [7, 0, date, cidade, frase, videoref, idSinal]) | |
| 599 | + .then(function(data) | |
| 600 | + { | |
| 601 | + res.status(200).send("Sinal atualizado"); | |
| 602 | + }) | |
| 603 | + .catch(function(error) | |
| 604 | + { | |
| 605 | + var message = "Erro ao atualizar sinal '" + nome + "'\n" + error; | |
| 606 | + console.log(message); | |
| 607 | + res.status(500).send(message); | |
| 608 | + }); | |
| 609 | + } | |
| 610 | + else | |
| 611 | + { | |
| 612 | + console.log("Não existe, inserindo o sinal: '" + nome + "'"); | |
| 613 | + db.one('INSERT INTO sinal (usuario, nome, classe, "idSelo", data, version, estado, cidade, frase, file) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "idSinal"', [login, nome, classe, selo, date, 0, estado, cidade, frase, videoref]) | |
| 614 | + .then(function(data) | |
| 615 | + { | |
| 616 | + var message = "Sinal[" + data.idSinal + "]: '" + nome + "', inserido com sucesso"; | |
| 617 | + console.log(message); | |
| 618 | + res.status(200).send(message); | |
| 619 | + }) | |
| 620 | + .catch(function(error) | |
| 621 | + { | |
| 622 | + res.status(500).send(error); | |
| 623 | + }); | |
| 624 | + } | |
| 625 | + }) | |
| 626 | + .catch(function(error) | |
| 627 | + { | |
| 628 | + console.log(error); | |
| 629 | + }) | |
| 630 | + .finally(function() | |
| 631 | + { | |
| 632 | + pgp.end(); | |
| 633 | + }); | |
| 634 | + } | |
| 635 | + ], | |
| 636 | + function(err, results) | |
| 637 | + { | |
| 638 | + if (err) | |
| 639 | + { | |
| 640 | + console.log(results[0]); | |
| 641 | + } | |
| 642 | + }); | |
| 643 | +}); | |
| 644 | + | |
| 645 | +module.exports = router; | ... | ... |
| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | +#!/bin/sh | |
| 2 | + | |
| 3 | +### BEGIN INIT INFO | |
| 4 | +# Provides: <SCRIPT_NAME> | |
| 5 | +# Required-Start: $all | |
| 6 | +# Required-Stop: $all | |
| 7 | +# Default-Start: 2 3 4 5 | |
| 8 | +# Default-Stop: 0 1 6 | |
| 9 | +# Short-Description: Service provided <SCRIPT_NAME> | |
| 10 | +# Description: Enable service provided <SCRIPT_NAME> API at boot | |
| 11 | +### END INIT INFO | |
| 12 | + | |
| 13 | +set -e | |
| 14 | + | |
| 15 | +export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | |
| 16 | + | |
| 17 | +CWD="<CURDIR>" | |
| 18 | + | |
| 19 | +case "$1" in | |
| 20 | + start) | |
| 21 | + cd "$CWD" | |
| 22 | + "<NPM>" start& | |
| 23 | + ;; | |
| 24 | + *) | |
| 25 | + echo "Usage: /etc/init.d/<SCRIPT_NAME> {start}" | |
| 26 | + exit 1 | |
| 27 | + ;; | |
| 28 | +esac | |
| 29 | + | |
| 30 | +exit 0 | ... | ... |
| ... | ... | @@ -0,0 +1,89 @@ |
| 1 | +SET statement_timeout = 0; | |
| 2 | +SET lock_timeout = 0; | |
| 3 | +SET client_encoding = 'UTF8'; | |
| 4 | +SET standard_conforming_strings = on; | |
| 5 | +SET check_function_bodies = false; | |
| 6 | +SET client_min_messages = warning; | |
| 7 | + | |
| 8 | +CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; | |
| 9 | + | |
| 10 | +COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; | |
| 11 | + | |
| 12 | +SET search_path = public, pg_catalog; | |
| 13 | + | |
| 14 | +SET default_tablespace = ''; | |
| 15 | + | |
| 16 | +SET default_with_oids = false; | |
| 17 | + | |
| 18 | +CREATE TABLE selo ( | |
| 19 | + "idSelo" integer NOT NULL, | |
| 20 | + "idSinal" integer, | |
| 21 | + data character varying(30), | |
| 22 | + estado character varying(30), | |
| 23 | + cidade character varying(30) | |
| 24 | +); | |
| 25 | + | |
| 26 | +ALTER TABLE public.selo OWNER TO wikilibras; | |
| 27 | + | |
| 28 | +CREATE SEQUENCE sequence | |
| 29 | + START WITH 1 | |
| 30 | + INCREMENT BY 1 | |
| 31 | + NO MINVALUE | |
| 32 | + NO MAXVALUE | |
| 33 | + CACHE 1; | |
| 34 | + | |
| 35 | +ALTER TABLE public.sequence OWNER TO wikilibras; | |
| 36 | + | |
| 37 | +CREATE TABLE sinal ( | |
| 38 | + data character varying(30), | |
| 39 | + -- TODO create table users | |
| 40 | + "idUsuario" integer, | |
| 41 | + usuario character varying(30), | |
| 42 | + version integer DEFAULT 0, | |
| 43 | + "idSinal" integer DEFAULT nextval('sequence'::regclass) NOT NULL, | |
| 44 | + "idSelo" integer, | |
| 45 | + nome character varying(30), | |
| 46 | + classe character varying(30), | |
| 47 | + frase character varying(100), | |
| 48 | + estado character varying(30), | |
| 49 | + cidade character varying(30), | |
| 50 | + file character varying(100), | |
| 51 | + blender character varying(100), | |
| 52 | + avatar character varying(100) | |
| 53 | +); | |
| 54 | + | |
| 55 | +ALTER TABLE public.sinal OWNER TO wikilibras; | |
| 56 | + | |
| 57 | +CREATE TABLE "tipoSelo" ( | |
| 58 | + "nomeSelo" character varying(40), | |
| 59 | + "idSelo" integer DEFAULT nextval('sequence'::regclass) NOT NULL | |
| 60 | +); | |
| 61 | + | |
| 62 | +ALTER TABLE public."tipoSelo" OWNER TO wikilibras; | |
| 63 | + | |
| 64 | +SELECT pg_catalog.setval('sequence', 1, false); | |
| 65 | + | |
| 66 | +INSERT INTO "tipoSelo" VALUES ('wikilibras', 1); | |
| 67 | +INSERT INTO "tipoSelo" VALUES ('especialista', 2); | |
| 68 | +INSERT INTO "tipoSelo" VALUES ('invalido_wikilibras', 3); | |
| 69 | +INSERT INTO "tipoSelo" VALUES ('invalido_especialista', 4); | |
| 70 | +INSERT INTO "tipoSelo" VALUES ('animadores', 5); | |
| 71 | +INSERT INTO "tipoSelo" VALUES ('invalido_animadores', 6); | |
| 72 | +INSERT INTO "tipoSelo" VALUES ('null', 7); | |
| 73 | + | |
| 74 | +ALTER TABLE ONLY sinal | |
| 75 | + ADD CONSTRAINT "idSinal" PRIMARY KEY ("idSinal"); | |
| 76 | + | |
| 77 | +ALTER TABLE ONLY "tipoSelo" | |
| 78 | + ADD CONSTRAINT "tipoSelo_pkey" PRIMARY KEY ("idSelo"); | |
| 79 | + | |
| 80 | +ALTER TABLE ONLY selo | |
| 81 | + ADD CONSTRAINT "selo_idSelo_fkey" FOREIGN KEY ("idSelo") REFERENCES "tipoSelo"("idSelo"); | |
| 82 | + | |
| 83 | +ALTER TABLE ONLY selo | |
| 84 | + ADD CONSTRAINT "selo_idSinal_fkey" FOREIGN KEY ("idSinal") REFERENCES sinal("idSinal"); | |
| 85 | + | |
| 86 | +REVOKE ALL ON SCHEMA public FROM PUBLIC; | |
| 87 | +REVOKE ALL ON SCHEMA public FROM postgres; | |
| 88 | +GRANT ALL ON SCHEMA public TO postgres; | |
| 89 | +GRANT ALL ON SCHEMA public TO PUBLIC; | ... | ... |