<commit_before>/**
 * Copyright 2015 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Creates an http server to handle static
 * files and list directories for use with the gulp live server
 */
var BBPromise = require('bluebird');
var app = require('express')();
var bacon = require('baconipsum');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var fs = BBPromise.promisifyAll(require('fs'));
var formidable = require('formidable');
var jsdom = require('jsdom');
var path = require('path');
var request = require('request');
var url = require('url');

app.use(bodyParser.json());
app.use(morgan('dev'));

app.use('/pwa', function(req, res, next) {
  var file;
  var contentType;
  if (!req.url || req.url == '/') {
    // pwa.html
    contentType = 'text/html';
    file = '/examples/pwa/pwa.html';
  } else if (req.url == '/pwa.js') {
    // pwa.js
    contentType = 'application/javascript';
    file = '/examples/pwa/pwa.js';
  } else if (req.url == '/pwa-sw.js') {
    // pwa.js
    contentType = 'application/javascript';
    file = '/examples/pwa/pwa-sw.js';
  } else {
    // Redirect to the underlying resource.
    // TODO(dvoytenko): would be nicer to do forward instead of redirect.
    res.writeHead(302, {'Location': req.url});
    res.end();
    return;
  }
  res.statusCode = 200;
  res.setHeader('Content-Type', contentType);
  fs.readFileAsync(process.cwd() + file).then((file) => {
    res.end(file);
  });
});

app.use('/api/show', function(req, res) {
  res.json({
    showNotification: true
  });
});

app.use('/api/dont-show', function(req, res) {
  res.json({
    showNotification: false
  });
});

app.use('/api/echo/post', function(req, res) {
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify(req.body, null, 2));
});

app.use('/form/html/post', function(req, res) {
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields) {
    res.setHeader('Content-Type', 'text/html');
    if (fields['email'] == 'already@subscribed.com') {
      res.statusCode = 500;
      res.end(`

Sorry ${fields['name']}!

The email ${fields['email']} is already subscribed!

      `);
    } else {
      res.end(`

Thanks ${fields['name']}!

Please make sure to confirm your email ${fields['email']}

      `);
    }
  });
});

app.use('/form/echo-json/post', function(req, res) {
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields) {
    res.setHeader('Content-Type', 'application/json');
    if (fields['email'] == 'already@subscribed.com') {
      res.statusCode = 500;
    }
    res.setHeader('AMP-Access-Control-Allow-Source-Origin',
        req.protocol + '://' + req.headers.host);
    res.end(JSON.stringify(fields));
  });
});

app.use('/share-tracking/get-outgoing-fragment', function(req, res) {
  res.setHeader('AMP-Access-Control-Allow-Source-Origin',
      req.protocol + '://' + req.headers.host);
  res.json({
    fragment: '54321'
  });
});

// Fetches an AMP document from the AMP proxy and replaces JS
// URLs, so that they point to localhost.
function proxyToAmpProxy(req, res, minify) {
  var url = 'https://cdn.ampproject.org/c' + req.url;
  var localUrlPrefix = getUrlPrefix(req);
  request(url, function (error, response, body) {
    body = body
        // Unversion URLs.
        .replace(/https\:\/\/cdn\.ampproject\.org\/rtv\/\d+\//g,
            'https://cdn.ampproject.org/')
        // <base> href pointing to the proxy, so that images, etc. still work.
        .replace('', '<base href="https://cdn.ampproject.org/">')
        .replace(/(https:\/\/cdn.ampproject.org\/.+?).js/g, '$1.max.js')
        .replace('https://cdn.ampproject.org/v0.max.js',
            localUrlPrefix + '/dist/amp.js')
        .replace(/https:\/\/cdn.ampproject.org\/v0\//g,
            localUrlPrefix + '/dist/v0/');
    if (minify) {
      body = body.replace(/\.max\.js/g, '.js')
          .replace('/dist/amp.js', '/dist/v0.js');
    }
    res.status(response.statusCode).send(body);
  });
}

var liveListUpdateFile = '/examples/live-list-update.amp.html';
var liveListCtr = 0;
var itemCtr = 2;
var liveListDoc = null;
var doctype = '<!doctype html>\n';
app.use(liveListUpdateFile, function(req, res) {
  if (!liveListDoc) {
    var liveListUpdateFullPath = `${process.cwd()}${liveListUpdateFile}`;
    var liveListFile = fs.readFileSync(liveListUpdateFullPath);
    liveListDoc = jsdom.jsdom(liveListFile);
  }
  var action = Math.floor(Math.random() * 3);
  var liveList = liveListDoc.querySelector('#my-live-list');
  var item1 = liveList.querySelector('#list-item-1');
  res.setHeader('Content-Type', 'text/html');
  res.statusCode = 200;
  if (liveListCtr != 0) {
    if (Math.random() < .8) {
      // Always run a replace on the first item
      liveListReplace(item1);

      if (Math.random() < .5) {
        liveListTombstone(liveList);
      }

      if (Math.random() < .8) {
        liveListInsert(liveList, item1);
      }
    } else {
      // Sometimes we want an empty response to simulate no changes.
      res.end(`${doctype}<html></html>`);
      return;
    }
  }
  var outerHTML = liveListDoc.documentElement./*OK*/outerHTML;
  res.end(`${doctype}${outerHTML}`);
  liveListCtr++;
});

function liveListReplace(item) {
  item.setAttribute('data-update-time', Date.now());
  var itemContents = item.querySelectorAll('.content');
  itemContents[0].textContent = Math.floor(Math.random() * 10);
  itemContents[1].textContent = Math.floor(Math.random() * 10);
}

function liveListInsert(liveList, node) {
  var iterCount = Math.floor(Math.random() * 2) + 1;
  console.log(`inserting ${iterCount} item(s)`);
  for (var i = 0; i < iterCount; i++) {
    var child = node.cloneNode(true);
    child.setAttribute('id', `list-item-${itemCtr++}`);
    child.setAttribute('data-sort-time', Date.now());
    liveList.querySelector('[items]').appendChild(child);
  }
}

function liveListTombstone(liveList) {
  var tombstoneId = Math.floor(Math.random() * itemCtr);
  console.log(`trying to tombstone #list-item-${tombstoneId}`);
  // We can tombstone any list item except item-1 since we always do a
  // replace example on item-1.
  if (tombstoneId != 1) {
    var item = liveList.querySelector(`#list-item-${tombstoneId}`);
    if (item) {
      item.setAttribute('data-tombstone', '');
    }
  }
}

function getLiveBlogItem() {
  var now = Date.now();
  // Value is inclusive of both min and max values.
  function range(min, max) {
    var values = Array.apply(null, Array(max - min + 1)).map((_, i) => min + i);
    return values[Math.round(Math.random() * (max - min))]
  }
  function flip() {
    return !!Math.floor(Math.random() * 2);
  }
  // Generate a 3 to 7 worded headline
  var headline = bacon(range(3, 7));
  var numOfParagraphs = range(1, 2);
  var body = Array.apply(null, Array(numOfParagraphs)).map(x => {
    return `<p>${bacon(range(50, 90))}</p>`;
  }).join('\n');

  var img =  `<amp-img
        src="${flip() ? 'https://placekitten.com/300/350' : 'https://baconmockup.com/300/350'}"
        layout="responsive"
         height="300" width="350">
      </amp-img>`;
  return `<!doctype html>

    <amp-live-list id="live-blog-1">

          ${headline}

              by Lorem Ipsum

              lorem.ipsum@

PublisherName News Reporter

${Date(now).replace(/ GMT.*$/, '')}

${body}

        ${img}

          <amp-social-share type="facebook"
              data-param-text="Hello world"
              data-param-href="https://example.com/?ref=URL"
              data-param-app_id="145634995501895"></amp-social-share>
          <amp-social-share type="twitter"></amp-social-share>

    </amp-live-list>`;
}

app.use('/examples/live-blog(-non-floating-button)?.amp.(min.|max.)?html',
  function(req, res, next) {
    if ('amp_latest_update_time' in req.query) {
      res.setHeader('Content-Type', 'text/html');
      res.end(getLiveBlogItem());
      return;
    }
    next();
});

// Proxy with unminified JS.
// Example:
// http://localhost:8000/max/s/www.washingtonpost.com/amphtml/news/post-politics/wp/2016/02/21/bernie-sanders-says-lower-turnout-contributed-to-his-nevada-loss-to-hillary-clinton/
app.use('/max/', function(req, res) {
  proxyToAmpProxy(req, res, /* minify */ false);
});

// Proxy with minified JS.
// Example:
// http://localhost:8000/min/s/www.washingtonpost.com/amphtml/news/post-politics/wp/2016/02/21/bernie-sanders-says-lower-turnout-contributed-to-his-nevada-loss-to-hillary-clinton/
app.use('/min/', function(req, res) {
  proxyToAmpProxy(req, res, /* minify */ true);
});

app.use('/examples/analytics.config.json', function(req, res, next) {
  res.setHeader('AMP-Access-Control-Allow-Source-Origin', getUrlPrefix(req));
  next();
});

app.use(['/examples/*', '/extensions/*'], function (req, res, next) {
  var sourceOrigin = req.query['__amp_source_origin'];
  if (sourceOrigin) {
    res.setHeader('AMP-Access-Control-Allow-Source-Origin', sourceOrigin);
  }
  next();
});

