<commit_before>var debug   = require('debug')('api:ctrlLocal'),
    models  = require('../models'),
    AWS     = require('aws-sdk'),
    uuid    = require('node-uuid'),
    s3      = new AWS.S3();

var AWS_PATH_PREFIX = 'https://s3.amazonaws.com/bikedeboa/';

var handleNotFound = function(data) {
    if(!data) {
        var err = new Error('Not Found');
        err.status = 404;
        throw err;
    }
    return data;
};

function LocalController(LocalModel) {
    this.model = LocalModel;
}

// ---------------- private functions ---------------- //

function promiseContTags(local) {
    return new Promise(function(resolve, reject) {
        models.sequelize.query('SELECT t.name, COUNT(*) FROM "Tag" t inner join "Review_Tags" rt on T.id = rt.tag_id inner join "Review" r on r.id = rt.review_id inner join "Local" l on r.local_id = l.id WHERE l.id = '+local.id+' GROUP BY t.id')
            .then(function(result, metatag) {
                local.dataValues.tags = result[0];
                resolve(local);
            });
    });
}

function getLocalsAndTags(locals) {
    return new Promise(function(resolve, reject) {
        var promises = [];

        locals.map(function(local){
            promises.push(promiseContTags(local));
        });

        Promise.all(promises).then(function(resp){
            resolve(resp);
        })
    });
}

function getTags(arrTagsId) {
    return new Promise(function(resolve, reject) {
        var promises = [];

        arrTagsId.map(function(tag) {
            promises.push(models.Tag.find({where: {id: tag.id}}));
        });

        Promise.all(promises).then(function(tags) {
            resolve(tags);
        });
    });
}

function saveImage(photo, id) {
    return new Promise(function(resolve, reject) {
        // valid photo exists
        if (!photo) reject('');

        // get base64 and type image for save
        var type = photo.split(',')[0] === 'data:image/png;base64' ? '.png' : photo.split(',')[0] === 'data:image/jpeg;base64' ? '.jpeg' : '',
        base64Data  =   type === '.png' ? photo.replace(/^data:image\/png;base64,/, "") : photo.replace(/^data:image\/jpeg;base64,/, "");
        base64Data  +=  base64Data.replace('+', ' ');
        // binaryData  =   new Buffer(base64Data, 'base64').toString('binary');
        binaryData  =   new Buffer(base64Data, 'base64');

        // path image
        var path = "images/";
        var imageName = path + id + type;

        // type invalid return
        if (!type) {
            reject(photo);
        }

        // Send image blob to Amazon S3
        s3.putObject(
            {
                Key: imageName,
                Body: binaryData,
                Bucket: 'bikedeboa',
                ACL: 'public-read'
            }, function(err, data){
                if (err) {
                    debug('Error uploading image ', imageName);
                    reject(err);
                } else {
                    debug('Succesfully uploaded the image', imageName);
                    resolve(imageName);
                }
            });
    });
}

// ---------------- private functions ---------------- //

