<commit_before>"use strict";

let express = require('express'),
    passport = require('passport'),
    moment = require('moment'),
    queries = require('../server/queries'),
    xml = require('../server/xml'),
    router = express.Router();

router.get('/', function (req, res, next) {
  return res.render('pages/index', {
    username: req.user ? req.user.username : null
  });
});

router.get('/about', function (req, res, next) {
  return res.render('pages/about', {
    username: req.user ? req.user.username : null
  });
});

router.get('/404', function (req, res, next) {
  return res.render('pages/404', {
    username: req.user ? req.user.username : null
  });
});

router.get('/500', function (req, res, next) {
  return res.render('pages/500', {
    username: req.user ? req.user.username : null
  });
});

router.get('/faq', function (req, res, next) {
  return res.render('pages/faq', {
    username: req.user ? req.user.username : null
  });
});

router.get('/news', function (req, res, next) {
  return res.render('pages/news', {
    username: req.user ? req.user.username : null
  });
});

router.get('/contact', function (req, res, next) {
  return res.render('pages/contact', {
    username: req.user ? req.user.username : null
  });
});

router.get('/privacypolicy', function (req, res, next) {
  return res.render('pages/privacypolicy', {
    username: req.user ? req.user.username : null
  });
});

router.get('/tos', function (req, res, next) {
  return res.render('pages/tos', {
    username: req.user ? req.user.username : null
  });
});

router.get('/upload', isLoggedIn, function (req, res, next) {
  return res.render('pages/upload', {
    username: req.user ? req.user.username : null,
    title: res.locals.title,
    author: res.locals.author,
    genre: res.locals.genre,
    lines: res.locals.lines,
    poem_check: res.locals.poem_check
  });
});

router.get('/encodesubmission', isLoggedIn, function (req, res, next) {
  return res.render('pages/encodesubmission', {
    username: req.user ? req.user.username : null
  });
});

router.get('/compare/:poem_id/:type_1/:version_1/:type_2/:version_2', isLoggedIn, queries.getEncodingsForCompare, function (req, res, next) {
  return res.render('pages/compare', {
    username: req.user ? req.user.username : null,
    encodings: res.locals.encodings,
    poem_id: req.params.poem_id
  });
});

router.get('/poem/:id', isLoggedIn, queries.getPoem, queries.getEncodingsByPoem, function (req, res, next) {
  return res.render('pages/poem', {
    moment: moment,
    username: req.user ? req.user.username : null,
    poem: res.locals.poem,
    encodings: res.locals.encodings
  });
});

router.get('/poem/:poem_id/encoding/:encoded_id', isLoggedIn, queries.getEncoding, function (req, res, next) {
  return res.render('pages/userencoding', {
    moment: moment,
    username: req.user ? req.user.username : null,
    encoding: res.locals.poemcoding
  });
});

router.get('/search', isLoggedIn, queries.searchPoems, function (req, res, next) {
  let search = req.query.q || "",
      total = parseInt(res.locals.poems.total),
      page = parseInt(res.locals.poems.page),
      pageSize = parseInt(res.locals.poems.pageSize);
  let totalPages = Math.ceil(total/pageSize);
  let pageBottom = page - 3 > 0 ? page - 3 : 1,
      pageTop = page + 7 > totalPages ? totalPages : page + 7;
  return res.render('pages/search', {
    moment: moment,
    username: req.user ? req.user.username : null,
    poems: res.locals.poems.poems,
    total: total,
    page: page,
    pageSize: pageSize,
    pageTop: pageTop,
    pageBottom: pageBottom,
    search: search,
    encodedSearch: encodeURIComponent(search)
  });
});

router.get('/settings', isLoggedIn, function (req, res, next) {
  return res.render('pages/settings', {
    username: req.user ? req.user.username : null
  });
});

router.get('/encode/:id', isLoggedIn, queries.getPoem, function (req, res, next) {
  return res.render('pages/encode', {
    username: req.user ? req.user.username : null,
    poem: res.locals.poem
  });
});

router.get('/profile/:username', isLoggedIn, queries.profileInfo, queries.getPoemsByUser, queries.getEncodingsByUser, function (req, res, next) {
  return res.render('pages/profile', {
    moment: moment,
    username: req.user ? req.user.username : null,
    profile: res.locals.profileInfo,
    poems: res.locals.poems,
    encodings: res.locals.encodings
  });
});

router.get('/signup', isNotLoggedIn, function (req, res, next) {
  return res.render('pages/signup', {
    message: req.flash('signupMessage'),
    first_name: res.locals.first_name,
    last_name: res.locals.last_name,
    email: res.locals.email,
    username: res.locals.username
  });
});

router.get('/login', isNotLoggedIn, function (req, res, next) {
  return res.render('pages/login', {
    message: req.flash('loginMessage'),
    username: res.locals.username
  });
});

router.get('/logout', function (req, res, next) {
  req.logout();
  return res.redirect('/');
});

router.post('/login', function (req, res, next) {
  passport.authenticate('local-login', {failureFlash: true}, function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/profile/' + user.username);
    });
  })(req, res, next);
});

router.post('/signup', function (req, res, next) {
  passport.authenticate('local-signup', {failureFlash: true}, function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/signup'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/profile/' + user.username);
    });
  })(req, res, next);
});

router.post('/submit', queries.addPoem, function (req, res, next) {
  return res.redirect('/poem/' + res.locals.poem.id);
});

router.post('/submitencode', queries.addPoem, function (req, res, next) {
  return res.redirect('/encode/' + res.locals.poem.id);
});

router.post('/poem/:id/encode', queries.encodePoem, function (req, res, next) {
  return res.redirect('/poem/' + req.params.id);
});

router.post('/compare/:poem_id', function (req, res, next) {
  if(req.body.optRadio1 && req.body.optRadio2)
    return res.redirect('/compare/' + req.params.poem_id + "/" + req.body.optRadio1 + "/" + req.body.optRadio2);
  return res.redirect('/poem/' + req.params.poem_id);
});

router.post('/validate', function (req, res, next) {
  //let str = '<TEI xmlns="http://www.tei-c.org/ns/1.0"><yes p:id="yeah">ff<yes>fgfM</yes>gf</yes> /n <sysy>d
<FF text="p98">jd</FF><hhh></sysy>
</hhh>jdjd</TEI>'.replace(/\/n/g, "");
  xml.validate(req.body.original, req.body.encoded, function (status, message) {
    return res.json({status: status, message: message});
  });
  //https://www.npmjs.com/package/libxml-xsd
});

module.exports = router;

function isLoggedIn (req, res, next) {
  if (req.isAuthenticated())
    return next();
  res.redirect('/');
}

function isNotLoggedIn (req, res, next) {
  if (!req.isAuthenticated())
    return next();
  res.redirect('/');
}
<commit_msg>Fixed search again<commit_after>"use strict";

let express = require('express'),
    passport = require('passport'),
    moment = require('moment'),
    queries = require('../server/queries'),
    xml = require('../server/xml'),
    router = express.Router();

router.get('/', function (req, res, next) {
  return res.render('pages/index', {
    username: req.user ? req.user.username : null
  });
});

router.get('/about', function (req, res, next) {
  return res.render('pages/about', {
    username: req.user ? req.user.username : null
  });
});

router.get('/404', function (req, res, next) {
  return res.render('pages/404', {
    username: req.user ? req.user.username : null
  });
});

router.get('/500', function (req, res, next) {
  return res.render('pages/500', {
    username: req.user ? req.user.username : null
  });
});

router.get('/faq', function (req, res, next) {
  return res.render('pages/faq', {
    username: req.user ? req.user.username : null
  });
});

router.get('/news', function (req, res, next) {
  return res.render('pages/news', {
    username: req.user ? req.user.username : null
  });
});

router.get('/contact', function (req, res, next) {
  return res.render('pages/contact', {
    username: req.user ? req.user.username : null
  });
});

router.get('/privacypolicy', function (req, res, next) {
  return res.render('pages/privacypolicy', {
    username: req.user ? req.user.username : null
  });
});

router.get('/tos', function (req, res, next) {
  return res.render('pages/tos', {
    username: req.user ? req.user.username : null
  });
});

router.get('/upload', isLoggedIn, function (req, res, next) {
  return res.render('pages/upload', {
    username: req.user ? req.user.username : null,
    title: res.locals.title,
    author: res.locals.author,
    genre: res.locals.genre,
    lines: res.locals.lines,
    poem_check: res.locals.poem_check
  });
});

router.get('/encodesubmission', isLoggedIn, function (req, res, next) {
  return res.render('pages/encodesubmission', {
    username: req.user ? req.user.username : null
  });
});

router.get('/compare/:poem_id/:type_1/:version_1/:type_2/:version_2', isLoggedIn, queries.getEncodingsForCompare, function (req, res, next) {
  return res.render('pages/compare', {
    username: req.user ? req.user.username : null,
    encodings: res.locals.encodings,
    poem_id: req.params.poem_id
  });
});

router.get('/poem/:id', isLoggedIn, queries.getPoem, queries.getEncodingsByPoem, function (req, res, next) {
  return res.render('pages/poem', {
    moment: moment,
    username: req.user ? req.user.username : null,
    poem: res.locals.poem,
    encodings: res.locals.encodings
  });
});

router.get('/poem/:poem_id/encoding/:encoded_id', isLoggedIn, queries.getEncoding, function (req, res, next) {
  return res.render('pages/userencoding', {
    moment: moment,
    username: req.user ? req.user.username : null,
    encoding: res.locals.poemcoding
  });
});

router.get('/search', isLoggedIn, queries.searchPoems, function (req, res, next) {
  let search = req.query.q || "",
      total = parseInt(res.locals.poems.total),
      page = parseInt(res.locals.poems.page),
      pageSize = parseInt(res.locals.poems.pageSize);
  let totalPages = total > 0 ? Math.ceil(total/pageSize) : 1;
  let pageBottom = page - 3 > 0 ? page - 3 : 1,
      pageTop = page + 7 > totalPages ? totalPages : page + 7;
  return res.render('pages/search', {
    moment: moment,
    username: req.user ? req.user.username : null,
    poems: res.locals.poems.poems,
    total: total,
    page: page,
    pageSize: pageSize,
    pageTop: pageTop,
    pageBottom: pageBottom,
    search: search,
    encodedSearch: encodeURIComponent(search)
  });
});

router.get('/settings', isLoggedIn, function (req, res, next) {
  return res.render('pages/settings', {
    username: req.user ? req.user.username : null
  });
});

router.get('/encode/:id', isLoggedIn, queries.getPoem, function (req, res, next) {
  return res.render('pages/encode', {
    username: req.user ? req.user.username : null,
    poem: res.locals.poem
  });
});