app.get('/examples/*', function(req, res, next) {
  var filePath = req.path;
  var mode = null;
  if (filePath.substr(-9) == '.max.html') {
    mode = 'max';
  } else if (filePath.substr(-9) == '.min.html') {
    mode = 'min';
  } else {
    return next();
  }
  filePath = filePath.substr(0, filePath.length - 9) + '.html';
  fs.readFileAsync(process.cwd() + filePath, 'utf8').then(file => {
    if (mode) {
      file = file.replace(/(https:\/\/cdn.ampproject.org\/.+?).js/g, '$1.max.js');
      file = file.replace('https://cdn.ampproject.org/v0.max.js', '/dist/amp.js');
      file = file.replace(/https:\/\/cdn.ampproject.org\/v0\//g, '/dist/v0/');
    }
    if (mode == 'min') {
      file = file.replace(/\.max\.js/g, '.js');
      file = file.replace('/dist/amp.js', '/dist/v0.js');
    }
    res.end(file);
  }).catch(() => {
    next();
  });
});

exports.app = app;

function getUrlPrefix(req) {
  return req.protocol + '://' + req.headers.host;
}
<commit_msg>Fix an issue that max.html pages are served without content-type in the headers. (#4481)<commit_after>/**
 * Copyright 2015 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Creates an http server to handle static
 * files and list directories for use with the gulp live server
 */
var BBPromise = require('bluebird');
var app = require('express')();
var bacon = require('baconipsum');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var fs = BBPromise.promisifyAll(require('fs'));
var formidable = require('formidable');
var jsdom = require('jsdom');
var path = require('path');
var request = require('request');
var url = require('url');

app.use(bodyParser.json());
app.use(morgan('dev'));

app.use('/pwa', function(req, res, next) {
  var file;
  var contentType;
  if (!req.url || req.url == '/') {
    // pwa.html
    contentType = 'text/html';
    file = '/examples/pwa/pwa.html';
  } else if (req.url == '/pwa.js') {
    // pwa.js
    contentType = 'application/javascript';
    file = '/examples/pwa/pwa.js';
  } else if (req.url == '/pwa-sw.js') {
    // pwa.js
    contentType = 'application/javascript';
    file = '/examples/pwa/pwa-sw.js';
  } else {
    // Redirect to the underlying resource.
    // TODO(dvoytenko): would be nicer to do forward instead of redirect.
    res.writeHead(302, {'Location': req.url});
    res.end();
    return;
  }
  res.statusCode = 200;
  res.setHeader('Content-Type', contentType);
  fs.readFileAsync(process.cwd() + file).then((file) => {
    res.end(file);
  });
});

app.use('/api/show', function(req, res) {
  res.json({
    showNotification: true
  });
});

app.use('/api/dont-show', function(req, res) {
  res.json({
    showNotification: false
  });
});

app.use('/api/echo/post', function(req, res) {
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify(req.body, null, 2));
});

app.use('/form/html/post', function(req, res) {
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields) {
    res.setHeader('Content-Type', 'text/html');
    if (fields['email'] == 'already@subscribed.com') {
      res.statusCode = 500;
      res.end(`

Sorry ${fields['name']}!

The email ${fields['email']} is already subscribed!

      `);
    } else {
      res.end(`

Thanks ${fields['name']}!

Please make sure to confirm your email ${fields['email']}

      `);
    }
  });
});

app.use('/form/echo-json/post', function(req, res) {
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields) {
    res.setHeader('Content-Type', 'application/json');
    if (fields['email'] == 'already@subscribed.com') {
      res.statusCode = 500;
    }
    res.setHeader('AMP-Access-Control-Allow-Source-Origin',
        req.protocol + '://' + req.headers.host);
    res.end(JSON.stringify(fields));
  });
});

app.use('/share-tracking/get-outgoing-fragment', function(req, res) {
  res.setHeader('AMP-Access-Control-Allow-Source-Origin',
      req.protocol + '://' + req.headers.host);
  res.json({
    fragment: '54321'
  });
});

// Fetches an AMP document from the AMP proxy and replaces JS
// URLs, so that they point to localhost.
function proxyToAmpProxy(req, res, minify) {
  var url = 'https://cdn.ampproject.org/c' + req.url;
  var localUrlPrefix = getUrlPrefix(req);
  request(url, function (error, response, body) {
    body = body
        // Unversion URLs.
        .replace(/https\:\/\/cdn\.ampproject\.org\/rtv\/\d+\//g,
            'https://cdn.ampproject.org/')
        // <base> href pointing to the proxy, so that images, etc. still work.
        .replace('', '<base href="https://cdn.ampproject.org/">')
        .replace(/(https:\/\/cdn.ampproject.org\/.+?).js/g, '$1.max.js')
        .replace('https://cdn.ampproject.org/v0.max.js',
            localUrlPrefix + '/dist/amp.js')
        .replace(/https:\/\/cdn.ampproject.org\/v0\//g,
            localUrlPrefix + '/dist/v0/');
    if (minify) {
      body = body.replace(/\.max\.js/g, '.js')
          .replace('/dist/amp.js', '/dist/v0.js');
    }
    res.status(response.statusCode).send(body);
  });
}

var liveListUpdateFile = '/examples/live-list-update.amp.html';
var liveListCtr = 0;
var itemCtr = 2;
var liveListDoc = null;
var doctype = '<!doctype html>\n';
app.use(liveListUpdateFile, function(req, res) {
  if (!liveListDoc) {
    var liveListUpdateFullPath = `${process.cwd()}${liveListUpdateFile}`;
    var liveListFile = fs.readFileSync(liveListUpdateFullPath);
    liveListDoc = jsdom.jsdom(liveListFile);
  }
  var action = Math.floor(Math.random() * 3);
  var liveList = liveListDoc.querySelector('#my-live-list');
  var item1 = liveList.querySelector('#list-item-1');
  res.setHeader('Content-Type', 'text/html');
  res.statusCode = 200;
  if (liveListCtr != 0) {
    if (Math.random() < .8) {
      // Always run a replace on the first item
      liveListReplace(item1);

      if (Math.random() < .5) {
        liveListTombstone(liveList);
      }

      if (Math.random() < .8) {
        liveListInsert(liveList, item1);
      }
    } else {
      // Sometimes we want an empty response to simulate no changes.
      res.end(`${doctype}<html></html>`);
      return;
    }
  }
  var outerHTML = liveListDoc.documentElement./*OK*/outerHTML;
  res.end(`${doctype}${outerHTML}`);
  liveListCtr++;
});

function liveListReplace(item) {
  item.setAttribute('data-update-time', Date.now());
  var itemContents = item.querySelectorAll('.content');
  itemContents[0].textContent = Math.floor(Math.random() * 10);
  itemContents[1].textContent = Math.floor(Math.random() * 10);
}

function liveListInsert(liveList, node) {
  var iterCount = Math.floor(Math.random() * 2) + 1;
  console.log(`inserting ${iterCount} item(s)`);
  for (var i = 0; i < iterCount; i++) {
    var child = node.cloneNode(true);
    child.setAttribute('id', `list-item-${itemCtr++}`);
    child.setAttribute('data-sort-time', Date.now());
    liveList.querySelector('[items]').appendChild(child);
  }
}

function liveListTombstone(liveList) {
  var tombstoneId = Math.floor(Math.random() * itemCtr);
  console.log(`trying to tombstone #list-item-${tombstoneId}`);
  // We can tombstone any list item except item-1 since we always do a
  // replace example on item-1.
  if (tombstoneId != 1) {
    var item = liveList.querySelector(`#list-item-${tombstoneId}`);
    if (item) {
      item.setAttribute('data-tombstone', '');
    }
  }
}

function getLiveBlogItem() {
  var now = Date.now();
  // Value is inclusive of both min and max values.
  function range(min, max) {
    var values = Array.apply(null, Array(max - min + 1)).map((_, i) => min + i);
    return values[Math.round(Math.random() * (max - min))]
  }
  function flip() {
    return !!Math.floor(Math.random() * 2);
  }
  // Generate a 3 to 7 worded headline
  var headline = bacon(range(3, 7));
  var numOfParagraphs = range(1, 2);
  var body = Array.apply(null, Array(numOfParagraphs)).map(x => {
    return `<p>${bacon(range(50, 90))}</p>`;
  }).join('\n');

  var img =  `<amp-img
        src="${flip() ? 'https://placekitten.com/300/350' : 'https://baconmockup.com/300/350'}"
        layout="responsive"
         height="300" width="350">
      </amp-img>`;
  return `<!doctype html>

    <amp-live-list id="live-blog-1">

          ${headline}

              by Lorem Ipsum

              lorem.ipsum@

PublisherName News Reporter

${Date(now).replace(/ GMT.*$/, '')}

${body}

        ${img}

          <amp-social-share type="facebook"
              data-param-text="Hello world"
              data-param-href="https://example.com/?ref=URL"
              data-param-app_id="145634995501895"></amp-social-share>
          <amp-social-share type="twitter"></amp-social-share>

    </amp-live-list>`;
}

app.use('/examples/live-blog(-non-floating-button)?.amp.(min.|max.)?html',
  function(req, res, next) {
    if ('amp_latest_update_time' in req.query) {
      res.setHeader('Content-Type', 'text/html');
      res.end(getLiveBlogItem());
      return;
    }
    next();
});

// Proxy with unminified JS.
// Example:
// http://localhost:8000/max/s/www.washingtonpost.com/amphtml/news/post-politics/wp/2016/02/21/bernie-sanders-says-lower-turnout-contributed-to-his-nevada-loss-to-hillary-clinton/
app.use('/max/', function(req, res) {
  proxyToAmpProxy(req, res, /* minify */ false);
});

// Proxy with minified JS.
// Example:
// http://localhost:8000/min/s/www.washingtonpost.com/amphtml/news/post-politics/wp/2016/02/21/bernie-sanders-says-lower-turnout-contributed-to-his-nevada-loss-to-hillary-clinton/
app.use('/min/', function(req, res) {
  proxyToAmpProxy(req, res, /* minify */ true);
});

app.use('/examples/analytics.config.json', function(req, res, next) {
  res.setHeader('AMP-Access-Control-Allow-Source-Origin', getUrlPrefix(req));
  next();
});

