コード例 #1
0
    handler: function(request, reply) {

        if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

        // in this endpoint the only search condition is built-in in the param of the url

        // the Validate.ids function has transformed request.params.ids in an
        // array of objects ready to used in the postgres functions; 
        // TODO: this array should be stored somewhere else
console.log("request.params.ids: ", request.params.ids);
        var Seneca = request.server.plugins["seneca-promise"]["seneca"];
        Seneca.actAsync({
                role: "initiatives",
                cmd: "read",
                searchConditions: request.params.ids
            })
            .then(function(data){

                if (data.length === 0) {
                    return reply(Boom.notFound("The resource does not exist."));
                }

                return reply(data).code(200);
            })
            .catch(function(err){

                err = err.isBoom ? err : Boom.badImplementation(err.message);
                return reply(err);
            });

    },
コード例 #2
0
    handler: function(request, reply) {

        if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

        // in this endpoint the only search condition is built-in in the param of the url

        var Seneca = request.server.plugins["seneca-promise"]["seneca"];
        Seneca.actAsync({
                role: "initiatives",
                cmd: "delete",
                searchConditions: request.params.ids[0]
            })
            .then(function(deletedData){

                if (deletedData.length === 0) {
                    return reply(Boom.notFound("The resource does not exist."));
                }

                return reply(deletedData).code(200);
            })
            .catch(function(err){

                err = err.isBoom ? err : Boom.badImplementation(err.message);
                return reply(err);
            });

    },
コード例 #3
0
ファイル: prerequisites.js プロジェクト: paulovieira/clima
	method: function(request, reply){

		Utils.logCallsite(Hoek.callStack()[0]);

		request.server.seneca.act("role: texts, cmd:readAll", function(err, data){
			return reply(err || data);
		});
	},