router.get('/profile/:username', isLoggedIn, queries.profileInfo, queries.getPoemsByUser, queries.getEncodingsByUser, function (req, res, next) {
  return res.render('pages/profile', {
    moment: moment,
    username: req.user ? req.user.username : null,
    profile: res.locals.profileInfo,
    poems: res.locals.poems,
    encodings: res.locals.encodings
  });
});

router.get('/signup', isNotLoggedIn, function (req, res, next) {
  return res.render('pages/signup', {
    message: req.flash('signupMessage'),
    first_name: res.locals.first_name,
    last_name: res.locals.last_name,
    email: res.locals.email,
    username: res.locals.username
  });
});

router.get('/login', isNotLoggedIn, function (req, res, next) {
  return res.render('pages/login', {
    message: req.flash('loginMessage'),
    username: res.locals.username
  });
});

router.get('/logout', function (req, res, next) {
  req.logout();
  return res.redirect('/');
});

router.post('/login', function (req, res, next) {
  passport.authenticate('local-login', {failureFlash: true}, function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/profile/' + user.username);
    });
  })(req, res, next);
});

router.post('/signup', function (req, res, next) {
  passport.authenticate('local-signup', {failureFlash: true}, function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/signup'); }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.redirect('/profile/' + user.username);
    });
  })(req, res, next);
});

router.post('/submit', queries.addPoem, function (req, res, next) {
  return res.redirect('/poem/' + res.locals.poem.id);
});

router.post('/submitencode', queries.addPoem, function (req, res, next) {
  return res.redirect('/encode/' + res.locals.poem.id);
});

router.post('/poem/:id/encode', queries.encodePoem, function (req, res, next) {
  return res.redirect('/poem/' + req.params.id);
});

router.post('/compare/:poem_id', function (req, res, next) {
  if(req.body.optRadio1 && req.body.optRadio2)
    return res.redirect('/compare/' + req.params.poem_id + "/" + req.body.optRadio1 + "/" + req.body.optRadio2);
  return res.redirect('/poem/' + req.params.poem_id);
});

router.post('/validate', function (req, res, next) {
  //let str = '<TEI xmlns="http://www.tei-c.org/ns/1.0"><yes p:id="yeah">ff<yes>fgfM</yes>gf</yes> /n <sysy>d
<FF text="p98">jd</FF><hhh></sysy>
</hhh>jdjd</TEI>'.replace(/\/n/g, "");
  xml.validate(req.body.original, req.body.encoded, function (status, message) {
    return res.json({status: status, message: message});
  });
  //https://www.npmjs.com/package/libxml-xsd
});

module.exports = router;

function isLoggedIn (req, res, next) {
  if (req.isAuthenticated())
    return next();
  res.redirect('/');
}

function isNotLoggedIn (req, res, next) {
  if (!req.isAuthenticated())
    return next();
  res.redirect('/');
}
<|endoftext|>


<commit_before>/*
 * to-markdown - an HTML to Markdown converter
 *
 * Copyright 2011, Dom Christie
 * Licenced under the MIT licence
 *
 */

var toMarkdown = function(string) {

  var ELEMENTS = [
    {
      patterns: 'p',
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '\n\n' + innerHTML + '\n\n' : '';
      }
    },
    {
      patterns: 'br',
      type: 'void',
      replacement: '\n'
    },
    {
      patterns: 'h([1-6])',
      replacement: function(str, hLevel, attrs, innerHTML) {
        var hPrefix = '';
        for(var i = 0; i < hLevel; i++) {
          hPrefix += '#';
        }
        return '\n\n' + hPrefix + ' ' + innerHTML + '\n\n';
      }
    },
    {
      patterns: 'hr',
      type: 'void',
      replacement: '\n\n* * *\n\n'
    },
    {
      patterns: 'a',
      replacement: function(str, attrs, innerHTML) {
        var href = attrs.match(attrRegExp('href')),
            title = attrs.match(attrRegExp('title'));
        return href ? '[' + innerHTML + ']' + '(' + href[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')' : str;
      }
    },
    {
      patterns: ['b', 'strong'],
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '**' + innerHTML + '**' : '';
      }
    },
    {
      patterns: ['i', 'em'],
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '_' + innerHTML + '_' : '';
      }
    },
    {
      patterns: 'code',
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '`' + innerHTML + '`' : '';
      }
    },
    {
      patterns: 'img',
      type: 'void',
      replacement: function(str, attrs, innerHTML) {
        var src = attrs.match(attrRegExp('src')),
            alt = attrs.match(attrRegExp('alt')),
            title = attrs.match(attrRegExp('title'));
        return '![' + (alt && alt[1] ? alt[1] : '') + ']' + '(' + src[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')';
      }
    }
  ];

  for(var i = 0, len = ELEMENTS.length; i < len; i++) {
    if(typeof ELEMENTS[i].patterns === 'string') {
      string = replaceEls(string, { tag: ELEMENTS[i].patterns, replacement: ELEMENTS[i].replacement, type:  ELEMENTS[i].type });
    }
    else {
      for(var j = 0, pLen = ELEMENTS[i].patterns.length; j < pLen; j++) {
        string = replaceEls(string, { tag: ELEMENTS[i].patterns[j], replacement: ELEMENTS[i].replacement, type:  ELEMENTS[i].type });
      }
    }
  }

  function replaceEls(html, elProperties) {
    var pattern = elProperties.type === 'void' ? '<' + elProperties.tag + '([^>]*)\\/?>' : '<' + elProperties.tag + '([^>]*)>(.*)<\\/' + elProperties.tag + '>',
        regex = new RegExp(pattern, 'gi'),
        markdown = '';
    if(typeof elProperties.replacement === 'string') {
      markdown = html.replace(regex, elProperties.replacement);
    }
    else {
      markdown = html.replace(regex, function(str, p1, p2, p3) {
        return elProperties.replacement.call(this, str, p1, p2, p3);
      });
    }
    return markdown;
  }

  function attrRegExp(attr) {
    return new RegExp(attr + '\\s*=\\s*["\']?([^"\']*)["\']?', 'i');
  }

  // Lists
  // use [\s\S] to match any char (rather than .) to fix . not matching across linebreaks: http://www.regular-expressions.info/dot.html#nodotall
  string = string.replace(/<(ul|ol)\b[^>]*>([\s\S]*?)<\/\1>/gi, function(str, listType, innerHTML) {
    window.console && console.log(str);
    var lis = innerHTML.split('
');
    for(i = 0, len = lis.length; i < len; i++) {
      if(lis[i]) {
        var prefix = (listType === 'ol') ? (i + 1) + ". " : "* ";
        lis[i] = lis[i].replace(/\s*
]*>(.*)/i, function(str, innerHTML) {
          return prefix + innerHTML + '\n';
        });
      }
    }
    return "\n\n" + lis.join('') + "\n";
  });

  function cleanUp(string) {
    string = string.replace(/^\s+|\s+$/g, ''); // trim leading/trailing whitespace
    string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2
    return string;
  }

  return cleanUp(string);
};<commit_msg>Improve replacement regex<commit_after>/*
 * to-markdown - an HTML to Markdown converter
 *
 * Copyright 2011, Dom Christie
 * Licenced under the MIT licence
 *
 */

var toMarkdown = function(string) {

  var ELEMENTS = [
    {
      patterns: 'p',
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '\n\n' + innerHTML + '\n\n' : '';
      }
    },
    {
      patterns: 'br',
      type: 'void',
      replacement: '\n'
    },
    {
      patterns: 'h([1-6])',
      replacement: function(str, hLevel, attrs, innerHTML) {
        var hPrefix = '';
        for(var i = 0; i < hLevel; i++) {
          hPrefix += '#';
        }
        return '\n\n' + hPrefix + ' ' + innerHTML + '\n\n';
      }
    },
    {
      patterns: 'hr',
      type: 'void',
      replacement: '\n\n* * *\n\n'
    },
    {
      patterns: 'a',
      replacement: function(str, attrs, innerHTML) {
        var href = attrs.match(attrRegExp('href')),
            title = attrs.match(attrRegExp('title'));
        return href ? '[' + innerHTML + ']' + '(' + href[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')' : str;
      }
    },
    {
      patterns: ['b', 'strong'],
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '**' + innerHTML + '**' : '';
      }
    },
    {
      patterns: ['i', 'em'],
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '_' + innerHTML + '_' : '';
      }
    },
    {
      patterns: 'code',
      replacement: function(str, attrs, innerHTML) {
        return innerHTML ? '`' + innerHTML + '`' : '';
      }
    },
    {
      patterns: 'img',
      type: 'void',
      replacement: function(str, attrs, innerHTML) {
        var src = attrs.match(attrRegExp('src')),
            alt = attrs.match(attrRegExp('alt')),
            title = attrs.match(attrRegExp('title'));
        return '![' + (alt && alt[1] ? alt[1] : '') + ']' + '(' + src[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')';
      }
    }
  ];

  for(var i = 0, len = ELEMENTS.length; i < len; i++) {
    if(typeof ELEMENTS[i].patterns === 'string') {
      string = replaceEls(string, { tag: ELEMENTS[i].patterns, replacement: ELEMENTS[i].replacement, type:  ELEMENTS[i].type });
    }
    else {
      for(var j = 0, pLen = ELEMENTS[i].patterns.length; j < pLen; j++) {
        string = replaceEls(string, { tag: ELEMENTS[i].patterns[j], replacement: ELEMENTS[i].replacement, type:  ELEMENTS[i].type });
      }
    }
  }

  function replaceEls(html, elProperties) {
    var pattern = elProperties.type === 'void' ? '<' + elProperties.tag + '\\b([^>]*)\\/?>' : '<' + elProperties.tag + '\\b([^>]*)>(.*?)<\\/' + elProperties.tag + '>',
        regex = new RegExp(pattern, 'gi'),
        markdown = '';
    if(typeof elProperties.replacement === 'string') {
      markdown = html.replace(regex, elProperties.replacement);
    }
    else {
      markdown = html.replace(regex, function(str, p1, p2, p3) {
        return elProperties.replacement.call(this, str, p1, p2, p3);
      });
    }
    return markdown;
  }

  function attrRegExp(attr) {
    return new RegExp(attr + '\\s*=\\s*["\']?([^"\']*)["\']?', 'i');
  }

  // Lists
  // use [\s\S] to match any char (rather than .) to fix . not matching across linebreaks: http://www.regular-expressions.info/dot.html#nodotall
  string = string.replace(/<(ul|ol)\b[^>]*>([\s\S]*?)<\/\1>/gi, function(str, listType, innerHTML) {
    window.console && console.log(str);
    var lis = innerHTML.split('
');
    for(i = 0, len = lis.length; i < len; i++) {
      if(lis[i]) {
        var prefix = (listType === 'ol') ? (i + 1) + ". " : "* ";
        lis[i] = lis[i].replace(/\s*
]*>(.*)/i, function(str, innerHTML) {
          return prefix + innerHTML + '\n';
        });
      }
    }
    return "\n\n" + lis.join('') + "\n";
  });

  function cleanUp(string) {
    string = string.replace(/^\s+|\s+$/g, ''); // trim leading/trailing whitespace
    string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2
    return string;
  }

  return cleanUp(string);
};<|endoftext|>