app.use(['/examples/*', '/extensions/*'], function (req, res, next) {
  var sourceOrigin = req.query['__amp_source_origin'];
  if (sourceOrigin) {
    res.setHeader('AMP-Access-Control-Allow-Source-Origin', sourceOrigin);
  }
  next();
});

app.get('/examples/*', function(req, res, next) {
  var filePath = req.path;
  var mode = null;
  if (filePath.substr(-9) == '.max.html') {
    mode = 'max';
  } else if (filePath.substr(-9) == '.min.html') {
    mode = 'min';
  } else {
    return next();
  }
  filePath = filePath.substr(0, filePath.length - 9) + '.html';
  fs.readFileAsync(process.cwd() + filePath, 'utf8').then(file => {
    if (mode) {
      file = file.replace(/(https:\/\/cdn.ampproject.org\/.+?).js/g, '$1.max.js');
      file = file.replace('https://cdn.ampproject.org/v0.max.js', '/dist/amp.js');
      file = file.replace(/https:\/\/cdn.ampproject.org\/v0\//g, '/dist/v0/');
    }
    if (mode == 'min') {
      file = file.replace(/\.max\.js/g, '.js');
      file = file.replace('/dist/amp.js', '/dist/v0.js');
    }
    res.send(file);
  }).catch(() => {
    next();
  });
});

exports.app = app;

function getUrlPrefix(req) {
  return req.protocol + '://' + req.headers.host;
}
<|endoftext|>


<commit_before>"use strict";

var bodyParser = require('body-parser');
var express = require('express');
var helmet = require('helmet');
var https = require('https');
var Mailgun = require('mailgun-js');
var mustacheExpress = require('mustache-express');
var querystring = require('querystring');

var mailgun_api_key = process.env.MAILGUN_API_KEY || 'key';
var mailgun_domain = process.env.MAILGUN_DOMAIN || 'domain';
var mailgun = new Mailgun({apiKey: mailgun_api_key, domain: mailgun_domain});

var gCaptchaSecret = process.env.GOOGLE_RECAPTCHA_SECRET || 'secret';

var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(helmet());
app.engine('html', mustacheExpress());
app.set('view engine', 'html');
app.set('views', 'client');

/**
 * Verify the google recaptcha response with google
 * @param key Value of g-recaptcha-response
 * @param ip End user IP
 * @param callback Callback function to send the success
 */
function verifyRecaptcha(key, ip, callback) {
  var postData = querystring.stringify({
    secret: gCaptchaSecret,
    response: key,
    remoteip: ip
  });
  var postOptions = {
    host: 'google.com',
    port: '443',
    path: '/recaptcha/api/siteverify',
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': Buffer.byteLength(postData)
    }
  };
  // Set up the request
  var post_req = https.request(postOptions, function(res) {
    var data = '';
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      data += chunk.toString();
    });
    res.on('end', function () {
      try {
        var parsedData = JSON.parse(data);
        callback(parsedData.success);
      } catch (e) {
        callback(false);
      }
    });
  });
  // post the data
  post_req.write(postData);
  post_req.end();
}

/**
 * Serve the index on root GET
 */
app.get('/', function (req, res) {
  res.render('index', {
    contactForm: true
  });
});

/**
 * Submit some mail on root POST if captcha is filled out properly
 */
app.post('/', function (req, res) {
  var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  var fromName = req.body.name || 'No Name';
  var fromEmail = req.body.email || 'noreply@pangspro.com';
  var fromMessage = req.body.message || 'No message';
  var gCaptchaResponse = req.body['g-recaptcha-response'] || 'no_response';

  verifyRecaptcha(gCaptchaResponse, ip, function (success) {
    if (success) {
      var fromField = fromName + ' <' + fromEmail + '>';
      var toField = 'Pangs Pro <pangspro@outlook.com>';
      var bccField = 'Alexander Wong <admin@alexander-wong.com>';
      var subject = 'Pangs Pro Contact Form';

      var data = {
        from: fromField,
        to: bccField,
        //bcc: bccField,
        subject: subject,
        text: fromMessage,
        html: fromMessage
      };

      mailgun.messages().send(data, function (err, body) {
        //If there is an error, render the error page
        if (err) {
          res.render('index', {
            contactForm: false,
            contactMessage: 'Message could not be sent. Please contact using email or telephone?'
          });
        }
        else {
          res.render('index', {
            contactForm: false,
            contactMessage: 'Message has been sent successfully! Thank you!'
          });
        }
      });
    } else {
      res.render('index', {
        contactForm: true,
        contactName: fromName,
        contactEmail: fromEmail,
        contactBodyMessage: fromMessage,
        contactMessage: 'Message could not be sent. (ReCaptcha Verification Failed) ' +
        'Please verify the reCaptcha.'
      })
    }
  });
});

// serve all static files inside the client directory
app.use(express.static('client'));

// health probe check for OpenShift
app.get('/health', function (req, res) {
  res.send('1');
});

app.listen(process.env.NODE_PORT || 3000, process.env.NODE_IP || 'localhost', function () {
  console.log(`Application worker ${process.pid} started...`);
});
<commit_msg>Reverted client email back<commit_after>"use strict";

var bodyParser = require('body-parser');
var express = require('express');
var helmet = require('helmet');
var https = require('https');
var Mailgun = require('mailgun-js');
var mustacheExpress = require('mustache-express');
var querystring = require('querystring');

var mailgun_api_key = process.env.MAILGUN_API_KEY || 'key';
var mailgun_domain = process.env.MAILGUN_DOMAIN || 'domain';
var mailgun = new Mailgun({apiKey: mailgun_api_key, domain: mailgun_domain});

var gCaptchaSecret = process.env.GOOGLE_RECAPTCHA_SECRET || 'secret';

var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(helmet());
app.engine('html', mustacheExpress());
app.set('view engine', 'html');
app.set('views', 'client');

/**
 * Verify the google recaptcha response with google
 * @param key Value of g-recaptcha-response
 * @param ip End user IP
 * @param callback Callback function to send the success
 */
function verifyRecaptcha(key, ip, callback) {
  var postData = querystring.stringify({
    secret: gCaptchaSecret,
    response: key,
    remoteip: ip
  });
  var postOptions = {
    host: 'google.com',
    port: '443',
    path: '/recaptcha/api/siteverify',
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': Buffer.byteLength(postData)
    }
  };
  // Set up the request
  var post_req = https.request(postOptions, function(res) {
    var data = '';
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      data += chunk.toString();
    });
    res.on('end', function () {
      try {
        var parsedData = JSON.parse(data);
        callback(parsedData.success);
      } catch (e) {
        callback(false);
      }
    });
  });
  // post the data
  post_req.write(postData);
  post_req.end();
}

/**
 * Serve the index on root GET
 */
app.get('/', function (req, res) {
  res.render('index', {
    contactForm: true
  });
});

/**
 * Submit some mail on root POST if captcha is filled out properly
 */
app.post('/', function (req, res) {
  var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  var fromName = req.body.name || 'No Name';
  var fromEmail = req.body.email || 'noreply@pangspro.com';
  var fromMessage = req.body.message || 'No message';
  var gCaptchaResponse = req.body['g-recaptcha-response'] || 'no_response';

  verifyRecaptcha(gCaptchaResponse, ip, function (success) {
    if (success) {
      var fromField = fromName + ' <' + fromEmail + '>';
      var toField = 'Pangs Pro <pangspro@outlook.com>';
      // var bccField = 'Alexander Wong <admin@alexander-wong.com>';
      var subject = 'Pangs Pro Contact Form';

      var data = {
        from: fromField,
        to: toField,
        // bcc: bccField,
        subject: subject,
        text: fromMessage,
        html: fromMessage
      };

      mailgun.messages().send(data, function (err, body) {
        //If there is an error, render the error page
        if (err) {
          res.render('index', {
            contactForm: false,
            contactMessage: 'Message could not be sent. Please contact using email or telephone?'
          });
        }
        else {
          res.render('index', {
            contactForm: false,
            contactMessage: 'Message has been sent successfully! Thank you!'
          });
        }
      });
    } else {
      res.render('index', {
        contactForm: true,
        contactName: fromName,
        contactEmail: fromEmail,
        contactBodyMessage: fromMessage,
        contactMessage: 'Message could not be sent. (ReCaptcha Verification Failed) ' +
        'Please verify the reCaptcha.'
      })
    }
  });
});

// serve all static files inside the client directory
app.use(express.static('client'));

// health probe check for OpenShift
app.get('/health', function (req, res) {
  res.send('1');
});

app.listen(process.env.NODE_PORT || 3000, process.env.NODE_IP || 'localhost', function () {
  console.log(`Application worker ${process.pid} started...`);
});
<|endoftext|>


<commit_before>const monthNames = ["January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"];

const weekDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

function outputTextForSale(saleInfo) {
    "use strict";
    const displayDateTime = new Date(saleInfo.displayDateTime.replace("T", " "));
    let dateI = "";

    if (displayDateTime < new Date()) {
        dateI = "NOW";
    } else {
        dateI = monthNames[displayDateTime.getMonth()].substring(0, 3).toUpperCase() + " " + displayDateTime.getDate();
    }
    return dateI + " - SEPT 6";
}

function outputTextForEvent(eventInfo) {
    "use strict";
    const startDateTime = new Date(eventInfo.startDateTime.replace("T", " "));

    return weekDays[startDateTime.getDay()].substring(0, 4).toUpperCase() + ", " + monthNames[startDateTime.getMonth()].substring(0, 3).toUpperCase() + " " + startDateTime.getDate();
}

