<commit_before>/**
 * Set up imports that are required at this level for the application
 */
const restify = require('restify');
const fs = require("fs");
const os = require('os');
const path = require('path')

/**
 * Set up imports from local files
 */
const log = require("./utils/logger.js");

// Set the app name and some other helpful variables
const appname = "RepApi";
const tempdir = os.tmpdir();
const pluginpath = "./plugins/";

// This variable will contain settings and api keys that are not public
log.info("Loading settings from config.json...");
const settings = require("./config.json");

log.info("Creating Restify Server...");
const server = restify.createServer({
    name: 'api.repkam09.com',
    version: '1.1.0'
});

server.use(restify.fullResponse());
server.use(restify.CORS());
server.use(restify.bodyParser({
    mapParams: true,
    mapFiles: true,
    overrideParams: false,
    keepExtensions: false,
    uploadDir: tempdir,
    multiples: true,
    hash: 'md5'
}));

var plugins = [];

// Go out and check the plugins list for endpoints to listen on
fs.readdir(pluginpath, (err, files) => {
    files.forEach(file => {
        fs.stat(pluginpath + "/" + file, (err, stats) => {
            if (!stats.isDirectory()) {
                let type = path.extname(file);
                if (type === ".js") {
                    // Load the plugin and check if it is enabled
                    const plugin = require(pluginpath + "/" + file);

                    // Check that this is a valid plugin.
                    // A Plugin must have a name, an enabled value, and a 'start' function
                    if (plugin.hasOwnProperty('name') && plugin.hasOwnProperty('enabled') && plugin.hasOwnProperty('start')) {
                        if (plugin.enabled) {
                            // If this plugin is enabled, start it!
                            log.info("Starting up " + plugin.name + " plugin");
                            plugin.start(server);
                        } else {
                            log.debug("Skipping " + plugin.name + " plugin because it is disabled");
                        }
                    } else {
                        // Found a potential plugin, but it is malformed or missing a property
                        log.info("Skipping file " + file + " because it is missing plugin properties");
                    }
                }
            }
        });
    });
});

// Startup the server
log.info("Starting Restify Server...");
server.listen(16001, () => {
    log.info(server.name + ' listening at ' + server.url);
});<commit_msg>Minor cleanup of not used code<commit_after>/**
 * Set up imports that are required at this level for the application
 */
const restify = require('restify');
const fs = require("fs");
const os = require('os');
const path = require('path')

/**
 * Set up imports from local files
 */
const log = require("./utils/logger.js");

// Set the app name and some other helpful variables
const appname = "RepApi";
const tempdir = os.tmpdir();
const pluginpath = "./plugins/";

// This variable will contain settings and api keys that are not public
log.info("Loading settings from config.json...");
const settings = require("./config.json");

log.info("Creating Restify Server...");
const server = restify.createServer({
    name: 'api.repkam09.com',
    version: '1.1.0'
});

server.use(restify.fullResponse());
server.use(restify.CORS());
server.use(restify.bodyParser({
    mapParams: true,
    mapFiles: true,
    overrideParams: false,
    keepExtensions: false,
    uploadDir: tempdir,
    multiples: true,
    hash: 'md5'
}));

// Go out and check the plugins list for endpoints to listen on
fs.readdir(pluginpath, (err, files) => {
    files.forEach(file => {
        fs.stat(pluginpath + "/" + file, (err, stats) => {
            if (!stats.isDirectory()) {
                let type = path.extname(file);
                if (type === ".js") {
                    // Load the plugin and check if it is enabled
                    const plugin = require(pluginpath + "/" + file);

                    // Check that this is a valid plugin.
                    // A Plugin must have a name, an enabled value, and a 'start' function
                    if (plugin.hasOwnProperty('name') && plugin.hasOwnProperty('enabled') && plugin.hasOwnProperty('start')) {
                        if (plugin.enabled) {
                            // If this plugin is enabled, start it!
                            log.info("Starting up " + plugin.name + " plugin");

                            // Call the plugins start method to attach the various get/post/etc
                            plugin.start(server);
                        } else {
                            log.debug("Skipping " + plugin.name + " plugin because it is disabled");
                        }
                    } else {
                        // Found a potential plugin, but it is malformed or missing a property
                        log.info("Skipping file " + file + " because it is missing plugin properties");
                    }
                }
            }
        });
    });
});

// Startup the server
log.info("Starting Restify Server...");
server.listen(16001, () => {
    log.info(server.name + ' listening at ' + server.url);
});<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var pkg = require('../package');
var each = angular.forEach;
var utils = require('../lib/utils');
var $safeApply = utils.$safeApply;
var merge = utils.merge;
var isCrossDomain = require('url').isCrossDomain;

/**
 * HyperController
 */

pkg.controller('HyperController', [
  '$scope',
  '$routeParams',
  'hyperBackend',
  'hyperLinkFormatter',
  function HyperController($scope, $routeParams, hyper, hyperLinkFormatter) {
    // keep track of current the subscriptions
    var subscriptions = {};

    $scope.$watch(function() {
      return $routeParams;
    }, function(newVal, oldVal) {

      // clean up the old parameters/values
      each(oldVal, function(value, key) {
        // the param hasn't changed since last time
        if ($routeParams[key] == value) return;

        // unsubscribe from the old url and clean up the scope
        if (subscriptions[key]) subscriptions[key]();
        delete $scope[key];
        delete subscriptions[key];
      });

      // add the new params
      each($routeParams, function(value, key) {
        // ignore slugs
        if (key === 'slug') return;

        // try decoding the parameter
        var href = hyperLinkFormatter.decode(value);

        // it didn't look like a valid url
        if (!href) return;

        // if it doesn't look like a url don't do anything with it
        if (href.indexOf('http') !== 0 && href.indexOf('/') !== 0) return;

        // don't allow CORS attacks
        // TODO give an error message
        if (isCrossDomain(href)) return;

        // subscribe to the href
        subscriptions[key] = hyper
          .get(href, function(err, body) {
            // TODO handle error with angular
            if (err) return console.error(err.stack || err);

            $safeApply.call($scope, function() {
              $scope[key] = merge($scope[key], body);
            });
          });
      });
    }, true);

    $scope.$on('$destroy', function() {
      each(subscriptions, function(off) {
        off();
      });
    });
  }
]);
<commit_msg>ignore cors for now<commit_after>/**
 * Module dependencies
 */

var pkg = require('../package');
var each = angular.forEach;
var utils = require('../lib/utils');
var $safeApply = utils.$safeApply;
var merge = utils.merge;
var isCrossDomain = require('url').isCrossDomain;

/**
 * HyperController
 */

pkg.controller('HyperController', [
  '$scope',
  '$routeParams',
  'hyperBackend',
  'hyperLinkFormatter',
  function HyperController($scope, $routeParams, hyper, hyperLinkFormatter) {
    // keep track of current the subscriptions
    var subscriptions = {};

    $scope.$watch(function() {
      return $routeParams;
    }, function(newVal, oldVal) {

      // clean up the old parameters/values
      each(oldVal, function(value, key) {
        // the param hasn't changed since last time
        if ($routeParams[key] == value) return;

        // unsubscribe from the old url and clean up the scope
        if (subscriptions[key]) subscriptions[key]();
        delete $scope[key];
        delete subscriptions[key];
      });

      // add the new params
      each($routeParams, function(value, key) {
        // ignore slugs
        if (key === 'slug') return;

        // try decoding the parameter
        var href = hyperLinkFormatter.decode(value);

        // it didn't look like a valid url
        if (!href) return;

        // if it doesn't look like a url don't do anything with it
        if (href.indexOf('http') !== 0 && href.indexOf('/') !== 0) return;

        // don't allow CORS attacks
        // TODO give an error message
        // if (isCrossDomain(href)) return;

        // subscribe to the href
        subscriptions[key] = hyper
          .get(href, function(err, body) {
            // TODO handle error with angular
            if (err) return console.error(err.stack || err);

            $safeApply.call($scope, function() {
              $scope[key] = merge($scope[key], body);
            });
          });
      });
    }, true);

    $scope.$on('$destroy', function() {
      each(subscriptions, function(off) {
        off();
      });
    });
  }
]);
<|endoftext|>


<commit_before>var path = require('path'),
    fs = require('fs');

exports.postImage = function(req, res){

    var fstream;
    req.pipe(req.busboy);
    req.busboy.on('file', function(fieldname, file, filename) {
        console.log('chillern med '+filename);
        fstream = fs.createWriteStream(__dirname+'/../uploads/'+filename);
        file.pipe(fstream);
        fstream.on('close', function() {
            res.json({path:'hva med nei.png'});
        });
    });
}

exports.getImages = function(req, res){
    res.sendfile(path.resolve('uploads/'));
}
<commit_msg>Added notes, and fixed image path<commit_after>var path = require('path'),
    fs = require('fs');

exports.postImage = function(req, res){

    var fstream;
    req.pipe(req.busboy);
    req.busboy.on('file', function(fieldname, file, filename) {
        fstream = fs.createWriteStream(path.resolve('./uploads/'+filename));
        file.pipe(fstream);
        fstream.on('close', function() {
            // TODO: return file url.
            res.json({path:'hva med nei.png'});
        });
    });
};

exports.getImages = function(req, res){
    // TODO: List all urls available
    res.sendfile(path.resolve('uploads/'));
};

// TODO:
// exports.getImage = function(req, res){};
<|endoftext|>


<commit_before>'use strict';

/**
 * Dependencies
 */
const extend = require('extend');

const gcal = require('../lib/google-calendar');
const render = require('../lib/render');
const geocode = require('../lib/geocode');
const CalendarEvent = require('../models/calendar-event');

/**
 * Expose index controller that shows the list of events
 */

module.exports = function * () {
  let events = yield gcal.events();
  events = yield events.map(addCoordinates);
  events = events.map(event => new CalendarEvent(event));

  const currentEvents = events.filter((event) => event.isCurrent);
  const futureEvents = events.filter((event) => !event.isCurrent);
  this.body = yield render('index', {events, currentEvents, futureEvents});
};

/**
 * Add longitude and latitude to the event
 */

function addCoordinates (event) {
  if (!event.location) {
    console.log('Event missing location', event);
  }

  return geocode(event.location || event.summary)
  .then(data => {
    let latitude = data.length > 0 ? data[0].latitude : '';
    let longitude = data.length > 0 ? data[0].longitude : '';
    return extend(event, {latitude, longitude});
  });
}
<commit_msg>refactor<commit_after>'use strict';

/**
 * Dependencies
 */
const extend = require('extend');

const gcal = require('../lib/google-calendar');
const render = require('../lib/render');
const geocode = require('../lib/geocode');
const CalendarEvent = require('../models/calendar-event');

/**
 * Expose index controller that shows the list of events
 */