<commit_before>/*
 * routes/index.js
 */

var BASE_PATH = "../lib/"

var _ = require('underscore')
  , Step = require('step')
  , common = require(BASE_PATH + 'common')
  , fs = require('fs')
  , gh = require(BASE_PATH + 'github')
  , jobs = require(BASE_PATH + 'jobs')
  , logging = require(BASE_PATH + 'logging')
  , User = require(BASE_PATH + 'models').User
  , Job = require(BASE_PATH + 'models').Job
  ;

var TEST_ONLY = "TEST_ONLY";
var TEST_AND_DEPLOY = "TEST_AND_DEPLOY";

/*
 * GET home page.
 */

exports.index = function(req, res){
  if (req.loggedIn == false){
  }
  if (req.session.return_to != null) {
    var return_to = req.session.return_to;
    req.session.return_to=null;
    res.redirect(return_to);
  } else {
    var code = "";
    if (req.param('code') !== undefined) {
      code = req.param('code');
          res.render('register.html', {invite_code:code});
    } else {
      if (req.user != undefined) {
        req.user.get_repo_config_list(function(err, repo_list) {
          if (err) throw err;
          res.render('index.html',{total_configured_projects:repo_list.length});
        });
      } else {
        res.render('index.html');
      }
    }

  }
};

function whitelist_repo_config(repo_config) {
  var trepo = {
    display_name:repo_config.display_url.replace(/^.*com\//gi, ''),
    display_url:repo_config.display_url,
    url:repo_config.url,
    project_type:repo_config.project_type,
    webhooks:repo_config.webhooks,
    prod_deploy_target:repo_config.deploy_target
  };
  return trepo;
}

function whitelist_repo_metadata(repo_metadata) {
  var trepo = {
    display_name:repo_metadata.html_url.replace(/^.*com\//gi, ''),
    url:repo_metadata.html_url,
    id:repo_metadata.id
  };
  return trepo;
}

/*
 * GET /kickoff  - start configuration wizard for a job
 */
exports.kickoff = function(req, res, github) {
  var gh = github || gh;
  // Assert cached github metadata
  if (req.user.github_metadata === undefined
    || req.user.github_metadata[req.user.github.id] === undefined) {
    res.statusCode = 400;
    res.end("please call /api/github/metadata before this");
  } else {
    // Find the metadata for the repo we are kicking off on
    var kickoff_repo_metadata = req.user.get_repo_metadata(req.params.githubId);
    var trepo = whitelist_repo_metadata(kickoff_repo_metadata);
    // Check whether someone else has already configured this repository
    User.findOne({'github_config.url':trepo.url.toLowerCase()}, function(err, user) {
      if (!user) {
        res.render('kickoff.html', {repo: JSON.stringify(trepo)})
      } else {
        res.render('kickoff-conflict.html', {repo: JSON.stringify(trepo)});
      }
    });

  }
};

/*
 * GET /account - account settings page
 */
exports.account = function(req, res){
  res.render('account.html');
};

/*
 * GET /:org/:repo/config - project config page
 */
exports.config = function(req, res)
{
  Step(
    function() {
      req.user.get_repo_config(req.repo_url, this);
    },
    function(err, repo_config) {
      if (err) {
        console.error("config() - Error fetching repo config for user %s: %s", req.user.email, err);
        res.statusCode = 400;
        return res.end("Bad Request");
      }
      this.repo_config = repo_config;
      req.user.get_prod_deploy_target(repo_config.url, this);
    },
    function(err, deploy_target) {
      var wrepo_config = whitelist_repo_config(this.repo_config);
      var deploy_on_green = this.repo_config.prod_deploy_target.deploy_on_green;
      // Default to true if not set
      if (deploy_on_green === undefined) {
        deploy_on_green = true;
      }
      var deploy_target_name = null;
      if (deploy_target) {
        deploy_target_name = deploy_target.app;
      }
      var params = {
        repo_url: this.repo_config.url,
        has_deploy_target: deploy_target != null,
        deploy_target_name: deploy_target_name,
        deploy_on_green: deploy_on_green
      };
      var apresParams = JSON.stringify(params);
      var projectPanels = common.panels['project_config'];
      var r = {
         // May be undefined if not configured
         display_name: wrepo_config.display_name,
         repo_org: req.params.org,
         repo_name: req.params.repo,
         apresController: "/javascripts/apres/controller/project_config.js",
         apresParams: apresParams,
         panels: [],
      };
      // TODO: factor out this logic so other resource handlers can use it later
      if (projectPanels) {
        // For each panel, read contents from FS or execute callback to get HTML
        Step(
          function() {
            var group = this.group();
            projectPanels.forEach(function(p) {
              var cb = group();
              var f = function(err, res) {
                p.contents = res;
                cb(err, p);
              };
              // Panel sources can be a string which assumed to be a filesystem path
              // or a function which is assumed to take a callback argument.
              if (typeof(p.src) === 'string') {
                fs.readFile(p.src, 'utf8', f);
              } else if (typeof(p.src) === 'function') {
                p.src(f);
              }
            });
          },
          function(err, panels) {
            if (err) {
              console.error("Error loading panels: %s", err);
              res.statusCode = 500;
              return res.end("Error handling request");
            }
            r.panels = panels;
            return res.render('project_config.html', r);
          }
        );
      } else {
        return res.render('project_config.html', r);
      }
    }
  );
};

/*
 * POST /webhook - Github push webhook handler
 */
exports.webhook_signature = function(req, res)
{
  gh.verify_webhook_req_signature(req, function(isOk, repo, user, payload) {
    var active = false;
    // Repo can be undefined
    if (isOk && repo) {
      active = repo.active;
    }
    // Default to active if property is missing.
    if (active === undefined) {
      active = true;
    }
    if (active && isOk && gh.webhook_commit_is_to_master(payload)) {
      console.log("received a correctly signed webhook for repo %s on master branch - starting task on user %s's behalf", repo.url, user.email);
      var github_commit_id = payload.after;
      var github_commit_info = gh.webhook_extract_latest_commit_info(payload);
      var repo_metadata = _.find(user.github_metadata[user.github.id].repos, function(item) {
        return repo.url == item.html_url.toLowerCase();
      });
      var repo_ssh_url;
      if (repo_metadata) {
        repo_ssh_url = repo_metadata.ssh_url;
      }
      console.debug("POST to Github /webhook payload: %j", payload);
      if (repo.has_prod_deploy_target) {
        var deploy_config = _.find(user[repo.prod_deploy_target.provider], function(item) {
          return item.account_id === repo.prod_deploy_target.account_id;
        });
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_AND_DEPLOY);
      } else {
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_ONLY);
      }
      res.end("webhook good");
    } else {
      console.log("received an incorrecly signed webhook or is not to master branch.");
      res.end("webhook bad or irrelevant");
    }
 });
};

exports.webhook_secret = function(req, res)
{
  gh.verify_webhook_req_secret(req, function(isOk, repo, user, payload) {
    var active = repo.active;
    // Default to active if property is missing.
    if (active === undefined)
      active = true;
    if (active && isOk && gh.webhook_commit_is_to_master(payload)) {
      console.log("received a correctly signed webhook for repo %s on master branch - starting task on user %s's behalf", repo.url, user.email);
      var github_commit_id = payload.after;
      var github_commit_info = gh.webhook_extract_latest_commit_info(payload);
      var repo_metadata = _.find(user.github_metadata[user.github.id].repos, function(item) {
        return repo.url == item.html_url.toLowerCase();
      });
      var repo_ssh_url = repo_metadata.ssh_url;
      console.debug("POST to Github /webhook payload: %j", payload);
      if (repo.has_prod_deploy_target) {
        var deploy_config = _.find(user[repo.prod_deploy_target.provider], function(item) {
          return item.account_id === repo.prod_deploy_target.account_id;
        });
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_AND_DEPLOY);
      } else {
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_ONLY);
      }
      res.end("webhook good");
    } else {
      console.log("gh: " + gh.webhook_commit_is_to_master(payload));
      console.log("received an incorrecly signed webhook or is not to master branch.");
      res.end("webhook bad or irrelevant");
    }
 });
};

/*
 * app.get('/:org/:repo/delete', middleware.require_resource_admin, routes.delete_project);
 * delete project. should be rewritten as backbone and api call
 * todo: should delete github webhook and deploy key
 * todo: should add 'archived' flag to jobs
 */

exports.delete_project = function(req,res) {
  var repo_url = "https://github.com/" + req.params.org + "/" + req.params.repo;
  repo_url = repo_url.toLowerCase();

  var conditions = { email: req.user.email }, update = {$pull : {github_config:{url:repo_url}}};
  User.update(conditions, update, function(err,numAffected) {
    if (err) throw err;
    console.log("deleted: " + repo_url);
    res.redirect("/");
  });
}

/*
 * /status endpoint
 * Executes a simple database query to verify that system is operational.
 * Assumes there is at least 1 user in the system.
 * Returns 200 on success.
 *
 * This is for use by Pingdom and similar monitoring systems.
 */
exports.status = function(req, res) {

  function error(message) {
    res.statusCode = 500;
    var resp = {
      status: "error",
      results: [],
      errors: [{message:message}]
    }
    return res.end(JSON.stringify(resp));
  }

  function ok() {
    res.statusCode = 200;
    var resp = {
      status: "ok",
      results: [{message:"system operational"}],
      errors: []
    }
    return res.end(JSON.stringify(resp));
  }

  try {
    User.findOne(function(err, user) {
      if (err) {
        return error("error retrieving user from DB: " + err);
      }
      if (!user) {
        return error("no users found in DB - mis-configured?")
      }
      return ok();
    });
  } catch(e) {
    console.log("exception: %s", e);
  }

};

<commit_msg>pretty<commit_after>/*
 * routes/index.js
 */

var BASE_PATH = "../lib/"

var _ = require('underscore')
  , Step = require('step')
  , common = require(BASE_PATH + 'common')
  , fs = require('fs')
  , gh = require(BASE_PATH + 'github')
  , jobs = require(BASE_PATH + 'jobs')
  , logging = require(BASE_PATH + 'logging')
  , User = require(BASE_PATH + 'models').User
  , Job = require(BASE_PATH + 'models').Job
  ;

var TEST_ONLY = "TEST_ONLY";
var TEST_AND_DEPLOY = "TEST_AND_DEPLOY";

/*
 * GET home page.
 */