function saleOrEventText(eventInfo) {
    "use strict";
    //const displayDateTime = new Date(eventInfo.displayDateTime.replace("T", " "));
    const startDateTime = new Date(eventInfo.startDateTime.replace("T", " "));
    const endDateTime = new Date(eventInfo.endDateTime.replace("T", " "));

    if (startDateTime.getTime() === endDateTime.getTime()) {
        return outputTextForEvent(eventInfo);
    } else {
        return outputTextForSale(eventInfo);
    }
}

// --- USAGE ---
// in html use something like:
//

// document.getElementById("eventDate").innerHTML = saleOrEventText(eventInfo);

// --- TESTS ---
//displayDateTime in the past
let event1Info = {
    "title": "Labor Day Sale",
    "displayDateTime": "2016-08-29T00:00",
    "startDateTime": "2016-08-31T00:00",
    "endDateTime": "2016-09-06T23:59"
};

//displayDateTime in the future
let event2Info = {
    "title": "X Day Sale",
    "displayDateTime": "2016-10-29T00:00",
    "startDateTime": "2016-08-31T00:00",
    "endDateTime": "2016-09-06T23:59"
};

//startDate and endDate are the same
let event3Info = {
    "title": "Party Day",
    "displayDateTime": "2016-10-29T00:00",
    "startDateTime": "2016-10-29T00:00",
    "endDateTime": "2016-10-29T00:00"
};

console.log(saleOrEventText(event1Info));

console.log(saleOrEventText(event2Info));

console.log(saleOrEventText(event3Info));
<commit_msg>Delete saleinfo.js<commit_after><|endoftext|>


<commit_before>/* eslint-disable */
const isDeveloping = process.env.NODE_ENV !== 'production';
const port = isDeveloping ? 1338 : process.env.PORT;
const path = require('path');
const express = require('express');
const app = express();

import React from 'react';
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import { ApolloProvider } from 'react-apollo';
import { getDataFromTree } from 'react-apollo/server';
import store from '../app/src/store.js';
import { routes } from '../app/src/routes.js';
import { createNetworkInterface } from 'apollo-client';
import Html from './utils/Html';
import createApolloClient from './utils/create-apollo-client';

const baseUrl = typeof process.env.BASE_URL !== 'undefined' ?
  process.env.BASE_URL : 'https://udacity-api.herokuapp.com/';
const apiUrl = `${baseUrl}graphql`;

app.use(express.static(__dirname + '/public'));

app.use((req, res) => {
  match({ routes, location: req.url },
    (error, redirectLocation, renderProps) => {
      if (redirectLocation) {
        res.redirect(redirectLocation.pathname + redirectLocation.search);
      } else if (error) {
        console.error('ROUTER ERROR:', error); // eslint-disable-line no-console
        res.status(500);
      } else if (renderProps) {
        const client = createApolloClient({
          ssrMode: true,
          networkInterface: createNetworkInterface({
            uri: apiUrl,
            credentials: 'same-origin',
            headers: req.headers,
          }),
        });

        const component = (
          <ApolloProvider client={client} store={store}>
            <RouterContext {...renderProps} />
          </ApolloProvider>
        );

        getDataFromTree(component).then((context) => {
          const content = renderToString(component);
          res.status(200);

          const html = (
            <Html
              content={content}
              scriptHash="d4264a9e03bc33000750"
              cssHash="00c9b6f42492b47b5aa808537955abf9"
              state={{ data: context.store.getState().apollo.data }}
            />
          );
          res.send(`<!doctype html>\n${renderToStaticMarkup(html)}`);
          res.end();
        }).catch(e => console.error('RENDERING ERROR:', e)); // eslint-disable-line no-console
      } else {
        res.status(404).send('Not found');
      }
    })
});

app.listen(port, '0.0.0.0', (err) => {
  if (err) {
    return console.warn(err);
  }
  return console.info(`==> 😎 Listening on port ${port}. Open http://0.0.0.0:${port}/ in your browser.`);
});
/* eslint-enable */
<commit_msg>Fix: add express static from current directory of process<commit_after>/* eslint-disable */
const isDeveloping = process.env.NODE_ENV !== 'production';
const port = isDeveloping ? 1338 : process.env.PORT;
const path = require('path');
const express = require('express');
const app = express();

import React from 'react';
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import { ApolloProvider } from 'react-apollo';
import { getDataFromTree } from 'react-apollo/server';
import store from '../app/src/store.js';
import { routes } from '../app/src/routes.js';
import { createNetworkInterface } from 'apollo-client';
import Html from './utils/Html';
import createApolloClient from './utils/create-apollo-client';

const baseUrl = typeof process.env.BASE_URL !== 'undefined' ?
  process.env.BASE_URL : 'https://udacity-api.herokuapp.com/';
const apiUrl = `${baseUrl}graphql`;

app.use(express.static(path.join(process.cwd(), 'public')));

app.use((req, res) => {
  match({ routes, location: req.url },
    (error, redirectLocation, renderProps) => {
      if (redirectLocation) {
        res.redirect(redirectLocation.pathname + redirectLocation.search);
      } else if (error) {
        console.error('ROUTER ERROR:', error); // eslint-disable-line no-console
        res.status(500);
      } else if (renderProps) {
        const client = createApolloClient({
          ssrMode: true,
          networkInterface: createNetworkInterface({
            uri: apiUrl,
            credentials: 'same-origin',
            headers: req.headers,
          }),
        });

        const component = (
          <ApolloProvider client={client} store={store}>
            <RouterContext {...renderProps} />
          </ApolloProvider>
        );

        getDataFromTree(component).then((context) => {
          const content = renderToString(component);
          res.status(200);

          const html = (
            <Html
              content={content}
              scriptHash="d4264a9e03bc33000750"
              cssHash="00c9b6f42492b47b5aa808537955abf9"
              state={{ data: context.store.getState().apollo.data }}
            />
          );
          res.send(`<!doctype html>\n${renderToStaticMarkup(html)}`);
          res.end();
        }).catch(e => console.error('RENDERING ERROR:', e)); // eslint-disable-line no-console
      } else {
        res.status(404).send('Not found');
      }
    })
});

app.listen(port, '0.0.0.0', (err) => {
  if (err) {
    return console.warn(err);
  }
  return console.info(`==> 😎 Listening on port ${port}. Open http://0.0.0.0:${port}/ in your browser.`);
});
/* eslint-enable */
<|endoftext|>


<commit_before>/**
 * Created by paul on 3/1/15.
 */
var express = require('express');

var app = express();

var samples = require('./samples');

app.use('/samples', samples);
app.use(express.static('./'));

var server = app.listen(3000, function () {

    var host = server.address().address
    var port = server.address().port

    console.log('Example app listening at http://%s:%s', host, port)

});<commit_msg>Changed port number.<commit_after>/**
 * Created by paul on 3/1/15.
 */
var express = require('express');

var app = express();

var samples = require('./samples');

app.use('/samples', samples);
app.use(express.static('./'));

var server = app.listen(8081, function () {

    var host = server.address().address
    var port = server.address().port

    console.log('Example app listening at http://%s:%s', host, port)

});<|endoftext|>


<commit_before>'use strict';

//module import and init.
var express = require('express');
var parser = require('body-parser');
var sqlite3 = require('sqlite3').verbose();

//database init (create if it does not exist)
var db = new sqlite3.Database('events.db');
db.run("CREATE TABLE IF NOT EXISTS events (time TEXT, remote_ip TEXT, host_ip TEXT, remote_port TEXT, service TEXT, type TEXT, host_longitude INTEGER, host_latitude INTEGER, remote_longitude INTEGER, remote_latitude INTEGER, remote_country_name TEXT, remote_city TEXT, username TEXT, password TEXT, description TEXT)");

// server and middleware for both
// url-encoded and json POST decoding
var server = express();

server.use(parser.urlencoded({'extended': false}));
server.use(parser.json());

//basic root
server.get('/', function(req, res) {

	res.status(200);
	res.set({
		'Content-type': 'text/plain'
	});

	res.send('welcome to the events server');
});