LocalController.prototype.getAll = function(request, response, next) {
    var query = {
        attributes: ['id', 'lat', 'lng', 'lat', 'structureType', 'isPublic', 'text', 'photo'].concat([
            [
                models.sequelize.literal('(SELECT COUNT(*) FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'reviews'
            ],
            [
                models.sequelize.literal('(SELECT AVG("rating") FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'average'
            ],
            [
                models.sequelize.literal('(SELECT COUNT(*) FROM "Checkin" WHERE "Checkin"."local_id" = "Local"."id")'),
                'checkins'
            ]
        ])
    };

    this.model.findAll(query)
        .then(function(locals) {
            response.json(locals);
        })
        .catch(next);
};

LocalController.prototype.getAllLight = function(request, response, next) {
    var query = {
        attributes: ['id', 'lat', 'lng'].concat([
            [
                models.sequelize.literal('(SELECT AVG("rating") FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'average'
            ],
        ])
    };

    this.model.findAll(query)
    .then(function(data) {
        response.json(data);
    })
    .catch(next);
};

LocalController.prototype.getById = function(request, response, next) {
    var query = {
      attributes: ['id', 'lat', 'lng', 'lat', 'structureType', 'isPublic', 'text', 'photo'].concat([
          [
              models.sequelize.literal('(SELECT COUNT(*) FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
              'reviews'
          ],
          [
              models.sequelize.literal('(SELECT COUNT(*) FROM "Checkin" WHERE "Checkin"."local_id" = "Local"."id")'),
              'checkins'
          ]
      ]),
      where: {id : request.params._id}
    }

  	this.model.find(query)
        .then(handleNotFound)
        .then(function(local){
            return promiseContTags(local)
              .then(function(resp){
                response.json(resp);
              });
        })
    .catch(next);
};

LocalController.prototype.create = function(request, response, next) {
  	var body = request.body;

    var _tags  = body.tags || [];
    var params = {
      lat: body.lat,
      lng: body.lng,
      structureType: body.structureType,
      isPublic: body.isPublic && (body.isPublic === 'true' ? 1 : 0),
      text: body.text,
      photo: ''
    };

    // create local
    this.model.create(params).then(handleGetTags).catch(next);

    // get tags informed
    function handleGetTags(local) {
      return getTags(_tags).then(handleSetTags.bind(null, local)).catch(next);
    }

    // set tags local
    function handleSetTags(local, tags) {
      return local.setTags(tags).then(handleSaveImage.bind(null, local)).catch(next);
    }

    // save image local
    function handleSaveImage(local) {
      return saveImage(body.photo, local.id).then(handleUpdateUrlLocal.bind(null, local)).catch(next);
    }

    // update local new image url
    function handleUpdateUrlLocal(local, url) {
      return local.update({photo: url}).then(handleResponse).catch(next);
    }

    // return response
    function handleResponse(local) {
      response.json(local);
    }
};

LocalController.prototype.update = function(request, response, next) {
    var _id  = request.params._id,
        body = request.body,
        self = this;

    var _local = {};
    if (body.lat) _local.lat = body.lat;
    if (body.lng) _local.lng = body.lng;
    if (body.structureType) _local.structureType = body.structureType;
    if (body.isPublic) _local.isPublic = body.isPublic && (body.isPublic === 'true' ? 1 : 0);
    if (body.text) _local.text = body.text;
    if (body.photo) _local.photo = body.photo;

  	var query = {
        where: {id : _id}
    };

    saveImage(body.photo).
        then(function(imageUrl){
            _local.photo = imageUrl;
            self.model.find(query)
                .then(handleNotFound)
                .then(function(data){
                    data.update(_local)
                        .then(function(local){
                            response.json(local);
                            return local;
                        })
                        .catch(next);
                    return data;
                })
            .catch(next);
        })
        .catch(next);
};

LocalController.prototype.remove = function(request, response, next) {
    var _id  = request.params._id;

    var query = {
        where: {id : _id}
    };

    this.model.destroy(query)
        .then(handleNotFound)
        .then(function(rowDeleted){
            if(rowDeleted === 1){
                response.json({
                    message: 'Deleted successfully'
                });
            }
        })
        .catch(next);
};

LocalController.prototype.removeAll = function(request, response, next) {
    var _id  = request.params._id;

    var query = {where: {}};

    this.model.destroy(query)
        .then(handleNotFound)
        .then(function(rowDeleted){
            response.json({
                message: 'Deleted successfully'
            });
        })
        .catch(next);
};

module.exports = function(LocalModel) {
  	return new LocalController(LocalModel);
};
<commit_msg>local image update and delete<commit_after>var debug   = require('debug')('api:ctrlLocal'),
    models  = require('../models'),
    AWS     = require('aws-sdk'),
    uuid    = require('node-uuid'),
    s3      = new AWS.S3();

var AWS_PATH_PREFIX = 'https://s3.amazonaws.com/bikedeboa/';

var handleNotFound = function(data) {
    if(!data) {
        var err = new Error('Not Found');
        err.status = 404;
        throw err;
    }
    return data;
};

function LocalController(LocalModel) {
    this.model = LocalModel;
}

// ---------------- private functions ---------------- //

function promiseContTags(local) {
    return new Promise(function(resolve, reject) {
        models.sequelize.query('SELECT t.name, COUNT(*) FROM "Tag" t inner join "Review_Tags" rt on T.id = rt.tag_id inner join "Review" r on r.id = rt.review_id inner join "Local" l on r.local_id = l.id WHERE l.id = '+local.id+' GROUP BY t.id')
            .then(function(result, metatag) {
                local.dataValues.tags = result[0];
                resolve(local);
            });
    });
}

function getLocalsAndTags(locals) {
    return new Promise(function(resolve, reject) {
        var promises = [];

        locals.map(function(local){
            promises.push(promiseContTags(local));
        });

        Promise.all(promises).then(function(resp){
            resolve(resp);
        })
    });
}

function getTags(arrTagsId) {
    return new Promise(function(resolve, reject) {
        var promises = [];

        arrTagsId.map(function(tag) {
            promises.push(models.Tag.find({where: {id: tag.id}}));
        });

        Promise.all(promises).then(function(tags) {
            resolve(tags);
        });
    });
}

function saveImage(photo, id) {
    return new Promise(function(resolve, reject) {
        // valid photo exists
        if (!photo) resolve('');

        // get base64 and type image for save
        var type = photo.split(',')[0] === 'data:image/png;base64' ? '.png' : photo.split(',')[0] === 'data:image/jpeg;base64' ? '.jpeg' : '',
        base64Data  =   type === '.png' ? photo.replace(/^data:image\/png;base64,/, "") : photo.replace(/^data:image\/jpeg;base64,/, "");
        base64Data  +=  base64Data.replace('+', ' ');
        // binaryData  =   new Buffer(base64Data, 'base64').toString('binary');
        binaryData  =   new Buffer(base64Data, 'base64');

        // path image
        var path = "images/";
        var imageName = path + id + type;

        // type invalid return
        if (!type) {
            reject(photo);
        }

        // Send image blob to Amazon S3
        s3.putObject(
            {
                Key: imageName,
                Body: binaryData,
                Bucket: 'bikedeboa',
                ACL: 'public-read'
            }, function(err, data){
                if (err) {
                    debug('Error uploading image ', imageName);
                    reject(err);
                } else {
                    debug('Succesfully uploaded the image', imageName);
                    resolve(AWS_PATH_PREFIX + imageName);
                }
            });
    });
}

function deleteImage(id) {
    return new Promise(function(resolve, reject) {
        // path image
        var path = "images/";
        var imageName = path + id;
        // params delete images
        var params = {
            Bucket: 'bikedeboa',
            Delete: {
                Objects: [
                    {
                      Key: imageName + '.jpeg'
                    },
                    {
                      Key: imageName + '.png'
                    }
                ]
            }
        };
        // delete imagens in s3
        s3.deleteObjects(params, function(err, data) {
            if (err){
                debug(err, err.stack);
                reject(err);
            } else {
                debug(data);
                resolve(data);
            }
        });
    });
}

// ---------------- private functions ---------------- //

LocalController.prototype.getAll = function(request, response, next) {
    var query = {
        attributes: ['id', 'lat', 'lng', 'lat', 'structureType', 'isPublic', 'text', 'photo'].concat([
            [
                models.sequelize.literal('(SELECT COUNT(*) FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'reviews'
            ],
            [
                models.sequelize.literal('(SELECT AVG("rating") FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'average'
            ],
            [
                models.sequelize.literal('(SELECT COUNT(*) FROM "Checkin" WHERE "Checkin"."local_id" = "Local"."id")'),
                'checkins'
            ]
        ])
    };

    this.model.findAll(query)
        .then(function(locals) {
            response.json(locals);
        })
        .catch(next);
};

LocalController.prototype.getAllLight = function(request, response, next) {
    var query = {
        attributes: ['id', 'lat', 'lng'].concat([
            [
                models.sequelize.literal('(SELECT AVG("rating") FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
                'average'
            ],
        ])
    };

    this.model.findAll(query)
        .then(function(data) {
            response.json(data);
        })
        .catch(next);
};

LocalController.prototype.getById = function(request, response, next) {
    var query = {
      attributes: ['id', 'lat', 'lng', 'lat', 'structureType', 'isPublic', 'text', 'photo'].concat([
          [
              models.sequelize.literal('(SELECT COUNT(*) FROM "Review" WHERE "Review"."local_id" = "Local"."id")'),
              'reviews'
          ],
          [
              models.sequelize.literal('(SELECT COUNT(*) FROM "Checkin" WHERE "Checkin"."local_id" = "Local"."id")'),
              'checkins'
          ]
      ]),
      where: {id : request.params._id}
    }

  	this.model.find(query)
        .then(handleNotFound)
        .then(function(local){
            return promiseContTags(local)
              .then(function(resp){
                response.json(resp);
              });
        })
    .catch(next);
};

LocalController.prototype.create = function(request, response, next) {
  	var body = request.body;

    var _tags  = body.tags || [];
    var params = {
      lat: body.lat,
      lng: body.lng,
      structureType: body.structureType,
      isPublic: body.isPublic && (body.isPublic === 'true' ? 1 : 0),
      text: body.text,
      photo: ''
    };

    // create local
    this.model.create(params).then(handleGetTags).catch(next);

    // get tags informed
    function handleGetTags(local) {
        return getTags(_tags).then(handleSetTags.bind(null, local)).catch(next);
    }

    // set tags local
    function handleSetTags(local, tags) {
        return local.setTags(tags).then(handleSaveImage.bind(null, local)).catch(next);
    }

    // save image local
    function handleSaveImage(local) {
        return saveImage(body.photo, local.id).then(handleUpdateUrlLocal.bind(null, local)).catch(next);
    }

    // update local new image url
    function handleUpdateUrlLocal(local, url) {
        return local.update({photo: url}).then(handleResponse).catch(next);
    }

    // return response
    function handleResponse(local) {
      response.json(local);
    }
};

LocalController.prototype.update = function(request, response, next) {
    var _id  = request.params._id,
        body = request.body,
        self = this;

    var _local = {};
    if (body.lat) _local.lat = body.lat;
    if (body.lng) _local.lng = body.lng;
    if (body.structureType) _local.structureType = body.structureType;
    if (body.isPublic) _local.isPublic = body.isPublic && (body.isPublic === 'true' ? 1 : 0);
    if (body.text) _local.text = body.text;

  	var query = {
        where: {id : _id}
    };

    this.model.find(query)
        .then(handleNotFound)
        .then(handleUpdateLocal)
        .catch(next);

    // update data local
    function handleUpdateLocal(local) {
        return local.update(_local).then(handleDeleteImage.bind(null, local)).catch(next);
    }

    // delete image local exists
    function handleDeleteImage(local) {
        if(body.photo){
            return deleteImage(_id).then(handleSaveImage.bind(null, local)).catch(next);
        } else {
            handleSaveImage(local);
        }
    }

    // save image local
    function handleSaveImage(local) {
        if (body.photo) {
            return saveImage(body.photo, _id).then(handleUpdateUrlLocal.bind(null, local)).catch(next);
        } else {
            handleUpdateUrlLocal(local);
        }
    }

    // update local new image url
    function handleUpdateUrlLocal(local, url) {
        if (url) {
            return local.update({photo: url}).then(handleResponse.bind(null, local)).catch(next);
        } else {
            handleResponse(local);
        }
    }

    // return response
    function handleResponse(local) {
        response.json(local);
    }
};

LocalController.prototype.remove = function(request, response, next) {
    var _id  = request.params._id;

    var query = {
        where: {id : _id}
    };

    this.model.destroy(query)
      .then(handleNotFound)
      .then(handleDeleteImage.bind(null, _id))
      .catch(next);

    function handleDeleteImage(id, data) {
        return deleteImage(id).then(handleResponse.bind(null, data)).catch(next);
    }

    function handleResponse(rowDeleted) {
      if(rowDeleted){
          response.json({
              message: 'Deleted successfully'
          });
      }
    }
};

LocalController.prototype.removeAll = function(request, response, next) {
    var _id  = request.params._id;

    var query = {where: {}};

    this.model.destroy(query)
        .then(handleNotFound)
        .then(function(rowDeleted){
            response.json({
                message: 'Deleted successfully'
            });
        })
        .catch(next);
};

module.exports = function(LocalModel) {
  	return new LocalController(LocalModel);
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var bourbon = require('node-bourbon');

module.exports = function(options) {
  function sassLoader(loadersDef) {
    return loadersDef + '?includePaths[]=' + [
      path.resolve(options.root, 'node_modules'),
      options.root,
      bourbon.includePaths
    ].join('&includePaths[]=');
  }

  return {
    resolve: {
      root: options.root,
      fallback: path.resolve(__dirname, 'node_modules'),
      extensions: ['', '.js', '.json', '.css', '.scss']
    },
    resolveLoader: {
      fallback: path.resolve(__dirname, 'node_modules')
    },

    // Packup-specific options, not directly used by webpack
    loaders: {
      js: {test: /\.js$/, include: [options.root], loaders: ['babel']},
      scss: {test: /\.scss$/, loader: sassLoader('style!css!sass')},
      css: {test: /\.css$/, loader: 'style!css'},

      // Images
      png: {test: /\.png$/, loader: 'url?limit=8192&mimetype=image/png'},
      gif: {test: /\.gif$/, loader: 'url?limit=8192&mimetype=image/gif'},
      jpg: {test: /\.jpe?g$/, loader: 'file?mimetype=image/jpg'},
      svg: {test: /\.svg$/, loader: 'url?limit=8192&mimetype=image/svg+xml'},

      // Fonts
      woff2: {test: /\.woff2$/, loader: 'url?limit=8192&mimetype=application/font-woff2'},
      woff: {test: /\.woff$/, loader: 'url?limit=8192&mimetype=application/font-woff'},
      ttf: {test: /\.ttf$/, loader: 'file'},
      eot: {test: /\.eot$/, loader: 'file'},

      // Other
      json: {test: /\.json$/, loader: 'json'},
      html: {test: /\.html$/, loader: 'file?name=[name].[ext]'}
    }
  };
}
<commit_msg>Remove resolve.extensions<commit_after>var path = require('path');
var fs = require('fs');
var bourbon = require('node-bourbon');

module.exports = function(options) {
  function sassLoader(loadersDef) {
    return loadersDef + '?includePaths[]=' + [
      path.resolve(options.root, 'node_modules'),
      options.root,
      bourbon.includePaths
    ].join('&includePaths[]=');
  }

  return {
    resolve: {
      root: options.root,
      fallback: path.resolve(__dirname, 'node_modules')
    },
    resolveLoader: {
      fallback: path.resolve(__dirname, 'node_modules')
    },

    // Packup-specific options, not directly used by webpack
    loaders: {
      js: {test: /\.js$/, include: [options.root], loaders: ['babel']},
      scss: {test: /\.scss$/, loader: sassLoader('style!css!sass')},
      css: {test: /\.css$/, loader: 'style!css'},

      // Images
      png: {test: /\.png$/, loader: 'url?limit=8192&mimetype=image/png'},
      gif: {test: /\.gif$/, loader: 'url?limit=8192&mimetype=image/gif'},
      jpg: {test: /\.jpe?g$/, loader: 'file?mimetype=image/jpg'},
      svg: {test: /\.svg$/, loader: 'url?limit=8192&mimetype=image/svg+xml'},

      // Fonts
      woff2: {test: /\.woff2$/, loader: 'url?limit=8192&mimetype=application/font-woff2'},
      woff: {test: /\.woff$/, loader: 'url?limit=8192&mimetype=application/font-woff'},
      ttf: {test: /\.ttf$/, loader: 'file'},
      eot: {test: /\.eot$/, loader: 'file'},

      // Other
      json: {test: /\.json$/, loader: 'json'},
      html: {test: /\.html$/, loader: 'file?name=[name].[ext]'}
    }
  };
}
<|endoftext|>


<commit_before>const mongoose = require('mongoose')
const Post = mongoose.model('Post')
const Comment_ = mongoose.model('Comment')
const Like = mongoose.model('Like')
const Photo = require('mongoose').model('Photo')
const Album = require('mongoose').model('Album')
const multer = require('multer')
const photoUploadsPath = require('../config/constants').photoUploadsPath
let parseReqBody = multer({ dest: photoUploadsPath }).array('addPhotoToPost')

module.exports = {
  addPost: (req, res) => {
    parseReqBody(req, res, function () {
      let albumName = 'newsfeed-photos-' + req.user._id
      let newPostInfo = req.body
      let postIsPublic = newPostInfo.publicPost.toString() === 'publicvisible'
      let newPost = new Post({
        author: req.user._id,
        category: req.user.category,
        content: newPostInfo.content,
        public: postIsPublic
      })

      if (newPost.content.length < 3) {
        req.session.errorMsg = "Your post's content is too short! It must be longer than 3 characters."
        req.session.failedPost = newPost  // attach the post content to be displayed on the redirect
        res.redirect('/')
        return
      }

      Album.findOrCreateAlbum(albumName, req.user._id)
        .then((album) => {
          let photoIndex = 1

          // create a photo object for each uploaded photo
          let photoUploadPromises = req.files.map(function (photo) {
            return new Promise((resolve, reject) => {
              let photoUp = Object.assign(photo, {
                author: req.user._id,
                album: album._id,
                classCss: album.classCss,
                public: postIsPublic,
                description: newPostInfo[photoIndex.toString()]
              })

              photoIndex += 1

              Photo.create(photoUp).then(photo => {
                resolve(photo._id)
              })
            })
          })
          Promise.all(photoUploadPromises).then(uploadedPhotos => {
            newPost.photos = uploadedPhotos
            Post.create(newPost).then(post => {
              res.redirect('/')
            })
          })
        })
    })
  },

  addComment: (req, res) => {
    let postId = req.params.id  // the post this comment is on
    let newComment = req.body
    newComment.author = req.user._id

    if (newComment.content.length < 2) {
      req.session.errorMsg = 'Your comment is too short! All comments must be longer than 2 characters.'
      res.redirect('/')
      return
    }

    Post.findById(postId).then(post => {
      if (!post) {
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }

      Comment_.create(newComment).then((newComment) => {
        post.addComment(newComment._id).then(() => {
          // Comment added!
          let returnUrl = '/'
          if (req.session.returnUrl) {
            returnUrl = req.session.returnUrl
            delete req.session.returnUrl
          }
          res.redirect(returnUrl)
        })
      })
    })
  },

  addLike: (req, res) => {
    // regex is: /post\/(.+)\/add(.{3,7})/
    let postId = req.params[0]
    let likeType = req.params[1]
    let userId = req.user._id
    Post.findById(postId).populate('likes').then(post => {
      if (!post) {
        // ERROR - Post with ID does not exist!
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }
      let likeIndex = post.likes.findIndex(like => {
        return like.author.equals(userId)
      })

      if (likeIndex !== -1) {
        // user has already liked this post
        if (post.likes[likeIndex].type === likeType) {
          res.redirect('/')
          return
        } else {
          // User is un-liking this photo and giving it a {likeType}
          // So we simply change the name of this like
          post.likes[likeIndex].type = likeType
          post.likes[likeIndex].save().then(() => {
            let returnUrl = '/'
            if (req.session.returnUrl) {
              returnUrl = req.session.returnUrl
              delete req.session.returnUrl
            }
            res.redirect(returnUrl)
            // Success!
          })
        }
      } else {
        // User is liking this post for the first time
        Like.create({ type: likeType, author: req.user._id }).then(like => {
          post.addLike(like._id).then(() => {
            let returnUrl = '/'
            if (req.session.returnUrl) {
              returnUrl = req.session.returnUrl
              delete req.session.returnUrl
            }

            res.redirect(returnUrl)
          })
        })
      }
    })
  },

  removeLike: (req, res) => {
    // regex is: /post\/(.+)\/remove(.{3,7})/
    let postId = req.params[0]
    let likeType = req.params[1]
    let userId = req.user._id

    Post.findById(postId).populate('likes').then(post => {
      if (!post) {
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }
      // Get the index of the user's like'
      let likeIndex = post.likes.findIndex(like => {
        return like.author.equals(userId)
      })

      if (likeIndex === -1) {
        // ERROR - User has not liked this at all
        res.redirect('/')
        return
      } else {
        if (post.likes[likeIndex].type !== likeType) {
          // ERROR - example: User is trying to unPAW a post he has LOVED
          res.redirect('/')
          return
        }
        let likeId = post.likes[likeIndex]._id
        post.removeLike(likeId).then(() => {
          // Like is removed!
          let returnUrl = '/'
          if (req.session.returnUrl) {
            returnUrl = req.session.returnUrl
            delete req.session.returnUrl
          }

          res.redirect(returnUrl)
          return
        })
        Like.findByIdAndRemove(likeId)
      }
    })
  }
}
<commit_msg>refactored post-controller a bit<commit_after>const mongoose = require('mongoose')
const Post = mongoose.model('Post')
const Comment_ = mongoose.model('Comment')
const Like = mongoose.model('Like')
const Photo = require('mongoose').model('Photo')
const Album = require('mongoose').model('Album')
const multer = require('multer')
const photoUploadsPath = require('../config/constants').photoUploadsPath
let parseReqBody = multer({ dest: photoUploadsPath }).array('addPhotoToPost')

module.exports = {
  addPost: (req, res) => {
    parseReqBody(req, res, function () {
      let albumName = 'newsfeed-photos-' + req.user._id
      let newPostInfo = req.body
      let postIsPublic = newPostInfo.publicPost.toString() === 'publicvisible'
      let newPost = new Post({
        author: req.user._id,
        category: req.user.category,
        content: newPostInfo.content,
        public: postIsPublic
      })

      if (newPost.content.length < 3) {
        req.session.errorMsg = "Your post's content is too short! It must be longer than 3 characters."
        req.session.failedPost = newPost  // attach the post content to be displayed on the redirect
        res.redirect('/')
        return
      }

      Album.findOrCreateAlbum(albumName, req.user._id)
        .then((album) => {
          let photoIndex = 1

          // create a photo object for each uploaded photo
          let photoUploadPromises = req.files.map(function (photo) {
            return new Promise((resolve, reject) => {
              let photoUp = Object.assign(photo, {
                author: req.user._id,
                album: album._id,
                classCss: album.classCss,
                public: postIsPublic,
                description: newPostInfo[photoIndex.toString()]
              })

              photoIndex += 1

              Photo.create(photoUp).then(photo => {
                resolve(photo._id)
              })
            })
          })
          Promise.all(photoUploadPromises).then(uploadedPhotos => {
            newPost.photos = uploadedPhotos
            Post.create(newPost).then(post => {
              res.redirect('/')
            })
          })
        })
    })
  },

  addComment: (req, res) => {
    let postId = req.params.id  // the post this comment is on
    let newComment = req.body
    newComment.author = req.user._id

    if (newComment.content.length < 2) {
      req.session.errorMsg = 'Your comment is too short! All comments must be longer than 2 characters.'
      res.redirect('/')
      return
    }

    Post.findById(postId).then(post => {
      if (!post) {
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }

      Comment_.create(newComment).then((newComment) => {
        post.addComment(newComment._id).then(() => {
          // Comment added!
          let returnUrl = '/'
          if (req.session.returnUrl) {
            returnUrl = req.session.returnUrl
            delete req.session.returnUrl
          }
          res.redirect(returnUrl)
        })
      })
    })
  },

  addLike: (req, res) => {
    // regex is: /post\/(.+)\/add(.{3,7})/
    let postId = req.params[0]
    let likeType = req.params[1]
    let userId = req.user._id
    Post.findById(postId).populate('likes').then(post => {
      if (!post) {
        // ERROR - Post with ID does not exist!
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }
      let likeIndex = post.likes.findIndex(like => {
        return like.author.equals(userId)
      })

      if (likeIndex !== -1) {
        // user has already liked this post
        if (post.likes[likeIndex].type === likeType) {
          res.redirect('/')
          return
        } else {
          // User is un-liking this photo and giving it a {likeType}
          // So we simply change the name of this like
          post.likes[likeIndex].type = likeType
          post.likes[likeIndex].save().then(() => {
            let returnUrl = '/'
            if (req.session.returnUrl) {
              returnUrl = req.session.returnUrl
              delete req.session.returnUrl
            }
            res.redirect(returnUrl)
            // Success!
          })
        }
      } else {
        // User is liking this post for the first time
        Like.create({ type: likeType, author: req.user._id }).then(like => {
          post.addLike(like._id).then(() => {
            let returnUrl = '/'
            if (req.session.returnUrl) {
              returnUrl = req.session.returnUrl
              delete req.session.returnUrl
            }

            res.redirect(returnUrl)
          })
        })
      }
    })
  },

  removeLike: (req, res) => {
    // regex is: /post\/(.+)\/remove(.{3,7})/
    let postId = req.params[0]
    let likeType = req.params[1]
    let userId = req.user._id

    Post.findById(postId).populate('likes').then(post => {
      if (!post) {
        req.session.errorMsg = 'No such post exists.'
        res.redirect('/')
        return
      }
      // Get the index of the user's like'
      let likeIndex = post.likes.findIndex(like => {
        return like.author.equals(userId)
      })

      if (likeIndex === -1) {
        // ERROR - User has not liked this at all
        res.redirect('/')
        return
      } else if (post.likes[likeIndex].type !== likeType) {
        // ERROR - example: User is trying to unPAW a post he has LOVED
        res.redirect('/')
        return
      }
      let likeId = post.likes[likeIndex]._id
      Like.findByIdAndRemove(likeId)

      post.removeLike(likeId).then(() => {
        // Like is removed!
        let returnUrl = '/'
        if (req.session.returnUrl) {
          returnUrl = req.session.returnUrl
          delete req.session.returnUrl
        }

        res.redirect(returnUrl)
        return
      })
    })
  }
}
<|endoftext|>


<commit_before>var models = require('../models/models.js');

// Autoload - factoriza el código si ruta incluye :quizId
exports.load = function(req, res, next, quizId) {
	models.Quiz.findById(quizId).then(
		function(quiz) {
			if (quiz) {
				req.quiz = quiz;
				next();
			} else {
				next(new Error('No existe quizId=' + quizId));
			}
		}
	).catch(function(error) {
		next(error);
	});
};

// GET /quizes
exports.index = function(req, res) {

	var filter = {};
	if (req.query.search !== undefined) {
		filter.where = [
			"lower(pregunta) like ?", "%" +
			req.query.search.split(" ").join("%").toLowerCase() + "%"
		];
	}

	models.Quiz
		.findAll(filter)
		.then(
			function(quizes) {
				res.render('quizes/index', {
					quizes: quizes
				});
			}
		)
		.catch(function(error) {
			next(error);
		});
};

// GET /quizes/:id
exports.show = function(req, res) {
	res.render('quizes/show', {
		quiz: req.quiz
	});
};

// GET /quizes/:id/answer
exports.answer = function(req, res) {
	var resultado = 'Incorrecto';
	if (req.query.respuesta === req.quiz.respuesta) {
		resultado = 'Correcto';
	}
	res.render('quizes/answer', {
		quiz: req.quiz,
		respuesta: resultado
	});
};

// GET /quizes/new
exports.new = function(req, res) {
	var quiz = models.Quiz.build({
		pregunta: "",
		respuesta: ""
	});

	res.render('quizes/new', {
		quiz: quiz
	});
};

// POST /quizes/create
exports.create = function(req, res) {
	var quiz = models.Quiz.build(req.body.quiz);

	// guarda en DB los campos pregunta y respuesta de quiz
	quiz.save({
		fields: ["pregunta", "respuesta"]
	}).then(function() {
		// res.redirect: Redirección HTTP a lista de preguntas
		res.redirect('/quizes');
	})
};
<commit_msg>Crear preguntas<commit_after>var models = require('../models/models.js');

// Autoload - factoriza el código si ruta incluye :quizId
exports.load = function(req, res, next, quizId) {
	models.Quiz.findById(quizId).then(
		function(quiz) {
			if (quiz) {
				req.quiz = quiz;
				next();
			} else {
				next(new Error('No existe quizId=' + quizId));
			}
		}
	).catch(function(error) {
		next(error);
	});
};

// GET /quizes
exports.index = function(req, res) {

	var filter = {};
	if (req.query.search !== undefined) {
		filter.where = [
			"lower(pregunta) like ?", "%" +
			req.query.search.split(" ").join("%").toLowerCase() + "%"
		];
	}

	models.Quiz
		.findAll(filter)
		.then(
			function(quizes) {
				res.render('quizes/index', {
					quizes: quizes
				});
			}
		)
		.catch(function(error) {
			next(error);
		});
};

// GET /quizes/:id
exports.show = function(req, res) {
	res.render('quizes/show', {
		quiz: req.quiz
	});
};

// GET /quizes/:id/answer
exports.answer = function(req, res) {
	var resultado = 'Incorrecto';
	if (req.query.respuesta.toLowerCase() === req.quiz.respuesta.toLowerCase()) {
		resultado = 'Correcto';
	}
	res.render('quizes/answer', {
		quiz: req.quiz,
		respuesta: resultado
	});
};

// GET /quizes/new
exports.new = function(req, res) {
	var quiz = models.Quiz.build({
		pregunta: "",
		respuesta: ""
	});

	res.render('quizes/new', {
		quiz: quiz
	});
};

// POST /quizes/create
exports.create = function(req, res) {
	var quiz = models.Quiz.build(req.body.quiz);

	// guarda en DB los campos pregunta y respuesta de quiz
	quiz.save({
		fields: ["pregunta", "respuesta"]
	}).then(function() {
		// res.redirect: Redirección HTTP a lista de preguntas
		res.redirect('/quizes');
	})
};
<|endoftext|>


<commit_before>var VCs;
var verifying = false;

function submitAnswer() {
    /* Protect against multiple requests */
    if(verifying)
        return;
    verifying = true;
    $("#right .footette").attr("class", "footetteDisabled");

    getVCLines(createEditor.getValue());
}

function getVCLines(content) {
    removeAllVCMarkers();
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=genVCs&project=Teaching_Project");

    socket.onmessage = function(message) {
        if(!verifying) return;

        // Extract the array of VCs from the message (trust me, this works)
        message = JSON.parse(message.data);
        if(message.status == "error") {
            $("#dialog-message").html("Your code is syntactically incorrect and thus could not be verified.");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }
        if(message.status != "complete") {
            return;
        }

	if(message.result == "") {
	    $("#dialog-message").html("Your code could not be verified; try a simpler answer and only use declared variables.");
	    $("#dialog-box").dialog("open");
        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");

        createEditor.focus();
        return;
	}

        message = decode(message.result);
        message = $(message).text();
        message = JSON.parse(message);

        // Simplify the VC information
        VCs = [];
        $.each(message.vcs, function (index, obj) {
            if (typeof obj.vc !== "undefined") VCs.push(obj);
        });

        addVCMarkers();
        verifyVCs(createEditor.getValue());
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function() { socket.send(content); };
}

function verifyVCs(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=verify2&project=Teaching_Project");

    socket.onmessage = function(message) {
        message = JSON.parse(message.data);
        if(message.status !== "processing") return;

        updateMarker(message.result);
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function() { socket.send(content); };
    socket.onclose = function() {
        if(doChecks() && succeed) {
            approved = true;
            $("#dialog-message").html("Your answer was verified and was semantically meaningful. You may move on to the next lesson.");
            $("#dialog-box").dialog("open");
            nextLessonAndSuccess();
        }
        if(!doChecks() && succeed) {
            approved = false;
            $("#dialog-message").html("Your answer was verified but semantically insufficient; try providing a more descriptive answer.");
            $("#dialog-box").dialog("open");
            createEditor.focus();
        }
        if(!succeed) {
            $("#dialog-message").html("Your answer was syntactically correct but unverifiable; the statement you are trying to prove is not true.");
            $("#dialog-box").dialog("open");
            if (currentLesson.self != currentLesson.nextLessonOnFailure)
                nextLessonAndFailure();
        }

        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
        sendData();
    }
}
<commit_msg>Some initial work<commit_after>var VCs;
var verifying = false;

function submitAnswer() {
    /* Protect against multiple requests */
//    if(verifying)
//        return;
//    verifying = true;
//    $("#right .footette").attr("class", "footetteDisabled");

    // Get student's code
    var content = createEditor.getValue();
    console.log(content);

    // Find all the confirm statements
    var regex = new RegExp("Confirm [^;]*;", "mg");
    var confirms = content.match(regex);
    console.log(confirms);

    // Remove the "Confirm " so that we can find the variable names
    var statement = confirms[0];
    statement = statement.substr(8);
    console.log(statement);

    // Split the string at the conditional
    regex = new RegExp("[<>=]");
    var parts = statement.split(regex);
    console.log(parts);

    // Find the variables use on the left side
    var left = parts[0];
    var right = parts[0];
    regex = new RegExp("[a-zA-Z]", "g");
    var variables = left.match(regex);
    console.log(variables);

    // Search for these variables on the right side
    variable = variables[0];
    regex = new RegExp("[^#]" + variable, "g");
    var trivials = right.match(regex);
    console.log(trivials);

//    getVCLines(createEditor.getValue());
}

function getVCLines(content) {
    removeAllVCMarkers();
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=genVCs&project=Teaching_Project");

    socket.onmessage = function(message) {
        if(!verifying) return;

        // Extract the array of VCs from the message (trust me, this works)
        message = JSON.parse(message.data);
        if(message.status == "error") {
            $("#dialog-message").html("Your code is syntactically incorrect and thus could not be verified.");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }
        if(message.status != "complete") {
            return;
        }

        if(message.result == "") {
            $("#dialog-message").html("Your code could not be verified; try a simpler answer and only use declared variables.");
            $("#dialog-box").dialog("open");
        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");

        createEditor.focus();
        return;
        }

        message = decode(message.result);
        message = $(message).text();
        message = JSON.parse(message);

        // Simplify the VC information
        VCs = [];
        $.each(message.vcs, function (index, obj) {
            if (typeof obj.vc !== "undefined") VCs.push(obj);
        });

        addVCMarkers();
        verifyVCs(createEditor.getValue());
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function() { socket.send(content); };
}

function verifyVCs(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=verify2&project=Teaching_Project");

    socket.onmessage = function(message) {
        message = JSON.parse(message.data);
        if(message.status !== "processing") return;

        updateMarker(message.result);
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function() { socket.send(content); };
    socket.onclose = function() {
        if(doChecks() && succeed) {
            approved = true;
            $("#dialog-message").html("Your answer was verified and was semantically meaningful. You may move on to the next lesson.");
            $("#dialog-box").dialog("open");
            nextLessonAndSuccess();
        }
        if(!doChecks() && succeed) {
            approved = false;
            $("#dialog-message").html("Your answer was verified but semantically insufficient; try providing a more descriptive answer.");
            $("#dialog-box").dialog("open");
            createEditor.focus();
        }
        if(!succeed) {
            $("#dialog-message").html("Your answer was syntactically correct but unverifiable; the statement you are trying to prove is not true.");
            $("#dialog-box").dialog("open");
            if (currentLesson.self != currentLesson.nextLessonOnFailure)
                nextLessonAndFailure();
        }

        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
        sendData();
    }
}

<|endoftext|>


<commit_before>/* global addVCMarkers approved createEditor currentLesson decode encode nextLessonAndSuccess nextLessonAndFailure
   removeAllVCMarkers sendData succeed toJSON updateMarker */

var VCs;
var verifying = false;

function submitAnswer() {
    /* Protect against multiple requests */
    if (verifying) {
        return;
    }

    verifying = true;
    $("#right .footette").attr("class", "footetteDisabled");

    var content = createEditor.getValue();

    if (checkForTrivials(content)) {
        getVCLines(content);
    } else {
        $("#dialog-message").html("Sorry, not the intended answer. Try again!");
        $("#dialog-box").dialog("open");
        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
        createEditor.focus();
    }
}

function checkForTrivials(content) {
    // Find all the confirm statements
    var regex = new RegExp("Confirm [^;]*;", "mg");
    var confirms = content.match(regex);
    if (confirms.length == 0) {
        return false;
    }

    var i;
    for (i = 0; i < confirms.length; i++) {
        // Remove the "Confirm " so that we can find the variable names
        var statement = confirms[i];
        statement = statement.substr(8);

        // Split the string at the conditional
        regex = new RegExp("[<>=]");
        var parts = statement.split(regex);
        if (parts.length != 2) {
            return false;
        }

        // Find the variables used on the left side
        var left = parts[0];
        var right = parts[1];
        regex = new RegExp("[a-zA-Z]", "g");
        var variables = left.match(regex);
        if (variables === null) {
            continue;
        }

        // Search for these variables on the right side
        var j;
        for (j = 0; j < variables.length; j++) {
            var variable = variables[j];
            regex = new RegExp("[^#]" + variable, "g");
            if (right.search(regex) > -1) {
                return false;
            }
        }
    }

    return true;
}

function getVCLines(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=genVCs&project=Teaching_Project");
    removeAllVCMarkers();

    socket.onmessage = function (message) {
        if (!verifying) {
            return;
        }

        // Extract the array of VCs from the message (trust me, this works)
        message = JSON.parse(message.data);
        if (message.status == "error") {
            $("#dialog-message").html("Sorry, can't parse your answer. Try again!");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }

        if (message.status != "complete") {
            return;
        }

        if (message.result == "") {
            $("#dialog-message").html("Sorry, can't parse your answer. Try again!");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }

        message = decode(message.result);
        message = $(message).text();
        message = JSON.parse(message);

        // Simplify the VC information
        VCs = [];
        $.each(message.vcs, function (index, obj) {
            if (typeof obj.vc !== "undefined") {
                VCs.push(obj);
            }
        });

        addVCMarkers();
        verifyVCs(createEditor.getValue());
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function () {
        socket.send(content);
    };
}

function verifyVCs(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=verify2&project=Teaching_Project");

    socket.onmessage = function (message) {
        message = JSON.parse(message.data);
        if (message.status !== "processing") {
            return;
        }

        updateMarker(message.result);
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function () {
        socket.send(content);
    };

    socket.onclose = function () {
        if (succeed) {
            approved = true;
            $("#dialog-message").html("Correct. On to the next lesson!");
            $("#dialog-box").dialog("open");
            nextLessonAndSuccess();
        } else {
            if (currentLesson.self != currentLesson.nextLessonOnFailure) {
                $("#dialog-message").html("Sorry, not correct. Try this other lesson!");
                $("#dialog-box").dialog("open");
                nextLessonAndFailure();
            } else {
                $("#dialog-message").html("Sorry, not correct. Try again!");
                $("#dialog-box").dialog("open");
            }
        }

        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
        sendData();
    };
}
<commit_msg>Send data before we reset the time!<commit_after>/* global addVCMarkers approved createEditor currentLesson decode encode nextLessonAndSuccess nextLessonAndFailure
   removeAllVCMarkers resetTime sendData succeed toJSON updateMarker */

var VCs;
var verifying = false;

function submitAnswer() {
    /* Protect against multiple requests */
    if (verifying) {
        return;
    }

    verifying = true;
    $("#right .footette").attr("class", "footetteDisabled");

    var content = createEditor.getValue();

    if (checkForTrivials(content)) {
        getVCLines(content);
    } else {
        $("#dialog-message").html("Sorry, not the intended answer. Try again!");
        $("#dialog-box").dialog("open");
        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
        createEditor.focus();
    }
}

function checkForTrivials(content) {
    // Find all the confirm statements
    var regex = new RegExp("Confirm [^;]*;", "mg");
    var confirms = content.match(regex);
    if (confirms.length == 0) {
        return false;
    }

    var i;
    for (i = 0; i < confirms.length; i++) {
        // Remove the "Confirm " so that we can find the variable names
        var statement = confirms[i];
        statement = statement.substr(8);

        // Split the string at the conditional
        regex = new RegExp("[<>=]");
        var parts = statement.split(regex);
        if (parts.length != 2) {
            return false;
        }

        // Find the variables used on the left side
        var left = parts[0];
        var right = parts[1];
        regex = new RegExp("[a-zA-Z]", "g");
        var variables = left.match(regex);
        if (variables === null) {
            continue;
        }

        // Search for these variables on the right side
        var j;
        for (j = 0; j < variables.length; j++) {
            var variable = variables[j];
            regex = new RegExp("[^#]" + variable, "g");
            if (right.search(regex) > -1) {
                return false;
            }
        }
    }

    return true;
}

function getVCLines(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=genVCs&project=Teaching_Project");
    removeAllVCMarkers();

    socket.onmessage = function (message) {
        if (!verifying) {
            return;
        }

        // Extract the array of VCs from the message (trust me, this works)
        message = JSON.parse(message.data);
        if (message.status == "error") {
            $("#dialog-message").html("Sorry, can't parse your answer. Try again!");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }

        if (message.status != "complete") {
            return;
        }

        if (message.result == "") {
            $("#dialog-message").html("Sorry, can't parse your answer. Try again!");
            $("#dialog-box").dialog("open");
            verifying = false;
            $("#right .footetteDisabled").attr("class", "footette");

            createEditor.focus();
            return;
        }

        message = decode(message.result);
        message = $(message).text();
        message = JSON.parse(message);

        // Simplify the VC information
        VCs = [];
        $.each(message.vcs, function (index, obj) {
            if (typeof obj.vc !== "undefined") {
                VCs.push(obj);
            }
        });

        addVCMarkers();
        verifyVCs(createEditor.getValue());
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function () {
        socket.send(content);
    };
}

function verifyVCs(content) {
    var socket = new WebSocket("wss://resolve.cs.clemson.edu/teaching/Compiler?job=verify2&project=Teaching_Project");

    socket.onmessage = function (message) {
        message = JSON.parse(message.data);
        if (message.status !== "processing") {
            return;
        }

        updateMarker(message.result);
    };

    content = encode(content);
    content = toJSON(content);

    socket.onopen = function () {
        socket.send(content);
    };

    socket.onclose = function () {
        if (succeed) {
            approved = true;
            $("#dialog-message").html("Correct. On to the next lesson!");
            $("#dialog-box").dialog("open");

            sendData(); // Need to send the data before we reset the time! (Need new "approved")
            nextLessonAndSuccess();
        } else {
            if (currentLesson.self != currentLesson.nextLessonOnFailure) {
                $("#dialog-message").html("Sorry, not correct. Try this other lesson!");
                $("#dialog-box").dialog("open");

				sendData(); // Need to send the data before we reset the time! ("approved" should be false)
                nextLessonAndFailure();
            } else {
                $("#dialog-message").html("Sorry, not correct. Try again!");
                $("#dialog-box").dialog("open");

				sendData(); // Need to send the data before we reset the time! ("approved" should be false)
				resetTime(); // Reset the time because it is a new attempt!
            }
        }

        verifying = false;
        $("#right .footetteDisabled").attr("class", "footette");
    };
}
<|endoftext|>


<commit_before>var cssRootPath = __dirname +  '/../../../src/widgets/themes/default/';
var cssRootFileName = cssRootPath + 'kekule.css';
var cssDestFileName = 'kekule.css';

var fs = require('fs');
var path = require('path');
var minify = require('node-minify');
var CleanCSS = require('clean-css');

const defMinifierName = 'clean-css';
const defMinifierOptions = {
	'clean-css': {
		level: 2
	}
};

var LINE_BREAK = /\r\n|\r|\n/;

var CssCompressor = class {
	constructor (destPath, minifierName, minifierOptions)
	{
		this._sourceLineMap = {};
		this._externalImgFileNames = [];
		this._externalImgRuleInfo = {};
		this._fileEncoding = 'utf8';
		this._rootPath = cssRootPath;
		this._rootFiles = [cssRootFileName];
		this.destPath = destPath;
		this.destFileName = cssDestFileName;
		this.minifierName = minifierName || defMinifierName;
		this.minifierOptions = minifierOptions || defMinifierOptions[this.minifierName];
	}

	// Combine all @import files to one
	_fetchImportFilesInline(cssSrcLines, cssPath)
	{
		var resultLines = [];
		var pattern = /@import url\([\'\"](.*)[\'\"]\)/;
		var lines = cssSrcLines;
		var self = this;
		lines.forEach(function(line){
			var matchResult = line.match(pattern);
			if (matchResult && matchResult[1])  // matched, an @import command
			{
				var fileName = path.resolve(cssPath, matchResult[1]);
				if (fs.existsSync(fileName))
				{
					var rawContent = fs.readFileSync(fileName, self._fileEncoding);
					var childPath = path.dirname(fileName);
					var content = self._fetchImportFilesInline(rawContent.split(LINE_BREAK), childPath);
					if (content)
						resultLines = resultLines.concat(content);
				}
			}
			else
				resultLines.push(line);
		});
		return resultLines;
	}

	//
	_getLastUnemptyLineIndex(cssLines, index)
	{
		var currIndex = index - 1;
		var currLine = (cssLines[currIndex] || '').trim();
		while (!currLine && currIndex >= 0)
		{
			--currIndex;
			currLine = cssLines[currIndex].trim();
		}
		if (currIndex < 0)
			return -1;
		else
			return currIndex;
	}
	_getNextUnemptyLineIndex(cssLines, index)
	{
		var currIndex = index + 1;
		var currLine = (cssLines[currIndex] || '').trim();
		var totalLineCount = cssLines.length;
		while (!currLine && currIndex < totalLineCount)
		{
			++currIndex;
			currLine = cssLines[currIndex].trim();
		}
		if (currIndex >= totalLineCount)
			return -1;
		else
			return currIndex;
	}

	_getBackgroundImageRuleInfo(cssLines, bgImagePropertyLineIndex)
	{
		var selector, selectorLineIndexBegin, selectorLineIndexEnd, leadingBracketLineIndex, tailingBracketLineIndex;
		// find the leading '{' and the selector line
		var lastLineIndex = this._getLastUnemptyLineIndex(cssLines, bgImagePropertyLineIndex);
		if (lastLineIndex >= 0)
		{
			var lastLine = cssLines[lastLineIndex].trim();
			if (lastLine === '{')  // found '{'
			{
				leadingBracketLineIndex = lastLineIndex;
				selectorLineIndexEnd = this._getLastUnemptyLineIndex(cssLines, lastLineIndex);
				if (selectorLineIndexEnd >= 0)
				{
					selectorLineIndexBegin = selectorLineIndexEnd;
					var i = selectorLineIndexEnd;
					do
					{
						var lastSelectorLineIndex = this._getLastUnemptyLineIndex(cssLines, i);
						if (lastSelectorLineIndex >= 0)
						{
							var lastSelectorLine = cssLines[lastSelectorLineIndex].trim();
							if (lastSelectorLine.lastIndexOf(',') === lastSelectorLine.length - 1)
							{
								selectorLineIndexBegin = lastSelectorLineIndex;
								--i;
							}
							else
								break;
						}
						else
							break;
					}
					while (true)
				}
			}
		}
		// find tailing bracket
		var nextLineIndex = this._getNextUnemptyLineIndex(cssLines, bgImagePropertyLineIndex);
		if (nextLineIndex >= 0)
		{
			var nextLine = cssLines[nextLineIndex].trim();
			if (nextLine === '}')
			{
				tailingBracketLineIndex = nextLineIndex;
			}
		}

		if (selectorLineIndexBegin >= 0 && selectorLineIndexEnd >= 0)
		{
			var result = {
				'selectorLines': cssLines.slice(selectorLineIndexBegin, selectorLineIndexEnd + 1), 'selectorLineIndexBegin': selectorLineIndexBegin, 'selectorLineIndexEnd': selectorLineIndexEnd,
				'leadingBracketLineIndex': leadingBracketLineIndex, 'tailingBracketLineIndex': tailingBracketLineIndex
			};
			//console.log(result.selectorLines[result.selectorLines.length - 1] == cssLines[selectorLineIndexEnd], result.selectorLines, cssLines[selectorLineIndexEnd]);

			return result;
		}
		else
			return null;
	}

	// turn external background image to base64 string
	_imgToBase64DataString(imgFileName)
	{
		if (fs.existsSync(imgFileName))
		{
			var buffer = fs.readFileSync(imgFileName);
			var strBase64 = buffer.toString('base64');
			var fileExt = path.extname(imgFileName);
			var dataType = 'data:image/' + fileExt.substr(1) + ';base64,';
			return dataType + strBase64;
		}
		return null;
	}

	_convertExternalBackgroundImageInline(cssLines, cssPath)
	{
		var self = this;
		var pattern = /(.*)background-image: url\(["'](.*)["']\)/;
		var result = [];
		//cssLines.forEach(function(line){
		var i = 0, l = cssLines.length;
		//for (var i = 0, l = cssLines.length; i < l; ++i)
		while (i < l)
		{
			var line = cssLines[i];
			var matchResult = line.match(pattern);
			if (matchResult && matchResult[2])  // matched, an background image property
			{
				var strLeading = matchResult[1];
				var url = matchResult[2];
				if (url.indexOf('data:') !== 0)  // not already base64
				{
					var ruleInfo = self._getBackgroundImageRuleInfo(cssLines, i);
					if (!ruleInfo)
						console.warn('Can not found rule info', url);
					//console.log('find', url);
					var imgFileName = path.resolve(cssPath, url);
					var prevRuleInfo = self._externalImgRuleInfo[imgFileName];
					//if (self._externalImgFileNames.indexOf(imgFileName) >= 0)  // has duplication, try merge rules
					if (prevRuleInfo)
					{
						//console.warn('Duplicated background image resource: ' + imgFileName + '!');
						// combine selector
						var currSelector = ruleInfo.selectorLines.join(' ');
						var prevSelectorLineIndex = prevRuleInfo.selectorLineIndexEnd;
						prevSelectorLineIndex = self._sourceLineMap[prevSelectorLineIndex] || prevSelectorLineIndex;
						//console.log('[prev]', prevRuleInfo, currSelector);  //, result[prevSelectorLineIndex]);
						//console.log(prevSelectorLineIndex, result.length, prevSelectorLineIndex < result.length);
						result[prevSelectorLineIndex] = result[prevSelectorLineIndex] + ', ' + currSelector;
						//console.log('[NEW]');
						//console.log(result[prevSelectorLineIndex].trim());

						// erase prev selector lines
						var eraseLineCount = i - ruleInfo.selectorLineIndexBegin;
						result.splice(result.length - eraseLineCount, eraseLineCount);
						//console.log('erase', eraseLineCount);

						//console.log('merge rules', url, result[prevSelectorLineIndex]);

						// skip current rule lines
						i = ruleInfo.tailingBracketLineIndex + 1;
						continue;
					}
					else
					{
						self._externalImgRuleInfo[imgFileName] = ruleInfo;
					}
					var strBase64 = self._imgToBase64DataString(imgFileName);
					if (strBase64)
					{
						var newLine = strLeading + 'background-image: url("' + strBase64 + '");';
						result.push(newLine);
						//console.log('toBase64', line, newLine);
						self._externalImgFileNames.push(imgFileName);  // register already handled image file names, avoid duplication
						self._sourceLineMap[i] = result.length - 1;
					}
				}
			}
			else
			{
				result.push(line);
				self._sourceLineMap[i] = result.length - 1;
			}

			++i;
		}
		//});
		return result;
	}

	prepareCssContent(targetCssFiles, cssPath)
	{
		var self = this;
		var result = [];
		targetCssFiles.forEach(function(fileName){
			//console.log('handle', fileName);
			// test
			if (fs.existsSync(fileName))
			{
				var rawContent = fs.readFileSync(fileName, self._fileEncoding);
				var rawLines = rawContent.split(LINE_BREAK);
				//var rawLines = rawContent.split('\n');
				var lines = self._fetchImportFilesInline(rawLines, cssPath);
				lines = self._convertExternalBackgroundImageInline(lines, cssPath);
				if (lines && lines.length)
					result = result.concat(lines);
			}
		});
		//console.log('rule info', this._externalImgRuleInfo);
		return result.join('\n');
	}

	minimize(cssString, callback)
	{
		var input = this._rootFiles[0];
		//console.log('input', input);
		minify.minify({
			'compressor': this.minifierName,
			//'content': cssString,
			'input': cssString,
			'output': './output.css',
			'callback': callback
		});
	}

	execute(destPath)
	{
		this._externalImgFileNames = [];
		this._externalImgRuleInfo = {};
		this._sourceLineMap = {};
		var self = this;
		var rootFiles = this._rootFiles;
		var outputPath = destPath || this.destPath;
		var destFileName = path.resolve(outputPath, this.destFileName);
		var preparedCssString = this.prepareCssContent(rootFiles, this._rootPath);

		/*
		this.minimize(preparedCssString, function(err, min){
			if (err)
				console.error(err);
			else
			{
				console.log('minimized: ', min);
			}
		});
		*/
		// TODO: currently fixed to CSS Clean
		var options = this.minifierOptions[this.minifierName];
		var output = new CleanCSS(options).minify(preparedCssString);
		if (output.errors && output.errors.length)
			console.warn(output.errors);
		if (output.warnings && output.warnings.length)
			console.warn(output.warnings);

		var result = output.styles;

		if (result && destFileName)
		{
			if (!fs.existsSync(outputPath)){
				fs.mkdirSync(outputPath, {recursive: true});
			}
			console.log('Min CSS file ' + this.destFileName + ' created');
			fs.writeFileSync(destFileName, result, 'utf-8');
		}

		return result;
	}
};

exports.CssCompressor = CssCompressor;<commit_msg>Handle external image cursor property in CSS<commit_after>var cssRootPath = __dirname +  '/../../../src/widgets/themes/default/';
var cssRootFileName = cssRootPath + 'kekule.css';
var cssDestFileName = 'kekule.css';

var fs = require('fs');
var path = require('path');
var minify = require('node-minify');
var CleanCSS = require('clean-css');

const defMinifierName = 'clean-css';
const defMinifierOptions = {
	'clean-css': {
		level: 2
	}
};

var LINE_BREAK = /\r\n|\r|\n/;

var CssCompressor = class {
	constructor (destPath, minifierName, minifierOptions)
	{
		this._sourceLineMap = {};
		this._externalImgFileNames = [];
		this._externalImgRuleInfo = {};
		this._fileEncoding = 'utf8';
		this._rootPath = cssRootPath;
		this._rootFiles = [cssRootFileName];
		this.destPath = destPath;
		this.destFileName = cssDestFileName;
		this.minifierName = minifierName || defMinifierName;
		this.minifierOptions = minifierOptions || defMinifierOptions[this.minifierName];
	}

	// Combine all @import files to one
	_fetchImportFilesInline(cssSrcLines, cssPath)
	{
		var resultLines = [];
		var pattern = /@import url\([\'\"](.*)[\'\"]\)/;
		var lines = cssSrcLines;
		var self = this;
		lines.forEach(function(line){
			var matchResult = line.match(pattern);
			if (matchResult && matchResult[1])  // matched, an @import command
			{
				var fileName = path.resolve(cssPath, matchResult[1]);
				if (fs.existsSync(fileName))
				{
					var rawContent = fs.readFileSync(fileName, self._fileEncoding);
					var childPath = path.dirname(fileName);
					var content = self._fetchImportFilesInline(rawContent.split(LINE_BREAK), childPath);
					if (content)
						resultLines = resultLines.concat(content);
				}
			}
			else
				resultLines.push(line);
		});
		return resultLines;
	}

	//
	_getLastUnemptyLineIndex(cssLines, index)
	{
		var currIndex = index - 1;
		var currLine = (cssLines[currIndex] || '').trim();
		while (!currLine && currIndex >= 0)
		{
			--currIndex;
			currLine = cssLines[currIndex].trim();
		}
		if (currIndex < 0)
			return -1;
		else
			return currIndex;
	}
	_getNextUnemptyLineIndex(cssLines, index)
	{
		var currIndex = index + 1;
		var currLine = (cssLines[currIndex] || '').trim();
		var totalLineCount = cssLines.length;
		while (!currLine && currIndex < totalLineCount)
		{
			++currIndex;
			currLine = cssLines[currIndex].trim();
		}
		if (currIndex >= totalLineCount)
			return -1;
		else
			return currIndex;
	}

	_getBackgroundImageRuleInfo(cssLines, bgImagePropertyLineIndex)
	{
		var selector, selectorLineIndexBegin, selectorLineIndexEnd, leadingBracketLineIndex, tailingBracketLineIndex;
		// find the leading '{' and the selector line
		var lastLineIndex = this._getLastUnemptyLineIndex(cssLines, bgImagePropertyLineIndex);
		if (lastLineIndex >= 0)
		{
			var lastLine = cssLines[lastLineIndex].trim();
			if (lastLine === '{')  // found '{'
			{
				leadingBracketLineIndex = lastLineIndex;
				selectorLineIndexEnd = this._getLastUnemptyLineIndex(cssLines, lastLineIndex);
				if (selectorLineIndexEnd >= 0)
				{
					selectorLineIndexBegin = selectorLineIndexEnd;
					var i = selectorLineIndexEnd;
					do
					{
						var lastSelectorLineIndex = this._getLastUnemptyLineIndex(cssLines, i);
						if (lastSelectorLineIndex >= 0)
						{
							var lastSelectorLine = cssLines[lastSelectorLineIndex].trim();
							if (lastSelectorLine.lastIndexOf(',') === lastSelectorLine.length - 1)
							{
								selectorLineIndexBegin = lastSelectorLineIndex;
								--i;
							}
							else
								break;
						}
						else
							break;
					}
					while (true)
				}
			}
		}
		// find tailing bracket
		var nextLineIndex = this._getNextUnemptyLineIndex(cssLines, bgImagePropertyLineIndex);
		if (nextLineIndex >= 0)
		{
			var nextLine = cssLines[nextLineIndex].trim();
			if (nextLine === '}')
			{
				tailingBracketLineIndex = nextLineIndex;
			}
		}

		if (selectorLineIndexBegin >= 0 && selectorLineIndexEnd >= 0)
		{
			var result = {
				'selectorLines': cssLines.slice(selectorLineIndexBegin, selectorLineIndexEnd + 1), 'selectorLineIndexBegin': selectorLineIndexBegin, 'selectorLineIndexEnd': selectorLineIndexEnd,
				'leadingBracketLineIndex': leadingBracketLineIndex, 'tailingBracketLineIndex': tailingBracketLineIndex
			};
			//console.log(result.selectorLines[result.selectorLines.length - 1] == cssLines[selectorLineIndexEnd], result.selectorLines, cssLines[selectorLineIndexEnd]);

			return result;
		}
		else
			return null;
	}

	// turn external background image to base64 string
	_imgToBase64DataString(imgFileName)
	{
		if (fs.existsSync(imgFileName))
		{
			var buffer = fs.readFileSync(imgFileName);
			var strBase64 = buffer.toString('base64');
			var fileExt = path.extname(imgFileName).substr(1).toLowerCase();
			var mimeType = fileExt === 'cur'? 'x-icon': fileExt;
			var dataType = 'data:image/' + mimeType + ';base64,';
			return dataType + strBase64;
		}
		return null;
	}

	_convertExternalCursorImageInline(cssLines, cssPath)
	{
		var propertyPattern = /(.*)cursor:\s*(url\(["'](.*)["']\))+/g;
		var urlPattern = /url\(["'](.*?)["']\)+/g;
		var result = [];
		var self = this;
		cssLines.forEach(function(line){
			var propMatch = line.match(propertyPattern);
			if (propMatch)
			{
				var newLine = line;
				var matches = line.matchAll(urlPattern);
				for (const match of matches) {
					var url = match[1];
					if (url)
					{
						if (url.indexOf('data:') !== 0)  // not already base64
						{
							var imgFileName = path.resolve(cssPath, url);
							var strBase64 = self._imgToBase64DataString(imgFileName);
							if (strBase64)
							{
								newLine = newLine.replace(url, strBase64);
							}
						}
					}
				}
				//console.log('convert to new cursor line', newLine);
				result.push(newLine);
			}
			else
				result.push(line);
		});
		return result;
	}

	_convertExternalBackgroundImageInline(cssLines, cssPath)
	{
		var self = this;
		var pattern = /(.*)background-image:\s*url\(["'](.*)["']\)/;
		var result = [];
		//cssLines.forEach(function(line){
		var i = 0, l = cssLines.length;
		//for (var i = 0, l = cssLines.length; i < l; ++i)
		while (i < l)
		{
			var line = cssLines[i];
			var matchResult = line.match(pattern);
			if (matchResult && matchResult[2])  // matched, an background image property
			{
				var strLeading = matchResult[1];
				var url = matchResult[2];
				if (url.indexOf('data:') !== 0)  // not already base64
				{
					var ruleInfo = self._getBackgroundImageRuleInfo(cssLines, i);
					if (!ruleInfo)
						console.warn('Can not found rule info', url);
					//console.log('find', url);
					var imgFileName = path.resolve(cssPath, url);
					var prevRuleInfo = self._externalImgRuleInfo[imgFileName];
					//if (self._externalImgFileNames.indexOf(imgFileName) >= 0)  // has duplication, try merge rules
					if (prevRuleInfo)
					{
						//console.warn('Duplicated background image resource: ' + imgFileName + '!');
						// combine selector
						var currSelector = ruleInfo.selectorLines.join(' ');
						var prevSelectorLineIndex = prevRuleInfo.selectorLineIndexEnd;
						prevSelectorLineIndex = self._sourceLineMap[prevSelectorLineIndex] || prevSelectorLineIndex;
						//console.log('[prev]', prevRuleInfo, currSelector);  //, result[prevSelectorLineIndex]);
						//console.log(prevSelectorLineIndex, result.length, prevSelectorLineIndex < result.length);
						result[prevSelectorLineIndex] = result[prevSelectorLineIndex] + ', ' + currSelector;
						//console.log('[NEW]');
						//console.log(result[prevSelectorLineIndex].trim());

						// erase prev selector lines
						var eraseLineCount = i - ruleInfo.selectorLineIndexBegin;
						result.splice(result.length - eraseLineCount, eraseLineCount);
						//console.log('erase', eraseLineCount);

						//console.log('merge rules', url, result[prevSelectorLineIndex]);

						// skip current rule lines
						i = ruleInfo.tailingBracketLineIndex + 1;
						continue;
					}
					else
					{
						self._externalImgRuleInfo[imgFileName] = ruleInfo;
					}
					var strBase64 = self._imgToBase64DataString(imgFileName);
					if (strBase64)
					{
						var newLine = strLeading + 'background-image: url("' + strBase64 + '");';
						result.push(newLine);
						//console.log('toBase64', line, newLine);
						self._externalImgFileNames.push(imgFileName);  // register already handled image file names, avoid duplication
						self._sourceLineMap[i] = result.length - 1;
					}
				}
			}
			else
			{
				result.push(line);
				self._sourceLineMap[i] = result.length - 1;
			}

			++i;
		}
		//});
		return result;
	}

	prepareCssContent(targetCssFiles, cssPath)
	{
		var self = this;
		var result = [];
		targetCssFiles.forEach(function(fileName){
			//console.log('handle', fileName);
			// test
			if (fs.existsSync(fileName))
			{
				var rawContent = fs.readFileSync(fileName, self._fileEncoding);
				var rawLines = rawContent.split(LINE_BREAK);
				//var rawLines = rawContent.split('\n');
				var lines = self._fetchImportFilesInline(rawLines, cssPath);
				lines = self._convertExternalBackgroundImageInline(lines, cssPath);
				lines = self._convertExternalCursorImageInline(lines, cssPath);
				if (lines && lines.length)
					result = result.concat(lines);
			}
		});
		//console.log('rule info', this._externalImgRuleInfo);
		return result.join('\n');
	}

	minimize(cssString, callback)
	{
		var input = this._rootFiles[0];
		//console.log('input', input);
		minify.minify({
			'compressor': this.minifierName,
			//'content': cssString,
			'input': cssString,
			'output': './output.css',
			'callback': callback
		});
	}

	execute(destPath)
	{
		this._externalImgFileNames = [];
		this._externalImgRuleInfo = {};
		this._sourceLineMap = {};
		var self = this;
		var rootFiles = this._rootFiles;
		var outputPath = destPath || this.destPath;
		var destFileName = path.resolve(outputPath, this.destFileName);
		var preparedCssString = this.prepareCssContent(rootFiles, this._rootPath);

		/*
		this.minimize(preparedCssString, function(err, min){
			if (err)
				console.error(err);
			else
			{
				console.log('minimized: ', min);
			}
		});
		*/
		// TODO: currently fixed to CSS Clean
		var options = this.minifierOptions[this.minifierName];
		var output = new CleanCSS(options).minify(preparedCssString);
		if (output.errors && output.errors.length)
			console.warn(output.errors);
		if (output.warnings && output.warnings.length)
			console.warn(output.warnings);

		var result = output.styles;

		if (result && outputPath && destFileName)
		{
			if (!fs.existsSync(outputPath)){
				fs.mkdirSync(outputPath, {recursive: true});
			}
			console.log('Min CSS file ' + this.destFileName + ' created');
			fs.writeFileSync(destFileName, result, 'utf-8');
		}

		return result;
	}
};

exports.CssCompressor = CssCompressor;<|endoftext|>


<commit_before>'use strict';

(function (client) {

    var character = function () { };

    if (typeof module === "object" && module && typeof module.exports === "object") {
        module.exports = character;
    }
    else {
        client.character = character;
    }

    character.prototype.position = {};
    character.prototype.hitPoints = 20;
    character.prototype.img = '';

})(this);
<commit_msg>add name attribute to character from codeanywhere<commit_after>'use strict';

(function (client) {

    var character = function () { };

    if (typeof module === "object" && module && typeof module.exports === "object") {
        module.exports = character;
    }
    else {
        client.character = character;
    }

    character.prototype.position = {};
    character.prototype.hitPoints = 20;
    character.prototype.img = '';
    character.prototype.name = '';

})(this);
<|endoftext|>


<commit_before>
// TODO: Genera la pagina del muro (Si usuario logueado)
exports.index = function(req, res) {
}

// TODO: Añade un post a la base de datos
exports.addPost = function(req, res) {
}

// TODO: Obtiene un post en concreto
exports.getPost = function(req, res) {
}

// TODO: Borra el post pasado como parametro
exports.deletePost = function(req, res) {
}

// Faltan los likes
<commit_msg>Añadidas funciones al muro (WIP)<commit_after>var swig 			= require('swig');
var mongoose 		= require ('mongoose');
var validator 		= require('express-validator');
var postModel 		= mongoose.model('Post');

// TODO: Genera la pagina del muro (Si usuario logueado)
exports.index = function(req, res) {
		var baseweb = swig.compileFile('views/base.html');
		var piecepost = swig.compileFile('views/piece-post.html');
		var piecenewpost = swig.compileFile('views/piece-newpost.html');

		postModel.list(20, 0, function (err, posts) {
			var postsRenders = Array();
			//Mete el form de post nuevo
			postsRenders.push(piecenewpost());

			//Renderiza los posts
			posts.forEach(function(post) {
				//Revisar
				postsRenders.push(piecepost(post));
			});

			res.status(200);
			//Manda todo
			res.send(baseweb({content: postsRenders}));

			res.end();
		});
}

// TODO: Añade un post a la base de datos
exports.addPost = function(req, res) {
  //Comprobaciones (no vacio)
	req.checkBody('title', 'El titulo no puede estar vacio').notEmpty();
  req.checkBody('body', 'El post debe tener contenido').notEmpty();
  var errors = req.validationErrors();
  console.log(errors);

  if (errors) {
    res.send("Errores en formulario");
	}
  else {
  	//Recuperar post e insertar
		var npost = new postModel(req.body);
		res.send("Post publicado correctamente");
  }
}

// TODO: Obtiene un post en concreto
exports.getPost = function(req, res) {
	var piecepost = swig.compileFile('views/piece-post.html');
	var id = req.body.id;

	post.get(function (err, post){
		if (err) res.json(err);
		else {
			//
			res.send("elpost");
			}
	});
}

// TODO: Borra el post pasado como parametro
exports.deletePost = function(req, res) {
	//Obtener post de algun modo y...
	post.delete(function (err, post){
		if (err) res.json(err);
		else {}
});
}

// Faltan los likes
<|endoftext|>


<commit_before>var DOMutil = require('../../../DOMutil');
var Points = require('./points');

function Bargraph(groupId, options) {
}

Bargraph.drawIcon = function (group, x, y, iconWidth, iconHeight, framework) {
  var fillHeight = iconHeight * 0.5;
  var path, fillPath;

  var outline = DOMutil.getSVGElement("rect", framework.svgElements, framework.svg);
  outline.setAttributeNS(null, "x", x);
  outline.setAttributeNS(null, "y", y - fillHeight);
  outline.setAttributeNS(null, "width", iconWidth);
  outline.setAttributeNS(null, "height", 2 * fillHeight);
  outline.setAttributeNS(null, "class", "vis-outline");

  var barWidth = Math.round(0.3 * iconWidth);
  var bar1Height = Math.round(0.4 * iconHeight);
  var bar2Height = Math.round(0.75 * iconHeight);

  var offset = Math.round((iconWidth - (2 * barWidth)) / 3);

  DOMutil.drawBar(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, barWidth, bar1Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
  DOMutil.drawBar(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
  //TODO: draw little points if drawPoints enabled.

  if (group.options.drawPoints.enabled == true) {
    var groupTemplate = {
      style: group.options.drawPoints.style,
      styles: group.options.drawPoints.styles,
      size: barWidth/5,
      className: group.className
    };
    DOMutil.drawPoint(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, groupTemplate, framework.svgElements, framework.svg);
    DOMutil.drawPoint(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, groupTemplate, framework.svgElements, framework.svg);
  }

}

/**
 * draw a bar graph
 *
 * @param groupIds
 * @param processedGroupData
 */
Bargraph.draw = function (groupIds, processedGroupData, framework) {
  var combinedData = [];
  var intersections = {};
  var coreDistance;
  var key, drawData;
  var group;
  var i,j;
  var barPoints = 0;

  // combine all barchart data
  for (i = 0; i < groupIds.length; i++) {
    group = framework.groups[groupIds[i]];
    if (group.options.style === 'bar') {
      if (group.visible === true && (framework.options.groups.visibility[groupIds[i]] === undefined || framework.options.groups.visibility[groupIds[i]] === true)) {
        for (j = 0; j < processedGroupData[groupIds[i]].length; j++) {
          combinedData.push({
            screen_x: processedGroupData[groupIds[i]][j].screen_x,
            screen_y: processedGroupData[groupIds[i]][j].screen_y,
            groupId: groupIds[i],
            label: processedGroupData[groupIds[i]][j].label
          });
          barPoints += 1;
        }
      }
    }
  }

  if (barPoints === 0) {return;}

  // sort by time and by group
  combinedData.sort(function (a, b) {
    if (a.screen_x === b.screen_x) {
      return a.groupId < b.groupId ? -1 : 1;
    }
    else {
      return a.screen_x - b.screen_x;
    }
  });

  // get intersections
  Bargraph._getDataIntersections(intersections, combinedData);

  // plot barchart
  for (i = 0; i < combinedData.length; i++) {
    group = framework.groups[combinedData[i].groupId];
    var minWidth = 0.1 * group.options.barChart.width;

    key = combinedData[i].screen_x;
    var heightOffset = 0;
    if (intersections[key] === undefined) {
      if (i+1 < combinedData.length) {coreDistance = Math.abs(combinedData[i+1].screen_x - key);}
      if (i > 0)                     {coreDistance = Math.min(coreDistance,Math.abs(combinedData[i-1].screen_x - key));}
      drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
    }
    else {
      var nextKey = i + (intersections[key].amount - intersections[key].resolved);
      var prevKey = i - (intersections[key].resolved + 1);
      if (nextKey < combinedData.length) {coreDistance = Math.abs(combinedData[nextKey].screen_x - key);}
      if (prevKey > 0)                   {coreDistance = Math.min(coreDistance,Math.abs(combinedData[prevKey].screen_x - key));}
      drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
      intersections[key].resolved += 1;

      if (group.options.stack === true) {
        if (combinedData[i].screen_y < group.zeroPosition) {
          heightOffset = intersections[key].accumulatedNegative;
          intersections[key].accumulatedNegative += group.zeroPosition - combinedData[i].screen_y;
        }
        else {
          heightOffset = intersections[key].accumulatedPositive;
          intersections[key].accumulatedPositive += group.zeroPosition - combinedData[i].screen_y;
        }
      }
      else if (group.options.barChart.sideBySide === true) {
        drawData.width = drawData.width / intersections[key].amount;
        drawData.offset += (intersections[key].resolved) * drawData.width - (0.5*drawData.width * (intersections[key].amount+1));
        if (group.options.barChart.align === 'left')       {drawData.offset -= 0.5*drawData.width;}
        else if (group.options.barChart.align === 'right') {drawData.offset += 0.5*drawData.width;}
      }
    }
    DOMutil.drawBar(combinedData[i].screen_x + drawData.offset, combinedData[i].screen_y - heightOffset, drawData.width, group.zeroPosition - combinedData[i].screen_y, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
    // draw points
    if (group.options.drawPoints.enabled === true) {
      let pointData = {
        screen_x:combinedData[i].screen_x,
        screen_y:combinedData[i].screen_y - heightOffset,
        groupId: combinedData[i].groupId,
        label: combinedData[i].label
      };
      Points.draw([pointData], group, framework, drawData.offset);
      //DOMutil.drawPoint(combinedData[i].x + drawData.offset, combinedData[i].y, group, framework.svgElements, framework.svg);
    }
  }
};

/**
 * Fill the intersections object with counters of how many datapoints share the same x coordinates
 * @param intersections
 * @param combinedData
 * @private
 */
Bargraph._getDataIntersections = function (intersections, combinedData) {
  // get intersections
  var coreDistance;
  for (var i = 0; i < combinedData.length; i++) {
    if (i + 1 < combinedData.length) {
      coreDistance = Math.abs(combinedData[i + 1].screen_x - combinedData[i].screen_x);
    }
    if (i > 0) {
      coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].screen_x - combinedData[i].screen_x));
    }
    if (coreDistance === 0) {
      if (intersections[combinedData[i].screen_x] === undefined) {
        intersections[combinedData[i].screen_x] = {amount: 0, resolved: 0, accumulatedPositive: 0, accumulatedNegative: 0};
      }
      intersections[combinedData[i].screen_x].amount += 1;
    }
  }
};

/**
 * Get the width and offset for bargraphs based on the coredistance between datapoints
 *
 * @param coreDistance
 * @param group
 * @param minWidth
 * @returns {{width: Number, offset: Number}}
 * @private
 */
Bargraph._getSafeDrawData = function (coreDistance, group, minWidth) {
  var width, offset;
  if (coreDistance < group.options.barChart.width && coreDistance > 0) {
    width = coreDistance < minWidth ? minWidth : coreDistance;

    offset = 0; // recalculate offset with the new width;
    if (group.options.barChart.align === 'left') {
      offset -= 0.5 * coreDistance;
    }
    else if (group.options.barChart.align === 'right') {
      offset += 0.5 * coreDistance;
    }
  }
  else {
    // default settings
    width = group.options.barChart.width;
    offset = 0;
    if (group.options.barChart.align === 'left') {
      offset -= 0.5 * group.options.barChart.width;
    }
    else if (group.options.barChart.align === 'right') {
      offset += 0.5 * group.options.barChart.width;
    }
  }

  return {width: width, offset: offset};
};

Bargraph.getStackedYRange = function(combinedData, groupRanges, groupIds, groupLabel, orientation) {
  if (combinedData.length > 0) {
    // sort by time and by group
    combinedData.sort(function (a, b) {
      if (a.screen_x === b.screen_x) {
        return a.groupId < b.groupId ? -1 : 1;
      }
      else {
        return a.screen_x - b.screen_x;
      }
    });
    var intersections = {};

    Bargraph._getDataIntersections(intersections, combinedData);
    groupRanges[groupLabel] = Bargraph._getStackedYRange(intersections, combinedData);
    groupRanges[groupLabel].yAxisOrientation = orientation;
    groupIds.push(groupLabel);
  }
}

Bargraph._getStackedYRange = function (intersections, combinedData) {
  var key;
  var yMin = combinedData[0].screen_y;
  var yMax = combinedData[0].screen_y;
  for (var i = 0; i < combinedData.length; i++) {
    key = combinedData[i].screen_x;
    if (intersections[key] === undefined) {
      yMin = yMin > combinedData[i].screen_y ? combinedData[i].screen_y : yMin;
      yMax = yMax < combinedData[i].screen_y ? combinedData[i].screen_y : yMax;
    }
    else {
      if (combinedData[i].screen_y < 0) {
        intersections[key].accumulatedNegative += combinedData[i].screen_y;
      }
      else {
        intersections[key].accumulatedPositive += combinedData[i].screen_y;
      }
    }
  }
  for (var xpos in intersections) {
    if (intersections.hasOwnProperty(xpos)) {
      yMin = yMin > intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMin;
      yMin = yMin > intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMin;
      yMax = yMax < intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMax;
      yMax = yMax < intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMax;
    }
  }

  return {min: yMin, max: yMax};
};

module.exports = Bargraph;<commit_msg>Put a proper scale limit on the bar icon Minor cleanup<commit_after>var DOMutil = require('../../../DOMutil');
var Points = require('./points');

function Bargraph(groupId, options) {
}

Bargraph.drawIcon = function (group, x, y, iconWidth, iconHeight, framework) {
  var fillHeight = iconHeight * 0.5;
  var path, fillPath;

  var outline = DOMutil.getSVGElement("rect", framework.svgElements, framework.svg);
  outline.setAttributeNS(null, "x", x);
  outline.setAttributeNS(null, "y", y - fillHeight);
  outline.setAttributeNS(null, "width", iconWidth);
  outline.setAttributeNS(null, "height", 2 * fillHeight);
  outline.setAttributeNS(null, "class", "vis-outline");

  var barWidth = Math.round(0.3 * iconWidth);
  var bar1Height = Math.round(0.4 * iconHeight);
  var bar2Height = Math.round(0.75 * iconHeight);

  var offset = Math.round((iconWidth - (2 * barWidth)) / 3);

  DOMutil.drawBar(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, barWidth, bar1Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
  DOMutil.drawBar(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, barWidth, bar2Height, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);

  if (group.options.drawPoints.enabled == true) {
    var groupTemplate = {
      style: group.options.drawPoints.style,
      styles: group.options.drawPoints.styles,
      size: Math.max(barWidth/5,group.options.drawPoints.size),
      className: group.className
    };
    DOMutil.drawPoint(x + 0.5 * barWidth + offset, y + fillHeight - bar1Height - 1, groupTemplate, framework.svgElements, framework.svg);
    DOMutil.drawPoint(x + 1.5 * barWidth + offset + 2, y + fillHeight - bar2Height - 1, groupTemplate, framework.svgElements, framework.svg);
  }

}

/**
 * draw a bar graph
 *
 * @param groupIds
 * @param processedGroupData
 */
Bargraph.draw = function (groupIds, processedGroupData, framework) {
  var combinedData = [];
  var intersections = {};
  var coreDistance;
  var key, drawData;
  var group;
  var i,j;
  var barPoints = 0;

  // combine all barchart data
  for (i = 0; i < groupIds.length; i++) {
    group = framework.groups[groupIds[i]];
    if (group.options.style === 'bar') {
      if (group.visible === true && (framework.options.groups.visibility[groupIds[i]] === undefined || framework.options.groups.visibility[groupIds[i]] === true)) {
        for (j = 0; j < processedGroupData[groupIds[i]].length; j++) {
          combinedData.push({
            screen_x: processedGroupData[groupIds[i]][j].screen_x,
            screen_y: processedGroupData[groupIds[i]][j].screen_y,
            groupId: groupIds[i],
            label: processedGroupData[groupIds[i]][j].label
          });
          barPoints += 1;
        }
      }
    }
  }

  if (barPoints === 0) {return;}

  // sort by time and by group
  combinedData.sort(function (a, b) {
    if (a.screen_x === b.screen_x) {
      return a.groupId < b.groupId ? -1 : 1;
    }
    else {
      return a.screen_x - b.screen_x;
    }
  });

  // get intersections
  Bargraph._getDataIntersections(intersections, combinedData);

  // plot barchart
  for (i = 0; i < combinedData.length; i++) {
    group = framework.groups[combinedData[i].groupId];
    var minWidth = 0.1 * group.options.barChart.width;

    key = combinedData[i].screen_x;
    var heightOffset = 0;
    if (intersections[key] === undefined) {
      if (i+1 < combinedData.length) {coreDistance = Math.abs(combinedData[i+1].screen_x - key);}
      if (i > 0)                     {coreDistance = Math.min(coreDistance,Math.abs(combinedData[i-1].screen_x - key));}
      drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
    }
    else {
      var nextKey = i + (intersections[key].amount - intersections[key].resolved);
      var prevKey = i - (intersections[key].resolved + 1);
      if (nextKey < combinedData.length) {coreDistance = Math.abs(combinedData[nextKey].screen_x - key);}
      if (prevKey > 0)                   {coreDistance = Math.min(coreDistance,Math.abs(combinedData[prevKey].screen_x - key));}
      drawData = Bargraph._getSafeDrawData(coreDistance, group, minWidth);
      intersections[key].resolved += 1;

      if (group.options.stack === true) {
        if (combinedData[i].screen_y < group.zeroPosition) {
          heightOffset = intersections[key].accumulatedNegative;
          intersections[key].accumulatedNegative += group.zeroPosition - combinedData[i].screen_y;
        }
        else {
          heightOffset = intersections[key].accumulatedPositive;
          intersections[key].accumulatedPositive += group.zeroPosition - combinedData[i].screen_y;
        }
      }
      else if (group.options.barChart.sideBySide === true) {
        drawData.width = drawData.width / intersections[key].amount;
        drawData.offset += (intersections[key].resolved) * drawData.width - (0.5*drawData.width * (intersections[key].amount+1));
        if (group.options.barChart.align === 'left')       {drawData.offset -= 0.5*drawData.width;}
        else if (group.options.barChart.align === 'right') {drawData.offset += 0.5*drawData.width;}
      }
    }
    DOMutil.drawBar(combinedData[i].screen_x + drawData.offset, combinedData[i].screen_y - heightOffset, drawData.width, group.zeroPosition - combinedData[i].screen_y, group.className + ' vis-bar', framework.svgElements, framework.svg, group.style);
    // draw points
    if (group.options.drawPoints.enabled === true) {
      let pointData = {
        screen_x:combinedData[i].screen_x,
        screen_y:combinedData[i].screen_y - heightOffset,
        groupId: combinedData[i].groupId,
        label: combinedData[i].label
      };
      Points.draw([pointData], group, framework, drawData.offset);
      //DOMutil.drawPoint(combinedData[i].x + drawData.offset, combinedData[i].y, group, framework.svgElements, framework.svg);
    }
  }
};

/**
 * Fill the intersections object with counters of how many datapoints share the same x coordinates
 * @param intersections
 * @param combinedData
 * @private
 */
Bargraph._getDataIntersections = function (intersections, combinedData) {
  // get intersections
  var coreDistance;
  for (var i = 0; i < combinedData.length; i++) {
    if (i + 1 < combinedData.length) {
      coreDistance = Math.abs(combinedData[i + 1].screen_x - combinedData[i].screen_x);
    }
    if (i > 0) {
      coreDistance = Math.min(coreDistance, Math.abs(combinedData[i - 1].screen_x - combinedData[i].screen_x));
    }
    if (coreDistance === 0) {
      if (intersections[combinedData[i].screen_x] === undefined) {
        intersections[combinedData[i].screen_x] = {amount: 0, resolved: 0, accumulatedPositive: 0, accumulatedNegative: 0};
      }
      intersections[combinedData[i].screen_x].amount += 1;
    }
  }
};

/**
 * Get the width and offset for bargraphs based on the coredistance between datapoints
 *
 * @param coreDistance
 * @param group
 * @param minWidth
 * @returns {{width: Number, offset: Number}}
 * @private
 */
Bargraph._getSafeDrawData = function (coreDistance, group, minWidth) {
  var width, offset;
  if (coreDistance < group.options.barChart.width && coreDistance > 0) {
    width = coreDistance < minWidth ? minWidth : coreDistance;

    offset = 0; // recalculate offset with the new width;
    if (group.options.barChart.align === 'left') {
      offset -= 0.5 * coreDistance;
    }
    else if (group.options.barChart.align === 'right') {
      offset += 0.5 * coreDistance;
    }
  }
  else {
    // default settings
    width = group.options.barChart.width;
    offset = 0;
    if (group.options.barChart.align === 'left') {
      offset -= 0.5 * group.options.barChart.width;
    }
    else if (group.options.barChart.align === 'right') {
      offset += 0.5 * group.options.barChart.width;
    }
  }

  return {width: width, offset: offset};
};

Bargraph.getStackedYRange = function(combinedData, groupRanges, groupIds, groupLabel, orientation) {
  if (combinedData.length > 0) {
    // sort by time and by group
    combinedData.sort(function (a, b) {
      if (a.screen_x === b.screen_x) {
        return a.groupId < b.groupId ? -1 : 1;
      }
      else {
        return a.screen_x - b.screen_x;
      }
    });
    var intersections = {};

    Bargraph._getDataIntersections(intersections, combinedData);
    groupRanges[groupLabel] = Bargraph._getStackedYRange(intersections, combinedData);
    groupRanges[groupLabel].yAxisOrientation = orientation;
    groupIds.push(groupLabel);
  }
}

Bargraph._getStackedYRange = function (intersections, combinedData) {
  var key;
  var yMin = combinedData[0].screen_y;
  var yMax = combinedData[0].screen_y;
  for (var i = 0; i < combinedData.length; i++) {
    key = combinedData[i].screen_x;
    if (intersections[key] === undefined) {
      yMin = yMin > combinedData[i].screen_y ? combinedData[i].screen_y : yMin;
      yMax = yMax < combinedData[i].screen_y ? combinedData[i].screen_y : yMax;
    }
    else {
      if (combinedData[i].screen_y < 0) {
        intersections[key].accumulatedNegative += combinedData[i].screen_y;
      }
      else {
        intersections[key].accumulatedPositive += combinedData[i].screen_y;
      }
    }
  }
  for (var xpos in intersections) {
    if (intersections.hasOwnProperty(xpos)) {
      yMin = yMin > intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMin;
      yMin = yMin > intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMin;
      yMax = yMax < intersections[xpos].accumulatedNegative ? intersections[xpos].accumulatedNegative : yMax;
      yMax = yMax < intersections[xpos].accumulatedPositive ? intersections[xpos].accumulatedPositive : yMax;
    }
  }

  return {min: yMin, max: yMax};
};

module.exports = Bargraph;<|endoftext|>