exports.index = function(req, res){
  if (req.loggedIn == false){
  }
  if (req.session.return_to != null) {
    var return_to = req.session.return_to;
    req.session.return_to=null;
    res.redirect(return_to);
  } else {
    var code = "";
    if (req.param('code') !== undefined) {
      code = req.param('code');
          res.render('register.html', {invite_code:code});
    } else {
      if (req.user != undefined) {
        req.user.get_repo_config_list(function(err, repo_list) {
          if (err) throw err;
          res.render('index.html',{total_configured_projects:repo_list.length});
        });
      } else {
        res.render('index.html');
      }
    }

  }
};

function whitelist_repo_config(repo_config) {
  var trepo = {
    display_name:repo_config.display_url.replace(/^.*com\//gi, ''),
    display_url:repo_config.display_url,
    url:repo_config.url,
    project_type:repo_config.project_type,
    webhooks:repo_config.webhooks,
    prod_deploy_target:repo_config.deploy_target
  };
  return trepo;
}

function whitelist_repo_metadata(repo_metadata) {
  var trepo = {
    display_name:repo_metadata.html_url.replace(/^.*com\//gi, ''),
    url:repo_metadata.html_url,
    id:repo_metadata.id
  };
  return trepo;
}

/*
 * GET /kickoff  - start configuration wizard for a job
 */
exports.kickoff = function(req, res, github) {
  var gh = github || gh;
  // Assert cached github metadata
  if (req.user.github_metadata === undefined
    || req.user.github_metadata[req.user.github.id] === undefined) {
    res.statusCode = 400;
    res.end("please call /api/github/metadata before this");
  } else {
    // Find the metadata for the repo we are kicking off on
    var kickoff_repo_metadata = req.user.get_repo_metadata(req.params.githubId);
    var trepo = whitelist_repo_metadata(kickoff_repo_metadata);
    // Check whether someone else has already configured this repository
    User.findOne({'github_config.url':trepo.url.toLowerCase()}, function(err, user) {
      if (!user) {
        res.render('kickoff.html', {repo: JSON.stringify(trepo)})
      } else {
        res.render('kickoff-conflict.html', {repo: JSON.stringify(trepo)});
      }
    });

  }
};

/*
 * GET /account - account settings page
 */
exports.account = function(req, res){
  res.render('account.html');
};

/*
 * GET /:org/:repo/config - project config page
 */
exports.config = function(req, res)
{
  Step(
    function() {
      req.user.get_repo_config(req.repo_url, this);
    },
    function(err, repo_config) {
      if (err) {
        console.error("config() - Error fetching repo config for user %s: %s", req.user.email, err);
        res.statusCode = 400;
        return res.end("Bad Request");
      }
      this.repo_config = repo_config;
      req.user.get_prod_deploy_target(repo_config.url, this);
    },
    function(err, deploy_target) {
      var wrepo_config = whitelist_repo_config(this.repo_config);
      var deploy_on_green = this.repo_config.prod_deploy_target.deploy_on_green;
      // Default to true if not set
      if (deploy_on_green === undefined) {
        deploy_on_green = true;
      }
      var deploy_target_name = null;
      if (deploy_target) {
        deploy_target_name = deploy_target.app;
      }
      var params = {
        repo_url: this.repo_config.url,
        has_deploy_target: deploy_target != null,
        deploy_target_name: deploy_target_name,
        deploy_on_green: deploy_on_green
      };
      var apresParams = JSON.stringify(params);
      var projectPanels = common.panels['project_config'];
      var r = {
         // May be undefined if not configured
         display_name: wrepo_config.display_name,
         repo_org: req.params.org,
         repo_name: req.params.repo,
         apresController: "/javascripts/apres/controller/project_config.js",
         apresParams: apresParams,
         panels: [],
      };
      // TODO: factor out this logic so other resource handlers can use it later
      if (projectPanels) {
        // For each panel, read contents from FS or execute callback to get HTML
        Step(
          function() {
            var group = this.group();
            projectPanels.forEach(function(p) {
              var cb = group();
              var f = function(err, res) {
                p.contents = res;
                cb(err, p);
              };
              // Panel sources can be a string which assumed to be a filesystem path
              // or a function which is assumed to take a callback argument.
              if (typeof(p.src) === 'string') {
                fs.readFile(p.src, 'utf8', f);
              } else if (typeof(p.src) === 'function') {
                p.src(f);
              }
            });
          },
          function(err, panels) {
            if (err) {
              console.error("Error loading panels: %s", err);
              res.statusCode = 500;
              return res.end("Error handling request");
            }
            r.panels = panels;
            return res.render('project_config.html', r);
          }
        );
      } else {
        return res.render('project_config.html', r);
      }
    }
  );
};

/*
 * POST /webhook - Github push webhook handler
 */
exports.webhook_signature = function(req, res)
{
  gh.verify_webhook_req_signature(req, function(isOk, repo, user, payload) {
    var active = false;
    // Repo can be undefined
    if (isOk && repo) {
      active = repo.active;
    }
    // Default to active if property is missing.
    if (active === undefined) {
      active = true;
    }
    if (active && isOk && gh.webhook_commit_is_to_master(payload)) {
      console.log("received a correctly signed webhook for repo %s on master branch - starting task on user %s's behalf", repo.url, user.email);
      var github_commit_id = payload.after;
      var github_commit_info = gh.webhook_extract_latest_commit_info(payload);
      var repo_metadata = _.find(user.github_metadata[user.github.id].repos, function(item) {
        return repo.url == item.html_url.toLowerCase();
      });
      var repo_ssh_url;
      if (repo_metadata) {
        repo_ssh_url = repo_metadata.ssh_url;
      }
      console.debug("POST to Github /webhook payload: %j", payload);
      if (repo.has_prod_deploy_target) {
        var deploy_config = _.find(user[repo.prod_deploy_target.provider], function(item) {
          return item.account_id === repo.prod_deploy_target.account_id;
        });
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_AND_DEPLOY);
      } else {
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_ONLY);
      }
      res.end("webhook good");
    } else {
      console.log("received an incorrecly signed webhook or is not to master branch.");
      res.end("webhook bad or irrelevant");
    }
 });
};

exports.webhook_secret = function(req, res)
{
  gh.verify_webhook_req_secret(req, function(isOk, repo, user, payload) {
    var active = repo.active;
    // Default to active if property is missing.
    if (active === undefined)
      active = true;
    if (active && isOk && gh.webhook_commit_is_to_master(payload)) {
      console.log("received a correctly signed webhook for repo %s on master branch - starting task on user %s's behalf", repo.url, user.email);
      var github_commit_id = payload.after;
      var github_commit_info = gh.webhook_extract_latest_commit_info(payload);
      var repo_metadata = _.find(user.github_metadata[user.github.id].repos, function(item) {
        return repo.url == item.html_url.toLowerCase();
      });
      var repo_ssh_url = repo_metadata.ssh_url;
      console.debug("POST to Github /webhook payload: %j", payload);
      if (repo.has_prod_deploy_target) {
        var deploy_config = _.find(user[repo.prod_deploy_target.provider], function(item) {
          return item.account_id === repo.prod_deploy_target.account_id;
        });
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_AND_DEPLOY);
      } else {
        jobs.startJob(user, repo, deploy_config, github_commit_info, repo_ssh_url, TEST_ONLY);
      }
      res.end("webhook good");
    } else {
      console.log("gh: " + gh.webhook_commit_is_to_master(payload));
      console.log("received an incorrecly signed webhook or is not to master branch.");
      res.end("webhook bad or irrelevant");
    }
 });
};

/*
 * app.get('/:org/:repo/delete', middleware.require_resource_admin, routes.delete_project);
 * delete project. should be rewritten as backbone and api call
 * todo: should delete github webhook and deploy key
 * todo: should add 'archived' flag to jobs
 */

exports.delete_project = function(req,res) {
  var repo_url = "https://github.com/" + req.params.org + "/" + req.params.repo;
  repo_url = repo_url.toLowerCase();

  var conditions = { email: req.user.email }, update = {$pull : {github_config:{url:repo_url}}};
  User.update(conditions, update, function(err,numAffected) {
    if (err) throw err;
    console.log("deleted: " + repo_url);
    res.redirect("/");
  });
}

/*
 * /status endpoint
 * Executes a simple database query to verify that system is operational.
 * Assumes there is at least 1 user in the system.
 * Returns 200 on success.
 *
 * This is for use by Pingdom and similar monitoring systems.
 */
exports.status = function(req, res) {

  function error(message) {
    res.statusCode = 500;
    var resp = {
      status: "error",
      results: [],
      errors: [{message:message}]
    }
    return res.end(JSON.stringify(resp));
  }

  function ok() {
    res.statusCode = 200;
    var resp = {
      status: "ok",
      results: [{message:"system operational"}],
      errors: []
    }
    return res.end(JSON.stringify(resp));
  }

  User.findOne(function(err, user) {
    if (err) {
      return error("error retrieving user from DB: " + err);
    }
    if (!user) {
      return error("no users found in DB - mis-configured?")
    }
    return ok();
  });

};

<|endoftext|>


<commit_before><commit_msg>Change request link<commit_after><|endoftext|>


<commit_before>var buster         = require('buster')
  , RequestHandler = require(__dirname + '/../lib/request-handler.js')
  , exec           = require('child_process').exec

buster.spec.expose()
buster.testRunner.timeout = 10000