//POST events for storage
server.post('/event', function(req, res) {

	res.status(200);
	res.set({
		'Content-Type': 'text/plain'
	});

	db.serialize(function() {
		var stmt = db.prepare(`INSERT INTO events (time, remote_ip, host_ip, remote_port,
						      service, type, host_longitude, host_latitude, remote_longitude,
						      remote_latitude, remote_country_name, remote_city, username, password,
						      description)
						      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
		stmt.run(req.body.time, req.body.remote_ip, req.body.host_ip,
				 req.body.remote_port, req.body.service, req.body.type,
				 req.body.host_longitude, req.body.host_latitude, req.body.remote_longitude,
				 req.body.remote_latitude, req.body.remote_country_name, req.body.remote_city,
				 req.body.username, req.body.password, req.body.description, req.body);
		stmt.finalize();
	}); //end insert

	console.log("Here is the body we recieved: ");
	console.log(req.body);

	//console.log(req.body.remote_ip);
	res.send('Thank you');

});

//app kick off!
server.listen(8080);
<commit_msg>add GET events route<commit_after>'use strict';

//module import and init.
var express = require('express');
var parser = require('body-parser');
var sqlite3 = require('sqlite3').verbose();

//database init (create if it does not exist)
var db = new sqlite3.Database('events.db');
db.run("CREATE TABLE IF NOT EXISTS events (time TEXT, remote_ip TEXT, host_ip TEXT, remote_port TEXT, service TEXT, type TEXT, host_longitude INTEGER, host_latitude INTEGER, remote_longitude INTEGER, remote_latitude INTEGER, remote_country_name TEXT, remote_city TEXT, username TEXT, password TEXT, description TEXT)");

var server = express();

// server and middleware for both url-encoded and json POST decoding
// and serving static content
server.use(parser.urlencoded({'extended': false}));
server.use(parser.json());
server.use('/', express.static(__dirname + '/static/'));

//basic root
server.get('/', function(req, res) {

	res.status(200);
	res.set({
		'Content-type': 'text/plain'
	});

	res.send('welcome to the events server');
});

//POST events for storage
//this could use some work on error checking
server.post('/event', function(req, res) {

	res.status(200);
	res.set({
		'Content-Type': 'text/plain'
	});

	db.serialize(function() {
		var stmt = db.prepare(`INSERT INTO events (time, remote_ip, host_ip, remote_port,
						       service, type, host_longitude, host_latitude, remote_longitude,
						       remote_latitude, remote_country_name, remote_city, username, password,
						       description)
						       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
		stmt.run(req.body.time, req.body.remote_ip, req.body.host_ip,
				 req.body.remote_port, req.body.service, req.body.type,
				 req.body.host_longitude, req.body.host_latitude, req.body.remote_longitude,
				 req.body.remote_latitude, req.body.remote_country_name, req.body.remote_city,
				 req.body.username, req.body.password, req.body.description, req.body);
		stmt.finalize();
	}); //end insert

	res.send('ok');
});

//GET events from storage
server.get('/events', function(req, res) {

	res.set({
		'Content-Type': 'application/json'
	});

	db.all('SELECT * FROM events', function(err, rows){
		if(err){
			res.status(500);
			res.send({
				"error": JSON.stringify(err),
				"events": []
			});
		}
		else {
			var events = [];
			rows.forEach(function(row, index, arr){
				events.push(JSON.stringify(row));
			});
			res.status(200);
			res.send({
				"error": null,
				"events": events
			});
		}
	});
});

//app kick off!
server.listen(8080);
<|endoftext|>


<commit_before>//schedule.js
var http = require('http');
var cheerio = require('cheerio');
var config = require('./configuration');

//Wrapper function that is being called by express.
function schedule(req, res, next) {
  get(req.match.url, function (json) {
    req.match.json = json;
    next();
  });
}

//Function for getting the page via http.
function get(url, callback) {
  http.get(url, function (res) {
    var _download = '';

    res.on('data', function (data) {
      _download += data;
    });

    res.on('end', function () {
      callback(to_json(_download));
    });
  });
}

//Function for converting the page into a json dataset.
function to_json(page) {
  var result = cheerio('td:nth-child(3) table', page);
  var amount_of_days = cheerio(result).find('tr.AccentDark').find('td').length - 1;
  var amount_of_hours = config().amount_of_hours;

  var schedule_data = [];

  //Looping for amount of days
  for (day = 0; day < amount_of_days; day++) {
    schedule_data[day] = [];

    //Looping for amount of hours
    for (hour = 0; hour < amount_of_hours; hour++) {
      var schedule = cheerio('tr:nth-child('+ (6 + hour) +')', result);

      //Looping for (optional) specialhours
      var amount_of_special_hours = schedule.find('table').eq(day).children().length;
      for (special_hour = 0; special_hour < amount_of_special_hours; special_hour++) {
        schedule_data[day][hour] = {teacher: [], chamber: [], course: [], changed: []};
        var selected_hour = schedule.find('table').eq(day).find('tr').eq(special_hour).find('td');

        schedule_data[day][hour].teacher[special_hour] = selected_hour.eq(0).html();
        schedule_data[day][hour].chamber[special_hour] = selected_hour.eq(2).html();
        schedule_data[day][hour].course[special_hour] = selected_hour.eq(4).html();

        schedule_data[day][hour].changed[special_hour] = selected_hour.eq(0).attr().class == 'tableCellNew' ? true : false;
      }
    }
  }

  return schedule_data;
}

//Exporting the schedule function.
module.exports = schedule;
<commit_msg>Fixed a bug where there would only one 'special_hour' would register.<commit_after>//schedule.js
var http = require('http');
var cheerio = require('cheerio');
var config = require('./configuration');

//Wrapper function that is being called by express.
function schedule(req, res, next) {
  get(req.match.url, function (json) {
    req.match.json = json;
    next();
  });
}

//Function for getting the page via http.
function get(url, callback) {
  http.get(url, function (res) {
    var _download = '';

    res.on('data', function (data) {
      _download += data;
    });

    res.on('end', function () {
      callback(to_json(_download));
    });
  });
}

//Function for converting the page into a json dataset.
function to_json(page) {
  var result = cheerio('td:nth-child(3) table', page);
  var amount_of_days = cheerio(result).find('tr.AccentDark').find('td').length - 1;
  var amount_of_hours = config().amount_of_hours;

  var schedule_data = [];

  //Looping for amount of days
  for (day = 0; day < amount_of_days; day++) {
     schedule_data[day] = [];

    //Looping for amount of hours
    for (hour = 0; hour < amount_of_hours; hour++) {
      var schedule = cheerio('tr:nth-child('+ (6 + hour) +')', result);

      //Looping for (optional) specialhours
      var amount_of_special_hours = schedule.find('table').eq(day).children().length;
      schedule_data[day][hour] = {teacher: [], chamber: [], course: [], changed: []};
      for (special_hour = 0; special_hour < amount_of_special_hours; special_hour++) {
         var selected_hour = schedule.find('table').eq(day).find('tr').eq(special_hour).find('td');

         schedule_data[day][hour].teacher[special_hour] = selected_hour.eq(0).html();
         schedule_data[day][hour].chamber[special_hour] = selected_hour.eq(2).html();
         schedule_data[day][hour].course[special_hour] = selected_hour.eq(4).html();

         schedule_data[day][hour].changed[special_hour] = selected_hour.eq(0).attr().class == 'tableCellNew' ? true : false;
      }
    }
  }

  return schedule_data;
}

//Exporting the schedule function.
module.exports = schedule;
<|endoftext|>


<commit_before><commit_msg>validation check Array-Object-Attributes in a separate function with Array.every<commit_after><|endoftext|>


<commit_before>/**
 * Created by Abhinav on 05-03-2017.
 */
var express = require('express');
var fs = require('fs');
var async=require('async');
var MongoClient = require('mongodb').MongoClient;
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var type = require('type-of-is');
var base64url = require('base64-url');
var historyid;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://mail.google.com'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
var HISTORY_PATH = TOKEN_DIR + 'History_id.txt';
var gcredentials="";
var mongo=require("./setupmongo.js");
var app=express();
app.listen(3000);
//mongo();
var url = 'mongodb://localhost:27017/automated';
// Use connect method to connect to the Server
var db;
    MongoClient.connect(url, function (err, dbs) {

        console.log("Connected correctly to server");
        db=dbs;
    });

app.get('/users/google/callback', function(req, res) {
    console.log(req.query.code);
    res.end("");
});

fs.readFile('../client_secret.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    gcredentials=JSON.parse(content);
    authorize(JSON.parse(content), start);
});

// Load client secrets from a local file.

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials,callback) {

    var clientSecret = credentials.web.client_secret;
    var clientId = credentials.web.client_id;
    var redirectUrl = credentials.web.redirect_uris[0];

    var auth = new googleAuth();
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

    google.options({
        auth: oauth2Client
    });

    // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, function(err, token) {
        if (err) {
            getNewToken(oauth2Client, callback);
        } else {
            oauth2Client.credentials = JSON.parse(token);
            callback(oauth2Client,list);
        }
    });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */

function getNewToken(oauth2Client, callback) {
    var authUrl = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES
    });
    console.log('Authorize this app by visiting this url: ', authUrl);
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('Enter the code that appears here and press enter: ', function(code) {
        rl.close();
        oauth2Client.getToken(code, function(err, token) {
            if (err) {
                console.log('Error while trying to retrieve access token', err);
                return;
            }
            oauth2Client.credentials = token;
            storeToken(token);
            callback(oauth2Client,list);
        });
    });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
    try {
        fs.mkdirSync(TOKEN_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(TOKEN_PATH, JSON.stringify(token));
    console.log('Token stored to ' + TOKEN_PATH);
}
function storehistoryid(token) {
    try {
        fs.mkdirSync(HISTORY_PATH);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(HISTORY_PATH, JSON.stringify(token));
   // console.log('Token stored to ' + HISTORY_PATH);
}

function start(auth,list){
    fs.readFile(HISTORY_PATH,function(err, hId) {
        if (err) {
            console.log(err);
        } else {
            historyid=JSON.parse(hId);

            list(auth,getmessage);
        }
    });

}

function list(auth,getmessage){
    console.log(historyid);
    var gmail = google.gmail('v1');
    gmail.users.history.list({
        auth: auth,
        userId: 'me',
        startHistoryId: historyid,
        historyTypes:'messageAdded',
        labelId:'INBOX'

    },  function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            getNewToken(auth,start);

          /* auth.refreshAccessToken(function(err, tokens) {
           storeToken(tokens)
           });*/
        }
        else{
        try
        {var id = response.history;
            historyid=response.historyId;
            storehistoryid(historyid);
           // console.log(response);
            console.log(id.length);
            for(var i=0;id[i];i++){
                // console.log(id[i].messages[0].id);

               // async.waterfall([getmessage(id[i].messages[0].id,auth,gmail,send),send(subject,gmail,auth,mailto,body)]);
                getmessage(id[i].messages[0].id,auth,gmail,makesubject);
                if(i==id.length-1){
                setTimeout(function (auth){
                    list(auth,getmessage);
                },5000);}
            }
        }
        catch(err) {
            //console.log(collection);
            console.log("no new messages");
            setTimeout(function (auth){
            list(auth,getmessage);
        },5000);}}
    });

}