module.exports = function * () {
  let events = yield gcal.events();
  events = yield events.map(addCoordinates);
  events = events.map(event => new CalendarEvent(event));

  this.body = yield render('index', {
    events,
    currentEvents: events.filter((event) => event.isCurrent),
    futureEvents: events.filter((event) => !event.isCurrent)
  });
};

/**
 * Add longitude and latitude to the event
 */

function addCoordinates (event) {
  if (!event.location) {
    console.log('Event missing location', event);
  }

  return geocode(event.location || event.summary)
  .then(data => {
    let latitude = data.length > 0 ? data[0].latitude : '';
    let longitude = data.length > 0 ? data[0].longitude : '';
    return extend(event, {latitude, longitude});
  });
}
<|endoftext|>


<commit_before>const async = require('async');
const Order_info_item_scrape = require('../models/Order_info_item_scrape.js');
const Message = require('../models/Message.js');
const passport = require('passport');
var PythonShell = require('python-shell');
var mongoose = require('mongoose');
var fs = require('fs');
const User = require('../models/User');
mongoose.Promise = require('bluebird');

var message_data = []

var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
  process.env.GOOGLE_ID,
  process.env.GOOGLE_SECRET,
  process.env.GOOGLE_URIS
);

var gmail = google.gmail({
  version: 'v1',
  auth: oauth2Client
});

//sub function to get message from gmail api
//**********//**********//**********//**********
function getMessage(i, email ,thread_id, callback) {
   gmail.users.messages.get({
     auth: oauth2Client,
     userId: email,
     id: thread_id.id,
     format: 'raw'
   },
     function(err, response2) {
       if (err) {
         console.log('The API returned an error: ' + err);
         return;
       }

       //for some reason i needed to create an _id to save to mongoose...:(
       var mongoose = require('mongoose');
       var ObjectId =  mongoose.Types.ObjectId;
       var x = new ObjectId();

       var date = new Date().getTime()
       const email_thread = new Message(
         {
           _id: x,
           email: email,
           date_extracted: date,
           thread_id: thread_id.id,
           encoded_message: response2['raw']
        }
       );
       email_thread.save();
       console.log('saved thread')
    })
    console.log('counter is ' + i)
 }

function getThreads(email, callback) {
  var retailers = ['contact@em.nordstrom.com']
  var key_words = '{subject:order subject:reciept subject:confirmation subject:purchase}'
  var lookback = 'before:2017/09/10'
  query = 'in: anywhere,' + retailers +','+ key_words +','+ lookback

  gmail.users.threads.list({
    auth: oauth2Client,
    userId: email,
    q: query
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }

    var threads = response['threads']
    console.log(threads.length)
    if(length in threads){
        console.log("yes, i have that property");

      if (threads.length == 0) {
        console.log('no threads found that match critera');
      } else {
        for (var i = 0; i < threads.length; i++) {
          var thread = threads[i];
          console.log(email)
          getMessage(i , email, thread)
        }
        if (i==threads.length){
          //callback(null);
        }
      }
    }
  });
}

//**********//**********//**********//**********
//**********//**********//**********//**********

exports.getOrder = (req, res) => {

console.log(process.cwd())
  if(req.user && req.user.initial_scrape_state == 'need_initial'){
    async.waterfall([

      function(callback) {
        //checking to see if the user has an initial status of need to scrape
          console.log(req.user.tokens[0].accessToken)
          if (req.user.tokens[0].accessToken) {
              //setting oauth2Client credentials if user has a token set up
              oauth2Client.setCredentials({
              access_token: req.user.tokens[0].accessToken,
              refresh_token: req.user.refresh_token[0].refreshToken
            });

            var retailers = ['contact@em.nordstrom.com']
            var key_words = '{subject:order subject:in process}'
            var lookback = ' newer_than:60d, before:2017/10/14'
            query = 'in: anywhere,' + retailers +','+ key_words + ',' + lookback

            gmail.users.threads.list({
              auth: oauth2Client,
              userId: req.user.email,
              q: query
            }, function(err, response) {
              if (err) {
                console.log('The API returned an error: ' + err);
                return;
              }

              var threads = response['threads']
              //dis don't work 10-20-2017
              try {
                if (threads.length == 0) {
                  console.log('no threads found that match critera');
                } else {
                  var j = 0
                  for (var i = 0; i < threads.length; i++) {
                    var thread = threads[i];
                    console.log(req.user.email)

                    //getMessage(i , req.user.email, thread)
                    gmail.users.messages.get({
                      auth: oauth2Client,
                      userId: req.user.email,
                      id: thread.id,
                      format: 'raw'
                    },
                      function(err, response2) {
                        if (err) {
                          console.log('The API returned an error: ' + err);
                          return;
                        }
                        var mongoose = require('mongoose');
                        var ObjectId =  mongoose.Types.ObjectId;
                        var x = new ObjectId();

                        var date = new Date().getTime()
                        const email_thread = new Message(
                          {
                            _id: x,
                            email: req.user.email,
                            date_extracted: date,
                            thread_id: thread.id,
                            encoded_message: response2['raw'],
                            status: 'need to scrape'
                         }
                        );
                        email_thread.save();
                        j++;
                        console.log('saved thread')
                        console.log(j)
                        if (j==threads.length){
                          callback(null, 'next1');
                        }
                     })
                  }
                }
              }catch(e){
                if(e){
                  callback(null, 'next1');
                }
              }
            });

            //*/
          }

        //else{
        //  callback(null, 'next1');
        //}

      },

      function(arg1, callback) {
        //in this subfunction i want to call the python scraper :D

          var PythonShell = require('python-shell');
          var path = process.cwd()+'/public/test_scripts/'
          var pyshell = new PythonShell('test.py', {scriptPath:path, pythonOptions: ['-u']});
          pyshell.on('message', function (message) {
            // received a message sent from the Python script (a simple "print" statement)
            console.log(message);
          });
          // end the input stream and allow the process to exit
          pyshell.end(function (err) {
            if (err) throw err;
            console.log('finished first python scrape');
            console.log(arg1)
            callback(null, 'next3');
          });

      },

      function(arg1, callback) {
        //in this subfunction i want to call the python scraper :D

          var PythonShell = require('python-shell');
          var path = process.cwd()+'/public/test_scripts/'
          var pyshell = new PythonShell('test_scrape_nordstrom.py',{scriptPath: path, pythonOptions: ['-u']});

          pyshell.on('message', function (message) {
            // received a message sent from the Python script (a simple "print" statement)
            console.log(message);

          });

          // end the input stream and allow the process to exit

          pyshell.end(function (err) {
            if (err) throw err;
            console.log('finished second python scrape');
            console.log(arg1)
            callback(null, 'next3');
          });

      },

      function(arg1, callback) {

            User.update(
              {'email': req.user.email }
              ,{$set:{'initial_scrape_state':'complete'}}
              , function(err, result) {
                    if (err) {console.log(err);}
                    else {console.log('saved')}
                }
            )
        console.log('task2')
        callback(null, 'next2');
      },
    ], function (err, arg1) {
      console.log(arg1)

      try {
        Order_info_item_scrape.find({ email: req.user.email }, (err, docs) => {
            res.render('orders', {orders: docs});
        });
      }catch(e){
        if(e){
          res.render('orders', {orders: docs});
        }
      }
  });
  }
  else{

     try {
        Order_info_item_scrape.find({ email: req.user.email }, (err, docs) => {
            res.render('orders', {orders: docs});
        });
      }catch(e){
        if(e){
          res.render('orders', {orders: docs});
        }
      }
  }

};
<commit_msg>trying to fix threads.length issue<commit_after>const async = require('async');
const Order_info_item_scrape = require('../models/Order_info_item_scrape.js');
const Message = require('../models/Message.js');
const passport = require('passport');
var PythonShell = require('python-shell');
var mongoose = require('mongoose');
var fs = require('fs');
const User = require('../models/User');
mongoose.Promise = require('bluebird');

var message_data = []

var google = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
  process.env.GOOGLE_ID,
  process.env.GOOGLE_SECRET,
  process.env.GOOGLE_URIS
);

var gmail = google.gmail({
  version: 'v1',
  auth: oauth2Client
});

//sub function to get message from gmail api
//**********//**********//**********//**********
function getMessage(i, email ,thread_id, callback) {
   gmail.users.messages.get({
     auth: oauth2Client,
     userId: email,
     id: thread_id.id,
     format: 'raw'
   },
     function(err, response2) {
       if (err) {
         console.log('The API returned an error: ' + err);
         return;
       }

       //for some reason i needed to create an _id to save to mongoose...:(
       var mongoose = require('mongoose');
       var ObjectId =  mongoose.Types.ObjectId;
       var x = new ObjectId();

       var date = new Date().getTime()
       const email_thread = new Message(
         {
           _id: x,
           email: email,
           date_extracted: date,
           thread_id: thread_id.id,
           encoded_message: response2['raw']
        }
       );
       email_thread.save();
       console.log('saved thread')
    })
    console.log('counter is ' + i)
 }

function getThreads(email, callback) {
  var retailers = ['contact@em.nordstrom.com']
  var key_words = '{subject:order subject:reciept subject:confirmation subject:purchase}'
  var lookback = 'before:2017/09/10'
  query = 'in: anywhere,' + retailers +','+ key_words +','+ lookback

  gmail.users.threads.list({
    auth: oauth2Client,
    userId: email,
    q: query
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }

    var threads = response['threads']
    console.log(threads.length)
    if(length in threads){
        console.log("yes, i have that property");

      if (threads.length == 0) {
        console.log('no threads found that match critera');
      } else {
        for (var i = 0; i < threads.length; i++) {
          var thread = threads[i];
          console.log(email)
          getMessage(i , email, thread)
        }
        if (i==threads.length){
          //callback(null);
        }
      }
    }
  });
}

//**********//**********//**********//**********
//**********//**********//**********//**********