describe('RequestHandler', function() {
  before(function(done) {
    this.tmpPathRoot = __dirname + '/tmp/oldTempFileTest' + ~~(Math.random() * 999999)

    exec('rm -rf' + this.tmpPathRoot + '; mkdir -p ' + this.tmpPathRoot, function() {
      this.handler = new RequestHandler({ tmpPathRoot: this.tmpPathRoot })
      done()
    }.bind(this))
  })

  describe('getImageProcessUrlMatch', function() {
    describe('without namespace', function() {
      it("returns a match array for valid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/resize/123/foo.jpg" })).toBeDefined()
      })

      it("returns no match array for invalid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/123/foo.jpg" })).toBeNull()
      })
    })

    describe('with namespacing', function() {
      before(function() {
        this.handler = new RequestHandler({ namespace: 'foo' })
      })

      it("returns a match array for valid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/resize/123/foo.jpg" })).toBeDefined()
      })

      it("returns no match array for invalid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/bar/123/foo.jpg" })).toBeNull()
      })
    })
  })

  describe("isImageProcessUrl", function() {
    describe('without namespace', function() {
      it('returns a match array for valid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/resize/123/foo.jpg" })).toBeDefined()
      })

      it('returns no match array for invalid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/123/foo.jpg" })).toBeFalsy()
      })
    })

    describe('with namespace', function() {
      before(function() {
        this.handler = new RequestHandler({ namespace: 'foo' })
      })

      it('returns a match array for valid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/resize/123/foo.jpg" })).toBeDefined()
      })

      it('returns no match array for invalid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/bar/123/foo.jpg" })).toBeFalsy()
      })
    })
  })

  describe('isImageSourceHostAllowed', function() {
    describe('with allowedHosts', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': { 'allowedHosts': [/^.*\.example\.com$/] }
        })
      })

      it('returns true if image source is allowed', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostAllowed(req)).toBeDefined()
      })

      it('returns false if image source is not allowed', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostAllowed(req)).toBeFalsy()
      })
    })

    describe('without allowedHosts', function() {
      it("returns true for every url", function() {
        var req1 = { query: {url: 'http://www.google.com/foo.jpg'} }
          , req2 = { query: {url: 'http://www.example.com/foo.jpg'} }

        expect(this.handler.isImageSourceHostAllowed(req1)).toBeTruthy()
        expect(this.handler.isImageSourceHostAllowed(req2)).toBeTruthy()
      })
    })
  })

  describe('isImageSourceHostTrusted', function() {
    describe('with trustedHosts', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': { 'trustedHosts': [/^.*\.example\.com$/] }
        })
      })

      it('returns true if image source is trusted', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeTruthy()
      })

      it('returns false if image source is not trusted', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeFalsy()
      })
    })

    describe('with trustedHosts as string', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': {'trustedHosts': ["^.*\.example\.com$"]}
        })
      })

      it('returns true if image source is trusted', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeTruthy()
      })

      it('returns false if image source is not trusted', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeFalsy()
      })
    })

    describe('without trustedHosts', function() {
      it('returns false for every url', function() {
        var req1 = { query: {url: 'http://www.google.com/foo.jpg'} }
          , req2 = { query: {url: 'http://www.example.com/foo.jpg'} }

        expect(this.handler.isImageSourceHostTrusted(req1)).toBeFalsy()
        expect(this.handler.isImageSourceHostTrusted(req2)).toBeFalsy()
      })
    })
  })

  describe('_isValidHash', function() {
    before(function() {
      this.handler = new RequestHandler({
        secret:       "my-very-secret-secret",
        magicHash:    "magic",
        whitelist: { trustedHosts: [/^.*\.google\.com$/] }
      })
    })

    it('returns true for the magic hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = this.handler.config.magicHash
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns true for the correct hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = this.handler.utils.hash("url=" + imgUrl)
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns false for the incorrect hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = "xxx"
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeFalsy()
    })

    it('returns true for trusted hosts', function() {
      var imgUrl = encodeURIComponent("http://www.google.com/intl/en_ALL/images/logo.gif")
        , hash   = "xxx"
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns true for trusted hosts without hash', function() {
      var imgUrl = encodeURIComponent("http://www.google.com/intl/en_ALL/images/logo.gif")
        , reqUrl = "http://host.com/resize/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })
  })

  describe('_afterResize', function() {
    before(function() {
      this.res = {
        send: function() {},
        contentType: function() {},
        sendfile: function(path, options, callback) { callback && callback() }
      }
    })

    it("returns a 500 if an error has occurred", function() {
      var mock = this.mock(this.res).expects('send').withArgs(500).once()

      new RequestHandler()._afterResize(new Error('barfooz'), null, this.res)

      mock.verify()
    })

    it("calls deleteTempfile if the option keepDownloads is false or not defined", function() {
      var handler = new RequestHandler()
        , path    = 'foo'
        , mock    = this.mock(handler).expects('deleteTempfile').withArgs(path).once()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })

    it("doesn't call deleteTempfile if the option keepDownloads is false or not defined", function() {
      var handler = new RequestHandler({ keepDownloads: true })
        , path    = 'foo'
        , mock    = this.mock(handler).expects('deleteTempfile').withArgs(path).never()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })

    it("checks the amount of used hdd space if the option keepDownloads is true and maxDownloadCacheSize is defiend", function() {
      var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })
        , path    = 'foo'
        , mock    = this.mock(handler).expects('checkDownloadCacheSize').once()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })
  })

  describe('checkDownloadCacheSize', function() {
    it("deletes old tempfiles if the amount of used hdd space is greater than the defined maxDownloadCacheSize", function(done) {
      var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })
        , mock    = this.mock(handler).expects('_deleteOldDownloads').once().callsArg(0)

      this.stub(handler, '_getTempFolderSize', function(callback) { callback(1100) })

      handler.checkDownloadCacheSize(done)

      mock.verify()
    })

    it("deletes the files returned by _getOldTempFiles", function(done) {
      var files = ['a.txt', 'b.txt', 'c.txt'].map(function(f) { return __dirname + '/tmp/' + f })

      exec(files.map(function(f) { return 'touch ' + f }).join(";"), function(err) {
        var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })

        this.stub(handler, '_getTempFolderSize', function(callback) { callback(1100) })
        this.stub(handler, '_getOldTempFiles', function(callback) { callback(files) })

        handler.checkDownloadCacheSize(function() {
          exec('ls -ila ' + __dirname + '/tmp', function(err, stdout, stderr) {
            files.forEach(function(f) {
              expect(stdout).not.toMatch(f)
            })

            done()
          })
        })
      }.bind(this))
    })
  })

  describe('_getOldTempFiles', function() {
    before(function() {
      this.handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000, tmpPathRoot: this.tmpPathRoot })
    })

    it('returns one fifth of all available files', function(done) {
      var commands = [
            'mkdir -p ' + this.tmpPathRoot,
            'touch ' + this.tmpPathRoot + '/1.txt',
            'touch ' + this.tmpPathRoot + '/2.txt',
            'touch ' + this.tmpPathRoot + '/3.txt',
            'touch ' + this.tmpPathRoot + '/4.txt',
            'touch ' + this.tmpPathRoot + '/5.txt'
          ]

      exec(commands.join('; sleep 1; '), function() {
        this.handler._getOldTempFiles(function(files) {
          expect(files).toEqual([ this.tmpPathRoot + '/1.txt' ])
          done()
        }.bind(this))
      }.bind(this))
    })
  })

  describe('_getTempFolderSize', function() {
    before(function() {
      this.handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000, tmpPathRoot: this.tmpPathRoot })
    })

    it("=>returns 0 if the folder is empty", function(done) {
      this.handler._getTempFolderSize(function(size) {
        expect(size).toEqual(0)
        done()
      })
    })

    it("=>returns 0 if the folder has less than 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/tiny.file bs=1024 count=10 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(0)
          done()
        })
      }.bind(this))
    })

    it("=>returns 1 if the folder has 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=1024 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(1)
          done()
        })
      }.bind(this))
    })

    it("=>returns 1 if the folder has slightly more than 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=1048 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(1)
          done()
        })
      }.bind(this))
    })

    it("=>returns 10 if the folder has 10mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=10240 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(10)
          done()
        })
      }.bind(this))
    })
  })
})
<commit_msg>removed focus rocket<commit_after>var buster         = require('buster')
  , RequestHandler = require(__dirname + '/../lib/request-handler.js')
  , exec           = require('child_process').exec

buster.spec.expose()
buster.testRunner.timeout = 10000