function getmessage(id,auth,gmail,makesubject) {console.log(id);
    gmail.users.messages.get({
        auth: auth,
        userId: 'me',
        id: id,
    },function (err,response){
        if (err){console.log("here take a error:"+err);
            return;}
        else
        {   for(var i=0;response.payload.headers[i];i++){
            if(response.payload.headers[i].name=="From"){
                var mailto=response.payload.headers[i].value;
                console.log(mailto);}
            else if(response.payload.headers[i].name=="Subject")
                var inputsubject=response.payload.headers[i].value;
        }
            var inputbody=response.payload.parts[0].body.data;
            inputbody =base64url.unescape(inputbody);
            inputbody=base64url.decode(inputbody);
            if(inputbody.lastIndexOf("\n")>0) {
                inputbody= inputbody.substring(0, inputbody.lastIndexOf("\n"));
               // inputbody=inputbody.replace(/\s/g,'').toLowerCase();
            }
            makesubject(auth,gmail,mailto,inputsubject,inputbody,send);
            }

    })
return;
}
function makesubject(auth,gmail,mailto,inputsubject,inputbody,send){
    console.log(inputbody);

    //console.log(mailto,inputsubject);
    var subject;
    var body="Subject or query is invalid.";
    if(inputsubject.replace(/\s/g,'').toLowerCase()=="search_database") {
        //setTimeout(function(){subject="Here is the requested query";},500);
        var collection = db.collection("dishes");
        var search = inputbody.split('\n')[0].replace(/\s/g, '').toLowerCase();
        if (!inputbody.split('\n')[1]) {
            body = "No information to search was given in 2nd line.\nThis was an invalid query for a valid query please refer to the instructions below:";
            subject = "No information to search.";
            send(subject, gmail, auth, mailto, body);

        }
        else {
            inputbody = inputbody.split('\n')[1].toLowerCase();
            if (search == "firstname") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by firstname");
                collection.find({firstname: inputbody}).toArray(function (err, docs) {
                    body = "No entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "lastname") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by lastname");
                collection.find({lastname: inputbody}).toArray(function (err, docs) {
                    bbody = "No entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "phoneno") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by phoneno");
                collection.find({phoneno: inputbody}).toArray(function (err, docs) {
                    body = "No entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "name") {
                console.log("required by name");
                var firstname = inputbody.split(' ')[0].replace(/\s/g, '');
                var lastname = inputbody.split(' ')[1].replace(/\s/g, '');
                console.log(firstname + "\n" + lastname);
                collection.find({
                    firstname: firstname,
                    lastname: lastname
                }).toArray(function (err, docs) {
                    body = "No entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });
            }
            else {
                subject = "Invalid Query!!";
                body = "This was an invalid query.\nFor a valid query please refer to the instructions below:";
                send(subject, gmail, auth, mailto, body);
            }
        }}
    else
        {
            subject = "Invalid Query!!";
            body = "This was an invalid query for a valid query please refer to the instructions below:";
            send(subject, gmail, auth, mailto, body);
        }

    }

function yo(subject,gmail,auth,mailto,body){console.log(subject);};
function send(subject,gmail,auth,mailto,body) { var string="To:"+mailto+"\n" +
    "From:Automated bot <automatedquery@gmail.com>\n"+
    "Content-type: text/html;charset=UTF-8\n"+
    "MIME-Version: 1.0\n"+
    "Subject:"+subject+"\n\n"+
    "
"+body+"
\n";

    var r=base64url.escape(base64url.encode(string));
    console.log(r);
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {raw:r}}
    )}
/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels1(auth) {
    var gmail = google.gmail('v1');
    gmail.users.messages.list({
        auth: auth,
        userId: 'me',
        maxResults: 5,
        labelIds: "INBOX"

    }, function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }
        var id = response.messages;
        {
            console.log(id);
            getmessage(id[0].id,auth,gmail);
        }
    });
}

<commit_msg>added crawler<commit_after>/**
 * Created by Abhinav on 05-03-2017.
 */
var express = require('express');
var fs = require('fs');
var async=require('async');
var MongoClient = require('mongodb').MongoClient;
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var type = require('type-of-is');
var base64url = require('base64-url');
var request = require('request');
var cheerio = require('cheerio');
var historyid;
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-nodejs-quickstart.json
var SCOPES = ['https://mail.google.com'];
var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
var TOKEN_PATH = TOKEN_DIR + 'gmail-nodejs-quickstart.json';
var HISTORY_PATH = TOKEN_DIR + 'History_id.txt';
var gcredentials="";
var movielink="http://www.imdb.com";

var app=express();
app.listen(3000);
var url = 'mongodb://localhost:27017/automated';
// Use connect method to connect to the Server
var db;
    MongoClient.connect(url, function (err, dbs) {
        if(err){
            console.log("error connecting the database");
            return;
        }
        else{
        console.log("Connected correctly to server");
        db=dbs;}
    });

app.get('/users/google/callback', function(req, res) {
    console.log(req.query.code);
    res.end("");
});

fs.readFile('../client_secret.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Gmail API.
    gcredentials=JSON.parse(content);
    authorize(JSON.parse(content), start);
});

// Load client secrets from a local file.

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials,callback) {

    var clientSecret = credentials.web.client_secret;
    var clientId = credentials.web.client_id;
    var redirectUrl = credentials.web.redirect_uris[0];

    var auth = new googleAuth();
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

    google.options({
        auth: oauth2Client
    });

    // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, function(err, token) {
        if (err) {
            getNewToken(oauth2Client, callback);
        } else {
            oauth2Client.credentials = JSON.parse(token);
            callback(oauth2Client,list);
        }
    });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */

function getNewToken(oauth2Client, callback) {
    var authUrl = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES
    });
    console.log('Authorize this app by visiting this url: ', authUrl);
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('Enter the code that appears here and press enter: ', function(code) {
        rl.close();
        oauth2Client.getToken(code, function(err, token) {
            if (err) {
                console.log('Error while trying to retrieve access token', err);
                return;
            }
            oauth2Client.credentials = token;
            storeToken(token);
            callback(oauth2Client,list);
        });
    });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
    try {
        fs.mkdirSync(TOKEN_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(TOKEN_PATH, JSON.stringify(token));
    console.log('Token stored to ' + TOKEN_PATH);
}
function storehistoryid(token) {
    try {
        fs.mkdirSync(HISTORY_PATH);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(HISTORY_PATH, JSON.stringify(token));
   // console.log('Token stored to ' + HISTORY_PATH);
}

function start(auth,list){
    fs.readFile(HISTORY_PATH,function(err, hId) {
        if (err) {
            console.log(err);
        } else {
            historyid=JSON.parse(hId);

            list(auth,getmessage);
        }
    });

}

function list(auth,getmessage){
    console.log(historyid);
    var gmail = google.gmail('v1');
    gmail.users.history.list({
        auth: auth,
        userId: 'me',
        startHistoryId: historyid,
        historyTypes:'messageAdded',
        labelId:'INBOX'

    },  function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            getNewToken(auth,start);

          /* auth.refreshAccessToken(function(err, tokens) {
           storeToken(tokens)
           });*/
        }
        else{
        try
        {var id = response.history;
            historyid=response.historyId;
            storehistoryid(historyid);
           // console.log(response);
            console.log(id.length);
            for(var i=0;id[i];i++){
                // console.log(id[i].messages[0].id);

               // async.waterfall([getmessage(id[i].messages[0].id,auth,gmail,send),send(subject,gmail,auth,mailto,body)]);
                getmessage(id[i].messages[0].id,auth,gmail,makesubject);
                if(i==id.length-1){
                setTimeout(function (auth){
                    list(auth,getmessage);
                },5000);}
            }
        }
        catch(err) {
            //console.log(collection);
            console.log("no new messages");
            setTimeout(function (auth){
            list(auth,getmessage);
        },10000);}}
    });

}