コード例 #4
0
ファイル: shapes.js プロジェクト: paulovieira/clima
internals.shapesUpdate = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    ChangeCase(args.dbQuery, "underscored");
    var ids = args.dbQuery.map(function(obj){ 
        return { id: obj.id };
    });

    // 1) read the resources to be updated (to verify that they exist)
    Db.func('shapes_read', JSON.stringify(ids))

        // 2) update the resources with the payload data
        .then(function(data) {

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            // TODO: verify that data.length === args.ids.length

            return Db.func("shapes_update", JSON.stringify(args.dbQuery))
        })

        // 3) read again the updated resources (to obtain the joined data)
        .then(function(updatedData) {

            if (updatedData.length === 0) {
                throw Boom.badRequest("The resource could not be updated.");
            }

            var updatedIds = updatedData.map(function(obj){ 
                return { id: obj.id }; 
            });

            return Db.func("shapes_read", JSON.stringify(updatedIds));
        })

        // 4) apply the object transform and reply
        .then(function(data){

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #5
0
	handler: function(request, reply) {

		Utils.logCallsite(Hoek.callStack()[0]);

	    var context = {
	    };

	    return reply.view('404', {
	        ctx: context
	    }).code(404);
	},
コード例 #6
0
ファイル: prerequisites.js プロジェクト: paulovieira/clima
	method: function(request, reply){

		Utils.logCallsite(Hoek.callStack()[0]);

		request.server.seneca.act({
				role: "maps", 
				cmd:"readMenu",
				pre: request.pre,
			}, function(err, data){

			return reply(err || data);
		});
	},
コード例 #7
0
	handler: function(request, reply) {

        if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

        var searchConditions = {};

        // in this endpoint we can have query string search conditions; if there are
        // no query strings, it means we don't have any conditions (that is, read all!);
        // however note that some query strings might have default values, so there's always at
        // least one value
        if(request.query.moderationStatusId){
            searchConditions["moderation_status_id"] = request.query.moderationStatusId;
        }
        if(request.query.typeId){
            searchConditions["type_id"] = request.query.typeId;
        }


        var Seneca = request.server.plugins["seneca-promise"]["seneca"];
        Seneca.actAsync({
                role: "initiatives", 
                cmd: "read",
                searchConditions: searchConditions
            })
            .then(function(data){

                if(request.query.csv){
                    // return promise
                    return CsvStringify(data, {header: true})
                        .then(function(csv){
                            
                            return reply(csv)
                                .code(200)
                                .header('content-type', 'text/csv')
                                .header('content-disposition', 'attachment; filename="rede_convergir_initiatives.csv"')

                        });

                }
                
                return reply(data).code(200);
            })
            .catch(function(err){

                // the action should always return a boom error
                err = err.isBoom ? err : Boom.badImplementation(err.message);
                return reply(err);
            });

	},
コード例 #8
0
ファイル: shapes.js プロジェクト: paulovieira/clima
internals.geoTablesReadAll = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    Db.query('select * from geo_tables')
        .then(function(data) {

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMapGeoTables);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #9
0
ファイル: texts.js プロジェクト: paulovieira/clima
internals.textsReadAll = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    Db.func('texts_read')
        .then(function(data) {

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #10
0
ファイル: prerequisites.js プロジェクト: paulovieira/clima
	method: function(request, reply){

		Utils.logCallsite(Hoek.callStack()[0]);

		Db.func("config_read", JSON.stringify({ key: "showEnglish" }))
		    .then(function(configRow) {
		        
		        var showEnglish = configRow[0]["value"];
		        return reply(showEnglish);
		    })
		    .catch(function(err) {

		        err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
		        return reply(err);
		    });

	},
コード例 #11
0
internals.initiativesRead = function(args, done){

    // TODO: add cache with catbox-memory here

    if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

    Db.func("initiatives_read", JSON.stringify(args.searchConditions))
        .then(function(data) {

            data = args.raw === true ? data : Hoek.transform(data, internals.fromDbToPublicAPI);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(Utils.getErrMsg(err));
            return done(err);
        });
};
コード例 #12
0
    handler: function(request, reply) {

    	Utils.logCallsite(Hoek.callStack()[0]);

        var context = {
            texts:      _.indexBy(request.pre.texts, "id"),
            textsArray: request.pre.texts,
            maps:       request.pre.maps,
            mapsMenu:   request.pre.mapsMenu,
            auth:       request.auth,
            urlParam1:  "cartografia",
            showEnglish: request.pre.showEnglish
        };

        return reply.view('cartografia', {
            ctx: context
        });

    },
コード例 #13
0
ファイル: texts.js プロジェクト: paulovieira/clima
internals.textsDelete = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    Db.func('texts_delete', JSON.stringify(args.query))
        .then(function(deletedData) {

            if (deletedData.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            return done(null, deletedData);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #14
0
ファイル: texts.js プロジェクト: paulovieira/clima
internals.textsCreate = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    ChangeCase(args.query, "underscored");

    internals.removeNewLines(args.query[0].contents);
    internals.decodeImg(args.query[0].contents);
    internals.encodePercentages(args.query[0].contents);

    // 1) create the resources with the payload data
    Db.func('texts_create', JSON.stringify(args.query))

        // 2) read the created resources (to obtain the joined data)
        .then(function(createdData) {

            if (createdData.length === 0) {
                throw Boom.badRequest("The resource could not be created.");
            }

            var createdIds = createdData.map(function(obj){ 
                return { id: obj.id }; 
            });

            return Db.func("texts_read", JSON.stringify(createdIds));
        })

        // 3) apply the object transform and reply
        .then(function(data){

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #15
0
    handler: function(request, reply) {

        if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

        // make sure the url fields have "http://"
        request.payload[0].url = internals.correctUrl(request.payload[0].url);
        request.payload[0].videoUrl = internals.correctUrl(request.payload[0].videoUrl);

        var Seneca = request.server.plugins["seneca-promise"]["seneca"];
        Seneca.actAsync({
                role: "initiatives",
                cmd: "upsert",
                data: request.payload[0]
            })
            .then(function(createdData){

                //console.log("createdData", createdData);

                if(Config.get("email:send")===true && createdData.length>=1){
                    
                    console.log("send email")
                    var emailCtx = {
                        lang: "pt",
                        name: createdData[0].name,
                        contactName: createdData[0].contactName,
                        email: createdData[0].email,
                    };

                    // TODO: the name of the template should be in the payload
                    var templateName = request.payload[0].emailTemplate;
                    Utils.sendEmail(templateName, emailCtx);
                }

                return reply(createdData).code(201);
            })
            .catch(function(err){

                err = err.isBoom ? err : Boom.badImplementation(err.message);
                return reply(err);
            });

    },
コード例 #16
0
ファイル: texts.js プロジェクト: paulovieira/clima
internals.textsRead = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    Db.func('texts_read', JSON.stringify(args.query))
        .then(function(data) {

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #17
0
    handler: function(request, reply) {

    	Utils.logCallsite(Hoek.callStack()[0]);

        if(!request.auth.isAuthenticated){
            Utils.serverLog(["auth"], "requested " + request.path + " but authentication failed - will now redirect to /{lang}/login");
            return reply.redirect("/" + request.params.lang + "/login");
        }

        var context = {
            texts:      _.indexBy(request.pre.texts, "id"),
            textsArray: request.pre.texts,
            auth:       request.auth,
            urlParam1:  "dashboard",
            showEnglish: request.pre.showEnglish
        };

        return reply.view('dashboard', {
            ctx: context
        });

    },
コード例 #18
0
ファイル: prerequisites.js プロジェクト: paulovieira/clima
	method: function(request, reply){

		Utils.logCallsite(Hoek.callStack()[0]);
		
		// this is the original array from the db
		var texts = request.pre.texts;
	


		// move the properties "contents.pt" and "contents.en" to the top-level of the object;

		// TODO: generalize for other languages
		for(var i=0, l=texts.length; i<l;  i++){


			texts[i].pt = texts[i].contents.pt;
			texts[i].en = texts[i].contents.en;

			// if the content is empty for one of the languages, use the corresponding default text
			// if(!texts[i].pt || !texts[i].en){
			// 	defaultText = _.findWhere(request.server.app.defaultTexts, {id: i});

			// 	if(!defaultText){
			// 		defaultText = {
			// 			contents: {
			// 				pt: "missing defaultText: " + i,
			// 				en: "missing defaultText: " + i						
			// 			}
			// 		};
			// 	}

			// 	texts[i].pt = texts[i].pt || defaultText.contents.pt;
			// 	texts[i].en = texts[i].en || defaultText.contents.en;
			// }
		}

		return reply(texts);
	},
コード例 #19
0
internals.initiativesDelete = function(args, done){

    if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }
debugger;
    
    // 1) delete the resource with the id param 
    Db.func("initiatives_delete", JSON.stringify(args.searchConditions))

        // 2) apply the object transform and reply
        .then(function(deletedData){
            debugger;
            // this should never happen, but we check anyway
            if (deletedData.length === 0) {
                throw Boom.notFound("The resource was created/updated but does not exist anymore.");
            }

            deletedData = (args.raw === true) ? 
                                        deletedData : 
                                        Hoek.transform(deletedData, internals.fromDbToPublicAPI);

            return done(null, deletedData);
        })

        // 4. handle errors
        .catch(function(err) {

            // PL/pgSQL Error "no_data_found"; 
            // this will happen when the we try to delete an initiative that has been deleted 
            // meanwhile (or that never existed)
            if(err.code === "P0002"){
                err = Boom.notFound("The resource does not exist.");
            }

            err = err.isBoom ? err : Boom.badImplementation(Utils.getErrMsg(err));
            return done(err);
        });
};
コード例 #20
0
	handler: function(request, reply) {

		Utils.logCallsite(Hoek.callStack()[0]);

	    var viewFile = Utils.getView(request);

        console.log("viewFile: ", viewFile);

	    // if the lang does not exist, show the 404 template with the default language (english)
		if(!request.params.lang){
		    return reply.view('404', {
		    }).code(404);
		}

        // update the global "lang" variable in Nunjucks 
        request.server.plugins["clima-web"].env.addGlobal("lang", request.params.lang);

        // if(Config.get('hapi.auth')===false){
        //     request.auth.credentials = Hoek.clone(Config.get("hapi.dummyCredentials"));
        //     request.auth.isAuthenticated = true;
        // }


        // TODO: we can filter request.pre.texts to send only the texts for this page

	    var context = {
	        urlParam1: request.params.level1,
	        urlParam2: request.params.level2,
	        urlParam3: request.params.level3,
	        urlParam4: request.params.level4,
	        urlParam5: request.params.level5,
	        urlWithoutLang: Utils.getUrlWithoutLang(request.params),
            auth: JSON.parse(JSON.stringify(request.auth)),
            showEnglish: request.pre.showEnglish
	        //textsArray: request.pre.texts,
            //defaultTexts: request.server.app.defaultTexts
	    };

	    // add the data available in request.pre that has been treated and ready to be used
	    // in the nunjucks template: texts, textArray, files, etc
	    for(var key in request.pre){
	        if(request.pre.hasOwnProperty(key)){
	            context[key] = request.pre[key];
	        }
	    }

        //return reply({"abc": 123})
	    // to get the texts in the views, instead of the array we want an object whose keys are the ids

        context.editableTexts = context.texts.filter(function(obj){
            return viewFile.indexOf(obj.pageName) >= 0;
        });

        context.editableTexts = _.indexBy(context.editableTexts, "editableId");
        context.texts = _.indexBy(context.texts, "id");
        context.showEnglish = request.pre.showEnglish;
        //console.log("context.editableTexts: ", context.editableTexts);
		// context.editableTexts = _.indexBy(context.editableTexts, "editableId");
  //       console.log("context.editableTexts: ", context.editableTexts);

	    var response = reply.view(viewFile, {
	        ctx: context
	    });

	    if(viewFile === "404"){
	    	response.code(404);
	    }

		return response;
	},
コード例 #21
0
ファイル: shapes.js プロジェクト: paulovieira/clima
internals.shapesCreate = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    var shapesSchema = "geo";
    var zipId        = args.payload[0]["zipId"];
    var fromSrid     = args.payload[0]["fromSrid"];
    var description  = args.payload[0]["description"];

    console.log("args.payload[0]: ", args.payload[0])


    var zipFile = _.findWhere(args.files, {id: zipId});

    if(!zipFile){
        return done(Boom.badRequest("The zip file with the shapes does not exist in the system (wrong id?)"));
    }

    var zipName     = zipFile.name;
    var zipExtname  = Path.extname(zipName);
    var zipBasename = Path.basename(zipName, zipExtname);
    var zipPhysicalPath = zipFile.physical_path;
    var rootDir = Config.get("instanceRootDir");

    if(zipExtname !== ".zip"){
        return done(Boom.badRequest("The file must be a zip"));
    }

    var zipFullPath = Path.join(rootDir, zipPhysicalPath, zipName);
    var tempDir     = Path.join(rootDir, zipPhysicalPath, "_extract_" + zipBasename + "_" + Utils.getRandomString());


    var shpFile = "", shpBasename = "", tableName = "";


    // step 1: delete tempDir (where the contents of the zip will be placed); if tempDir does not exists,
    // it won't do anything (err will be null); then create the dir, which will be empty for sure
    /* Possible errors in this step:
        - the directory can't be created
    */

    internals.prepareDir(tempDir)

        // step 2: extract the zip into tempDir and verify that all the necessary files are present
        /* Possible errors in this step:
            - the zip is invalid (can't be extracted)
            - the zip has more than 1 .shp file (or no .shp files)
            - the zip doesn't have the necessary files: .shp, .prj, .shx and .dbf
        */

        .then(function(){

            var deferred = Q.defer();
            Fs.createReadStream(zipFullPath)
                .pipe(Unzip.Extract({ path: tempDir }))
                .on("close", function(){

                    // the zip has been successfully extracted; now get an array 
                    // with the names of files in tempDir that have the .shp extension
                    var extractedFiles = Fs.readdirSync(tempDir);

                    var shpFiles = extractedFiles.filter(function(filename){
                        return Path.extname(filename) === ".shp";
                    });

                    if(shpFiles.length!==1){
                        return deferred.reject(Boom.badRequest("The zip must contain one .shp file (and only one)"));
                    }

                    shpFile = shpFiles[0];
                    shpBasename = Path.basename(shpFile, Path.extname(shpFile));

                    // make sure the zip file also has the other mandatory files
                    var requiredFiles = [shpBasename + ".prj", shpBasename + ".shx", shpBasename + ".dbf"];

                    if(_.intersection(extractedFiles, requiredFiles).length < requiredFiles.length){
                        return deferred.reject(Boom.badRequest("The zip must contain files with the following extensions: .shp, .prj, .shx, .dbf"));
                    }

                    return deferred.resolve();
                })
                .on("error", function(err){
                    return deferred.reject(Boom.badRequest("The zip is invalid"));
                });

            return deferred.promise;
        })

        // step 3: execute shp2pgsql

        /* Possible errors in this step:
            - in the callback for child process' exec, the err argument is not undefined
            - in the callback for child process' exec, the stdout is not as expected
            - TODO: we might have to use "-W LATIN1" (default: "UTF-8")
        */
        .then(function(){

            var deferred = Q.defer();

            // define the table name (based on the shape file basename, after being slugified)
            tableName = _s(shpBasename).slugify().replaceAll("-", "_").value();

            if(
                _.findWhere(args.shapes, {table_name: tableName}) || 
                _.findWhere(args.geoTables, {table_name: tableName})
            ){
                tableName = tableName + "_" + Utils.getRandomString();
            }

            // the basic command is:  
            //   shp2pgsql -D -I -s 4326 <path-to-shp-file>  <name-of-schema>.<name-of-the-table>   |  psql --dbname=<name-of-the-database>

            // however we might have to do srid conversion (option "-s", done in this step) and/or set the encoding to latin1 (option "-W", done in the next step)

            var tplString;
            if(fromSrid===4326){
                tplString = 'shp2pgsql -D -I -s 4326                 "<%= shapePath %>" <%= schema %>.<%= tableName %>';
            }
            else{
                // psql --help: "reprojects from given SRID (cannot be used with -D)"
                tplString = 'shp2pgsql    -I -s <%= fromSrid %>:4326 "<%= shapePath %>" <%= schema %>.<%= tableName %>';
            }

            var command1 = _.template(tplString);
            var command2 = _.template('psql --dbname=<%= dbName %>');

            var command = command1({fromSrid: fromSrid, shapePath: Path.join(tempDir, shpFile), schema: shapesSchema, tableName: tableName}) + 
                        " | " + 
                        command2({dbName: Config.get("db.postgres.database") });

            Utils.serverLog(["shp2pgsql"], command);

            // maxBuffer specifies the largest amount of data allowed on stdout or stderr (we set to 5mb)
            Exec(command, {maxBuffer: 1024 * 5000}, function(err, stdout, stderr){

                if(err){
                    return deferred.reject(Boom.badImplementation("ChildProcess.exec error: " + err.message));
                }

                if(_s.include(stdout.toLowerCase(), "create index") && 
                    _s.include(stdout.toLowerCase(), "commit")){
                    return deferred.resolve();
                }
                else{
                    // TODO: stderr might be big (if the shape if also big)?
                    return deferred.reject(Boom.badImplementation("shp2pgsql error: " + stderr));
                }

            });

            return deferred.promise;
        })

        // step 4: execute shp2pgsql again, now with a different enconding (case the previous execution has failed)
        .catch(function(err){

            // check if we had the "Unable to convert field name to UTF-8" error
            var encodingErr = /utf/i.test(err.message);
            if(!encodingErr){
                throw err;
            }

            var deferred = Q.defer();


            // the command is now:  shp2pgsql -W "latin1" -D -I -s 4326 <path-to-shp-file>  <name-of-schema>.<name-of-the-table>   |  psql --dbname=<name-of-the-database>
            var tplString;
            if(fromSrid===4326){
                tplString = 'shp2pgsql -W "latin1" -D -I -s 4326 "<%= shapePath %>" <%= schema %>.<%= tableName %>';
            }
            else{
                // "reprojects from given SRID (cannot be used with -D)"
                tplString = 'shp2pgsql -W "latin1" -I -s <%= fromSrid %>:4326 "<%= shapePath %>" <%= schema %>.<%= tableName %>';
            }

            var command1 = _.template(tplString);
            var command2 = _.template('psql --dbname=<%= dbName %>');

            var command = command1({fromSrid: fromSrid, shapePath: Path.join(tempDir, shpFile), schema: shapesSchema, tableName: tableName}) + 
                        " | " + 
                        command2({dbName: Config.get("db.postgres.database") });

            Utils.serverLog(["shp2pgsql"], command);

            // maxBuffer specifies the largest amount of data allowed on stdout or stderr (we set to 1mb)
            Exec(command, {maxBuffer: 1024 * 1000}, function(err, stdout, stderr){

                if(err){
                    return deferred.reject(Boom.badImplementation("ChildProcess.exec error: " + err.message));
                }

                if(_s.include(stdout.toLowerCase(), "create index") && 
                    _s.include(stdout.toLowerCase(), "commit")){
                    return deferred.resolve();
                }
                else{
                    // TODO: stderr might be big (if the shape if also big)?
                    return deferred.reject(Boom.badImplementation("shp2pgsql error: " + stderr));
                }

            });

            return deferred.promise;

        })

        // step 5-7: the usual
        .then(function(){

            var dbData = {
                
                schemaName: shapesSchema,
                tableName: tableName,
                srid: fromSrid,
                description: description,
                fileId: zipId,
                ownerId: args.payload[0]["ownerId"]
            };
            ChangeCase(dbData, "underscored");

            var promise = Db.func("shapes_create", JSON.stringify(dbData));
            return promise;
        })

        .then(function(createdData) {

            if (createdData.length === 0) {
                throw Boom.badRequest("The resource could not be created.");
            }

            var createdIds = createdData.map(function(obj){ 
                return { id: obj.id }; 
            });

            var promise = Db.func("shapes_read", JSON.stringify(createdIds));
            return promise;
        })

        .then(function(data){

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })

        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        })

        // whatever happens, we always want to delete the temporary directory where the zip was extracted
        .finally(function(){
            console.log("delete temp dir");
            Rimraf(tempDir, function(err){
                if(err){
                    // nothing to do!
                }
            });
        });

};
コード例 #22
0
ファイル: shapes.js プロジェクト: paulovieira/clima
internals.shapesDelete = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);

    Db.func('shapes_delete', JSON.stringify(args.dbQuery))
        .then(function(deletedData) {

            if (deletedData.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            return deletedData;
        })

        // delete the zip file associated with this shape
        .then(function(data){

            var deletedShape = _.findWhere(args.shapes, {id: data[0].deleted_id});
            if(deletedShape.length == 0){
                return deletedShape;
            }

            var deferred = Q.defer();

            // http -v DELETE localhost:3000/api/v1/files/123

            var uri = "http://localhost:" + Config.get("port") + "/api/v1/files/" + deletedShape.file_data.id;
            
            var options = {
                headers: {
                    "content-type": "application/json"
                },
                json: true
            };

            if(args.headers.cookie){
                options.headers.cookie = args.headers.cookie;
            }

            Wreck.delete(uri, options, function(err, response, payload){
                //console.log("payload from DELETE /api/v1/files/xxx:: ", payload);

                if(response.statusCode === 200){
                    data[0].deleted_file_id = payload[0].deleted_id;
                }
                else if(response.statusCode >= 400 && response.statusCode < 500){
                    data[0].deleted_file_id = "None (" + payload.message + ")";
                }

                // even if there was an error deleting the file, we always want the deferred to be resolved
                return deferred.resolve(data);
            })

            return deferred.promise;
        })
        .then(function(data){

            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });

};
コード例 #23
0
ファイル: texts.js プロジェクト: paulovieira/clima
internals.textsUpdate = function(args, done){

    Utils.logCallsite(Hoek.callStack()[0]);
    debugger;

    // TODO: this next snippet is done in the validation; we are temporarily removing
    // the validation for PUT /api/texts because there is some strange error with joi
    if (_.isObject(args.query) && !_.isArray(args.query)) {
        args.query = [args.query];
    }

    ChangeCase(args.query, "underscored");

    var ids = args.query.map(function(obj){ 
        return { id: obj.id };
    });

    internals.removeNewLines(args.query[0].contents);
    internals.decodeImg(args.query[0].contents);
    internals.encodePercentages(args.query[0].contents);

    // 1) read the resources to be updated (to verify that they exist)
    Db.func('texts_read', JSON.stringify(ids))

        // 2) update the resources with the payload data
        .then(function(data) {

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            // TODO: verify that data.length === args.ids.length

            return Db.func("texts_update", JSON.stringify(args.query))
        })

        // 3) read again the updated resources (to obtain the joined data)
        .then(function(updatedData) {

            if (updatedData.length === 0) {
                throw Boom.badRequest("The resource could not be updated.");
            }

            var updatedIds = updatedData.map(function(obj){ 
                return { id: obj.id }; 
            });

            return Db.func("texts_read", JSON.stringify(updatedIds));
        })

        // 4) apply the object transform and reply
        .then(function(data){

            if (data.length === 0) {
                throw Boom.notFound("The resource does not exist.");
            }

            data = args.raw === true ? data : Hoek.transform(data, internals.transformMap);
            return done(null, data);
        })
        .catch(function(err) {

            err = err.isBoom ? err : Boom.badImplementation(err.msg, err);
            return done(err);
        });
};
コード例 #24
0
internals.initiativesUpsert = function(args, done){

    if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

    var data = Utils.changeCase(args.data, "underscored");

    if(!data.slug){
        data.slug = _s.slugify(data.name);
    }
    
    // 1) create/update the resources with the payload data (which is in data)
    Db.func("initiatives_upsert", JSON.stringify(data))

        // 2) read the created/updated resources (to obtain the joined data)
        .then(function(upsertedData) {

            // this should never happen, but we check anyway
            if (upsertedData.length === 0) {
                throw Boom.badImplementation("The resource could not be created/updated.");
            }

            return Db.func("initiatives_read", JSON.stringify({id: upsertedData[0].id}));
        })

        // 3) apply the object transform and reply
        .then(function(upsertedData){

            // this is very unlikely to happen, but we check anyway
            if (upsertedData.length === 0) {
                throw Boom.notFound("The resource was created/updated but does not exist anymore.");
            }

            upsertedData = (args.raw === true) ? 
                                        upsertedData : 
                                        Hoek.transform(upsertedData, internals.fromDbToPublicAPI);

            return done(null, upsertedData);
        })

        // 4. handle errors
        .catch(function(err) {

            // PL/pgSQL Error "no_data_found"; 
            // this will happen when the we try to update an initiative that has been deleted meanwhile
            // (or that was never created)
            if(err.code === "P0002"){
                err = Boom.notFound("The resource does not exist.");
            }

            // PL/pgSQL Error "unique_violation"; 
            // this will happen when we try to update (insert?) a row with a repeated slug (already 
            // present in some other project)
            if(err.code === "23505"){
                if(err.detail.indexOf("slug") >= 0){
                    err = Boom.conflict("The provided value for slug is already in use by other initiative. Please choose a different slug.");
                }
                else{
                    err = Boom.conflict();
                }
            }

            err = err.isBoom ? err : Boom.badImplementation(Utils.getErrMsg(err));
            return done(err);
        });
};
コード例 #25
0
    handler: function(request, reply) {
console.log("update: \n", request.payload[0]);

        if(global.NODE_ENV==="dev"){  Utils.logCallsite(Hoek.callStack()[1]);  }

        // make sure the url fields have "http://"
        request.payload[0].url = internals.correctUrl(request.payload[0].url);
        request.payload[0].videoUrl = internals.correctUrl(request.payload[0].videoUrl);

        var Seneca = request.server.plugins["seneca-promise"]["seneca"];

        var previousData = [];
        Seneca.actAsync({
                role: "initiatives",
                cmd: "read",
                searchConditions: [{ id: request.payload[0].id }] // xxx
            })
            .delay(500)
            .then(function(data){

                if (data.length === 0) {
                    return reply(Boom.notFound("The resource does not exist."));
                }

                // bad hack - use function scope to place the retrieved data in a variable that can
                // be accessed in the next step
                previousData = data;
//console.log("previousData: \n", previousData)

                return Seneca.actAsync({
                    role: "initiatives",
                    cmd: "upsert",
                    data: request.payload[0]
                });
            })
            .then(function(updatedData){

                if(Config.get("email:send")===true 
                    && updatedData.length>=1
                    && previousData[0].moderationStatusId === "moderation_status_001_pending"
                    && updatedData[0].moderationStatusId === "moderation_status_002_approved"
                    ){
                    
                    var emailCtx = {
                        lang: "pt",
                        name: updatedData[0].name,
                        contactName: updatedData[0].contactName,
                        email: updatedData[0].email,
                        slug: updatedData[0].slug,
                    };
                    
                    // TODO: the name of the template should be in the payload
                    var templateName = "approved";
                    Utils.sendEmail(templateName, emailCtx);

                }

                return reply(updatedData).code(200);
            })
            .catch(function(err){

                err = err.isBoom ? err : Boom.badImplementation(err.message);
                return reply(err);
            });

    },