describe('RequestHandler', function() {
  before(function(done) {
    this.tmpPathRoot = __dirname + '/tmp/oldTempFileTest' + ~~(Math.random() * 999999)

    exec('rm -rf' + this.tmpPathRoot + '; mkdir -p ' + this.tmpPathRoot, function() {
      this.handler = new RequestHandler({ tmpPathRoot: this.tmpPathRoot })
      done()
    }.bind(this))
  })

  describe('getImageProcessUrlMatch', function() {
    describe('without namespace', function() {
      it("returns a match array for valid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/resize/123/foo.jpg" })).toBeDefined()
      })

      it("returns no match array for invalid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/123/foo.jpg" })).toBeNull()
      })
    })

    describe('with namespacing', function() {
      before(function() {
        this.handler = new RequestHandler({ namespace: 'foo' })
      })

      it("returns a match array for valid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/resize/123/foo.jpg" })).toBeDefined()
      })

      it("returns no match array for invalid urls", function() {
        expect(this.handler.getImageProcessUrlMatch({ originalUrl: "/foo/bar/123/foo.jpg" })).toBeNull()
      })
    })
  })

  describe("isImageProcessUrl", function() {
    describe('without namespace', function() {
      it('returns a match array for valid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/resize/123/foo.jpg" })).toBeDefined()
      })

      it('returns no match array for invalid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/123/foo.jpg" })).toBeFalsy()
      })
    })

    describe('with namespace', function() {
      before(function() {
        this.handler = new RequestHandler({ namespace: 'foo' })
      })

      it('returns a match array for valid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/resize/123/foo.jpg" })).toBeDefined()
      })

      it('returns no match array for invalid urls', function() {
        expect(this.handler.isImageProcessUrl({ originalUrl: "/foo/bar/123/foo.jpg" })).toBeFalsy()
      })
    })
  })

  describe('isImageSourceHostAllowed', function() {
    describe('with allowedHosts', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': { 'allowedHosts': [/^.*\.example\.com$/] }
        })
      })

      it('returns true if image source is allowed', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostAllowed(req)).toBeDefined()
      })

      it('returns false if image source is not allowed', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostAllowed(req)).toBeFalsy()
      })
    })

    describe('without allowedHosts', function() {
      it("returns true for every url", function() {
        var req1 = { query: {url: 'http://www.google.com/foo.jpg'} }
          , req2 = { query: {url: 'http://www.example.com/foo.jpg'} }

        expect(this.handler.isImageSourceHostAllowed(req1)).toBeTruthy()
        expect(this.handler.isImageSourceHostAllowed(req2)).toBeTruthy()
      })
    })
  })

  describe('isImageSourceHostTrusted', function() {
    describe('with trustedHosts', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': { 'trustedHosts': [/^.*\.example\.com$/] }
        })
      })

      it('returns true if image source is trusted', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeTruthy()
      })

      it('returns false if image source is not trusted', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeFalsy()
      })
    })

    describe('with trustedHosts as string', function() {
      before(function() {
        this.handler = new RequestHandler({
          'whitelist': {'trustedHosts': ["^.*\.example\.com$"]}
        })
      })

      it('returns true if image source is trusted', function() {
        var req = { query: {url: 'http://www.example.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeTruthy()
      })

      it('returns false if image source is not trusted', function() {
        var req = { query: {url: 'http://www.google.com/foo.jpg'} }
        expect(this.handler.isImageSourceHostTrusted(req)).toBeFalsy()
      })
    })

    describe('without trustedHosts', function() {
      it('returns false for every url', function() {
        var req1 = { query: {url: 'http://www.google.com/foo.jpg'} }
          , req2 = { query: {url: 'http://www.example.com/foo.jpg'} }

        expect(this.handler.isImageSourceHostTrusted(req1)).toBeFalsy()
        expect(this.handler.isImageSourceHostTrusted(req2)).toBeFalsy()
      })
    })
  })

  describe('_isValidHash', function() {
    before(function() {
      this.handler = new RequestHandler({
        secret:       "my-very-secret-secret",
        magicHash:    "magic",
        whitelist: { trustedHosts: [/^.*\.google\.com$/] }
      })
    })

    it('returns true for the magic hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = this.handler.config.magicHash
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns true for the correct hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = this.handler.utils.hash("url=" + imgUrl)
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns false for the incorrect hash', function() {
      var imgUrl = encodeURIComponent("http://www.example.com/intl/en_ALL/images/logo.gif")
        , hash   = "xxx"
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeFalsy()
    })

    it('returns true for trusted hosts', function() {
      var imgUrl = encodeURIComponent("http://www.google.com/intl/en_ALL/images/logo.gif")
        , hash   = "xxx"
        , reqUrl = "http://host.com/resize/" + hash + "/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })

    it('returns true for trusted hosts without hash', function() {
      var imgUrl = encodeURIComponent("http://www.google.com/intl/en_ALL/images/logo.gif")
        , reqUrl = "http://host.com/resize/foo.jpg?url=" + imgUrl
        , parsed = require("url").parse(reqUrl, true)
        , req    = { originalUrl: parsed.pathname + parsed.search, query: parsed.query }

      expect(this.handler._isValidHash(req)).toBeTruthy()
    })
  })

  describe('_afterResize', function() {
    before(function() {
      this.res = {
        send: function() {},
        contentType: function() {},
        sendfile: function(path, options, callback) { callback && callback() }
      }
    })

    it("returns a 500 if an error has occurred", function() {
      var mock = this.mock(this.res).expects('send').withArgs(500).once()

      new RequestHandler()._afterResize(new Error('barfooz'), null, this.res)

      mock.verify()
    })

    it("calls deleteTempfile if the option keepDownloads is false or not defined", function() {
      var handler = new RequestHandler()
        , path    = 'foo'
        , mock    = this.mock(handler).expects('deleteTempfile').withArgs(path).once()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })

    it("doesn't call deleteTempfile if the option keepDownloads is false or not defined", function() {
      var handler = new RequestHandler({ keepDownloads: true })
        , path    = 'foo'
        , mock    = this.mock(handler).expects('deleteTempfile').withArgs(path).never()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })

    it("checks the amount of used hdd space if the option keepDownloads is true and maxDownloadCacheSize is defiend", function() {
      var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })
        , path    = 'foo'
        , mock    = this.mock(handler).expects('checkDownloadCacheSize').once()

      handler._afterResize(null, path, this.res)

      mock.verify()
    })
  })

  describe('checkDownloadCacheSize', function() {
    it("deletes old tempfiles if the amount of used hdd space is greater than the defined maxDownloadCacheSize", function(done) {
      var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })
        , mock    = this.mock(handler).expects('_deleteOldDownloads').once().callsArg(0)

      this.stub(handler, '_getTempFolderSize', function(callback) { callback(1100) })

      handler.checkDownloadCacheSize(done)

      mock.verify()
    })

    it("deletes the files returned by _getOldTempFiles", function(done) {
      var files = ['a.txt', 'b.txt', 'c.txt'].map(function(f) { return __dirname + '/tmp/' + f })

      exec(files.map(function(f) { return 'touch ' + f }).join(";"), function(err) {
        var handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000 })

        this.stub(handler, '_getTempFolderSize', function(callback) { callback(1100) })
        this.stub(handler, '_getOldTempFiles', function(callback) { callback(files) })

        handler.checkDownloadCacheSize(function() {
          exec('ls -ila ' + __dirname + '/tmp', function(err, stdout, stderr) {
            files.forEach(function(f) {
              expect(stdout).not.toMatch(f)
            })

            done()
          })
        })
      }.bind(this))
    })
  })

  describe('_getOldTempFiles', function() {
    before(function() {
      this.handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000, tmpPathRoot: this.tmpPathRoot })
    })

    it('returns one fifth of all available files', function(done) {
      var commands = [
            'mkdir -p ' + this.tmpPathRoot,
            'touch ' + this.tmpPathRoot + '/1.txt',
            'touch ' + this.tmpPathRoot + '/2.txt',
            'touch ' + this.tmpPathRoot + '/3.txt',
            'touch ' + this.tmpPathRoot + '/4.txt',
            'touch ' + this.tmpPathRoot + '/5.txt'
          ]

      exec(commands.join('; sleep 1; '), function() {
        this.handler._getOldTempFiles(function(files) {
          expect(files).toEqual([ this.tmpPathRoot + '/1.txt' ])
          done()
        }.bind(this))
      }.bind(this))
    })
  })

  describe('_getTempFolderSize', function() {
    before(function() {
      this.handler = new RequestHandler({ keepDownloads: true, maxDownloadCacheSize: 1000, tmpPathRoot: this.tmpPathRoot })
    })

    it("returns 0 if the folder is empty", function(done) {
      this.handler._getTempFolderSize(function(size) {
        expect(size).toEqual(0)
        done()
      })
    })

    it("returns 0 if the folder has less than 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/tiny.file bs=1024 count=10 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(0)
          done()
        })
      }.bind(this))
    })

    it("returns 1 if the folder has 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=1024 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(1)
          done()
        })
      }.bind(this))
    })

    it("returns 1 if the folder has slightly more than 1mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=1048 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(1)
          done()
        })
      }.bind(this))
    })

    it("returns 10 if the folder has 10mb of content", function(done) {
      exec('dd if=/dev/zero of=' + this.tmpPathRoot + '/big.file bs=1024 count=10240 conv=notrunc', function() {
        this.handler._getTempFolderSize(function(size) {
          expect(size).toEqual(10)
          done()
        })
      }.bind(this))
    })
  })
})
<|endoftext|>


<commit_before>var app = module.parent.exports.app,
  gc = require("./gcode"),
  fs = require('fs'),
  serialPort = require("serialport"),
  sp = '', gcode=[],
  motorXY = {pasos:2000,avance:46.51},
  motorZ = {pasos:2000,avance:5.23},
  SerialPort = serialPort.SerialPort;

app.io.route('connection', function(req) {});
/* GET listado de puertos. */
app.get('/portslist', function(req, res){
  serialPort.list(function (err, ports){
    if(ports!=undefined && ports.length > 0){
      sp = new SerialPort(ports.slice(-1)[0].comName,{
        parser: serialPort.parsers.readline("\n"),
        dataBits: 8, baudrate:9600, parity: 'none',
        stopBits: 1, flowControl: false
      },false);// para que no abra la conecion al crear
      console.log("Puerto Selecionado %s",ports.slice(-1)[0].comName);
      //req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Arduino conectado por puerto "+ports.slice(-1)[0].comName,pasos:''});
      res.json({'ports':ports,'portSele':ports.slice(-1)[0]});
    }else{
      res.json({'ports':[{manufacturer:"Sin Arduino",comName:''}],'portSele':undefined});
    }

  });
});

/* GET home page. */
app.get('/', function(req, res){
  res.render('index.jade', {titulo: "CNC Mar",motorXY:motorXY});
});

app.post('/conect', function (req, res) {
  console.log("POST -> /conect");
  if(req.body.comUSB!=''){
    sp = new SerialPort(req.body.comUSB,{
      parser: serialPort.parsers.readline("\n"),
      dataBits: 8, baudrate:9600, parity: 'none',
      stopBits: 1, flowControl: false
    },false);// para que no abra la conecion al crear
    console.log("Puerto Selecionado %s",req.body.comUSB);
    req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Arduino conectado por puerto "+req.body.comUSB,pasos:''});
    res.json(true);
   }
});

//app.get('/comando/:code', function (req, res) {
app.post('/comando', function (req, res) {
  //console.log("GET -> /comando, %s",req.params.code);
  console.log("GET -> /comando, tipo: %s, %s",req.body.tipo,req.body.code);
  //req.body.tipo // si es undefined comando directo
  if(req.body.tipo=='pasos'){
    var code = req.body.code.replace('[','').replace(']','').split(',');
    var ejes = [ // para mostrar en mm cuanto avansa
     code[0] * motorXY.avance / motorXY.pasos,
     code[1] * motorXY.avance / motorXY.pasos,
     code[2] * motorZ.avance / motorZ.pasos
    ];
    start( ejes ,req.body.code,code);
  }else if(req.body.tipo=='mm'){
    var code = req.body.code.replace('[','').replace(']','').split(',');
    var pasos = [ // para mostrar cuantos pasos son eso mm
      Math.round(code[0] *(motorXY.pasos/motorXY.avance)),
      Math.round(code[1] *(motorXY.pasos/motorXY.avance)),
      Math.round(code[2] *(motorZ.pasos/motorZ.avance))
      ]
    var pasosString='['+pasos[0]+','+pasos[1]+','+pasos[2]+']'
    start(code,pasosString,pasos);
  }
  if(req.body.tipo==undefined){
    start('',req.body.code,'');
  }
  function start(ejes,code,pasos){
    console.log(ejes);
    sp.open(function(err) {
      sp.drain(function(){});
      sp.write(new Buffer(code+'\n'),function(err) {
        req.io.broadcast('lineaGCode', {nro:'',ejes:ejes,code:"Comando manual: "+code, pasos:pasos});
        sp.on('data',function(data){
          console.log("arduino termino: %s",data?'terminado':'');
          sp.close(function(err) {
            res.json(data);
          });//close
        });//data
      });//write
    });//open
  }
});//post

app.get('/comenzar', function(req, res){
  console.log("GET -> /comenzar")
  function getPasos(l){
    if(l!==0){
      var a = gcode[l-1].ejes
    }else{
      var a = gcode[l].ejes;
    }
    var x=[0,0,0],b = gcode[l].ejes;
    //console.log("B: %s - A: %s = ",b,a);
    x[0] = Math.round((b[0]-a[0])*motorXY.pasos / motorXY.avance);
    x[1] = Math.round((b[1]-a[1])*motorXY.pasos / motorXY.avance);
    x[2] = Math.round((b[2]-a[2])*motorZ.pasos / motorZ.avance);
    return x;
  }
if(sp!=='' && gcode.length>0){
//var i= req.paramslineaInicual!=undefined?req.paramslineaInicual:0;
var i=0;
  sp.open(function(err){
    sp.on('data',function(d){
      i++;
      if(i<gcode.length){
        sp.write(new Buffer(getPasos(i)+'\n'),function(err,results){
          console.log("I: %s - Cordenadas: %s",i,gcode[i].ejes);
          req.io.broadcast('lineaGCode', {nro:i,ejes:gcode[i].ejes,code:gcode[i].code,pasos:getPasos(i)});
        });//write
      }else{
        sp.close(function(err){
          console.log("Terminado.");
          req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:'Terminado.',pasos:''});
        });//close
      }
    });
    sp.drain(function(){});
    sp.write(new Buffer(getPasos(i)+'\n'),function(err,results){
        console.log("I: %s - Cordenadas: %s",i,gcode[i].ejes);
        req.io.broadcast('lineaGCode', {nro:i,ejes:gcode[i].ejes,code:gcode[i].code,pasos:getPasos(i)});
    });//write
  });//open

  res.json(true);
}else{
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Selecione el arduino.",pasos:''});
  res.json(false);
}
});