function getmessage(id,auth,gmail,makesubject) {console.log(id);
    gmail.users.messages.get({
        auth: auth,
        userId: 'me',
        id: id,
    },function (err,response){
        if (err){console.log("here take a error:"+err);
            return;}
        else
        {   for(var i=0;response.payload.headers[i];i++){
            if(response.payload.headers[i].name=="From"){
                var mailto=response.payload.headers[i].value;
                console.log(mailto);}
            else if(response.payload.headers[i].name=="Subject")
                var inputsubject=response.payload.headers[i].value;
        }
            var inputbody=response.payload.parts[0].body.data;
            inputbody =base64url.unescape(inputbody);
            inputbody=base64url.decode(inputbody);
            if(inputbody.lastIndexOf("\n")>0) {
                inputbody= inputbody.substring(0, inputbody.lastIndexOf("\n"));
               // inputbody=inputbody.replace(/\s/g,'').toLowerCase();
            }
            makesubject(auth,gmail,mailto,inputsubject,inputbody,send);
            }

    })
return;
}
function makesubject(auth,gmail,mailto,inputsubject,inputbody,send){
    console.log(inputbody);

    //console.log(mailto,inputsubject);
    var subject;
    var body="Subject or query is invalid.";
    if(inputsubject.replace(/\s/g,'').toLowerCase()=="database") {
        //setTimeout(function(){subject="Here is the requested query";},500);
        var collection = db.collection("dishes");
        var search = inputbody.split('\n')[0].replace(/\s/g, '').toLowerCase();
        if (!inputbody.split('\n')[1]) {
            body = "No information to search was given in 2nd line.\nThis was an invalid query for a valid query please refer to the instructions below:";
            subject = "No information to search.";
            send(subject, gmail, auth, mailto, body);

        }
        else {
            inputbody = inputbody.split('\n')[1].toLowerCase();
            if (search == "firstname") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by firstname");
                collection.find({firstname: inputbody}).toArray(function (err, docs) {
                    body = "No entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0) body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "lastname") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by lastname");
                collection.find({lastname: inputbody}).toArray(function (err, docs) {
                    body = "NO entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "phoneno") {
                inputbody = inputbody.replace(/\s/g, '');
                console.log("required by phoneno");
                collection.find({phoneno: inputbody}).toArray(function (err, docs) {
                    body = "NO entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });

            }
            else if (search == "name") {
                console.log("required by name");
                var firstname = inputbody.split(' ')[0].replace(/\s/g, '');
                var lastname = inputbody.split(' ')[1].replace(/\s/g, '');
                console.log(firstname + "\n" + lastname);
                collection.find({
                    firstname: firstname,
                    lastname: lastname
                }).toArray(function (err, docs) {
                    body = "NO entry with this detail in the database";
                    subject = "Here is the requested query";
                    for (var i = 0; docs[i]; i++) {
                        if(i==0)
                            body="";
                        // body.concat(docs[i].name)
                        body = body + (i + 1) + ".
";
                        body = body + "Name:" + docs[i].firstname + " " + docs[i].lastname + "
";
                        body = body + "Phone no:" + docs[i].phoneno + "
";
                        body = body + "Id:" + docs[i]._id + "

";
                        //console.log(docs[i].name);
                    }

                    send(subject, gmail, auth, mailto, body);
                });
            }
            else {
                subject = "Invalid Query!!";
                body = "This was an invalid query.\nFor a valid query please refer to the instructions below:";
                send(subject, gmail, auth, mailto, body);
            }
        }}
        else if(inputsubject.replace(/\s/g,'').toLowerCase()=="movie") {
        inputbody = inputbody.split('\n')[0].toLowerCase();
        url = 'http://www.imdb.com/find?ref_=nv_sr_fn&q='+inputbody+'&s=all';
        body = "";
        subject = "Here is the requested query";
        var data=[];
        request(url, function(error, response, html){
            if(!error){
                var $ = cheerio.load(html);

                var title, link;

                $('.result_text a').each(function(i, elem){
                    data[i]= $(this);
                });
                title = data[0].text();
                link=   data[0].attr("href");
                link=movielink+link;

            }
            console.log(link);
            request(link, function(err, resp, htm){
                if(!error){
                    var $ = cheerio.load(htm);

                    $('.title_wrapper').each(function(i, elem){
                        data[i]= $(this);
                    })
                    ;
                    body=data[0].html();
                    send(subject, gmail, auth, mailto, body);

                }

            })
        })
    }
    else
        {
            subject = "Invalid Query!!";
            body = "This was an invalid query for a valid query please refer to the instructions below:";
            send(subject, gmail, auth, mailto, body);
        }

    }

//function yo(subject,gmail,auth,mailto,body){console.log(subject);};
function send(subject,gmail,auth,mailto,body) { var string="To:"+mailto+"\n" +
    "From:Automated bot <automatedquery@gmail.com>\n"+
    "Content-type: text/html;charset=UTF-8\n"+
    "MIME-Version: 1.0\n"+
    "Subject:"+subject+"\n\n"+
    "
"+body+"
\n";

    var r=base64url.escape(base64url.encode(string));
    console.log(r);
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {raw:r}}
    )}
/**
 * Lists the labels in the user's account.
 *
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listLabels1(auth) {
    var gmail = google.gmail('v1');
    gmail.users.messages.list({
        auth: auth,
        userId: 'me',
        maxResults: 5,
        labelIds: "INBOX"

    }, function (err, response) {
        if (err) {
            console.log('The API returned an error: ' + err);
            return;
        }
        var id = response.messages;
        {
            console.log(id);
            getmessage(id[0].id,auth,gmail);
        }
    });
}

<|endoftext|>


<commit_before><commit_msg>Remove _key which was added before for convenience. It's better to let user decide the key to use.<commit_after><|endoftext|>


<commit_before><commit_msg>[lib] Add missing callback call.<commit_after><|endoftext|>


<commit_before>"use strict";

//Declare a global data object for caching events
var EVENTS_DATA = {};

var express = require('express');
var app = express(),
  bodyParser = require('body-parser'),
  request = require('request'),
  ical2json = require("ical2json"),
  dateParser = require("./Utils"),
  async = require("async");

/* To Allow cross-domain Access-Control*/
var allowCrossDomain = function (req, res, next) {
  res.setHeader('Access-Control-Allow-Credentials', true);
  res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  // intercept OPTIONS method
  if ('OPTIONS' == req.method) {
    res.send(200);
  }
  else {
    next();
  }
};

app.use(allowCrossDomain);
// Parsing json and urlencoded requests
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(bodyParser.json({type: 'application/vnd.api+json'}));

app.get('/', function (req, res) {
  res.send("Server running...");
});

// API to validate ical url
app.post('/validate', function (req, res) {
  if (req.body.url) {
    request(req.body.url, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        var data = ical2json.convert(body);
        if (data && data.VEVENT && data.VEVENT.length)
          res.send({'statusCode': 200});
        else
          res.send({'statusCode': 404});
      } else
        res.send({'statusCode': 500});
    });
  } else
    res.send({'statusCode': 404});
});

// API to fetch events from an ical url
app.post('/events', function (req, res) {
  var limit = req.body.limit || 10;
  var offset = req.body.offset || 0;
  var paginatedListOfEvents = [];
  if (req.body.url) {
    if (EVENTS_DATA[req.body.url]) {
      returnEventIndexFromCurrentDate(EVENTS_DATA[req.body.url], function (index) {
        if (index != -1) {
          paginatedListOfEvents = EVENTS_DATA[req.body.url].slice(offset + index, (offset + index + limit));
          res.send({
            'statusCode': 200,
            'events': paginatedListOfEvents,
            'totalEvents': EVENTS_DATA[req.body.url].length - index
          });
        } else {
          res.send({
            'statusCode': 200,
            'events': [],
            'totalEvents': 0
          });
        }
      });
    }
    else {
      request(req.body.url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          var data = ical2json.convert(body);
          if (data && data.VEVENT && data.VEVENT.length) {
            processData(data.VEVENT, function (events) {
              data.VEVENT = events;
              data.VEVENT = data.VEVENT.sort(function (a, b) {
                return a.startDate - b.startDate;
              });
              EVENTS_DATA[req.body.url] = data.VEVENT;
              returnEventIndexFromCurrentDate(data.VEVENT, function (index) {
                if (index != -1) {
                  paginatedListOfEvents = data.VEVENT.slice(offset + index, (offset + index + limit));
                  res.send({
                    'statusCode': 200,
                    'events': paginatedListOfEvents,
                    'totalEvents': data.VEVENT.length - index
                  });
                } else {
                  res.send({
                    'statusCode': 200,
                    'events': [],
                    'totalEvents': 0
                  });
                }
              });
            });
          }
          else
            res.send({'statusCode': 404, 'events': null});
        } else
          res.send({'statusCode': 500, 'events': null});
      });
    }
  } else
    res.send({'statusCode': 404, 'events': null});
});

// API to fetch single event with given index from an ical url
app.post('/event', function (req, res) {
  var index = req.body.index || 0;
  if (req.body.url) {
    if (EVENTS_DATA[req.body.url] && EVENTS_DATA[req.body.url].length) {
      var event = EVENTS_DATA[req.body.url][index];
      res.send({'statusCode': 200, 'event': event});
    }
    else {
      request(req.body.url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          var data = ical2json.convert(body);
          if (data && data.VEVENT && data.VEVENT.length) {
            var event = data.VEVENT[index];
            res.send({'statusCode': 200, 'event': event});
          }
          else
            res.send({'statusCode': 404, 'event': null});
        } else
          res.send({'statusCode': 500, 'event': null});
      });
    }
  } else
    res.send({'statusCode': 404, 'event': null});
});

var server = app.listen(3020, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Server app listening at http://%s:%s', host, port);
});

function processData(events, callback) {
  async.each(events, function (event, cb) {
    event = dateParser(event);
    cb();
  }, function () {
    callback(events);
  });
}

// Method to get index from which the events from current date onwards start

function returnEventIndexFromCurrentDate(events, callback) {
  var currentDate = +new Date(),
    eventIndex = -1;
  async.forEachOf(events, function (event, index, cb) {
    if (event.startDate >= currentDate) {
      eventIndex = index;
      cb("error");
    }
  }, function () {
    callback(eventIndex);
  });
}

module.exports = function () {
  return server;
};<commit_msg>Now correct event is opened on clicking event title in widget, Fixed node proxy api.<commit_after>"use strict";

//Declare a global data object for caching events
var EVENTS_DATA = {};

var express = require('express');
var app = express(),
  bodyParser = require('body-parser'),
  request = require('request'),
  ical2json = require("ical2json"),
  dateParser = require("./Utils"),
  async = require("async");

/* To Allow cross-domain Access-Control*/
var allowCrossDomain = function (req, res, next) {
  res.setHeader('Access-Control-Allow-Credentials', true);
  res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  // intercept OPTIONS method
  if ('OPTIONS' == req.method) {
    res.send(200);
  }
  else {
    next();
  }
};

app.use(allowCrossDomain);
// Parsing json and urlencoded requests
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(bodyParser.json({type: 'application/vnd.api+json'}));

app.get('/', function (req, res) {
  res.send("Server running...");
});

// API to validate ical url
app.post('/validate', function (req, res) {
  if (req.body.url) {
    request(req.body.url, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        var data = ical2json.convert(body);
        if (data && data.VEVENT && data.VEVENT.length)
          res.send({'statusCode': 200});
        else
          res.send({'statusCode': 404});
      } else
        res.send({'statusCode': 500});
    });
  } else
    res.send({'statusCode': 404});
});