exports.getOrder = (req, res) => {

console.log(process.cwd())
  if(req.user && req.user.initial_scrape_state == 'need_initial'){
    async.waterfall([

      function(callback) {
        //checking to see if the user has an initial status of need to scrape
          console.log(req.user.tokens[0].accessToken)
          if (req.user.tokens[0].accessToken) {
              //setting oauth2Client credentials if user has a token set up
              oauth2Client.setCredentials({
              access_token: req.user.tokens[0].accessToken,
              refresh_token: req.user.refresh_token[0].refreshToken
            });

            var retailers = ['contact@em.nordstrom.com']
            var key_words = '{subject:order subject:in process}'
            var lookback = ' newer_than:60d, before:2017/10/14'
            query = 'in: anywhere,' + retailers +','+ key_words + ',' + lookback

            gmail.users.threads.list({
              auth: oauth2Client,
              userId: req.user.email,
              q: query
            }, function(err, response) {
              if (err) {
                console.log('The API returned an error: ' + err);
                return;
              }

              var threads = response['threads']
              //dis don't work 10-20-2017
              try {
                if (threads.length == 0) {
                  console.log('no threads found that match critera');
                } else {
                  var j = 0
                  for (var i = 0; i < threads.length; i++) {
                    var thread = threads[i];
                    console.log(req.user.email)

                    //getMessage(i , req.user.email, thread)
                    gmail.users.messages.get({
                      auth: oauth2Client,
                      userId: req.user.email,
                      id: thread.id,
                      format: 'raw'
                    },
                      function(err, response2) {
                        if (err) {
                          console.log('The API returned an error: ' + err);
                          return;
                        }
                        var mongoose = require('mongoose');
                        var ObjectId =  mongoose.Types.ObjectId;
                        var x = new ObjectId();

                        var date = new Date().getTime()
                        const email_thread = new Message(
                          {
                            _id: x,
                            email: req.user.email,
                            date_extracted: date,
                            thread_id: thread.id,
                            encoded_message: response2['raw'],
                            status: 'need to scrape'
                         }
                        );
                        email_thread.save();
                        j++;
                        console.log('saved thread')
                        console.log(j)
                        if (j==threads.length){
                          callback(null, 'next1');
                        }
                     })
                  }
                }
              }catch(e){
                if(e){
                  callback(null, 'next1');
                }
              }
            });

            //*/
          }

        //else{
        //  callback(null, 'next1');
        //}

      },

      function(arg1, callback) {
        //in this subfunction i want to call the python scraper :D

          var PythonShell = require('python-shell');
          var path = process.cwd()+'/public/test_scripts/'
          var pyshell = new PythonShell('test.py', {scriptPath:path, pythonOptions: ['-u']});
          pyshell.on('message', function (message) {
            // received a message sent from the Python script (a simple "print" statement)
            console.log(message);
          });
          // end the input stream and allow the process to exit
          pyshell.end(function (err) {
            if (err) throw err;
            console.log('finished first python scrape');
            console.log(arg1)
            callback(null, 'next3');
          });

      },

      function(arg1, callback) {
        //in this subfunction i want to call the python scraper :D

          var PythonShell = require('python-shell');
          var path = process.cwd()+'/public/test_scripts/'
          var pyshell = new PythonShell('test_scrape_nordstrom.py',{scriptPath: path, pythonOptions: ['-u']});

          pyshell.on('message', function (message) {
            // received a message sent from the Python script (a simple "print" statement)
            console.log(message);

          });

          // end the input stream and allow the process to exit

          pyshell.end(function (err) {
            if (err) throw err;
            console.log('finished second python scrape');
            console.log(arg1)
            callback(null, 'next3');
          });

      },

      function(arg1, callback) {

            User.update(
              {'email': req.user.email }
              ,{$set:{'initial_scrape_state':'complete'}}
              , function(err, result) {
                    if (err) {console.log(err);}
                    else {console.log('saved')}
                }
            )
        console.log('task2')
        callback(null, 'next2');
      },
    ], function (err, arg1) {
      console.log(arg1)

      try {
        Order_info_item_scrape.find({ email: req.user.email }, (err, docs) => {
            res.render('orders', {orders: docs});
        });
      }catch(e){
        if(e){
          res.render('orders');
        }
      }
  });
  }
  else{

     try {
        Order_info_item_scrape.find({ email: req.user.email }, (err, docs) => {
            res.render('orders', {orders: docs});
        });
      }catch(e){
        if(e){
          res.render('orders');
        }
      }
  }

};
<|endoftext|>


<commit_before>var rolesModel = require('../data/models/roles');
var async = require('async');

function findAll (req, res, next) {
    rolesModel.findOne({ name: 'admin' }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.find({})
            .populate('parentId')
            .exec(function (err, roles) {
                if (err) {
                    return next(err);
                }
                res.send(roles);
            });
        });
    });
}

function findById (req, res, next) {
    rolesModel.findOne({ name: 'admin' }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findById(req.params.id)
            .populate('parentId')
            .exec(function (err, role) {
                if (err) {
                    return next(err);
                }
                res.send(role);
            });
        });
    });
}

function add (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function (err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function () {
            rolesModel.findOne({ _id: req.body.parentId }, function (err, parent) {
                if (err) {
                    return next(err);
                }
                var newRole = new rolesModel({
                    name: req.body.name,
                    parentId: parent._id
                });
                newRole.save(function (err, role) {
                    if (err) {
                        return next(err);
                    }
                    res.send(role);
                });
            });
        });
    });
}

function update (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function (err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function () {
            rolesModel.findOne({ _id: req.body.parentId }, function (err, parent) {
                if (err) {
                    return next(err);
                }
                if (parent) {
                    /*rolesModel.update({_id: req.params.id}, req.body, function (err, rawResponse) {
                        if (err) {
                            next(err);
                        }
                        res.send(rawResponse);
                    });*/
                    var newRole = new rolesModel({
                        name: req.body.name,
                        parentId: parent._id
                    });
                    newRole.save({ _id: req.params.id }, function (err, role) {
                        if (err) {
                            return next(err);
                        }
                        res.send(role);
                    });
                }
                else {
                    res.status(404).send();
                }
            });
        });
    });

}

function del (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({_id: req.params.id }, function(err, role) {
                if (err) {
                    return next(err);
                }
                role.remove(function(err, result) {
                    res.send(result);
                });
            });
        });
    });
}

function findDescendants (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({ _id: req.params.id }, function (err, role) {
                if (err) {
                    return next(err);
                }
                role.descendants(function (err, roles) {
                    var roleIds = [];
                    roles.forEach(function (role) {
                        roleIds.push(role._id);
                    });
                    rolesModel.find({ _id: { $in: roleIds } })
                    .populate('parentId')
                    .exec(function (err, roles) {
                        if (err) {
                            return next(err);
                        }
                        console.log(roles);
                        res.send(roles);
                    });
                });
            });
        });
    });
}

function findSelfAndDecendants (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({ _id: req.params.id }, function (err, role) {
                if (err) {
                    return next(err);
                }
                role.selfAndDescendants(function (err, roles) {
                    var roleIds = [];
                    roles.forEach(function (role) {
                        roleIds.push(role._id);
                    });
                    rolesModel.find({ _id: { $in: roleIds } })
                    .populate('parentId')
                    .exec(function (err, roles) {
                        if (err) {
                            return next(err);
                        }
                        console.log(roles);
                        res.send(roles);
                    });
                });
            });
        });
    });
}

module.exports = {
    findAll: findAll,
    findById: findById,
    add: add,
    update: update,
    delete: del,
    findDescendants: findDescendants,
    findSelfAndDecendants: findSelfAndDecendants
}

//***************************test code***********************************************
/*async.forEach(roles, function (role, cb) {
    rolesModel.populate(
        role,
        { path: 'parentId' }
    );
    console.log(role);
});*/

/*roles.forEach(function (role) {
    role
    .populate({
        path: 'parentId'
    });
    console.log(role);
})*/<commit_msg>roles update ctrl edited<commit_after>var rolesModel = require('../data/models/roles');
var async = require('async');

function findAll (req, res, next) {
    rolesModel.findOne({ name: 'admin' }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.find({})
            .populate('parentId')
            .exec(function (err, roles) {
                if (err) {
                    return next(err);
                }
                res.send(roles);
            });
        });
    });
}

function findById (req, res, next) {
    rolesModel.findOne({ name: 'admin' }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findById(req.params.id)
            .populate('parentId')
            .exec(function (err, role) {
                if (err) {
                    return next(err);
                }
                res.send(role);
            });
        });
    });
}

function add (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function (err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function () {
            rolesModel.findOne({ _id: req.body.parentId }, function (err, parent) {
                if (err) {
                    return next(err);
                }
                var newRole = new rolesModel({
                    name: req.body.name,
                    parentId: parent._id
                });
                newRole.save(function (err, role) {
                    if (err) {
                        return next(err);
                    }
                    res.send(role);
                });
            });
        });
    });
}

function update (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function (err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function () {
            rolesModel.findOne({ _id: req.body.parentId }, function (err, parent) {
                if (err) {
                    return next(err);
                }
                if (parent) {
                    var newRole = new rolesModel({
                        name: req.body.name,
                        parentId: parent._id
                    });
                    newRole.save({ _id: req.params.id }, function (err, role) {
                        if (err) {
                            return next(err);
                        }
                        res.send(role);
                    });
                }
                else {
                    res.status(404).send();
                }
            });
        });
    });

}

function del (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({_id: req.params.id }, function(err, role) {
                if (err) {
                    return next(err);
                }
                role.remove(function(err, result) {
                    res.send(result);
                });
            });
        });
    });
}

function findDescendants (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({ _id: req.params.id }, function (err, role) {
                if (err) {
                    return next(err);
                }
                role.descendants(function (err, roles) {
                    var roleIds = [];
                    roles.forEach(function (role) {
                        roleIds.push(role._id);
                    });
                    rolesModel.find({ _id: { $in: roleIds } })
                    .populate('parentId')
                    .exec(function (err, roles) {
                        if (err) {
                            return next(err);
                        }
                        console.log(roles);
                        res.send(roles);
                    });
                });
            });
        });
    });
}

function findSelfAndDecendants (req, res, next) {
    rolesModel.findOne({ lft: 1 }, function(err, root) {
        if (err) {
            return next(err);
        }
        rolesModel.rebuildTree(root, root.lft, function() {
            rolesModel.findOne({ _id: req.params.id }, function (err, role) {
                if (err) {
                    return next(err);
                }
                role.selfAndDescendants(function (err, roles) {
                    var roleIds = [];
                    roles.forEach(function (role) {
                        roleIds.push(role._id);
                    });
                    rolesModel.find({ _id: { $in: roleIds } })
                    .populate('parentId')
                    .exec(function (err, roles) {
                        if (err) {
                            return next(err);
                        }
                        console.log(roles);
                        res.send(roles);
                    });
                });
            });
        });
    });
}

module.exports = {
    findAll: findAll,
    findById: findById,
    add: add,
    update: update,
    delete: del,
    findDescendants: findDescendants,
    findSelfAndDecendants: findSelfAndDecendants
}

//***************************test code***********************************************
/*async.forEach(roles, function (role, cb) {
    rolesModel.populate(
        role,
        { path: 'parentId' }
    );
    console.log(role);
});*/

/*roles.forEach(function (role) {
    role
    .populate({
        path: 'parentId'
    });
    console.log(role);
})*/<|endoftext|>


<commit_before>#!/usr/bin/env node