app.post('/cargar', function (req, res) {
  console.log("POST -> /cargar");
  var tmp_path = req.files.file.path;
  var data = fs.readFileSync(tmp_path);
  var fileContent = data.toString();
  gcode = gc(fileContent);
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Archivo cargado. lineas: "+gcode.length,pasos:''});
  res.json({lineas:gcode.length});
});

app.get('/chart', function(req, res){  res.render('chart.jade', {titulo: "Arduino"});});

app.post('/moverOrigen', function (req, res) {
  sp.write("o\n");
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:req.body.comando,pasos:''});
});
<commit_msg>index.jade dele line console.log<commit_after>var app = module.parent.exports.app,
  gc = require("./gcode"),
  fs = require('fs'),
  serialPort = require("serialport"),
  sp = '', gcode=[],
  motorXY = {pasos:2000,avance:46.51},
  motorZ = {pasos:2000,avance:5.23},
  SerialPort = serialPort.SerialPort;

app.io.route('connection', function(req) {});
/* GET listado de puertos. */
app.get('/portslist', function(req, res){
  serialPort.list(function (err, ports){
    if(ports!=undefined && ports.length > 0){
      sp = new SerialPort(ports.slice(-1)[0].comName,{
        parser: serialPort.parsers.readline("\n"),
        dataBits: 8, baudrate:9600, parity: 'none',
        stopBits: 1, flowControl: false
      },false);// para que no abra la conecion al crear
      console.log("Puerto Selecionado %s",ports.slice(-1)[0].comName);
      //req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Arduino conectado por puerto "+ports.slice(-1)[0].comName,pasos:''});
      res.json({'ports':ports,'portSele':ports.slice(-1)[0]});
    }else{
      res.json({'ports':[{manufacturer:"Sin Arduino",comName:''}],'portSele':undefined});
    }

  });
});

/* GET home page. */
app.get('/', function(req, res){
  res.render('index.jade', {titulo: "CNC Mar",motorXY:motorXY});
});

app.post('/conect', function (req, res) {
  console.log("POST -> /conect");
  if(req.body.comUSB!=''){
    sp = new SerialPort(req.body.comUSB,{
      parser: serialPort.parsers.readline("\n"),
      dataBits: 8, baudrate:9600, parity: 'none',
      stopBits: 1, flowControl: false
    },false);// para que no abra la conecion al crear
    console.log("Puerto Selecionado %s",req.body.comUSB);
    req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Arduino conectado por puerto "+req.body.comUSB,pasos:''});
    res.json(true);
   }
});

//app.get('/comando/:code', function (req, res) {
app.post('/comando', function (req, res) {
  //console.log("GET -> /comando, %s",req.params.code);
  console.log("GET -> /comando, tipo: %s, %s",req.body.tipo,req.body.code);
  //req.body.tipo // si es undefined comando directo
  if(req.body.tipo=='pasos'){
    var code = req.body.code.replace('[','').replace(']','').split(',');
    var ejes = [ // para mostrar en mm cuanto avansa
     code[0] * motorXY.avance / motorXY.pasos,
     code[1] * motorXY.avance / motorXY.pasos,
     code[2] * motorZ.avance / motorZ.pasos
    ];
    start( ejes ,req.body.code,code);
  }else if(req.body.tipo=='mm'){
    var code = req.body.code.replace('[','').replace(']','').split(',');
    var pasos = [ // para mostrar cuantos pasos son eso mm
      Math.round(code[0] *(motorXY.pasos/motorXY.avance)),
      Math.round(code[1] *(motorXY.pasos/motorXY.avance)),
      Math.round(code[2] *(motorZ.pasos/motorZ.avance))
      ]
    var pasosString='['+pasos[0]+','+pasos[1]+','+pasos[2]+']'
    start(code,pasosString,pasos);
  }
  if(req.body.tipo==undefined){
    start('',req.body.code,'');
  }
  function start(ejes,code,pasos){
    sp.open(function(err) {
      sp.drain(function(){});
      sp.write(new Buffer(code+'\n'),function(err) {
        req.io.broadcast('lineaGCode', {nro:'',ejes:ejes,code:"Comando manual: "+code, pasos:pasos});
        sp.on('data',function(data){
          console.log("arduino termino: %s",data?'terminado':'');
          sp.close(function(err) {
            res.json(data);
          });//close
        });//data
      });//write
    });//open
  }
});//post

app.get('/comenzar', function(req, res){
  console.log("GET -> /comenzar")
  function getPasos(l){
    if(l!==0){
      var a = gcode[l-1].ejes
    }else{
      var a = gcode[l].ejes;
    }
    var x=[0,0,0],b = gcode[l].ejes;
    //console.log("B: %s - A: %s = ",b,a);
    x[0] = Math.round((b[0]-a[0])*motorXY.pasos / motorXY.avance);
    x[1] = Math.round((b[1]-a[1])*motorXY.pasos / motorXY.avance);
    x[2] = Math.round((b[2]-a[2])*motorZ.pasos / motorZ.avance);
    return x;
  }
if(sp!=='' && gcode.length>0){
//var i= req.paramslineaInicual!=undefined?req.paramslineaInicual:0;
var i=0;
  sp.open(function(err){
    sp.on('data',function(d){
      i++;
      if(i<gcode.length){
        sp.write(new Buffer(getPasos(i)+'\n'),function(err,results){
          console.log("I: %s - Cordenadas: %s",i,gcode[i].ejes);
          req.io.broadcast('lineaGCode', {nro:i,ejes:gcode[i].ejes,code:gcode[i].code,pasos:getPasos(i)});
        });//write
      }else{
        sp.close(function(err){
          console.log("Terminado.");
          req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:'Terminado.',pasos:''});
        });//close
      }
    });
    sp.drain(function(){});
    sp.write(new Buffer(getPasos(i)+'\n'),function(err,results){
        console.log("I: %s - Cordenadas: %s",i,gcode[i].ejes);
        req.io.broadcast('lineaGCode', {nro:i,ejes:gcode[i].ejes,code:gcode[i].code,pasos:getPasos(i)});
    });//write
  });//open

  res.json(true);
}else{
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Selecione el arduino.",pasos:''});
  res.json(false);
}
});

app.post('/cargar', function (req, res) {
  console.log("POST -> /cargar");
  var tmp_path = req.files.file.path;
  var data = fs.readFileSync(tmp_path);
  var fileContent = data.toString();
  gcode = gc(fileContent);
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:"Archivo cargado. lineas: "+gcode.length,pasos:''});
  res.json({lineas:gcode.length});
});

app.get('/chart', function(req, res){  res.render('chart.jade', {titulo: "Arduino"});});

app.post('/moverOrigen', function (req, res) {
  sp.write("o\n");
  req.io.broadcast('lineaGCode', {nro:'',ejes:'',code:req.body.comando,pasos:''});
});
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');

/* GET home page. */
router.get('/home', function(req, res, next) {
  res.render('index', {
    title: 'Express'
  });
});

var results = [];
router.get('/scrape/:searchParam', function(req, res) {

  urls = ['http://www.amazon.com/s/ref=nb_sb_ss_c_0_9?url=search-alias%3Daps&field-keywords=' + req.params.searchParam,
    'http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1311.R1.TR12.TRC2.A0.H0.Xwact.TRS0&_nkw=' + req.params.searchParam
  ];
  console.log(getData(urls, middleFunc));
  res.json(results);

});

function middleFunc(objs){
  console.log('callback::' + objs);
  results = objs;
  console.log('results callback:: ' + results);
}

function getData(urls, callback){

  for (i = 0; i < urls.length; i++) {
    request(urls[i], function(error, response, html) {
      if (!error) {
        var $ = cheerio.load(html);

        var objs = [];
        var title, price, url;

        $('.s-item-container').each(function(i, element) {
          var data = $(element);

          if (data.find('h2.s-access-title').length > 0)
            title = data.find('h2.s-access-title').text();

          if (data.find('span.a-color-price').length > 0)
            price = data.find('span.a-color-price').eq(0).text();

          if (data.find('a.a-link-normal').length > 0)
            url = data.find('a.a-link-normal').attr('href');

          objs.push({
            'title': title,
            'price': price,
            'url': url
          });

        });

        $('.sresult').each(function(i, element) {
          var data = $(element);

          if (data.find('a.vip').length > 0)
            title = data.find('a.vip').text();

          objs.push({
            'title': title,
            'price': 0,
            'url': 'N/A'
          });

        });

      }
      console.log('results:: ' + objs);
      callback(objs);
    });
  }

  //console.log(result);

  //res.end(objs);

}

module.exports = router;
<commit_msg>Update index.js<commit_after>var express = require('express');
var router = express.Router();
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');

/* GET home page. */
router.get('/home', function(req, res, next) {
  res.render('index', {
    title: 'Express'
  });
});

var results = [];
router.get('/scrape/:searchParam', function(req, res) {

  urls = ['http://www.amazon.com/s/ref=nb_sb_ss_c_0_9?url=search-alias%3Daps&field-keywords=' + req.params.searchParam,
    'http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1311.R1.TR12.TRC2.A0.H0.Xwact.TRS0&_nkw=' + req.params.searchParam
  ];
  results = getData(urls, middleFunc));
  res.json(results);

});

function middleFunc(objs){
  console.log('callback::' + objs);
  return objs;

}

function getData(urls, callback){

  for (i = 0; i < urls.length; i++) {
    request(urls[i], function(error, response, html) {
      if (!error) {
        var $ = cheerio.load(html);

        var objs = [];
        var title, price, url;

        $('.s-item-container').each(function(i, element) {
          var data = $(element);

          if (data.find('h2.s-access-title').length > 0)
            title = data.find('h2.s-access-title').text();

          if (data.find('span.a-color-price').length > 0)
            price = data.find('span.a-color-price').eq(0).text();

          if (data.find('a.a-link-normal').length > 0)
            url = data.find('a.a-link-normal').attr('href');

          objs.push({
            'title': title,
            'price': price,
            'url': url
          });

        });

        $('.sresult').each(function(i, element) {
          var data = $(element);

          if (data.find('a.vip').length > 0)
            title = data.find('a.vip').text();

          objs.push({
            'title': title,
            'price': 0,
            'url': 'N/A'
          });

        });

      }
      console.log('results:: ' + objs);
      callback(objs);
    });
  }

  //console.log(result);

  //res.end(objs);

}