// API to fetch events from an ical url
app.post('/events', function (req, res) {
  var limit = req.body.limit || 10;
  var offset = req.body.offset || 0;
  var paginatedListOfEvents = [];
  if (req.body.url) {
    if (EVENTS_DATA[req.body.url]) {
      returnEventIndexFromCurrentDate(EVENTS_DATA[req.body.url], function (index) {
        if (index != -1) {
          paginatedListOfEvents = EVENTS_DATA[req.body.url].slice(offset + index, (offset + index + limit));
          res.send({
            'statusCode': 200,
            'events': paginatedListOfEvents,
            'totalEvents': EVENTS_DATA[req.body.url].length - index
          });
        } else {
          res.send({
            'statusCode': 200,
            'events': [],
            'totalEvents': 0
          });
        }
      });
    }
    else {
      request(req.body.url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          var data = ical2json.convert(body);
          if (data && data.VEVENT && data.VEVENT.length) {
            processData(data.VEVENT, function (events) {
              data.VEVENT = events;
              data.VEVENT = data.VEVENT.sort(function (a, b) {
                return a.startDate - b.startDate;
              });
              EVENTS_DATA[req.body.url] = data.VEVENT;
              returnEventIndexFromCurrentDate(data.VEVENT, function (index) {
                if (index != -1) {
                  paginatedListOfEvents = data.VEVENT.slice(offset + index, (offset + index + limit));
                  res.send({
                    'statusCode': 200,
                    'events': paginatedListOfEvents,
                    'totalEvents': data.VEVENT.length - index
                  });
                } else {
                  res.send({
                    'statusCode': 200,
                    'events': [],
                    'totalEvents': 0
                  });
                }
              });
            });
          }
          else
            res.send({'statusCode': 404, 'events': null});
        } else
          res.send({'statusCode': 500, 'events': null});
      });
    }
  } else
    res.send({'statusCode': 404, 'events': null});
});

// API to fetch single event with given index from an ical url
app.post('/event', function (req, res) {
  var index = req.body.index || 0;
  if (req.body.url) {
    if (EVENTS_DATA[req.body.url] && EVENTS_DATA[req.body.url].length) {
      returnEventIndexFromCurrentDate(EVENTS_DATA[req.body.url], function (indexOfCurrentDateEvent) {
        if (index != -1) {
          var event = EVENTS_DATA[req.body.url][Number(index) + indexOfCurrentDateEvent];
          res.send({'statusCode': 200, 'event': event});
        } else {
          res.send({'statusCode': 404, 'event': null});
        }
      });
    }
    else {
      request(req.body.url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
          var data = ical2json.convert(body);
          if (data && data.VEVENT && data.VEVENT.length) {
            processData(data.VEVENT, function (events) {
              data.VEVENT = events;
              data.VEVENT = data.VEVENT.sort(function (a, b) {
                return a.startDate - b.startDate;
              });
              EVENTS_DATA[req.body.url] = data.VEVENT;
              returnEventIndexFromCurrentDate(data.VEVENT, function (indexOfCurrentDateEvent) {
                if (index != -1) {
                  var event = data.VEVENT[Number(index) + indexOfCurrentDateEvent];
                  res.send({'statusCode': 200, 'event': event});
                } else {
                  res.send({'statusCode': 404, 'event': null});
                }
              });
            });
          }
          else
            res.send({'statusCode': 404, 'event': null});
        } else
          res.send({'statusCode': 500, 'event': null});
      });
    }
  } else
    res.send({'statusCode': 404, 'event': null});
});

var server = app.listen(3020, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Server app listening at http://%s:%s', host, port);
});

function processData(events, callback) {
  async.each(events, function (event, cb) {
    event = dateParser(event);
    cb();
  }, function () {
    callback(events);
  });
}

// Method to get index from which the events from current date onwards start

function returnEventIndexFromCurrentDate(events, callback) {
  var currentDate = +new Date(),
    eventIndex = -1;
  async.forEachOf(events, function (event, index, cb) {
    if (event.startDate >= currentDate) {
      eventIndex = index;
      cb("error");
    }
  }, function () {
    callback(eventIndex);
  });
}

module.exports = function () {
  return server;
};<|endoftext|>


<commit_before>var express = require('express');
var app     = express();
var http    = require('http');
var mongoose= require('mongoose');

app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);

if ('development' === app.get('env')){
  app.use(express.errorHandler());
}
else if('test' === app.get('env')){
  app.use(express.errorHandler());
  database = 'test';
}

require('./routes');

http.createServer(app).listen(app.get('port'), function(){
  console.log('Listening on ' + app.get('port'));
});

exports.app = app;
<commit_msg>Fix previous error. Add require('./models/task')<commit_after>var express = require('express');
var app     = express();
var http    = require('http');
var mongoose= require('mongoose');

app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);

if ('development' === app.get('env')){
  app.use(express.errorHandler());
}
else if('test' === app.get('env')){
  app.use(express.errorHandler());
  database = 'test';
}

require('./models/task');
require('./routes');

http.createServer(app).listen(app.get('port'), function(){
  console.log('Listening on ' + app.get('port'));
});

exports.app = app;
<|endoftext|>


<commit_before>var arrayAdd = basis.array.add;
var walk = require('./ast.js').walk;
var consts = require('../const.js');
var TYPE_ATTRIBUTE_EVENT = consts.TYPE_ATTRIBUTE_EVENT;
var TYPE_CONTENT = consts.TYPE_CONTENT;
var CONTENT_PRIORITY = consts.CONTENT_PRIORITY;
var TOKEN_BINDINGS = consts.TOKEN_BINDINGS;
var TOKEN_REFS = consts.TOKEN_REFS;

//
// common
//

function resourceHash(resource){
  return [
    resource.type,
    resource.url,
    resource.isolate
  ].join(';');
}

function addUnique(array, items){
  for (var i = 0; i < items.length; i++)
    arrayAdd(array, items[i]);
}

//
// tokens
//

function getTokenName(token){
  return (token.prefix ? token.prefix + ':' : '') + token.name;
}

function bindingList(token){
  var refs = token.refs;

  return refs && refs.length == 1 ? refs[0] : 0;
}

function getTokenAttrValues(token){
  var result = {};

  if (token.attrs)
    for (var i = 0, attr; attr = token.attrs[i]; i++)
      result[getTokenName(attr)] = attr.value;

  return result;
}

function getTokenAttrs(token){
  var result = {};

  if (token.attrs)
    for (var i = 0, attr; attr = token.attrs[i]; i++)
      result[getTokenName(attr)] = attr;

  return result;
}

function parseOptionsValue(str){
  var result = {};
  var pairs = (str || '').trim().split(/\s*,\s*/);

  for (var i = 0; i < pairs.length; i++)
  {
    var pair = pairs[i].split(/\s*:\s*/);

    if (pair.length != 2)
    {
      // error
      return {};
    }

    result[pair[0]] = pair[1];
  }

  return result;
}

//
// location and debug
//

function getLocation(template, loc){
  if (loc)
    return (template.sourceUrl || '') + ':' + loc.start.line + ':' + (loc.start.column + 1);
}

function addTemplateWarn(template, options, message, loc){
  if (loc && options.loc)
  {
    message = Object(message);
    message.loc = typeof loc == 'string' ? loc : getLocation(template, loc);
  }

  template.warns.push(message);
}

function addTokenLocation(template, options, dest, source){
  if (options.loc && source && source.loc && !dest.loc)
    dest.loc = getLocation(template, source.loc);
}

module.exports = {
  resourceHash: resourceHash,
  addUnique: addUnique,

  getTokenName: getTokenName,
  bindingList: bindingList,
  getTokenAttrValues: getTokenAttrValues,
  getTokenAttrs: getTokenAttrs,
  parseOptionsValue: parseOptionsValue,

  getLocation: getLocation,
  addTemplateWarn: addTemplateWarn,
  addTokenLocation: addTokenLocation
};
<commit_msg>fix warnings<commit_after>var arrayAdd = basis.array.add;

//
// common
//

function resourceHash(resource){
  return [
    resource.type,
    resource.url,
    resource.isolate
  ].join(';');
}

function addUnique(array, items){
  for (var i = 0; i < items.length; i++)
    arrayAdd(array, items[i]);
}

//
// tokens
//

function getTokenName(token){
  return (token.prefix ? token.prefix + ':' : '') + token.name;
}

function bindingList(token){
  var refs = token.refs;

  return refs && refs.length == 1 ? refs[0] : 0;
}

function getTokenAttrValues(token){
  var result = {};

  if (token.attrs)
    for (var i = 0, attr; attr = token.attrs[i]; i++)
      result[getTokenName(attr)] = attr.value;

  return result;
}

function getTokenAttrs(token){
  var result = {};

  if (token.attrs)
    for (var i = 0, attr; attr = token.attrs[i]; i++)
      result[getTokenName(attr)] = attr;

  return result;
}

function parseOptionsValue(str){
  var result = {};
  var pairs = (str || '').trim().split(/\s*,\s*/);

  for (var i = 0; i < pairs.length; i++)
  {
    var pair = pairs[i].split(/\s*:\s*/);

    if (pair.length != 2)
    {
      // error
      return {};
    }

    result[pair[0]] = pair[1];
  }

  return result;
}

//
// location and debug
//

function getLocation(template, loc){
  if (loc)
    return (template.sourceUrl || '') + ':' + loc.start.line + ':' + (loc.start.column + 1);
}

function addTemplateWarn(template, options, message, loc){
  if (loc && options.loc)
  {
    message = Object(message);
    message.loc = typeof loc == 'string' ? loc : getLocation(template, loc);
  }

  template.warns.push(message);
}

function addTokenLocation(template, options, dest, source){
  if (options.loc && source && source.loc && !dest.loc)
    dest.loc = getLocation(template, source.loc);
}

module.exports = {
  resourceHash: resourceHash,
  addUnique: addUnique,

  getTokenName: getTokenName,
  bindingList: bindingList,
  getTokenAttrValues: getTokenAttrValues,
  getTokenAttrs: getTokenAttrs,
  parseOptionsValue: parseOptionsValue,

  getLocation: getLocation,
  addTemplateWarn: addTemplateWarn,
  addTokenLocation: addTokenLocation
};
<|endoftext|>