try {
  // eslint-disable-next-line import/no-unassigned-import
  require('../dist/now.js');
} catch (err) {
  if (err.code === 'ENOENT' && err.syscall === 'uv_cwd') {
    console.error(`Current path doesn't exist!`);
    process.exit(1);
  }
}
<commit_msg>Made `npm run link` work (#1715)<commit_after>#!/usr/bin/env node

try {
  // eslint-disable-next-line import/no-unassigned-import
  require('../dist');
} catch (err) {
  if (err.code === 'ENOENT' && err.syscall === 'uv_cwd') {
    console.error(`Current path doesn't exist!`);
    process.exit(1);
  }
}
<|endoftext|>


<commit_before>var UserForm = require('../forms/user')
  , Tag  = require('../models/tag').Tag
  , User = require('../models/user').User
  , middleware = require('../utils/middleware');

var blockSigninUser = middleware.blockSigninUser
  , loadUser        = middleware.loadUser;

module.exports = function (app) {
  app.get('/', loadUser, function (req, res) {
    res.render('users/home', {
        title: 'Mufano'
      , user: req.user
    });
  });

  app.get('/signup', blockSigninUser, function (req, res) {
    res.render('users/signup', {
        title: 'ユーザ登録'
      , user: null
    });
  });

  app.post('/users/create', UserForm.signup, function (req, res) {
    if (req.form.isValid) {
      User.signup(req.form, function (errs, user) {
        if (errs) {
          res.send({ errors: errs }, 403);
        } else {
          req.session.user_id = user._id;
          res.send();
        }
      });
    } else {
      res.send({ errors: req.form.errors }, 403);
    }
  });

  app.get('/explore', loadUser, function (req, res) {
    Tag.find({}).desc('posts_count').run(function (err, tags) {
      res.render('users/explore', {
          title: 'Explore'
        , user: req.user
        , tags: tags
      });
    });
  });
};
<commit_msg>タイトルの修正<commit_after>var UserForm = require('../forms/user')
  , Tag  = require('../models/tag').Tag
  , User = require('../models/user').User
  , middleware = require('../utils/middleware');

var blockSigninUser = middleware.blockSigninUser
  , loadUser        = middleware.loadUser;

module.exports = function (app) {
  app.get('/', loadUser, function (req, res) {
    res.render('users/home', {
        title: 'Anoside'
      , user: req.user
    });
  });

  app.get('/signup', blockSigninUser, function (req, res) {
    res.render('users/signup', {
        title: 'ユーザ登録'
      , user: null
    });
  });

  app.post('/users/create', UserForm.signup, function (req, res) {
    if (req.form.isValid) {
      User.signup(req.form, function (errs, user) {
        if (errs) {
          res.send({ errors: errs }, 403);
        } else {
          req.session.user_id = user._id;
          res.send();
        }
      });
    } else {
      res.send({ errors: req.form.errors }, 403);
    }
  });

  app.get('/explore', loadUser, function (req, res) {
    Tag.find({}).desc('posts_count').run(function (err, tags) {
      res.render('users/explore', {
          title: 'Explore'
        , user: req.user
        , tags: tags
      });
    });
  });
};
<|endoftext|>


<commit_before>const assert = require('assert');
const contests = require('../contests');
const langInfos = require('../data/infos.json');
const languages = require('../data/languages');
const Language = require('../models/Language');

module.exports.getLanguageMap = async ({team = null, contest} = {}) => {
	const languageRecords = await Language.find({contest})
		.populate({
			path: 'solution',
			populate: {path: 'user'},
		})
		.exec();

	if (!languages[contest.id]) {
		return [];
	}

	const languageCells = languages[contest.id].map((language) => {
		if (language && language.type === 'language') {
			return Object.assign({}, language, {
				record: languageRecords.find(
					(languageRecord) => languageRecord.slug === language.slug,
				),
			});
		}

		return Object.assign({}, language);
	});

	return languageCells.map((cell, index) => {
		if (cell.type === 'language') {
			const solvedTeam =
				cell.record &&
				cell.record.solution &&
				cell.record.solution.user.getTeam(contest);
			const langInfo = langInfos.find(({slug}) => slug === cell.slug);
			const codeLimit = getCodeLimit(cell.slug);

			if (contest.isEnded()) {
				if (cell.record && cell.record.solution) {
					return {
						type: 'language',
						solved: true,
						team: solvedTeam,
						solution: {
							_id: cell.record.solution._id,
							size: cell.record.solution.size,
							user: cell.record.solution.user.name(),
						},
						slug: cell.slug,
						name: cell.name,
						link: cell.link,
						info: langInfo,
						limit: codeLimit,
						available: false,
					};
				}

				return {
					type: 'language',
					solved: false,
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available: false,
				};
			}

			assert({}.hasOwnProperty.call(contests, contest.id));
			const {getPrecedingIndices} = contests[contest.id];

			const precedingCells = getPrecedingIndices(index).filter((i) => languageCells[i].type !== undefined).map(
				(i) => languageCells[i],
			);

			const available =
				typeof team === 'number' &&
				(
					contest.id === 'hackathon2018' ||
					cell.team === team ||
					solvedTeam === team ||
					precedingCells.some(
						(c) => (
							c.team === team ||
							(
								c.record &&
								c.record.solution &&
								c.record.solution.user.getTeam(contest)
							) === team
						),
					)
				);

			if (cell.record && cell.record.solution) {
				return {
					type: 'language',
					solved: true,
					team: solvedTeam,
					solution: {
						_id: cell.record.solution._id,
						size: cell.record.solution.size,
						user: cell.record.solution.user.name(),
					},
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available,
				};
			}

			if (
				precedingCells.some(
					(c) => c.type === 'base' ||
						(c.type === 'language' && c.record && c.record.solution),
				)
			) {
				return {
					type: 'language',
					solved: false,
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available,
				};
			}

			return {
				type: 'unknown',
			};
		} else if (cell.type === 'base') {
			return {
				type: 'base',
				team: cell.team,
			};
		}

		return {
			type: 'unknown',
		};
	});
};

const getCodeLimit = (languageId) => {
	if (languageId === 'fernando') {
		return 1024 * 1024;
	}

	if (
		[
			'unlambda',
			'blc',
			'function2d',
			'brainfuck-bfi',
			'brainfuck-esotope',
			'taxi',
			'function2d',
		].includes(languageId)
	) {
		return 100 * 1024;
	}

	return 10 * 1024;
};

module.exports.getCodeLimit = getCodeLimit;

module.exports.getTimeLimit = (languageId) => {
	if (
		[
			'kotlin',
			'husk',
		].includes(languageId)
	) {
		return 30 * 1000;
	}

	return 10 * 1000;
};
<commit_msg>Change code limit of pure-folders to 1MB<commit_after>const assert = require('assert');
const contests = require('../contests');
const langInfos = require('../data/infos.json');
const languages = require('../data/languages');
const Language = require('../models/Language');

module.exports.getLanguageMap = async ({team = null, contest} = {}) => {
	const languageRecords = await Language.find({contest})
		.populate({
			path: 'solution',
			populate: {path: 'user'},
		})
		.exec();

	if (!languages[contest.id]) {
		return [];
	}

	const languageCells = languages[contest.id].map((language) => {
		if (language && language.type === 'language') {
			return Object.assign({}, language, {
				record: languageRecords.find(
					(languageRecord) => languageRecord.slug === language.slug,
				),
			});
		}

		return Object.assign({}, language);
	});

	return languageCells.map((cell, index) => {
		if (cell.type === 'language') {
			const solvedTeam =
				cell.record &&
				cell.record.solution &&
				cell.record.solution.user.getTeam(contest);
			const langInfo = langInfos.find(({slug}) => slug === cell.slug);
			const codeLimit = getCodeLimit(cell.slug);

			if (contest.isEnded()) {
				if (cell.record && cell.record.solution) {
					return {
						type: 'language',
						solved: true,
						team: solvedTeam,
						solution: {
							_id: cell.record.solution._id,
							size: cell.record.solution.size,
							user: cell.record.solution.user.name(),
						},
						slug: cell.slug,
						name: cell.name,
						link: cell.link,
						info: langInfo,
						limit: codeLimit,
						available: false,
					};
				}

				return {
					type: 'language',
					solved: false,
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available: false,
				};
			}

			assert({}.hasOwnProperty.call(contests, contest.id));
			const {getPrecedingIndices} = contests[contest.id];

			const precedingCells = getPrecedingIndices(index).filter((i) => languageCells[i].type !== undefined).map(
				(i) => languageCells[i],
			);

			const available =
				typeof team === 'number' &&
				(
					contest.id === 'hackathon2018' ||
					cell.team === team ||
					solvedTeam === team ||
					precedingCells.some(
						(c) => (
							c.team === team ||
							(
								c.record &&
								c.record.solution &&
								c.record.solution.user.getTeam(contest)
							) === team
						),
					)
				);

			if (cell.record && cell.record.solution) {
				return {
					type: 'language',
					solved: true,
					team: solvedTeam,
					solution: {
						_id: cell.record.solution._id,
						size: cell.record.solution.size,
						user: cell.record.solution.user.name(),
					},
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available,
				};
			}

			if (
				precedingCells.some(
					(c) => c.type === 'base' ||
						(c.type === 'language' && c.record && c.record.solution),
				)
			) {
				return {
					type: 'language',
					solved: false,
					slug: cell.slug,
					name: cell.name,
					link: cell.link,
					info: langInfo,
					limit: codeLimit,
					available,
				};
			}

			return {
				type: 'unknown',
			};
		} else if (cell.type === 'base') {
			return {
				type: 'base',
				team: cell.team,
			};
		}

		return {
			type: 'unknown',
		};
	});
};

const getCodeLimit = (languageId) => {
	if (
		[
			'fernando',
			'pure-folders',
		].includes(languageId)
	) {
		return 1024 * 1024;
	}

	if (
		[
			'unlambda',
			'blc',
			'function2d',
			'brainfuck-bfi',
			'brainfuck-esotope',
			'taxi',
			'function2d',
		].includes(languageId)
	) {
		return 100 * 1024;
	}

	return 10 * 1024;
};

module.exports.getCodeLimit = getCodeLimit;

module.exports.getTimeLimit = (languageId) => {
	if (
		[
			'kotlin',
			'husk',
		].includes(languageId)
	) {
		return 30 * 1000;
	}

	return 10 * 1000;
};
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Vote = require('../models/Vote');
var votesController = exports;

// generic vote controller
exports.voteFor = function (type, root) {

  return function (req, res, next) {

    var item_id;

    req.assert('amount', 'Items can only be upvoted.').equals('1');
    req.assert('id', 'Invalid item id.').notEmpty();

    var errors = req.validationErrors();

    if (errors) {
      req.flash('errors', errors);
      return res.redirect(req.get('referrer') || root);
    }

    if (!req.user) {
      req.flash('errors', { msg: 'Only members can upvote items.' });
      return res.redirect('/signup');
    }

    try {
      item_id = new mongoose.Types.ObjectId(req.params.id);
    } catch(e) {
      item_id = req.params.id.toString();
    }

    var vote = new Vote({
      item: item_id,
      voter: req.user.id,
      amount: req.body.amount,
      itemType: type
    });

    vote.save(function (err) {
      if (err) {
        if (err.code === 11000) {
          req.flash('errors', { msg: 'You can only upvote an item once.' });
        }
        console.log(err);
        return res.redirect(req.get('referrer') || root);
      }

      req.flash('success', { msg: 'Item upvoted. Awesome!' });
      res.redirect(req.get('referrer') || root);
    });
  };

};

// generic vote retrieval
/**
 * Query the Votes collection to find votes for item(s)
 * @param  {String}           type     Type of item. Should be `news`, `comment`, or `issue`
 * @param  {String | Array}   id       Either a string or an array of strings (or object id's) defining the item(s) to be queried about
 * @param  {Function}         callback Evaluated with an error as the first parameter and the votes found as the second
 */
exports.retrieveVotesFor = function (type, id, callback) {

  if(arguments.length === 1) {
    return function (id, callback) {
      return votesController.retrieveVotesFor(type, id, callback);
    };
  }

  // special case of allowing a null type for news
  if(type === 'news') {
    type = { $in: ['news', null] };
  }

  // pass an array of ids to find votes for all of them
  if(Array.isArray(id)) {
    id = { $in: id };
  }

  Vote
  .find({
    item: id,
    itemType: type
  })
  .exec(callback);
};

// add a `votes` count and `votedFor` property for a particular item, vote array, and user
exports.addVotesToItem = function (item, item_id, user, votes) {

  item = typeof item.toObject === 'function' ? item.toObject() : item;
  item_id = item_id.toString();

  item.votes = votes
    .filter(function (vote) {
      return vote.item.toString() === item_id;
    })
    .reduce(function (prev, curr, i) {

      // count this item as voted for if the logged in user has a vote tallied
      if(user && user.id && curr.voter.toString() === user.id.toString()) {
        item.votedFor = true;
      }

      return prev + curr.amount;
    }, 0);

  return item;
};

// all-in-one query
/**
 * Add a `votes` property to an Array of Objects based on their type, `id` property, and the current user
 * @param {String}            type       Type of item. Should be `news`, `comment`, or `issue`
 * @param {String}            idProperty Property of the object that defines it's id. For mongoose docs, this is `_id`
 * @param {Array | Object}    items      Array of objects (or a single object) that votes should be added to. This converts mongoose objects into plain objects.
 * @param {User}              user       A user object with an `id` property
 * @param {Function}          callback   Function to be evaluated with an error as the first parameter, and the modified objects as the second
 */
exports.addVotesFor = function (type, idProperty, items, user, callback) {

  var isArray;

  if(arguments.length === 2) {
    return function (items, user, callback) {
      return votesController.addVotesFor(type, idProperty, items, user, callback);
    };
  }

  wasArray = Array.isArray(items);

  // make a non-array argument behave as an array for now to simplify our dealing with it
  if(!wasArray) items = [items];

  votesController.retrieveVotesFor(type, items.map(function (item) {
    return item[idProperty];
  }), function (err, votes) {

    if(err) return callback(err);

    // add the votes to the objects themselves
    items = items.map(function (item) {
      return votesController.addVotesToItem(item, item[idProperty], user, votes);
    });

    // convert back if it wasn't passed in as an array
    if(!wasArray) items = items[0];

    callback(null, items);
  });
};
<commit_msg>stop decimals from being cast to objectid's<commit_after>var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Vote = require('../models/Vote');
var votesController = exports;

// generic vote controller
exports.voteFor = function (type, root) {

  return function (req, res, next) {

    req.assert('amount', 'Items can only be upvoted.').equals('1');
    req.assert('id', 'Invalid item id.').notEmpty();

    var errors = req.validationErrors();

    if (errors) {
      req.flash('errors', errors);
      return res.redirect(req.get('referrer') || root);
    }

    if (!req.user) {
      req.flash('errors', { msg: 'Only members can upvote items.' });
      return res.redirect('/signup');
    }

    var vote = new Vote({
      item: castToObjectIdOrString(req.params.id),
      voter: req.user.id,
      amount: req.body.amount,
      itemType: type
    });

    vote.save(function (err) {
      if (err) {
        if (err.code === 11000) {
          req.flash('errors', { msg: 'You can only upvote an item once.' });
        }
        console.log(err);
        return res.redirect(req.get('referrer') || root);
      }

      req.flash('success', { msg: 'Item upvoted. Awesome!' });
      res.redirect(req.get('referrer') || root);
    });
  };

};

function castToObjectIdOrString(id) {
  var item_id;

  if(isNumber(id)) {
    return id.toString();
  }

  try {
    item_id = new mongoose.Types.ObjectId(id);
  } catch(e) {
    item_id = id.toString();
  }

  return item_id;
}

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

// generic vote retrieval
/**
 * Query the Votes collection to find votes for item(s)
 * @param  {String}           type     Type of item. Should be `news`, `comment`, or `issue`
 * @param  {String | Array}   id       Either a string or an array of strings (or object id's) defining the item(s) to be queried about
 * @param  {Function}         callback Evaluated with an error as the first parameter and the votes found as the second
 */
exports.retrieveVotesFor = function (type, id, callback) {

  if(arguments.length === 1) {
    return function (id, callback) {
      return votesController.retrieveVotesFor(type, id, callback);
    };
  }

  // special case of allowing a null type for news
  if(type === 'news') {
    type = { $in: ['news', null] };
  }

  // pass an array of ids to find votes for all of them
  if(Array.isArray(id)) {
    id = { $in: id };
  }

  Vote
  .find({
    item: id,
    itemType: type
  })
  .exec(callback);
};

// add a `votes` count and `votedFor` property for a particular item, vote array, and user
exports.addVotesToItem = function (item, item_id, user, votes) {

  item = typeof item.toObject === 'function' ? item.toObject() : item;
  item_id = item_id.toString();

  item.votes = votes
    .filter(function (vote) {
      return vote.item.toString() === item_id;
    })
    .reduce(function (prev, curr, i) {

      // count this item as voted for if the logged in user has a vote tallied
      if(user && user.id && curr.voter.toString() === user.id.toString()) {
        item.votedFor = true;
      }

      return prev + curr.amount;
    }, 0);

  return item;
};

// all-in-one query
/**
 * Add a `votes` property to an Array of Objects based on their type, `id` property, and the current user
 * @param {String}            type       Type of item. Should be `news`, `comment`, or `issue`
 * @param {String}            idProperty Property of the object that defines it's id. For mongoose docs, this is `_id`
 * @param {Array | Object}    items      Array of objects (or a single object) that votes should be added to. This converts mongoose objects into plain objects.
 * @param {User}              user       A user object with an `id` property
 * @param {Function}          callback   Function to be evaluated with an error as the first parameter, and the modified objects as the second
 */
exports.addVotesFor = function (type, idProperty, items, user, callback) {

  var isArray;

  if(arguments.length === 2) {
    return function (items, user, callback) {
      return votesController.addVotesFor(type, idProperty, items, user, callback);
    };
  }

  wasArray = Array.isArray(items);

  // make a non-array argument behave as an array for now to simplify our dealing with it
  if(!wasArray) items = [items];

  votesController.retrieveVotesFor(type, items.map(function (item) {
    return castToObjectIdOrString(item[idProperty]);
  }), function (err, votes) {

    if(err) return callback(err);

    // add the votes to the objects themselves
    items = items.map(function (item) {
      return votesController.addVotesToItem(item, item[idProperty], user, votes);
    });

    // convert back if it wasn't passed in as an array
    if(!wasArray) items = items[0];

    callback(null, items);
  });
};
<|endoftext|>


<commit_before>"use strict";

const fs = require('fs');
const shell = require('node-powershell');
const archiver = require('archiver');
const packagejson = require('../package.json');
const distzip = 'dist.zip';
const archive = archiver('zip', {
	zlib: {level: 0} // Sets the compression level.
});
const ignoreList = '--ignore=borderless\.js --ignore=CALGamma\.js --ignore=titlerenamer\.js --ignore=autoit-compiler\.js --ignore=daocstarter\.au3 --ignore=.*\.md$ --ignore=handle64\.exe --ignore=creative\.less --ignore=mixins\.less --ignore=variables\.less';
const packagercmd = 'electron-packager . daocstarter --platform win32 --arch x64 --out dist --icon=img\\i.ico --overwrite ' + ignoreList;
const autoitcmd = '& "C:\\Program Files (x86)\\AutoIt3\\Aut2Exe\\Aut2exe.exe" /in "C:\\electron\\daocstarter\\daocstarter.au3" /icon img\\i.ico /comp 4'
const daocstarterau3 = "daocstarter.au3";
const exe = "daocstarter.exe"
const buffer = new Buffer (
	'#RequireAdmin\r\n' +
	'#NoTrayIcon\r\n' +
	'#include <Misc.au3>\r\n' +
	'#include <array.au3>\r\n' +
	'_Singleton(@ScriptName)\r\n' +
	'Global Const $VERSION = "' + packagejson.version + '"\r\n' +
	'Global Const $DIST_ZIP_PATH = @AppDataDir & "\\daocstarter\\" & $VERSION; & "\\daocstarter-win32-x64"\r\n' +
	'Global Const $WORKINGDIR = $DIST_ZIP_PATH & "\\dist\\daocstarter-win32-x64"\r\n' +
	'Global Const $EXE = $WORKINGDIR & "\\daocstarter.exe"\r\n' +
	'Global Const $TMP_ZIP_PATH = @TempDir & "\\dist.zip"\r\n' +
	';~ DirRemove($DIST_ZIP_PATH, 1)\r\n' +
	'If Not FileExists($EXE) Then\r\n' +
	'\tFileInstall(".\\dist.zip", $TMP_ZIP_PATH, 1);1=overwrite\r\n' +
	'\t_Zip_UnzipAll($TMP_ZIP_PATH, $DIST_ZIP_PATH & "\\")\r\n' +
	'EndIf\r\n' +
	'ShellExecute($EXE, "", $WORKINGDIR)\r\n' +
	'Func _Zip_UnzipAll($hZipFile, $hDestPath)\r\n' +
	'\tIf Not FileExists($hDestPath) Then DirCreate($hDestPath)\r\n' +
	'\tLocal $aArray[1], $oApp = ObjCreate("Shell.Application")\r\n' +
	'\t$oApp.Namespace($hDestPath).CopyHere($oApp.Namespace($hZipFile).Items)\r\n' +
	'\tFor $item In $oApp.Namespace($hZipFile).Items\r\n' +
	'\t\t_ArrayAdd($aArray, $item)\r\n' +
	'\tNext\r\n' +
	'\tWhile 1\r\n' +
	'\t\tIf ControlGetHandle("[CLASS:#32770]", "", "[CLASS:SysAnimate32; INSTANCE:1]") <> "" And WinGetState("[CLASS:#32770]") <> @SW_HIDE Then WinSetState(WinGetHandle("[CLASS:#32770]"), "", @SW_HIDE)\r\n' +
	'\t\tIf FileExists($hDestPath & "\\" & $aArray[UBound($aArray) - 1]) Then Return SetError(0, 0, 1)\r\n' +
	'\t\tSleep(500)\r\n' +
	'\tWEnd\r\n' +
	'EndFunc\r\n'
);

try {
	fs.unlinkSync(daocstarterau3);
	console.log('successfully deleted ' + daocstarterau3);
} catch(error) {
	console.log(error + "...");
}
fs.open(daocstarterau3, 'w', (err, fd) => {
	if (err) {
		throw 'error opening file: ' + err;
	}
	fs.write(fd, buffer, 0, buffer.length, null, (err) => {
		if (err) {
			throw 'error writing file: ' + err;
		}
		fs.close(fd, () => {
			console.log('file written');
			try {
				fs.unlinkSync(distzip);
				console.log('successfully deleted ' + distzip);
				fs.unlinkSync(exe);
				console.log('successfully deleted ' + exe);
			} catch(error) {
				console.log(error + "...");
			}
			const ps = new shell({executionPolicy: 'Bypass', debugMsg:false, noProfile:true});
			ps.addCommand(packagercmd)
			.then(() => {
				ps.invoke();
			})
			.then((output) => {
				return ps.dispose();
			})
			.then(() => {
				console.log('successfully executed ' + packagercmd);
				const fileOutput = fs.createWriteStream(distzip);
				fileOutput.on('close', () => {
					console.log(archive.pointer() + ' total bytes; archiver has been finalized and the output file descriptor has closed.');
					const powershell = new shell({executionPolicy: 'Bypass', debugMsg:false, noProfile:true});
					powershell.addCommand(autoitcmd)
					.then(() => {
						powershell.invoke();
					})
					.then(output => {
						powershell.dispose();
						console.log("writing " + exe + "...");
					})
					.catch(err => {
						console.log(err);
						powershell.dispose();
					});
				});
				archive.pipe(fileOutput);
				archive.glob("dist/daocstarter-win32-x64/**");
				archive.on('error', err => {
					throw err;
				});
				archive.finalize();
			})
			.catch(err => {
				ps.dispose();
			});
		})
	});
});
<commit_msg>increased compression lvl ~8megabyte saved<commit_after>"use strict";

const fs = require('fs');
const shell = require('node-powershell');
const archiver = require('archiver');
const packagejson = require('../package.json');
const distzip = 'dist.zip';
const archive = archiver('zip', {zlib: {level: 9} /* Sets the compression level.0-9*/});
const ignoreList = '--ignore=borderless\.js --ignore=CALGamma\.js --ignore=titlerenamer\.js --ignore=autoit-compiler\.js --ignore=daocstarter\.au3 --ignore=.*\.md$ --ignore=handle64\.exe --ignore=creative\.less --ignore=mixins\.less --ignore=variables\.less';
const packagercmd = 'electron-packager . daocstarter --platform win32 --arch x64 --out dist --icon=img\\i.ico --overwrite ' + ignoreList;
const autoitcmd = '& "C:\\Program Files (x86)\\AutoIt3\\Aut2Exe\\Aut2exe.exe" /in "C:\\electron\\daocstarter\\daocstarter.au3" /icon img\\i.ico /comp 4'
const daocstarterau3 = "daocstarter.au3";
const exe = "daocstarter.exe"
const buffer = new Buffer (
	'#RequireAdmin\r\n' +
	'#NoTrayIcon\r\n' +
	'#include <Misc.au3>\r\n' +
	'#include <array.au3>\r\n' +
	'_Singleton(@ScriptName)\r\n' +
	'Global Const $VERSION = "' + packagejson.version + '"\r\n' +
	'Global Const $DIST_ZIP_PATH = @AppDataDir & "\\daocstarter\\" & $VERSION; & "\\daocstarter-win32-x64"\r\n' +
	'Global Const $WORKINGDIR = $DIST_ZIP_PATH & "\\dist\\daocstarter-win32-x64"\r\n' +
	'Global Const $EXE = $WORKINGDIR & "\\daocstarter.exe"\r\n' +
	'Global Const $TMP_ZIP_PATH = @TempDir & "\\dist.zip"\r\n' +
	';~ DirRemove($DIST_ZIP_PATH, 1)\r\n' +
	'If Not FileExists($EXE) Then\r\n' +
	'\tFileInstall(".\\dist.zip", $TMP_ZIP_PATH, 1);1=overwrite\r\n' +
	'\t_Zip_UnzipAll($TMP_ZIP_PATH, $DIST_ZIP_PATH & "\\")\r\n' +
	'EndIf\r\n' +
	'ShellExecute($EXE, "", $WORKINGDIR)\r\n' +
	'Func _Zip_UnzipAll($hZipFile, $hDestPath)\r\n' +
	'\tIf Not FileExists($hDestPath) Then DirCreate($hDestPath)\r\n' +
	'\tLocal $aArray[1], $oApp = ObjCreate("Shell.Application")\r\n' +
	'\t$oApp.Namespace($hDestPath).CopyHere($oApp.Namespace($hZipFile).Items)\r\n' +
	'\tFor $item In $oApp.Namespace($hZipFile).Items\r\n' +
	'\t\t_ArrayAdd($aArray, $item)\r\n' +
	'\tNext\r\n' +
	'\tWhile 1\r\n' +
	'\t\tIf ControlGetHandle("[CLASS:#32770]", "", "[CLASS:SysAnimate32; INSTANCE:1]") <> "" And WinGetState("[CLASS:#32770]") <> @SW_HIDE Then WinSetState(WinGetHandle("[CLASS:#32770]"), "", @SW_HIDE)\r\n' +
	'\t\tIf FileExists($hDestPath & "\\" & $aArray[UBound($aArray) - 1]) Then Return SetError(0, 0, 1)\r\n' +
	'\t\tSleep(500)\r\n' +
	'\tWEnd\r\n' +
	'EndFunc\r\n'
);

try {
	fs.unlinkSync(daocstarterau3);
	console.log('successfully deleted ' + daocstarterau3);
} catch(error) {
	console.log(error + "...");
}
fs.open(daocstarterau3, 'w', (err, fd) => {
	if (err) {
		throw 'error opening file: ' + err;
	}
	fs.write(fd, buffer, 0, buffer.length, null, (err) => {
		if (err) {
			throw 'error writing file: ' + err;
		}
		fs.close(fd, () => {
			console.log('file written');
			try {
				fs.unlinkSync(distzip);
				console.log('successfully deleted ' + distzip);
				fs.unlinkSync(exe);
				console.log('successfully deleted ' + exe);
			} catch(error) {
				console.log(error + "...");
			}
			const ps = new shell({executionPolicy: 'Bypass', debugMsg:false, noProfile:true});
			ps.addCommand(packagercmd)
			.then(() => {
				ps.invoke();
			})
			.then((output) => {
				return ps.dispose();
			})
			.then(() => {
				console.log('successfully executed ' + packagercmd);
				const fileOutput = fs.createWriteStream(distzip);
				fileOutput.on('close', () => {
					console.log(archive.pointer() + ' total bytes; archiver has been finalized and the output file descriptor has closed.');
					const powershell = new shell({executionPolicy: 'Bypass', debugMsg:false, noProfile:true});
					powershell.addCommand(autoitcmd)
					.then(() => {
						powershell.invoke();
					})
					.then(output => {
						powershell.dispose();
						console.log("writing " + exe + "...");
					})
					.catch(err => {
						console.log(err);
						powershell.dispose();
					});
				});
				archive.pipe(fileOutput);
				archive.glob("dist/daocstarter-win32-x64/**");
				archive.on('error', err => {
					throw err;
				});
				archive.finalize();
			})
			.catch(err => {
				ps.dispose();
			});
		})
	});
});
<|endoftext|>


<commit_before>/* global $, SaveToJson, schema, util, window */

function getFilename(rawFilename) {
  if (rawFilename instanceof Array) {
    const [filename] = rawFilename;
    return `${filename.substr(0, filename.lastIndexOf('.'))}.jpg`;
  }

  return rawFilename;
}

const album = {
  form: {
    schema: { // HTML element ID, XML node name
      Init: () => { // loop thru fields and get jQuery elements
        const ids = [];
        $.each(schema, (elementId) => {
          if (ids.length !== 0) {
            ids.push(',');
          }
          ids.push('#', elementId);
        });
        ids.push(); // remove trailing comma delimiter
        album.form.schema.dom = $(ids.join(''));
      },
      GetDom: () => {
        if (!album.form.schema.dom) {
          album.form.schema.Init();
        }

        return album.form.schema.dom;
      },
    },
    Clear: () => {
      album.form.schema.GetDom()
        .val('')
        .siblings('.suggestions')
        .html('')
        .siblings('input[type=checkbox]')
        .prop('checked', false)
        .siblings('input[type=text]')
        .prop('disabled', false)
        .siblings('label')
        .find('select')
        .prop('disabled', false); // reference <select>
      $('#filename').prop('checked', true); // keep filename disabled
    },
    PopulateFromPhoto: (_data) => {
      const data = $.extend({}, _data);
      const seen = {};
      data.filename = (data.filename instanceof Array) ? data.filename[0] : data.filename;

      function clickField($e) { // click on .suggestion

        const txt = $(this).text();
        const originDom = $(this).data('origin');
        if (originDom) {
          originDom.val(txt); // move clicked txt to input val
        }
        $(this).remove(); // remove suggestion
        $e.preventDefault();
      }

      function eachField() {
        // remove duplicates
        const txt = $(this).text();
        if (seen[txt]) {
          $(this).remove();
        } else {
          seen[txt] = true;
        }
      }

      const UpdateFieldOrDiv = ($field, mergeDatum) => {
        const noSuggestions = $field.siblings('.suggestions').length === 0 || $field.siblings('.suggestions').html().length === 0;
        const emptyOrSameVal = $field.val() === '' || $field.val() === mergeDatum;
        if ((noSuggestions && emptyOrSameVal) || $field.prop('disabled')) { // update form field based on thumb selection
          $field.val(mergeDatum.replace(/&/gi, '&')); // XML format to normal
        } else { // build suggestion
          const wasVal = $field.val();
          let suggestion1 = '';
          let suggestion2 = '';
          if (wasVal !== '') {
            suggestion1 = $('').text(wasVal).data('origin', $field);
          }

          if (mergeDatum !== '') {
            suggestion2 = $('').text(mergeDatum).data('origin', $field);
          }

          $field
            .val('')
            .siblings('.suggestions')
            .append(suggestion1, ' ', suggestion2)
            .find('a')
            .click(clickField)
            .each(eachField);
        }
      };

      $.each(schema, (elementId, xmlName) => { // loop thru all form fields to display XML data
        let fieldValue;
        if (xmlName.indexOf('.') === -1) {
          fieldValue = data[xmlName];
        } else { // dot syntax found
          const xmlNameArray = xmlName.split('.');
          if (data[xmlNameArray[0]]) {
            fieldValue = data[xmlNameArray[0]][xmlNameArray[1]];
          }
        }
        if (!fieldValue) {
          return true; // continue
        }
        UpdateFieldOrDiv($(`#${elementId}`), fieldValue);
        return true;
      });

      album.photo.Preview(data.filename);
    },
    SplitGeoOnPaste: function SplitGeoOnPaste() {
      if (this.value.indexOf(',') !== -1) {
        const geocode = this.value.split(',');
        $('#geo_lat').val(geocode[0].trim());
        $('#geo_lon').val(geocode[1].trim());
      }
    },
  },
  photo: {
    recentIndex: 0, // for selecting a photo range & keyboard nav
    GetData: () => {
      const divs = $('#listPhotos > div');
      if (divs.length > 0) {
        return divs.eq(album.photo.recentIndex).data('photo');
      }

      return false;
    },
    Invoke: function invokePhoto(e) { // click on photo
      if (e.ctrlKey) { // allow multiples
        album.photo.recentIndex = $(this).toggleClass('selected').index();
        album.form.PopulateFromPhoto($(this).data('photo'));
      } else if (e.shiftKey) { // select range
        const clickedPhotoIndex = $(this).index();
        let sm = (clickedPhotoIndex < album.photo.recentIndex) ? clickedPhotoIndex : album.photo.recentIndex;
        const lg = (clickedPhotoIndex < album.photo.recentIndex) ? album.photo.recentIndex : clickedPhotoIndex;
        const divs = $('#listPhotos > div');
        for (sm; sm <= lg; sm += 1) {
          album.form.PopulateFromPhoto(divs.eq(sm).addClass('selected').data('photo'));
        }
      } else { // only select one
        album.form.Clear();
        /* change .select class */
        album.photo.recentIndex = $(this).siblings().removeClass('selected').end()
          .addClass('selected')
          .index();
        album.form.PopulateFromPhoto($(this).data('photo'));
      }
    },
    Preview: (_filename) => {
      const filename = `${_filename.substr(0, _filename.lastIndexOf('.'))}.jpg`;
      const photoPath = [
        '../galleries/',
        $('#editGalleries').val(),
        '/media/photos/',
        filename.substr(0, filename.indexOf('-')),
        '/',
        filename,
      ].join('');
      const originalPath = [
        '../galleries/',
        $('#editGalleries').val(),
        '/media/originals/',
        filename.substr(0, filename.indexOf('-')),
        '/',
        filename,
      ].join('');
      $('#photoPreview')
        .attr('data-original', originalPath)
        .css({
          'background-image': `url(${photoPath})`,
          cursor: 'zoom-in',
        })
        .click((event) => window.open(event.target.getAttribute('data-original'), '_blank'))
    },
    Sort: function sortPhoto() {
      $('#listPhotos span').remove(); // clear previous sort labels
      const AlphaSort = (_x, _y, xmlNode) => {
        let x = $(_x).data('photo')[xmlNode];
        x = (x === null) ? '' : x;
        let y = $(_y).data('photo')[xmlNode];
        y = (y === null) ? '' : y;
        const xLarger = (x > y) ? 1 : -1;
        return (x === y) ? 0 : xLarger;
      };
      const SortByCity = (x, y) => AlphaSort(x, y, schema.city);
      const SortByLocation = (x, y) => AlphaSort(x, y, schema.location);
      const SortByDate = (x, y) => AlphaSort(x, y, schema.filename);
      const SortByXml = (_x, _y) => {
        const x = $(_x).data('photo').id;
        const y = $(_y).data('photo').id;
        return parseInt(x, 10) - parseInt(y, 10);
      };
      let sortBy; // alias for (above) sort function
      const sortVal = $(this).val().toLowerCase();

      switch (sortVal) {
        case 'city': sortBy = SortByCity; break;
        case 'location': sortBy = SortByLocation; break;
        case 'filename': sortBy = SortByDate; break;
        default: sortBy = SortByXml; break;
      }

      $.each($('#listPhotos > div').get().sort(sortBy), (i, newDiv) => { // reposition based on sort
        const xmlNode = schema[sortVal];
        const sortLabel = $(newDiv).data('photo')[xmlNode];
        if (sortLabel === undefined) {
          $('#listPhotos').append(newDiv);
        } else {
          $('#listPhotos').append(newDiv).append(`<span>${sortLabel}</span>`);
        }
      });
    },
  },
  json: {}, // current album data
  Generate: () => { // output album.xml
    const galleryName = $('#editGalleries').val();

    $('#listPhotos').html(''); // clear previous gallery
    $.each(album.json.album.item, (i, item) => {
      const filename = getFilename(item.filename);
      const year = filename.substr(0, filename.indexOf('-'));

      $('
')
        .click(album.photo.Invoke)
        .data('photo', item)
        .html([''].join(''))
        .appendTo('#listPhotos');
    });
  },
};
const ConvertXmlToJson = (xmlData) => {
  album.json = $.parseJSON(util.xml.convertToJsonString(xmlData, ''));
  $('#rawAlbumJson').val(JSON.stringify(album.json)); // display in textarea
  album.Generate();
};
const GetAlbumXml = () => { // both <select> and btn call this function
  let isAlbumChangable = ($('#listPhotos').html() === ''); // rule1 must be empty
  if (!isAlbumChangable) {
    // otherwise confirm before clearing
    isAlbumChangable = window.confirm('Change photo album?'); // eslint-disable-line no-alert
  }
  if (isAlbumChangable) {
    $.get(`../galleries/${$('#editGalleries').val()}/${$('#editAlbums').val()}.xml`)
      .success(ConvertXmlToJson);

    $('#sortGallery')[0].selectedIndex = 0; // reset sort dropdown
  }
};
const PopulateAlbums = (xmlData) => { // complete gallery xml
  const options = [];
  $('album', xmlData).each((i, gallery) => {
    options.push('<option>', $('album_name', gallery).text(), '</option>');
  });

  $('#editAlbums').append(options.join(''));
};
const GetGalleryNames = () => { // both <select> and btn call this function
  let isGalleryChangable = $('#listPhotos').html() === ''; // rule1 must be empty
  if (!isGalleryChangable) {
    // otherwise confirm before clearing
    isGalleryChangable = window.confirm('Change photo gallery?'); // eslint-disable-line no-alert
  }
  if (isGalleryChangable) {
    $.get(`../galleries/${$('#editGalleries').val()}/gallery.xml`)
      .success(PopulateAlbums);

    $('#editAlbums').get(0).length = 0; // clear albums dropdown
    $('#editAlbums').html('<option value="">Edit these album photos</option>');
    $('#sortGallery')[0].selectedIndex = 0; // reset sort dropdown
    $('#listPhotos').html(''); // clear previous gallery
  }
};

function ToggleDisable() {
  $(this)
    .parent()
    .find('input[type=text], select')
    .prop('disabled', $(this).prop('checked')); // disable text field if checkbox is checked
}

$(window).ready(() => {
  $('#changeGallery').click(GetGalleryNames);
  $('#changeAlbum').click(GetAlbumXml);
  $('#editAlbums').change(GetAlbumXml);
  $('#sortGallery').change(album.photo.Sort);
  $('#changeSort').click(album.photo.Sort);
  $('#saveToJson').click(SaveToJson);
  $('input[type=checkbox]').click(ToggleDisable);
  $('#geo_lat').change(album.form.SplitGeoOnPaste);

  album.form.schema.GetDom().add('textarea#rawAlbumJsonToXml').keydown(($e) => {
    $e.stopPropagation(); // allow text selction, not photo pagination
  });

  $(window.document).keydown(($e) => {
    let math;
    const arrow = {
      left: 37,
      up: 38,
      right: 39,
      down: 40,
    };
    if ($e.which === arrow.left) {
      math = -1;
    } else if ($e.which === arrow.up) {
      math = -4;
    } else if ($e.which === arrow.right) {
      math = +1;
    } else if ($e.which === arrow.down) {
      math = +4;
    }

    if (math !== undefined) {
      album.form.Clear();
      album.photo.recentIndex = $('#listPhotos div').eq(album.photo.recentIndex).removeClass('selected')
        .end()
        .eq(album.photo.recentIndex + math)
        .addClass('selected')
        .index(); // change selection

      if (album.photo.recentIndex !== -1) {
        album.form.PopulateFromPhoto(album.photo.GetData());
      }
    }
  });
});
<commit_msg>fix(API > Edit Album): Windows Control and Mac Command key support<commit_after>/* global $, SaveToJson, schema, util, window */

function getFilename(rawFilename) {
  if (rawFilename instanceof Array) {
    const [filename] = rawFilename;
    return `${filename.substr(0, filename.lastIndexOf('.'))}.jpg`;
  }

  return rawFilename;
}

const album = {
  form: {
    schema: { // HTML element ID, XML node name
      Init: () => { // loop thru fields and get jQuery elements
        const ids = [];
        $.each(schema, (elementId) => {
          if (ids.length !== 0) {
            ids.push(',');
          }
          ids.push('#', elementId);
        });
        ids.push(); // remove trailing comma delimiter
        album.form.schema.dom = $(ids.join(''));
      },
      GetDom: () => {
        if (!album.form.schema.dom) {
          album.form.schema.Init();
        }

        return album.form.schema.dom;
      },
    },
    Clear: () => {
      album.form.schema.GetDom()
        .val('')
        .siblings('.suggestions')
        .html('')
        .siblings('input[type=checkbox]')
        .prop('checked', false)
        .siblings('input[type=text]')
        .prop('disabled', false)
        .siblings('label')
        .find('select')
        .prop('disabled', false); // reference <select>
      $('#filename').prop('checked', true); // keep filename disabled
    },
    PopulateFromPhoto: (_data) => {
      const data = $.extend({}, _data);
      const seen = {};
      data.filename = (data.filename instanceof Array) ? data.filename[0] : data.filename;

      function clickField($e) { // click on .suggestion

        const txt = $(this).text();
        const originDom = $(this).data('origin');
        if (originDom) {
          originDom.val(txt); // move clicked txt to input val
        }
        $(this).remove(); // remove suggestion
        $e.preventDefault();
      }

      function eachField() {
        // remove duplicates
        const txt = $(this).text();
        if (seen[txt]) {
          $(this).remove();
        } else {
          seen[txt] = true;
        }
      }

      const UpdateFieldOrDiv = ($field, mergeDatum) => {
        const noSuggestions = $field.siblings('.suggestions').length === 0 || $field.siblings('.suggestions').html().length === 0;
        const emptyOrSameVal = $field.val() === '' || $field.val() === mergeDatum;
        if ((noSuggestions && emptyOrSameVal) || $field.prop('disabled')) { // update form field based on thumb selection
          $field.val(mergeDatum.replace(/&/gi, '&')); // XML format to normal
        } else { // build suggestion
          const wasVal = $field.val();
          let suggestion1 = '';
          let suggestion2 = '';
          if (wasVal !== '') {
            suggestion1 = $('').text(wasVal).data('origin', $field);
          }

          if (mergeDatum !== '') {
            suggestion2 = $('').text(mergeDatum).data('origin', $field);
          }

          $field
            .val('')
            .siblings('.suggestions')
            .append(suggestion1, ' ', suggestion2)
            .find('a')
            .click(clickField)
            .each(eachField);
        }
      };

      $.each(schema, (elementId, xmlName) => { // loop thru all form fields to display XML data
        let fieldValue;
        if (xmlName.indexOf('.') === -1) {
          fieldValue = data[xmlName];
        } else { // dot syntax found
          const xmlNameArray = xmlName.split('.');
          if (data[xmlNameArray[0]]) {
            fieldValue = data[xmlNameArray[0]][xmlNameArray[1]];
          }
        }
        if (!fieldValue) {
          return true; // continue
        }
        UpdateFieldOrDiv($(`#${elementId}`), fieldValue);
        return true;
      });

      album.photo.Preview(data.filename);
    },
    SplitGeoOnPaste: function SplitGeoOnPaste() {
      if (this.value.indexOf(',') !== -1) {
        const geocode = this.value.split(',');
        $('#geo_lat').val(geocode[0].trim());
        $('#geo_lon').val(geocode[1].trim());
      }
    },
  },
  photo: {
    recentIndex: 0, // for selecting a photo range & keyboard nav
    GetData: () => {
      const divs = $('#listPhotos > div');
      if (divs.length > 0) {
        return divs.eq(album.photo.recentIndex).data('photo');
      }

      return false;
    },
    Invoke: function invokePhoto(e) { // click on photo
      if (e.ctrlKey || e.metaKey) { // allow multiples
        album.photo.recentIndex = $(this).toggleClass('selected').index();
        album.form.PopulateFromPhoto($(this).data('photo'));
      } else if (e.shiftKey) { // select range
        const clickedPhotoIndex = $(this).index();
        let sm = (clickedPhotoIndex < album.photo.recentIndex) ? clickedPhotoIndex : album.photo.recentIndex;
        const lg = (clickedPhotoIndex < album.photo.recentIndex) ? album.photo.recentIndex : clickedPhotoIndex;
        const divs = $('#listPhotos > div');
        for (sm; sm <= lg; sm += 1) {
          album.form.PopulateFromPhoto(divs.eq(sm).addClass('selected').data('photo'));
        }
      } else { // only select one
        album.form.Clear();
        /* change .select class */
        album.photo.recentIndex = $(this).siblings().removeClass('selected').end()
          .addClass('selected')
          .index();
        album.form.PopulateFromPhoto($(this).data('photo'));
      }
    },
    Preview: (_filename) => {
      const filename = `${_filename.substr(0, _filename.lastIndexOf('.'))}.jpg`;
      const photoPath = [
        '../galleries/',
        $('#editGalleries').val(),
        '/media/photos/',
        filename.substr(0, filename.indexOf('-')),
        '/',
        filename,
      ].join('');
      const originalPath = [
        '../galleries/',
        $('#editGalleries').val(),
        '/media/originals/',
        filename.substr(0, filename.indexOf('-')),
        '/',
        filename,
      ].join('');
      $('#photoPreview')
        .attr('data-original', originalPath)
        .css({
          'background-image': `url(${photoPath})`,
          cursor: 'zoom-in',
        })
        .click((event) => window.open(event.target.getAttribute('data-original'), '_blank'))
    },
    Sort: function sortPhoto() {
      $('#listPhotos span').remove(); // clear previous sort labels
      const AlphaSort = (_x, _y, xmlNode) => {
        let x = $(_x).data('photo')[xmlNode];
        x = (x === null) ? '' : x;
        let y = $(_y).data('photo')[xmlNode];
        y = (y === null) ? '' : y;
        const xLarger = (x > y) ? 1 : -1;
        return (x === y) ? 0 : xLarger;
      };
      const SortByCity = (x, y) => AlphaSort(x, y, schema.city);
      const SortByLocation = (x, y) => AlphaSort(x, y, schema.location);
      const SortByDate = (x, y) => AlphaSort(x, y, schema.filename);
      const SortByXml = (_x, _y) => {
        const x = $(_x).data('photo').id;
        const y = $(_y).data('photo').id;
        return parseInt(x, 10) - parseInt(y, 10);
      };
      let sortBy; // alias for (above) sort function
      const sortVal = $(this).val().toLowerCase();

      switch (sortVal) {
        case 'city': sortBy = SortByCity; break;
        case 'location': sortBy = SortByLocation; break;
        case 'filename': sortBy = SortByDate; break;
        default: sortBy = SortByXml; break;
      }

      $.each($('#listPhotos > div').get().sort(sortBy), (i, newDiv) => { // reposition based on sort
        const xmlNode = schema[sortVal];
        const sortLabel = $(newDiv).data('photo')[xmlNode];
        if (sortLabel === undefined) {
          $('#listPhotos').append(newDiv);
        } else {
          $('#listPhotos').append(newDiv).append(`<span>${sortLabel}</span>`);
        }
      });
    },
  },
  json: {}, // current album data
  Generate: () => { // output album.xml
    const galleryName = $('#editGalleries').val();

    $('#listPhotos').html(''); // clear previous gallery
    $.each(album.json.album.item, (i, item) => {
      const filename = getFilename(item.filename);
      const year = filename.substr(0, filename.indexOf('-'));

      $('
')
        .click(album.photo.Invoke)
        .data('photo', item)
        .html([''].join(''))
        .appendTo('#listPhotos');
    });
  },
};
const ConvertXmlToJson = (xmlData) => {
  album.json = $.parseJSON(util.xml.convertToJsonString(xmlData, ''));
  $('#rawAlbumJson').val(JSON.stringify(album.json)); // display in textarea
  album.Generate();
};
const GetAlbumXml = () => { // both <select> and btn call this function
  let isAlbumChangable = ($('#listPhotos').html() === ''); // rule1 must be empty
  if (!isAlbumChangable) {
    // otherwise confirm before clearing
    isAlbumChangable = window.confirm('Change photo album?'); // eslint-disable-line no-alert
  }
  if (isAlbumChangable) {
    $.get(`../galleries/${$('#editGalleries').val()}/${$('#editAlbums').val()}.xml`)
      .success(ConvertXmlToJson);

    $('#sortGallery')[0].selectedIndex = 0; // reset sort dropdown
  }
};
const PopulateAlbums = (xmlData) => { // complete gallery xml
  const options = [];
  $('album', xmlData).each((i, gallery) => {
    options.push('<option>', $('album_name', gallery).text(), '</option>');
  });

  $('#editAlbums').append(options.join(''));
};
const GetGalleryNames = () => { // both <select> and btn call this function
  let isGalleryChangable = $('#listPhotos').html() === ''; // rule1 must be empty
  if (!isGalleryChangable) {
    // otherwise confirm before clearing
    isGalleryChangable = window.confirm('Change photo gallery?'); // eslint-disable-line no-alert
  }
  if (isGalleryChangable) {
    $.get(`../galleries/${$('#editGalleries').val()}/gallery.xml`)
      .success(PopulateAlbums);

    $('#editAlbums').get(0).length = 0; // clear albums dropdown
    $('#editAlbums').html('<option value="">Edit these album photos</option>');
    $('#sortGallery')[0].selectedIndex = 0; // reset sort dropdown
    $('#listPhotos').html(''); // clear previous gallery
  }
};

function ToggleDisable() {
  $(this)
    .parent()
    .find('input[type=text], select')
    .prop('disabled', $(this).prop('checked')); // disable text field if checkbox is checked
}

$(window).ready(() => {
  $('#changeGallery').click(GetGalleryNames);
  $('#changeAlbum').click(GetAlbumXml);
  $('#editAlbums').change(GetAlbumXml);
  $('#sortGallery').change(album.photo.Sort);
  $('#changeSort').click(album.photo.Sort);
  $('#saveToJson').click(SaveToJson);
  $('input[type=checkbox]').click(ToggleDisable);
  $('#geo_lat').change(album.form.SplitGeoOnPaste);

  album.form.schema.GetDom().add('textarea#rawAlbumJsonToXml').keydown(($e) => {
    $e.stopPropagation(); // allow text selction, not photo pagination
  });

  $(window.document).keydown(($e) => {
    let math;
    const arrow = {
      left: 37,
      up: 38,
      right: 39,
      down: 40,
    };
    if ($e.which === arrow.left) {
      math = -1;
    } else if ($e.which === arrow.up) {
      math = -4;
    } else if ($e.which === arrow.right) {
      math = +1;
    } else if ($e.which === arrow.down) {
      math = +4;
    }

    if (math !== undefined) {
      album.form.Clear();
      album.photo.recentIndex = $('#listPhotos div').eq(album.photo.recentIndex).removeClass('selected')
        .end()
        .eq(album.photo.recentIndex + math)
        .addClass('selected')
        .index(); // change selection

      if (album.photo.recentIndex !== -1) {
        album.form.PopulateFromPhoto(album.photo.GetData());
      }
    }
  });
});
<|endoftext|>


<commit_before>define([
  'extensions/collections/filteredcollection',
  'extensions/views/filter'
], function(Collection, Filter) {

  var collection = new Collection(
    $.map($('#services-list li'), function (li) {
      var $li = $(li);
      return {
        title: $li.text(),
        el: $li
      };
    })
  );

  var view = new Filter({
    el: $('#filter-wrapper'),
    listEl: $('#services-list dl'),
    countEl: $('#services-list .count'),
    label: 'Find a service named:',
    placeholder: 'Example: Licensing',
    collection: collection
  });
  view.render();
});
<commit_msg>Services controller returns a function<commit_after>define([
  'extensions/collections/filteredcollection',
  'extensions/views/filter'
], function(Collection, Filter) {
  return function() {
    var collection = new Collection(
      $.map($('#services-list li'), function (li) {
        var $li = $(li);
        return {
          title: $li.text(),
          el: $li
        };
      })
    );

    var view = new Filter({
      el: $('#filter-wrapper'),
      listEl: $('#services-list dl'),
      countEl: $('#services-list .count'),
      label: 'Find a service named:',
      placeholder: 'Example: Licensing',
      collection: collection
    });
    view.render();
  };
});
<|endoftext|>