module.exports = router;
<|endoftext|>


<commit_before>var sdf = require("../src/simpleDateFormat.js");

describe("simple date format with default locale", function () {
  /*
   * All the tests below assumes the SimpleDateFormat's default locale is
   * EN_US which means every text in English and the first day of the week
   * is Sunday.
   */

	it("formats era designator", function() {
    var d = new Date();
    expect(new sdf.SimpleDateFormat("G").format(d)).toBe("AD");
  });

  it("formats year", function() {
    var d = new Date(89, 11, 6);
    expect(new sdf.SimpleDateFormat("y").format(d)).toBe("1989");
    expect(new sdf.SimpleDateFormat("yy").format(d)).toBe("89");
    expect(new sdf.SimpleDateFormat("yyy").format(d)).toBe("1989");
    expect(new sdf.SimpleDateFormat("yyyy").format(d)).toBe("1989");
  });

  it("formats week year", function() {
    /*
     * A week year is in sync with a WEEK_OF_YEAR cycle. All weeks between the
     * first and last weeks (inclusive) have the same week year value.
     * Therefore, the first and last days of a week year may have different
     * calendar year values.
     *
     * For example, January 1, 1998 is a Thursday. If getFirstDayOfWeek() is
     * MONDAY and getMinimalDaysInFirstWeek() is 4 (ISO 8601 standard compatible
     * setting), then week 1 of 1998 starts on December 29, 1997, and ends on
     * January 4, 1998. The week year is 1998 for the last three days of
     * calendar year 1997. If, however, getFirstDayOfWeek() is SUNDAY, then week
     * 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998; the
     * first three days of 1998 then are part of week 53 of 1997 and their week
     * year is 1997.
     */

    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("Y").format(d)).toBe("1998");
    expect(new sdf.SimpleDateFormat("YY").format(d)).toBe("98");
    expect(new sdf.SimpleDateFormat("YYY").format(d)).toBe("1998");
    expect(new sdf.SimpleDateFormat("YYYY").format(d)).toBe("1998");
  });

  it("formats month in year (context sensitive)", function() {
    var d = new Date(17, 5, 5);
    expect(new sdf.SimpleDateFormat("M")).toBe("6");
    expect(new sdf.SimpleDateFormat("MM")).toBe("06");
    expect(new sdf.SimpleDateFormat("MMM")).toBe("Jul");
    expect(new sdf.SimpleDateFormat("MMMM")).toBe("July");
  });

  it("formats month in year (standalone form)", function() {
    /*
     * In English there is no difference in standalon and context sensitive
     * forms, however here is a thread that explains a the difference between
     * them:
     * http://stackoverflow.com/questions/32840336/standalone-form-of-month-name-in-java-date-format
     */

    var d = new Date(17, 5, 5);
    expect(new sdf.SimpleDateFormat("L")).toBe("6");
    expect(new sdf.SimpleDateFormat("LL")).toBe("06");
    expect(new sdf.SimpleDateFormat("LLL")).toBe("Jul");
    expect(new sdf.SimpleDateFormat("LLLL")).toBe("July");
  });

  it("formats week in year", function() {
    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("w").format(d)).toBe("1");
    expect(new sdf.SimpleDateFormat("ww").format(d)).toBe("01");
  });

  it("formats week in month", function() {
    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("W").format(d)).toBe("5");
  });

  it("formats day in year", function() {
    var d = new Date(97, 0, 3);
    expect(new sdf.SimpleDateFormat("D").format(d)).toBe("3");
    expect(new sdf.SimpleDateFormat("DD").format(d)).toBe("03");
    expect(new sdf.SimpleDateFormat("DDD").format(d)).toBe("003");
  });

  it("formats day in month", function() {
    var d = new Date(117, 5, 5);
    expect(new sdf.SimpleDateFormat("d")).toBe("5");
    expect(new sdf.SimpleDateFormat("dd")).toBe("05");
  });

  it("formats the day of week in month", function() {
    //it is the second Wendesday in May
    var d = new Date(117, 4, 10);
    expect(new sdf.SimpleDateFormat("F")).toBe("2");
  });

  it("formats the day name in week", function() {
    var d = new Date(117, 4, 10);
    expect(new sdf.SimpleDateFormat("E").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EE").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EEE").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EEEE").format(d)).toBe("Wednesday");
  });

  it("formats the day number in week", function() {
    //first day of the week is always Monday, does not matter which locale you use
    expect(new sdf.SimpleDateFormat("u").format(new Date(117, 4, 8))).toBe("1");
    expect(new sdf.SimpleDateFormat("u").format(new Date(117, 4, 7))).toBe("7");
  });
});
<commit_msg>Add SimpleDateFormat javadoc examples as test.<commit_after>var sdf = require("../src/simpleDateFormat.js");

describe("simple date format with default locale", function () {
  /*
   * All the tests below assumes the SimpleDateFormat's default locale is
   * EN_US which means every text in English and the first day of the week
   * is Sunday.
   */

	it("formats era designator", function() {
    var d = new Date();
    expect(new sdf.SimpleDateFormat("G").format(d)).toBe("AD");
  });

  it("formats year", function() {
    var d = new Date(89, 11, 6);
    expect(new sdf.SimpleDateFormat("y").format(d)).toBe("1989");
    expect(new sdf.SimpleDateFormat("yy").format(d)).toBe("89");
    expect(new sdf.SimpleDateFormat("yyy").format(d)).toBe("1989");
    expect(new sdf.SimpleDateFormat("yyyy").format(d)).toBe("1989");
  });

  it("formats week year", function() {
    /*
     * A week year is in sync with a WEEK_OF_YEAR cycle. All weeks between the
     * first and last weeks (inclusive) have the same week year value.
     * Therefore, the first and last days of a week year may have different
     * calendar year values.
     *
     * For example, January 1, 1998 is a Thursday. If getFirstDayOfWeek() is
     * MONDAY and getMinimalDaysInFirstWeek() is 4 (ISO 8601 standard compatible
     * setting), then week 1 of 1998 starts on December 29, 1997, and ends on
     * January 4, 1998. The week year is 1998 for the last three days of
     * calendar year 1997. If, however, getFirstDayOfWeek() is SUNDAY, then week
     * 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998; the
     * first three days of 1998 then are part of week 53 of 1997 and their week
     * year is 1997.
     */

    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("Y").format(d)).toBe("1998");
    expect(new sdf.SimpleDateFormat("YY").format(d)).toBe("98");
    expect(new sdf.SimpleDateFormat("YYY").format(d)).toBe("1998");
    expect(new sdf.SimpleDateFormat("YYYY").format(d)).toBe("1998");
  });

  it("formats month in year (context sensitive)", function() {
    var d = new Date(17, 5, 5);
    expect(new sdf.SimpleDateFormat("M")).toBe("6");
    expect(new sdf.SimpleDateFormat("MM")).toBe("06");
    expect(new sdf.SimpleDateFormat("MMM")).toBe("Jul");
    expect(new sdf.SimpleDateFormat("MMMM")).toBe("July");
  });

  it("formats month in year (standalone form)", function() {
    /*
     * In English there is no difference in standalon and context sensitive
     * forms, however here is a thread that explains a the difference between
     * them:
     * http://stackoverflow.com/questions/32840336/standalone-form-of-month-name-in-java-date-format
     */

    var d = new Date(17, 5, 5);
    expect(new sdf.SimpleDateFormat("L")).toBe("6");
    expect(new sdf.SimpleDateFormat("LL")).toBe("06");
    expect(new sdf.SimpleDateFormat("LLL")).toBe("Jul");
    expect(new sdf.SimpleDateFormat("LLLL")).toBe("July");
  });

  it("formats week in year", function() {
    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("w").format(d)).toBe("1");
    expect(new sdf.SimpleDateFormat("ww").format(d)).toBe("01");
  });

  it("formats week in month", function() {
    var d = new Date(97, 11, 28);
    expect(new sdf.SimpleDateFormat("W").format(d)).toBe("5");
  });

  it("formats day in year", function() {
    var d = new Date(97, 0, 3);
    expect(new sdf.SimpleDateFormat("D").format(d)).toBe("3");
    expect(new sdf.SimpleDateFormat("DD").format(d)).toBe("03");
    expect(new sdf.SimpleDateFormat("DDD").format(d)).toBe("003");
  });

  it("formats day in month", function() {
    var d = new Date(117, 5, 5);
    expect(new sdf.SimpleDateFormat("d")).toBe("5");
    expect(new sdf.SimpleDateFormat("dd")).toBe("05");
  });

  it("formats the day of week in month", function() {
    //it is the second Wendesday in May
    var d = new Date(117, 4, 10);
    expect(new sdf.SimpleDateFormat("F")).toBe("2");
  });

  it("formats the day name in week", function() {
    var d = new Date(117, 4, 10);
    expect(new sdf.SimpleDateFormat("E").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EE").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EEE").format(d)).toBe("Wed");
    expect(new sdf.SimpleDateFormat("EEEE").format(d)).toBe("Wednesday");
  });

  it("formats the day number in week", function() {
    //first day of the week is always Monday, does not matter which locale you use
    expect(new sdf.SimpleDateFormat("u").format(new Date(117, 4, 8))).toBe("1");
    expect(new sdf.SimpleDateFormat("u").format(new Date(117, 4, 7))).toBe("7");
  });

  it("combines patterns", function() {
    var d = new Date(101, 6, 4, 12, 8, 56);
    //expect(new sdf.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z").format(d)).toBe("2001.07.04 AD at 12:08:56 PDT");
    expect(new sdf.SimpleDateFormat("EEE, MMM d, ''yy").format(d)).toBe("Wed, Jul 4, '01");
    //expect(new sdf.SimpleDateFormat("h:mm a").format(d)).toBe("12:08 PM");
    //expect(new sdf.SimpleDateFormat("hh 'o''clock' a, zzzz").format(d)).toBe("12 o'clock PM, Pacific Daylight Time");
    //expect(new sdf.SimpleDateFormat("K:mm a, z").format(d)).toBe("0:08 PM, PDT");
    //expect(new sdf.SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa").format(d)).toBe("02001.July.04 AD 12:08 PM");
    //expect(new sdf.SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z").format(d)).toBe("Wed, 4 Jul 2001 12:08:56 -0700");
    //expect(new sdf.SimpleDateFormat("yyMMddHHmmssZ").format(d)).toBe("010704120856-0700");
    //expect(new sdf.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(d)).toBe("2001-07-04T12:08:56.235-0700");
    //expect(new sdf.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX").format(d)).toBe("2001-07-04T12:08:56.235-07:00");
    expect(new sdf.SimpleDateFormat("YYYY-'W'ww-u").format(d)).toBe("2001-W27-3");
  });
});
<|endoftext|>