<commit_before>/**
 * YTS-downloader
 * Download recently released torrent files from yts.ag based on criteria specified
 *
 * @license MIT
 * @copyright 2016, Dan Wilson [killroyboy@gmail.com]
 */

var cron = require('cron').CronJob,
    got = require('got'),
    _ = require('lodash'),
    config = require('config'),
    moment = require('moment'),
    pattern = config.frequency.cron_pattern,
    fs = require('fs'),
    path = require('path'),
    flatCache = require('flat-cache'),
    cache = flatCache.load('yts-downloader', path.resolve('./cache')),
    logger = require('eazy-logger').Logger({
        useLevelPrefixes: true,
        level : config.log_level
    }),
    downloaded = 0, total = parseInt(cache.getKey('total-downloaded')) || 0, responded = 0, requested = 0;

// compile a manual pattern
if (!pattern) {
    var order = ['seconds', 'minutes', 'hours', 'daymonth', 'months', 'dayweek'],
        patternParts = [];

    var unit = config.frequency.unit,
        value = config.frequency.value,
        found = false;

    for (var x = 0; x < order.length; x++) {
        if (order[x] === unit) {
            found = true;
            patternParts.push(value);
        } else if (found) {
            patternParts.push('*');
        } else {
            patternParts.push('0');
        }
    }
    pattern = patternParts.join(' ');
}

// create the directory if it doesn't exist
if (!fs.existsSync(config.destination)) {
    logger.info('Creating destination directory', config.destination);
    fs.mkdirSync(config.destination);
}

/**
 * Request the recent movies from the base URL (yts.ag)
 * @param callback
 */
var requestRecentMovies = function (callback) {
    var url = config.baseurl + '/list_movies.json?',
        query = config.query;

    if (query.minimum_rating) {
        url += '&minimum_rating=' + query.minimum_rating;
    }

    if (query.quality) {
        url += '&quality=' + query.quality;
    }

    if (query.genre) {
        url += '&genre=' + query.genre;
    }

    logger.debug('Requesting url', url);
    got(url).then(response => {
        logger.debug('Response:', response.statusCode, response.statusMessage);
        callback(response.body);
    }).catch(error => {
        logger.error('Error requesting url:', error.response.body);
    });
};

/**
 * Download the torrent file and save it to the destination directory
 * @param torrents
 * @param movie
 */
var downloadFile = function (movie) {
    requested++; // track how many downloads we request
    var localFile = config.destination + '/' + movie.title + '.torrent';
    _.each(movie.torrents, function (torrent) {
        logger.trace('Checking for quality', torrent.quality, config.query.quality);
        if (torrent.quality === config.query.quality) {
            logger.debug('Downloading Torrent', movie.title, torrent.url, localFile);
            // if pre-download script, run it
            if (config.pre_download_script) {
                //exec(config.pre_download_script);
            }

            got.stream(torrent.url).on('error', (error) => {
                responded++; // track how many we get back
                logger.error('Error Downloading', movie.title, error.toString());
            }).on('response', (response) => {
                logger.trace('Setting cache key for', movie.id, movie.title);
                cache.setKey(movie.id, true);
                responded++; // track how many we get back
                downloaded++;
            }).pipe(fs.createWriteStream(localFile));
        }
    });
};

/**
 * Parse the JSON body and cycle through each movie
 *
 * @param body
 */
var handleResponse = function (body) {
    var response = JSON.parse(body),
        movies = response.data.movies,
        matchCriteria = true,
        checked = 0,
        printer = null,
        last = cache.getKey('last_uploaded') || config.since;

    // reset current run count
    downloaded = 0;

    // loop through all the movies and download if it's new
    _.each(movies, function (movie) {
        matchCriteria = true;
        logger.trace('Checking cache key', movie.id, movie.title);
        if (!cache.getKey(movie.id)) {
            logger.debug('Examining', movie.title_long);

            if (config.filter.mpa_ratings.length) {
                if (config.filter.mpa_ratings.indexOf(movie.mpa_rating) < 0) {
                    logger.debug('Ignoring', movie.title, 'because MPA Rating:', movie.mpa_rating);
                    cache.setKey(movie.id, true);
                    matchCriteria = false;
                }
            }

            // only check this if we are still planning to download
            if (matchCriteria && config.filter.minimum_year) {
                if (parseInt(movie.year) < parseInt(config.filter.minimum_year)) {
                    logger.debug('Ignoring', movie.title, 'because year:', movie.year);
                    cache.setKey(movie.id, true);
                    matchCriteria = false;
                }
            }

            if (matchCriteria) {
                logger.info('Downloading', movie.title_long);
                if (config.script_before) {
					const { execFile } = require('child_process');
					const child = execFile('node', ['--version'], (error, stdout, stderr) => {
						if (error) {
							throw error;
						}
					});
                }
                downloadFile(movie);
            }

            // cache the latest uploaded date
            if (movie.date_uploaded_unix > last) {
                last = movie.date_uploaded_unix;
            }
        }
    });
    cache.setKey('last_uploaded', last);

    var final = setInterval(function () {
        if (responded === requested || ++checked > (movies.length * 2)) {
            clearInterval(final);
            total += downloaded;
            cache.setKey('total-downloaded', total);
            printer = config.always_log_results || downloaded > 0 ? logger.info : logger.debug;
            printer('Movies:', movies.length);
            printer('Downloaded:', downloaded);
			printer('Total:', total);
            cache.save();
        }
    }, 200);
};

logger.trace('Cron Pattern:', pattern);

/**
 * Start the cron
 */
var job = new cron({
    cronTime : pattern,
    onTick : function () {
        logger.info('yts-downloader', moment().toString());
        requestRecentMovies(handleResponse);
    },
    runOnInit : config.run_at_start,
    start : true
});
<commit_msg>handle running before script a bit better<commit_after>/**
 * YTS-downloader
 * Download recently released torrent files from yts.ag based on criteria specified
 *
 * @license MIT
 * @copyright 2016, Dan Wilson [killroyboy@gmail.com]
 */

var cron = require('cron').CronJob,
    got = require('got'),
    _ = require('lodash'),
    config = require('config'),
    moment = require('moment'),
    pattern = config.frequency.cron_pattern,
    fs = require('fs'),
    path = require('path'),
    flatCache = require('flat-cache'),
    cache = flatCache.load('yts-downloader', path.resolve('./cache')),
    execFile = require('child_process'),
    logger = require('eazy-logger').Logger({
        useLevelPrefixes: true,
        level : config.log_level
    }),
    downloaded = 0, total = parseInt(cache.getKey('total-downloaded')) || 0, responded = 0, requested = 0;

// compile a manual pattern
if (!pattern) {
    var order = ['seconds', 'minutes', 'hours', 'daymonth', 'months', 'dayweek'],
        patternParts = [];

    var unit = config.frequency.unit,
        value = config.frequency.value,
        found = false;

    for (var x = 0; x < order.length; x++) {
        if (order[x] === unit) {
            found = true;
            patternParts.push(value);
        } else if (found) {
            patternParts.push('*');
        } else {
            patternParts.push('0');
        }
    }
    pattern = patternParts.join(' ');
}

// create the directory if it doesn't exist
if (!fs.existsSync(config.destination)) {
    logger.info('Creating destination directory', config.destination);
    fs.mkdirSync(config.destination);
}

/**
 * Request the recent movies from the base URL (yts.ag)
 * @param callback
 */
var requestRecentMovies = function (callback) {
    var url = config.baseurl + '/list_movies.json?',
        query = config.query;

    if (query.minimum_rating) {
        url += '&minimum_rating=' + query.minimum_rating;
    }

    if (query.quality) {
        url += '&quality=' + query.quality;
    }

    if (query.genre) {
        url += '&genre=' + query.genre;
    }

    logger.debug('Requesting url', url);
    got(url).then(response => {
        logger.debug('Response:', response.statusCode, response.statusMessage);
        callback(response.body);
    }).catch(error => {
        logger.error('Error requesting url:', error.response.body);
    });
};

/**
 * Download the torrent file and save it to the destination directory
 * @param torrents
 * @param movie
 */
var downloadFile = function (movie) {
    requested++; // track how many downloads we request
    var localFile = config.destination + '/' + movie.title + '.torrent';
    _.each(movie.torrents, function (torrent) {
        logger.trace('Checking for quality', torrent.quality, config.query.quality);
        if (torrent.quality === config.query.quality) {
            logger.debug('Downloading Torrent', movie.title, torrent.url, localFile);
            // if pre-download script, run it
            if (config.pre_download_script) {
                //exec(config.pre_download_script);
            }

            got.stream(torrent.url).on('error', (error) => {
                responded++; // track how many we get back
                logger.error('Error Downloading', movie.title, error.toString());
            }).on('response', (response) => {
                logger.trace('Setting cache key for', movie.id, movie.title);
                cache.setKey(movie.id, true);
                responded++; // track how many we get back
                downloaded++;
            }).pipe(fs.createWriteStream(localFile));
        }
    });
};

/**
 * Parse the JSON body and cycle through each movie
 *
 * @param body
 */
var handleResponse = function (body) {
    var response = JSON.parse(body),
        movies = response.data.movies,
        matchCriteria = true,
        checked = 0,
        printer = null,
        last = cache.getKey('last_uploaded') || config.since;

    // reset current run count
    downloaded = 0;

    // loop through all the movies and download if it's new
    _.each(movies, function (movie) {
        matchCriteria = true;
        logger.trace('Checking cache key', movie.id, movie.title);
        if (!cache.getKey(movie.id)) {
            logger.debug('Examining', movie.title_long);

            if (config.filter.mpa_ratings.length) {
                if (config.filter.mpa_ratings.indexOf(movie.mpa_rating) < 0) {
                    logger.debug('Ignoring', movie.title, 'because MPA Rating:', movie.mpa_rating);
                    cache.setKey(movie.id, true);
                    matchCriteria = false;
                }
            }

            // only check this if we are still planning to download
            if (matchCriteria && config.filter.minimum_year) {
                if (parseInt(movie.year) < parseInt(config.filter.minimum_year)) {
                    logger.debug('Ignoring', movie.title, 'because year:', movie.year);
                    cache.setKey(movie.id, true);
                    matchCriteria = false;
                }
            }

            if (matchCriteria) {
                logger.info('Downloading', movie.title_long);
                if (config.script_before) {
					execFile(config.script_before, [], (error, stdout, stderr) => {
						if (error) {
							throw error;
						}
					});
                }
                downloadFile(movie);
            }

            // cache the latest uploaded date
            if (movie.date_uploaded_unix > last) {
                last = movie.date_uploaded_unix;
            }
        }
    });
    cache.setKey('last_uploaded', last);

    var final = setInterval(function () {
        if (responded === requested || ++checked > (movies.length * 2)) {
            clearInterval(final);
            total += downloaded;
            cache.setKey('total-downloaded', total);
            printer = config.always_log_results || downloaded > 0 ? logger.info : logger.debug;
            printer('Movies:', movies.length);
            printer('Downloaded:', downloaded);
			printer('Total:', total);
            cache.save();
        }
    }, 200);
};

logger.trace('Cron Pattern:', pattern);

/**
 * Start the cron
 */
var job = new cron({
    cronTime : pattern,
    onTick : function () {
        logger.info('yts-downloader', moment().toString());
        requestRecentMovies(handleResponse);
    },
    runOnInit : config.run_at_start,
    start : true
});
<|endoftext|>


<commit_before>var fs = require("fs");
var twitterPkg = require("twitter");
var express = require('express');
var hexu = require("hexu");
var app = express();

var addData = require("./data.js").addData;

var config = JSON.parse(fs.readFileSync("./config.json"));

var data = JSON.parse(fs.readFileSync("./data.json"));

var Twitter = new twitterPkg(config);

var terminals = {};
var startwords = [];
var wordstats = {};

for (var i = 0; i < data.length; i++) {
    var words = data[i].split(' ');
    terminals[words[words.length-1]] = true;
    startwords.push(words[0]);
    for (var j = 0; j < words.length - 1; j++) {
        if (wordstats.hasOwnProperty(words[j])) {
            wordstats[words[j]].push(words[j+1]);
        } else {
            wordstats[words[j]] = [words[j+1]];
        }
    }
}

var choice = function (a) {
    var i = Math.floor(a.length * Math.random());
    return a[i];
};

var generate = function (min_length) {
    word = choice(startwords);
    var title = [word];
    while (wordstats.hasOwnProperty(word)) {
        var next_words = wordstats[word];
        word = choice(next_words);
        title.push(word);
        if (title.length > min_length && terminals.hasOwnProperty(word)) break;
    }
    if (title.length < min_length) return generate(min_length);
    return title.join(' ');
};

var makePost = function() {
  var post = generate(5);
  Twitter.post('statuses/update', {status: post},  function(error, tweet, response){
    if(error){
      console.log(hexu.red(error));
    }
    console.log(hexu.green("Tweeted: " + post));
    addData(post);
  });
}

var greeting = function() {
  Twitter.post('statuses/update', {status: "I'm alive. Hello world?"},  function(error, tweet, response){
    if(error){
      console.log(error);
    }
    console.log(tweet);  // Tweet body.
    console.log(response);  // Raw response object.
  });
}

// Routes
app.get("/", function(req, res) {
  res.header('Content-Type', 'application/json');
  res.sendFile(__dirname + "/data.json");
});

app.listen(3000);

// greeting()
makePost()
setInterval(makePost, 1000 * 60 * 60)
<commit_msg>remove<commit_after>var fs = require("fs");
var twitterPkg = require("twitter");
var express = require('express');
var hexu = require("hexu");
var app = express();

var addData = require("./data.js").addData;

var config = JSON.parse(fs.readFileSync("./config.json"));

var data = JSON.parse(fs.readFileSync("./data.json"));

var Twitter = new twitterPkg(config);

var terminals = {};
var startwords = [];
var wordstats = {};

for (var i = 0; i < data.length; i++) {
    var words = data[i].split(' ');
    terminals[words[words.length-1]] = true;
    startwords.push(words[0]);
    for (var j = 0; j < words.length - 1; j++) {
        if (wordstats.hasOwnProperty(words[j])) {
            wordstats[words[j]].push(words[j+1]);
        } else {
            wordstats[words[j]] = [words[j+1]];
        }
    }
}

var choice = function (a) {
    var i = Math.floor(a.length * Math.random());
    return a[i];
};

var generate = function (min_length) {
    word = choice(startwords);
    var title = [word];
    while (wordstats.hasOwnProperty(word)) {
        var next_words = wordstats[word];
        word = choice(next_words);
        title.push(word);
        if (title.length > min_length && terminals.hasOwnProperty(word)) break;
    }
    if (title.length < min_length) return generate(min_length);
    return title.join(' ');
};

var makePost = function() {
  var post = generate(5);
  Twitter.post('statuses/update', {status: post},  function(error, tweet, response){
    if(error){
      console.log(hexu.red(error));
    }
    console.log(hexu.green("Tweeted: " + post));
    addData(post);
  });
}

var greeting = function() {
  Twitter.post('statuses/update', {status: "I'm alive. Hello world?"},  function(error, tweet, response){
    if(error){
      console.log(error);
    }
  });
}

// Routes
app.get("/", function(req, res) {
  res.header('Content-Type', 'application/json');
  res.sendFile(__dirname + "/data.json");
});

app.listen(3000);

// greeting()
makePost()
setInterval(makePost, 1000 * 60 * 60)
<|endoftext|>


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

'use strict';

const git = require('git-child');
const del = require('del');
const chalk = require('chalk');
const exec = require('promised-exec');
const argv = require('yargs').argv;

const RELEASES_BRANCH = process.env.BR_RELEASES_BRANCH || argv.b || 'releases';
const GH_TOKEN = process.env.GH_TOKEN || argv.t;
const DIST_DIR = process.env.BR_DIST_DIR || argv.d || 'dist';
const COMMIT_MESSAGE = process.env.BR_DIST_DIR || argv.m || 'Release v%ver%';
const BUILD_SCRIPT = process.env.BR_BUILD_SCRIPT || argv.s || 'build-dist';

function main() {
  branchRelease()
  .catch(err => fail(err));
}

function branchRelease() {
  return wasVersionChanged().then(versions => {
    if (versions[0] !== versions[1]) return buildAndPublish(versions[1]);
    log(chalk.green('Package version was not changed'));
  });
}

function wasVersionChanged() {
  let version;
  return git.checkout('master')
  .then(() => git.show('HEAD:package.json'))
  .then(contents => {
    version = JSON.parse(contents).version;
    return git.show('HEAD^:package.json')
  })
  .then(contents => {
    const prevVersion = JSON.parse(contents).version;
    return [prevVersion, version];
  })
}

function buildAndPublish(version) {
  log(`running: 'git checkout -B ${RELEASES_BRANCH}'`);
  return git.checkout({B: RELEASES_BRANCH})
  .then(() => {
    log(`running: 'git pull origin ${RELEASES_BRANCH}'`);
    return git.pull(['origin', RELEASES_BRANCH]);
  })
  .then(() => {
    log(`running: 'git merge master'`);
    return git.merge('master');
  })
  .then(() => {
    log('Clearing dist folder');
    return del([ DIST_DIR + '/**/*' ]);
  })
  .then(() => {
    let buildCommand = `npm run-script ${BUILD_SCRIPT}`;
    log(`running: '${buildCommand}'`);
    return exec(buildCommand);
  })
  .then(() => {
    log(`running: 'git add .'`);
    return git.add('.');
  })
  .then(() => {
    log(`running: 'git add ${DIST_DIR} -f'`);
    return git.add({
      _: DIST_DIR,
      f: true
    });
  })
  .then(() => {
    const commitMessage = COMMIT_MESSAGE.replace('%ver%', version);
    log(`running: 'git commit -m ${commitMessage}'`);
    return git.commit({m: commitMessage});
  })
  .then(() => {
    log(`running: 'git tag ${version}'`);
    return git.tag(version);
  })
  .then(() => {
    return git.config({
      'get':true,
      '_': 'remote.origin.url'
    });
  })
  .then((remoteUrl) => {
    let repoRef = remoteUrl.split('@').length > 1 ? remoteUrl.split('@')[1] : remoteUrl;
    repoRef = repoRef.trim();
    if (repoRef.startsWith('https://'))
      repoRef = repoRef.substring(8);

    let args = `${RELEASES_BRANCH}:${RELEASES_BRANCH}`;
    if (GH_TOKEN) {
      args = [`https://${GH_TOKEN}@${repoRef}`, args];
    }
    log(`running: 'git push --follow-tags`);
    return git.push({
      'follow-tags': true,
      '_': args
    });
  })
  .finally(() => {
    log('switching back to master branch');
    return git.checkout('master');
  })
  .then(() => {
    log(chalk.green("Released successfully"))
  })
}

function log() {
  console.log.apply(console, arguments);
}

function fail(err) {
  let message = err.message || err.string;
  if (GH_TOKEN)
    message = message.replace(GH_TOKEN, 'xxGH_TOKENxx');
  log(chalk.red('Release failed:'))
  log(chalk.red(message));
  process.exit(1);
}

if (require.main === module) {
  main();
}

module.exports = branchRelease;
<commit_msg>Add push --tags step<commit_after>#!/usr/bin/env node

'use strict';

const git = require('git-child');
const del = require('del');
const chalk = require('chalk');
const exec = require('promised-exec');
const argv = require('yargs').argv;

const RELEASES_BRANCH = process.env.BR_RELEASES_BRANCH || argv.b || 'releases';
const GH_TOKEN = process.env.GH_TOKEN || argv.t;
const DIST_DIR = process.env.BR_DIST_DIR || argv.d || 'dist';
const COMMIT_MESSAGE = process.env.BR_DIST_DIR || argv.m || 'Release v%ver%';
const BUILD_SCRIPT = process.env.BR_BUILD_SCRIPT || argv.s || 'build-dist';

function main() {
  branchRelease()
  .catch(err => fail(err));
}

function branchRelease() {
  return wasVersionChanged().then(versions => {
    if (versions[0] !== versions[1]) return buildAndPublish(versions[1]);
    log(chalk.green('Package version was not changed'));
  });
}

function wasVersionChanged() {
  let version;
  return git.checkout('master')
  .then(() => git.show('HEAD:package.json'))
  .then(contents => {
    version = JSON.parse(contents).version;
    return git.show('HEAD^:package.json')
  })
  .then(contents => {
    const prevVersion = JSON.parse(contents).version;
    return [prevVersion, version];
  })
}

function buildAndPublish(version) {
  let repoRef;

  log(`running: 'git checkout -B ${RELEASES_BRANCH}'`);
  return git.checkout({B: RELEASES_BRANCH})
  .then(() => {
    log(`running: 'git pull origin ${RELEASES_BRANCH}'`);
    return git.pull(['origin', RELEASES_BRANCH]);
  })
  .then(() => {
    log(`running: 'git merge master'`);
    return git.merge('master');
  })
  .then(() => {
    log('Clearing dist folder');
    return del([ DIST_DIR + '/**/*' ]);
  })
  .then(() => {
    let buildCommand = `npm run-script ${BUILD_SCRIPT}`;
    log(`running: '${buildCommand}'`);
    return exec(buildCommand);
  })
  .then(() => {
    log(`running: 'git add .'`);
    return git.add('.');
  })
  .then(() => {
    log(`running: 'git add ${DIST_DIR} -f'`);
    return git.add({
      _: DIST_DIR,
      f: true
    });
  })
  .then(() => {
    const commitMessage = COMMIT_MESSAGE.replace('%ver%', version);
    log(`running: 'git commit -m ${commitMessage}'`);
    return git.commit({m: commitMessage});
  })
  .then(() => {
    log(`running: 'git tag ${version}'`);
    return git.tag(version);
  })
  .then(() => {
    return git.config({
      'get':true,
      '_': 'remote.origin.url'
    });
  })
  .then((remoteUrl) => {
    repoRef = remoteUrl.split('@').length > 1 ? remoteUrl.split('@')[1] : remoteUrl;
    repoRef = repoRef.trim();
    if (repoRef.startsWith('https://'))
      repoRef = repoRef.substring(8);

    let args = `${RELEASES_BRANCH}:${RELEASES_BRANCH}`;
    if (GH_TOKEN) {
      args = [`https://${GH_TOKEN}@${repoRef}`, args];
    }
    log(`running: 'git push'`);
    return git.push({
      '_': args
    });
  })
  .then(() => {
    let args = [];
    if (GH_TOKEN) {
      args = [`https://${GH_TOKEN}@${repoRef}`];
    }
    log(`running: 'git push --tags'`);
    return git.push({
      'tags': true,
      '_': args
    });
  })
  .finally(() => {
    log('switching back to master branch');
    return git.checkout('master');
  })
  .then(() => {
    log(chalk.green("Released successfully"))
  })
}

function log() {
  console.log.apply(console, arguments);
}

function fail(err) {
  let message = err.message || err.string;
  if (GH_TOKEN)
    message = message.replace(GH_TOKEN, 'xxGH_TOKENxx');
  log(chalk.red('Release failed:'))
  log(chalk.red(message));
  process.exit(1);
}

if (require.main === module) {
  main();
}

module.exports = branchRelease;
<|endoftext|>


<commit_before>var express = require('express')
	, bodyParser = require('body-parser')
	, log = require('npmlog')

	Cloud = require('vigour-js/browser/network/cloud')
    .inject(require('vigour-js/browser/network/cloud/datacloud'))
  , Data = require('vigour-js/data')
  , fs = require('vigour-fs')

  , spriteMaker = require('./spriteMaker')
  , imgManip = require('./imgManip')
  , util = require('./util')

	, config = require('./config')

	, cloud = new Cloud('ws://' + config.cloudHost + ':' + config.cloudPort)
	, data = new Data(cloud.data.get(config.mtvCloudDataFieldName))

	, subscribeObj = {}

subscribeObj[config.mtvCloudDataFieldName] =  {
	// regions: {
		// $: {
		// 	$: {
		'Netherlands': { // Only use Netherlands until the cloud can support more
			$: {	// Only use en until the cloud can support more
				shows: {
					$: {
						img: true
						, number: true
						, seasons: {
							$: {
								number: true
								, episodes: {
									$: {
										img: true
										, number: true
									}
								}
							}
						}
					}
				},
				channels: {
					$: {
						img: true
						, number: true
					}
				}
			}
		}
	// }
}

cloud.subscribe(subscribeObj)

app = express();

app.use(bodyParser.urlencoded({
	extended: true
}));

app.get('/image/:id/:width/:height'
	, function (req, res, next) {
		var tmpDir = config.tmpDir + '/' + Math.random().toString().slice(1)
			, out = config.outDir + '/' + encodeURIComponent(req.originalUrl)
			, desiredDimensions = {
				width: req.params.width
				, height: req.params.height
			}
			, url = util.urlFromId(req.params.id)
			, path = tmpDir + '/' + 'original'
		util.prepare(function (err) {
			if (err) {
				err.message += ": Error creating temp dir"
				err.path = config.tmpDir
				res.status(500).end(err.toString())
			} else {
				fs.mkdir(tmpDir, function (err) {
					if (err) {
						err.message += ": Error creating temp directory"
						err.path = tmpDir
						res.status(500).end(err)
					} else {
						fs.exists(config.outDir, function (exists) {
							if (exists) {
								finish()
							} else {
								fs.mkdir(config.outDir, function (err) {
									if (err) {
										err.message += ": Error creating output directory"
										err.path = config.outDir
										res.status(500).end(err.toString())
									} else {
										finish()
									}
								})
							}
						})
					}
				})
			}
		})
	function finish () {
		fs.writeFile(path
			, url
			, {
				maxTries: config.maxTries
				, retryOn404: true
			}
			, function (err) {
				if (err) {
					err.message += ': Download error'
					err.url = url
					res.status(500).end(err.toString())
					util.cleanup(tmpDir)
				} else {
					imgManip.effect(req.query
						, path
						, desiredDimensions
						, out
						, function (err, newPath) {
							if (err) {
								err.message += ": Error creating image"
								err.path = path
								res.status(500).end(err.toString())
								util.cleanup(tmpDir)
							} else {
								util.setHeaders(res)
								res.sendFile(newPath
									, {
										root: __dirname
									}
									, function (err) {
										if (err) {
											err.message += ": Error sending file"
											log.error(err)
										}
										util.cleanup(tmpDir)
									})
							}
						})
				}
			})
		}
	})

app.get('/sprite/:country/:lang/shows/:width/:height'
	, function (req, res, next) {
		var p = req.params
		req.pathToSpriteData = [p.country
			, p.lang
			, 'shows'
		]
		next()
	}
	, spriteMaker.requestSprite)

// app.get('/sprite/:country/:lang/channels/:width/:height'
// 	, function (req, res, next) {
// 		var p = req.params
// 		requestSprite(req
// 			, res
// 			, next
// 			, [p.country
// 				, p.lang
// 				, 'channels'
// 			])
// 	})

app.get('/sprite/:country/:lang/episodes/:showId/:seasonId/:width/:height'
	, function (req, res, next) {
		var p = req.params
		req.pathToSpriteData = [p.country
			, p.lang
			, 'shows'
			, p.showId
			, 'seasons'
			, p.seasonId
			, 'episodes'
		]
		next()
	}
	, spriteMaker.requestSprite)

app.get('*'
	, function (req, res, next) {
		res.status(400).end(config.invalidRequestMessage)
	})

data.addListener(function listen () {
	app.listen(config.port);
	console.log('Listening on port ', config.port);
	this.removeListener(listen)
})
<commit_msg>Cache constructed images<commit_after>var express = require('express')
	, bodyParser = require('body-parser')
	, log = require('npmlog')

	Cloud = require('vigour-js/browser/network/cloud')
    .inject(require('vigour-js/browser/network/cloud/datacloud'))
  , Data = require('vigour-js/data')
  , fs = require('vigour-fs')

  , spriteMaker = require('./spriteMaker')
  , imgManip = require('./imgManip')
  , util = require('./util')

	, config = require('./config')

	, cloud = new Cloud('ws://' + config.cloudHost + ':' + config.cloudPort)
	, data = new Data(cloud.data.get(config.mtvCloudDataFieldName))

	, subscribeObj = {}

subscribeObj[config.mtvCloudDataFieldName] =  {
	// regions: {
		// $: {
		// 	$: {
		'Netherlands': { // Only use Netherlands until the cloud can support more
			$: {	// Only use en until the cloud can support more
				shows: {
					$: {
						img: true
						, number: true
						, seasons: {
							$: {
								number: true
								, episodes: {
									$: {
										img: true
										, number: true
									}
								}
							}
						}
					}
				},
				channels: {
					$: {
						img: true
						, number: true
					}
				}
			}
		}
	// }
}

cloud.subscribe(subscribeObj)

app = express();

app.use(bodyParser.urlencoded({
	extended: true
}));

app.get('/image/:id/:width/:height'
	, function (req, res, next) {
		var out = config.outDir + '/' + encodeURIComponent(req.originalUrl)
			, tmpDir
			, desiredDimensions
			, url
			, path
		fs.exists(out + '.jpg', function (exists) {
			if (exists) {
				res.sendFile(out + '.jpg'
					, {
						root: __dirname
					}
					, function (err) {
						if (err) {
							console.error(err)
						}
					})
			} else {
				fs.exists(out + '.png', function (exists) {
					if (exists) {
						res.sendFile(out + '.png'
							, {
								root: __dirname
							}
							, function (err) {
								if (err) {
									console.error(err)
								}
							})
					} else {
						tmpDir = config.tmpDir + '/' + Math.random().toString().slice(1)
						desiredDimensions = {
							width: req.params.width
							, height: req.params.height
						}
						url = util.urlFromId(req.params.id)
						path = tmpDir + '/' + 'original'
						util.prepare(function (err) {
							if (err) {
								err.message += ": Error creating temp dir"
								err.path = config.tmpDir
								res.status(500).end(err.toString())
							} else {
								fs.mkdir(tmpDir, function (err) {
									if (err) {
										err.message += ": Error creating temp directory"
										err.path = tmpDir
										res.status(500).end(err)
									} else {
										fs.exists(config.outDir, function (exists) {
											if (exists) {
												finish()
											} else {
												fs.mkdir(config.outDir, function (err) {
													if (err) {
														err.message += ": Error creating output directory"
														err.path = config.outDir
														res.status(500).end(err.toString())
													} else {
														finish()
													}
												})
											}
										})
									}
								})
							}
						})
					function finish () {
						fs.writeFile(path
							, url
							, {
								maxTries: config.maxTries
								, retryOn404: true
							}
							, function (err) {
								if (err) {
									err.message += ': Download error'
									err.url = url
									res.status(500).end(err.toString())
									util.cleanup(tmpDir)
								} else {
									imgManip.effect(req.query
										, path
										, desiredDimensions
										, out
										, function (err, newPath) {
											if (err) {
												err.message += ": Error creating image"
												err.path = path
												res.status(500).end(err.toString())
												util.cleanup(tmpDir)
											} else {
												util.setHeaders(res)
												res.sendFile(newPath
													, {
														root: __dirname
													}
													, function (err) {
														if (err) {
															err.message += ": Error sending file"
															log.error(err)
														}
														util.cleanup(tmpDir)
													})
											}
										})
								}
							})
						}
					}
				})
			}
		})
	})

app.get('/sprite/:country/:lang/shows/:width/:height'
	, function (req, res, next) {
		var p = req.params
		req.pathToSpriteData = [p.country
			, p.lang
			, 'shows'
		]
		next()
	}
	, spriteMaker.requestSprite)

// app.get('/sprite/:country/:lang/channels/:width/:height'
// 	, function (req, res, next) {
// 		var p = req.params
// 		requestSprite(req
// 			, res
// 			, next
// 			, [p.country
// 				, p.lang
// 				, 'channels'
// 			])
// 	})

app.get('/sprite/:country/:lang/episodes/:showId/:seasonId/:width/:height'
	, function (req, res, next) {
		var p = req.params
		req.pathToSpriteData = [p.country
			, p.lang
			, 'shows'
			, p.showId
			, 'seasons'
			, p.seasonId
			, 'episodes'
		]
		next()
	}
	, spriteMaker.requestSprite)

app.get('*'
	, function (req, res, next) {
		res.status(400).end(config.invalidRequestMessage)
	})

data.addListener(function listen () {
	app.listen(config.port);
	console.log('Listening on port ', config.port);
	this.removeListener(listen)
})
<|endoftext|>


<commit_before>'use strict';
//a version from scratch built using Actions on Google Client Library

process.env.DEBUG = 'actions-on-google:*';
const ApiAiApp = require('actions-on-google').ApiAiApp;
const https = require('https');
const http = require('http');
const queryString = require('query-string');

// API.AI actions
const UNRECOGNIZED_DEEP_LINK = 'deeplink.unknown';
const FETCH_INFO = 'fetch.info';

// API.AI parameter names
const CATEGORY_ARGUMENT = 'category';

// API.AI Contexts/lifespans
const SOLAR = 'solar';
const INFORMATION_GIVEN = 'information-given';
const DEFAULT_LIFESPAN = 5;
const END_LIFESPAN = 0;

const PVoutputParameter = {
  // consider adding more like 'peak'
  POWER: 'power',
  ENERGY: 'energy',
  EFFICIENCY: 'efficiency'
};

const LINK_OUT_TEXT = 'Learn more';
const PVOUTPUT_LINK = 'https://pvoutput.org/';
const NEXT_INFO_DIRECTIVE = 'Would you like to know anything else?';
const CONFIRMATION_SUGGESTIONS = ['Sure', 'No thanks'];

const NO_INPUTS = [
  'I didn\'t hear that.',
  'If you\'re still there, say that again.',
  'We can stop here. See you soon.'
];
function convertDate (startDate) {
  var year = startDate.substring(0, 4);
  var month = startDate.substring(4, 6);
  var day = startDate.substring(6, 8);

  return year + '-' + month + '-' + day;
}

exports.PVoutputFullfilment = (request, response) => {
  const app = new ApiAiApp({ request, response });

  //let requestHeader = JSON.stringify(request.headers);
  //console.log('Request headers: ' + requestHeader);
  //let requestBody = JSON.stringify(request.body);
  //console.log('Request body: ' + requestBody);

  function unrecognised (app) {

  }

  function handler (app){

    function fetchInfo (app, service, queryStringArg){
      var PVdict = {"date":"","time":"","energy":"","power":"","efficiency":""};
      var PVmessagesDict = {};
      https.get('https://pvoutput.org/service/r2/'+service+'.jsp' + queryStringArg, function(PVres){
        console.log('sending: https://pvoutput.org/service/r2/'+service+'.jsp' + queryStringArg);
        PVres.setEncoding('utf8');
        PVres.on('data', function(chunk) {
          let PVoutput = chunk.split(',');
          switch (service) {
            case "getstatus":
              PVdict.date = PVoutput[0];
              PVdict.time = PVoutput[1];
              PVdict.energy = (PVoutput[2]/1000).toString();
              PVdict.power = (PVoutput[3]/1000).toString();
              PVdict.efficiency = (PVoutput[6]*100).toString();
              var today = new Date();
              var date = new Date(convertDate(PVdict.date));
              var dateString0 = " on " + date.toDateString() + ". ";
              if (date.toDateString() == today.toDateString()) {
                dateString0 = " today. ";
              }
              PVmessagesDict = {
                  "":"I am sorry please ask again but specify if you want information about power, energy or efficiency. ",
                  "energy": "As of "+ PVdict.time + dateString0 + PVdict.energy + " kilowatt hours had been produced. ",
                  "power":"The power output as of " + PVdict.time + dateString0 + " was " + PVdict.power + " kilowatts. ",
                  "efficiency": "As of "+ PVdict.time + dateString0 +"The solar array was outputting at  " + PVdict.efficiency + " percent of capacity. "};
              break;
            case "getstatistic":
              PVdict.energy = (PVoutput[0]/1000).toString();
              PVdict.energyExported = (PVoutput[1]/1000).toString();
              PVdict.averageEnergy= (PVoutput[2]/1000).toString();
              PVdict.maxEnergy = (PVoutput[4]/1000).toString();
              PVdict.efficiency = (PVoutput[5]*100).toString();
              PVdict.recordEfficiency = (PVoutput[9]*100).toString();
              PVdict.fromDate = PVoutput[7];
              let fromDate = new Date(convertDate(PVdict.fromDate));
              PVdict.toDate = PVoutput[8];
              let toDate = new Date(convertDate(PVdict.toDate));
              var dateString1 = "between " + fromDate.toDateString() + " and " + toDate.toDateString();
              if (PVdict.fromDate == PVdict.toDate) {
                dateString1 = "on "+ fromDate.toDateString();
              }
              PVmessagesDict = {
                  "":"I am sorry please ask again but specify if you want information about power, energy or efficiency. ",
                  "energy": PVdict.energy + " kilowatt hours were produced " + dateString1,
                  "power":"The average power output " + dateString1 + " was " +  " kilowatts. ",
                  "maximumPower" : "The maximum power output " + dateString1 + " was " +  " kilowatts. ",
                  "efficiency":"The average efficiency of the solar array "+ dateString1 +" was  " + PVdict.efficiency + " percent of capacity. "};
              break;
            default:

          }
          //makes dataIntent equal to the parameters made but removes duplicates
          let dataIntent = [...new Set(request.body.result.parameters.PVoutputParameter)];

          var speech = "";
          for (var i = 0; i < dataIntent.length; i++) {
              speech += PVmessagesDict[dataIntent[i]];
          }
          app.ask(speech);
        });
      });
    }

    var myQueryString = {
    sid : request.body.result.parameters.SID.SID,
    key : request.body.result.parameters.readOnlyAPIKey,
    };

    switch (request.body.result.parameters.time.length) {
      //no time specified
      case 0:
        let myQueryStringified0 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus', myQueryStringified0);
        break;
      //just time specified time: 17:30:00
      case 8:
        //pvoutput api does not handle future times very well so we need to check of the time is recent, if it is we will set t to an empty string
        var time1 = request.body.result.parameters.time.slice(0,5);

        let serverDate = new Date();
        var requestDate = new Date();
        requestDate.setHours(parseInt(time1.slice(0,2)));
        requestDate.setMinutes(parseInt(time1.slice(3)));

        let timeLag = serverDate.getTime() - requestDate.getTime()
        if (timeLag <= 600000) {
          myQueryString.t = '';
        } else {
          myQueryString.t = time1;
        }
        let myQueryStringified1 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus',myQueryStringified1);
        break;
      // just date specified in the format of time: 2014-08-09
      case 10:
        let formattedDate = request.body.result.parameters.time.replace(/-/g,'');
        myQueryString.dt = formattedDate;
        myQueryString.df = formattedDate;

        let myQueryStringified2 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatistic',myQueryStringified2);
        break;
      //time periods: 13:30:00/14:30:00
      case 17:

        break;
      //combined date&time: 2014-08-09T16:30:00Z
      case 20:
        let formattedDateTime = request.body.result.parameters.time.replace(/-/g,'').split('T');

        formattedDateTime[1] = formattedDateTime[1].slice(0,5);

        myQueryString.d = formattedDateTime[0];
        myQueryString.t = formattedDateTime[1];

        let myQueryStringified4 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus',myQueryStringified4);
        break;
      //date periods: 2014-01-01/2014-12-31
      case 21:
        let formattedDateRange = request.body.result.parameters.time.replace(/-/g,'').split('/');

        myQueryString.df = formattedDateRange[0];
        myQueryString.dt = formattedDateRange[1];

        let myQueryStringified5 = '?' + queryString.stringify(myQueryString);

        fetchInfo(app, 'getstatistic',myQueryStringified5);
        break;
      //combined date&time period: 2017-02-08T08:00:00Z/2017-02-08T12:00:00Z
      case 41:

        break;
      default:
        fetchInfo(app, 'getstatus', "?"+queryString.stringify(myQueryString));
        break;

  }

  }
  let actionMap = new Map();
  actionMap.set(UNRECOGNIZED_DEEP_LINK, unrecognised);
  actionMap.set(FETCH_INFO, handler);

  app.handleRequest(actionMap);

};
<commit_msg>expands options<commit_after>'use strict';
//a version from scratch built using Actions on Google Client Library

process.env.DEBUG = 'actions-on-google:*';
const ApiAiApp = require('actions-on-google').ApiAiApp;
const https = require('https');
const http = require('http');
const queryString = require('query-string');

// API.AI actions
const UNRECOGNIZED_DEEP_LINK = 'deeplink.unknown';
const FETCH_INFO = 'fetch.info';

// API.AI parameter names
const CATEGORY_ARGUMENT = 'category';

// API.AI Contexts/lifespans
const SOLAR = 'solar';
const INFORMATION_GIVEN = 'information-given';
const DEFAULT_LIFESPAN = 5;
const END_LIFESPAN = 0;

const PVoutputParameter = {
  // consider adding more like 'peak'
  POWER: 'power',
  ENERGY: 'energy',
  EFFICIENCY: 'efficiency'
};

const LINK_OUT_TEXT = 'Learn more';
const PVOUTPUT_LINK = 'https://pvoutput.org/';
const NEXT_INFO_DIRECTIVE = 'Would you like to know anything else?';
const CONFIRMATION_SUGGESTIONS = ['Sure', 'No thanks'];

const NO_INPUTS = [
  'I didn\'t hear that.',
  'If you\'re still there, say that again.',
  'We can stop here. See you soon.'
];
function convertDate (startDate) {
  var year = startDate.substring(0, 4);
  var month = startDate.substring(4, 6);
  var day = startDate.substring(6, 8);

  return year + '-' + month + '-' + day;
}

exports.PVoutputFullfilment = (request, response) => {
  const app = new ApiAiApp({ request, response });

  //let requestHeader = JSON.stringify(request.headers);
  //console.log('Request headers: ' + requestHeader);
  //let requestBody = JSON.stringify(request.body);
  //console.log('Request body: ' + requestBody);

  function unrecognised (app) {

  }

  function handler (app){

    function fetchInfo (app, service, queryStringArg){
      var PVdict = {"date":"","time":"","energy":"","power":"","efficiency":""};
      var PVmessagesDict = {};
      https.get('https://pvoutput.org/service/r2/'+service+'.jsp' + queryStringArg, function(PVres){
        console.log('sending: https://pvoutput.org/service/r2/'+service+'.jsp' + queryStringArg);
        PVres.setEncoding('utf8');
        PVres.on('data', function(chunk) {
          let PVoutput = chunk.split(',');
          switch (service) {
            case "getstatus":
              PVdict.date = PVoutput[0];
              PVdict.time = PVoutput[1];
              PVdict.energy = (PVoutput[2]/1000).toString();
              PVdict.power = (PVoutput[3]/1000).toString();
              PVdict.efficiency = (PVoutput[6]*100).toString();
              var today = new Date();
              var date = new Date(convertDate(PVdict.date));
              var dateString0 = " on " + date.toDateString() + ". ";
              if (date.toDateString() == today.toDateString()) {
                dateString0 = " today. ";
              }
              PVmessagesDict = {
                  "":"I am sorry please ask again but specify if you want information about power, energy or efficiency. ",
                  "energy": "As of "+ PVdict.time + dateString0 + PVdict.energy + " kilowatt hours had been produced. ",
                  "power":"The power output as of " + PVdict.time + dateString0 + " was " + PVdict.power + " kilowatts. ",
                  "efficiency": "As of "+ PVdict.time + dateString0 +"The solar array was outputting at  " + PVdict.efficiency + " percent of capacity. "};
              break;
            case "getstatistic":
              PVdict.energy = (PVoutput[0]/1000).toString();
              PVdict.energyExported = (PVoutput[1]/1000).toString();
              PVdict.averageEnergy= (PVoutput[2]/1000).toString();
              PVdict.maxEnergy = (PVoutput[4]/1000).toString();
              PVdict.efficiency = (PVoutput[5]*100).toString();
              PVdict.recordEfficiency = (PVoutput[9]*100).toString();
              PVdict.recordDate = PVoutput[10];
              let recordDate = new Date(convertDate(PVdict.recordDate));
              PVdict.fromDate = PVoutput[7];
              let fromDate = new Date(convertDate(PVdict.fromDate));
              PVdict.toDate = PVoutput[8];
              let toDate = new Date(convertDate(PVdict.toDate));
              var dateString1 = "between " + fromDate.toDateString() + " and " + toDate.toDateString();
              if (PVdict.fromDate == PVdict.toDate) {
                dateString1 = "on "+ fromDate.toDateString();
              }
              PVmessagesDict = {
                  "":"I am sorry please ask again but specify if you want information about power, energy or efficiency. ",
                  "energy": PVdict.energy + " kilowatt hours were produced " + dateString1,
                  "power":"I am sorry I cant tell you about power output in a date range. ",
                  "averageEnergy":"The average daily energy production " + dateString1 + " was " + PVdict.averageEnergy,
                  "maxEnergy":"The maximum daily energy production " + dateString1 + " was " + PVdict.averageEnergy + ", recorded on "+recordDate.toDateString(),
                  "efficiency":"The average efficiency of the solar array "+ dateString1 +" was  " + PVdict.efficiency + " percent of capacity. "};
              break;
            default:

          }
          //makes dataIntent equal to the parameters made but removes duplicates
          let dataIntent = [...new Set(request.body.result.parameters.PVoutputParameter)];

          var speech = "";
          for (var i = 0; i < dataIntent.length; i++) {
              speech += PVmessagesDict[dataIntent[i]];
          }
          app.ask(speech);
        });
      });
    }

    var myQueryString = {
    sid : request.body.result.parameters.SID.SID,
    key : request.body.result.parameters.readOnlyAPIKey,
    };

    switch (request.body.result.parameters.time.length) {
      //no time specified
      case 0:
        let myQueryStringified0 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus', myQueryStringified0);
        break;
      //just time specified time: 17:30:00
      case 8:
        //pvoutput api does not handle future times very well so we need to check of the time is recent, if it is we will set t to an empty string
        var time1 = request.body.result.parameters.time.slice(0,5);

        let serverDate = new Date();
        var requestDate = new Date();
        requestDate.setHours(parseInt(time1.slice(0,2)));
        requestDate.setMinutes(parseInt(time1.slice(3)));

        let timeLag = serverDate.getTime() - requestDate.getTime()
        if (timeLag <= 600000) {
          myQueryString.t = '';
        } else {
          myQueryString.t = time1;
        }
        let myQueryStringified1 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus',myQueryStringified1);
        break;
      // just date specified in the format of time: 2014-08-09
      case 10:
        let formattedDate = request.body.result.parameters.time.replace(/-/g,'');
        myQueryString.dt = formattedDate;
        myQueryString.df = formattedDate;

        let myQueryStringified2 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatistic',myQueryStringified2);
        break;
      //time periods: 13:30:00/14:30:00
      case 17:

        break;
      //combined date&time: 2014-08-09T16:30:00Z
      case 20:
        let formattedDateTime = request.body.result.parameters.time.replace(/-/g,'').split('T');

        formattedDateTime[1] = formattedDateTime[1].slice(0,5);

        myQueryString.d = formattedDateTime[0];
        myQueryString.t = formattedDateTime[1];

        let myQueryStringified4 = '?' + queryString.stringify(myQueryString);
        fetchInfo(app, 'getstatus',myQueryStringified4);
        break;
      //date periods: 2014-01-01/2014-12-31
      case 21:
        let formattedDateRange = request.body.result.parameters.time.replace(/-/g,'').split('/');

        myQueryString.df = formattedDateRange[0];
        myQueryString.dt = formattedDateRange[1];

        let myQueryStringified5 = '?' + queryString.stringify(myQueryString);

        fetchInfo(app, 'getstatistic',myQueryStringified5);
        break;
      //combined date&time period: 2017-02-08T08:00:00Z/2017-02-08T12:00:00Z
      case 41:

        break;
      default:
        fetchInfo(app, 'getstatus', "?"+queryString.stringify(myQueryString));
        break;

  }

  }
  let actionMap = new Map();
  actionMap.set(UNRECOGNIZED_DEEP_LINK, unrecognised);
  actionMap.set(FETCH_INFO, handler);

  app.handleRequest(actionMap);

};
<|endoftext|>


<commit_before>var fs = require('fs')

fs.readdir('.', function(err, files) {
    if (err) {
        console.log(err)
    } else {
        files.forEach(function(file) {
            if (file.endsWith('.json')) {
                console.log(file);
                console.log(getDockerCommandLine(file))
                console.log()
            }
        });
    }
});

function hasWrapChar(str) {
	var wrapChars = [' ', '&', ';'];
	for (var c in wrapChars)
		if (str.indexOf(wrapChars[c]) !== -1)
			return true;
	return false;
}

function getDockerCommandLine(fileName) {
    var dockerConfig = require('./' + fileName)[0];
    var command = 'docker run -d';
    command += ' --name=' + dockerConfig['Name'].substring(1);

    function getEnvs(dockerConfig) {
        var ret = '';

        var envs = dockerConfig['Config']['Env'];
        if (envs != null) {
            for (var i = 0; i < envs.length; i++) {
                var env = envs[i];
                if (!env.startsWith('PATH') && !env.startsWith('LANG') && !env.startsWith('LC_ALL')) {
                    ret += ' -e ';
                    if (hasWrapChar(env)) {
                        ret += env.substring(0, env.indexOf('=')) + '="' + env.substring(env.indexOf('=')+1) + '"';
                    } else {
                        ret += env;
                    }
                }
            }
        }

        return ret;
    }

    function getHostConfig(dockerConfig) {
        var ret = '';

        if (Object.keys(dockerConfig['HostConfig']['PortBindings']).length > 0) {
            for (var port in dockerConfig['HostConfig']['PortBindings']) {
                var bindings = dockerConfig['HostConfig']['PortBindings'][port];
                for (var i = 0; i < bindings.length; i++) {
                    ret += ' -p ' + bindings[i]['HostPort'] + ':' + port.split('/')[0];
                }
            }
        }

        if (dockerConfig['HostConfig']['Links'] != null) {
            var links = dockerConfig['HostConfig']['Links'];
            for (var i = 0; i < links.length; i++) {
                var link = links[i];
                var splitted = link.split('/');
                ret += ' --link ' + splitted[1] + splitted[3];
            }
        }

        return ret;
    }

    command += getEnvs(dockerConfig);
    command += getHostConfig(dockerConfig);

    command += ' ' + dockerConfig['Config']['Image'];

    return command;
}
<commit_msg>Created documentation for hasWrapChar function<commit_after>var fs = require('fs')

fs.readdir('.', function(err, files) {
    if (err) {
        console.log(err)
    } else {
        files.forEach(function(file) {
            if (file.endsWith('.json')) {
                console.log(file);
                console.log(getDockerCommandLine(file))
                console.log()
            }
        });
    }
});

/**
 * If a environment variable value has one of this characters, it needs to be wrapped with double quotation
 */
function hasWrapChar(str) {
	var wrapChars = [' ', '&', ';'];
	for (var c in wrapChars)
		if (str.indexOf(wrapChars[c]) !== -1)
			return true;
	return false;
}

function getDockerCommandLine(fileName) {
    var dockerConfig = require('./' + fileName)[0];
    var command = 'docker run -d';
    command += ' --name=' + dockerConfig['Name'].substring(1);

    function getEnvs(dockerConfig) {
        var ret = '';

        var envs = dockerConfig['Config']['Env'];
        if (envs != null) {
            for (var i = 0; i < envs.length; i++) {
                var env = envs[i];
                if (!env.startsWith('PATH') && !env.startsWith('LANG') && !env.startsWith('LC_ALL')) {
                    ret += ' -e ';
                    if (hasWrapChar(env)) {
                        ret += env.substring(0, env.indexOf('=')) + '="' + env.substring(env.indexOf('=')+1) + '"';
                    } else {
                        ret += env;
                    }
                }
            }
        }

        return ret;
    }

    function getHostConfig(dockerConfig) {
        var ret = '';

        if (Object.keys(dockerConfig['HostConfig']['PortBindings']).length > 0) {
            for (var port in dockerConfig['HostConfig']['PortBindings']) {
                var bindings = dockerConfig['HostConfig']['PortBindings'][port];
                for (var i = 0; i < bindings.length; i++) {
                    ret += ' -p ' + bindings[i]['HostPort'] + ':' + port.split('/')[0];
                }
            }
        }

        if (dockerConfig['HostConfig']['Links'] != null) {
            var links = dockerConfig['HostConfig']['Links'];
            for (var i = 0; i < links.length; i++) {
                var link = links[i];
                var splitted = link.split('/');
                ret += ' --link ' + splitted[1] + splitted[3];
            }
        }

        return ret;
    }

    command += getEnvs(dockerConfig);
    command += getHostConfig(dockerConfig);

    command += ' ' + dockerConfig['Config']['Image'];

    return command;
}
<|endoftext|>


<commit_before>'use strict';

angular.module('ng-app-config', [])
  .service('$config', Config);

function Config() {
  var vm = this;

  vm.$ = {};
  vm.$.load = load;

  function load(data) {
    for (var key in data) {
      vm[key] = data[key];
    }
  }
}
<commit_msg>refactor(module): change module name to ng.config<commit_after>'use strict';

angular.module('ng.config', [])
  .service('$config', Config);

function Config() {
  var vm = this;

  vm.$ = {};
  vm.$.load = load;

  function load(data) {
    for (var key in data) {
      vm[key] = data[key];
    }
  }
}
<|endoftext|>


<commit_before>"use strict";

var _ = require('lodash');

var asana = require('asana');
var tlsVars = require('./tlsConstants.js')
var asanaKey = process.env.ASANAKEY;
let client = undefined;
let projectID = undefined;

let tlsUsers = {
    pendingPromise: null
};

let autoCacheTimeout = 15000;
let pageLimit = 100;

let tlsTagNames = {
    name: 'tlsTagNames',
    deferredFunctions: [],
    pendingPromise: null,
    refreshTime: 120000
};

let tlsTasks = {
    name: 'tlsTasks',
    data: [],
    deferredFunctions: [],
    pendingPromise: null,
    refreshTime: 30000
};

//stores the static info associated with the tag and task
//requests so that we don't have to pass a million parameters
//when there are multiple pages of data
let asanaRequestDetails = {
    tags: {
        apiFunction: 'findByWorkspace',
        identifier: tlsVars.WORKSPACE_TLS
    },
    tasks: {
        apiFunction: 'findByProject',
        identifier: projectID
    }
}

module.exports = {

    /**
     * Always needs to be run first to startup the connection between node and asana.
     * Everything else uses this connection to run.
     *
     * @param {String} requestedProjectID The id of the project that all other functions will refer to
     * @return {Object} The connection to the Asana server
     **/
    connect: function (requestedProjectID) {
        let tlsAsana = this;
        projectID = requestedProjectID;

        return new Promise(function(resolve, reject){
            try {
                client = asana.Client.create().useAccessToken(asanaKey);
                if (client) {
                    tlsAsana.updateTagNames();
                    tlsAsana.updateTasks();
                    tlsAsana.autoCacheCheck(autoCacheTimeout);
                    resolve(client);
                }
            }
            catch (err) {
                reject(err);
            }
        });
    },

    /**
     * Gets all the users that we are authorized access to with the current API key.
     * Sets a property within tlsUsers that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with user data
     */
    updateUsers: function() {
        tlsUsers.pendingPromise = new Promise( function(resolve, reject){
            client.users.findByWorkspace(36641419235321, {'opt_fields': 'id,name,email'}).then(response => {
                tlsUsers.data = response.data;
                tlsUsers.lastUpdated = Date.now();
                resolve(response);
            });
        });

        return tlsUsers.pendingPromise;
    },

    /**
     * Sets the tlsTagNames variable with the tags currently stored in Asana for quick (cached) reference later.
     * Sets a property within tlsTagNames that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with tag data
     */
    updateTagNames: function() {
        let tlsAsana = this;

        tlsTagNames.pendingPromise = new Promise( function(resolve, reject){
            client.tags.findByWorkspace(tlsVars.WORKSPACE_TLS, {limit: pageLimit}).then(function(response) {
                if( response != undefined) {
                    //hayden..if there are more pages let get the other pages of responses
                    if(response._response.next_page){
                        tlsAsana.combinePaginatedData('tags', response).then(function(response){
                            updateTlsTagCache(response);
                            resolve(tlsTagNames);
                        });
                    }
                    else {
                        updateTlsTagCache(response.data);
                        resolve(tlsTagNames);
                    }
                }
                else{
                    resolve(false);
                }

                function updateTlsTagCache(fullTagData){
                    _.forEach(fullTagData, function(value, key){
                        tlsTagNames[value.name] = value.id;
                    });

                    tlsTagNames['lastUpdated'] = Date.now();
                }
            });
        });

        return tlsTagNames.pendingPromise;
    },

    /**
     * Sets the tlsTasks variable with the tasks currently stored in Asana for quick (cached) reference later.
     * Sets a property within tlsTasks that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with task data
     */
    updateTasks: function(){
        let tlsAsana = this;

        tlsTasks.pendingPromise = new Promise( function(resolve, reject){
            client.tasks.findByProject(projectID, {limit: pageLimit, opt_fields: 'id,name,projects,assignee,external,created_at,tags.name,tags.color'}).then(function(response){
                if(response != undefined){
                    //hayden..if there are more pages let get the other pages of responses
                    if(response._response.next_page){
                        tlsAsana.combinePaginatedData('tasks', response).then(function(response){
                            updateTlsTaskCache(response);
                            resolve(tlsTasks);
                        });
                    }
                    else {
                        updateTlsTaskCache(response.data);
                        resolve(tlsTasks);
                    }
                }
                else{
                    resolve(false);
                }

                function updateTlsTaskCache(fullTaskData){
                    tlsTasks.data = [];
                    _.forEach(fullTaskData, function(value, key){
                        tlsTasks.data.push(value);
                    });

                    tlsTasks['lastUpdated'] = Date.now();
                }
            });
        });

        return tlsTasks.pendingPromise;
    },

    /**
     * Concatonates data arrays -- for now it is the tag names and ids, but I think I can use it for
     * tasks as well. Will change the name if I can use it for tasks also.
     *
     * @param {String} type Request type from Asana API (currently tags or tasks)
     * @param {Object} previousResponse Full Asana response that was paginated
     * @return {Promise} An array of data objects
     */
    combinePaginatedData: function(type, previousResponse){
        let tlsAsana = this;
        let offsetHash = previousResponse._response.next_page.offset;

        //Asana API function needed to get paginated data
        let apiFunction = asanaRequestDetails[type].apiFunction;

        //Name of id used with Asana API function (workspaceId or projectId currently)
        let identifier = asanaRequestDetails[type].identifier;

        return new Promise( function(resolve, reject){
            client[type][apiFunction](identifier, {limit: pageLimit, offset: offsetHash}).then(function(response){
                if(response._response.next_page){
                    tlsAsana.combinePaginatedData(type, response).then(function(response){
                        //combine the previous page's data with the current page
                        let combinedTagData = previousResponse.data.concat(response);
                        resolve(combinedTagData);
                    });
                }else{
                    //combine last page of data with the previous pages' data
                    let combinedTagData = previousResponse.data.concat(response.data);
                    resolve(combinedTagData);
                }
            });
        });
    },

    /**
     * Checks when a cache was last updated and sees if it needs to be refreshed
     *
     * @param {Object} cache - Local cache that may need to be updated
     * @param {Function} updateFunc - Name of the function that will be called if update is necessary
     * @return {Promise} Promise from the cache function that could be finished or in progress
     *                   (cache.pendingPromise), or just being created (updateFunc)
     */
    checkLastCacheUpdate: function(cache, updateFunc){
        //If cache has never been updated see if we can access the pending
        //update promise-if not, explicitly update this cache
        if(!cache.lastUpdated){
            if(cache.pendingPromise){
                return cache.pendingPromise;
            }
            else {
                return updateFunc();
            }
        }
        else if( ( Date.now() - cache.lastUpdated ) >= cache.refreshTime ) {
            //console.log( cache.name + ' cache age X, it is ' + (Date.now() - cache.lastUpdated) + 'ms old --- !!!');
            return updateFunc();
        }
        else {
            //console.log( cache.name + ' cache age $, it is ' + (Date.now() - cache.lastUpdated) + 'ms old');
            return cache.pendingPromise;
        }
    },

    /**
     * Simplifies the tag cache check function call because it is repeated frequently
     */
    checkTagCache: function(){
        return this.checkLastCacheUpdate(tlsTagNames, this.updateTagNames);
    },

    /**
     * Simplifies the task cache check function call because it is repeated frequently
     */
    checkTaskCache: function(){
        return this.checkLastCacheUpdate(tlsTasks, this.updateTasks);
    },

    /**
     * Simplifies the call to both the tag and task cache check function calls because
     * they are repeated frequently
     */
    checkBothCaches: function(){
        let promiseArray = [
            this.checkLastCacheUpdate(tlsTagNames, this.updateTagNames),
            this.checkLastCacheUpdate(tlsTasks, this.updateTasks)
        ];

        return Promise.all(promiseArray);
    },

    /**
     *
     */
    autoCacheCheck: function(timeout){
        let tlsAsana = this;

        return new Promise(function(resolve, reject){
            setTimeout(function(){
                resolve(tlsAsana.checkBothCaches());
            }, timeout);
        }).then(() => {
            return tlsAsana.autoCacheCheck(timeout);
        });
    },

    /**
     * Check the age of the task cache and then gets a list of all of the cached
     * tasks that have a tag with the passed ID
     *
     * @param {Number} tag Tag Id number
     * @return {Array} Array containing all task objects with a specific tag in Asana
     **/
    getTasksByTag: function (tag) {
        return this.checkTaskCache().then(function(){
            return _.filter(tlsTasks.data, function(x){
                return _.find(x.tags, {'id': tag});
            });
        });
    },

    /**
     * Looks for a the local tag cache for a plain english tag name and returns the corresponding
     * Asana tag ID.
     *
     * @param tagName The name of the tag you are looking up in plain english (the Asana tag name)
     * @returns {String} the Asana id that represents the tagName you've passed in. Note that this is a cached tag.
     */
    getTagIDByName: function(tagName){
        return this.checkTagCache().then(function(){
            if(tlsTagNames[tagName]){
                return tlsTagNames[tagName];
            }
            else{
                throw new Error('Error, no tag exists in the cache with that name');
            }
        });
    },

    /**
     * Checks the task cache age and returns information about a specific task
     *
     * @param taskID - the id of the cached task we are interested in
     * @return {Object} Information about a specific task in the task cache
     **/
    getTaskInfoByID: function (taskID) {
        return this.checkTaskCache().then(function(){
            return _.find(tlsTasks.data, function(x){
                return x.id == taskID;
            })
        });
    },

    /**
     * Check the tag and task cache ages and then returns all of the tasks that are unassigned
     *
     * @return {Array} An array containing the task objects that have an unassigned tag
     **/
    getUnassignedTasks: function () {
        var tlsAsana = this;

        return this.checkBothCaches().then(function(){
            return tlsAsana.getTasksByTag( tlsTagNames.captioning_unassigned );
        });
    },

    /**
     * Returns all of the new requests
     *
     * @return {Promise} A promise containing only the new requests in Asana
     **/
    getNewTasks: function () {
        var tlsAsana = this;

        return this.checkBothCaches().then(function(){
            return tlsAsana.getTasksByTag( tlsTagNames['New Request'] );
        });
    },

    /**
    * Returns a list of all of the projects currently in Asana
    *
    * @return {Promise} A promise containing a list of all of the projects
    */
    getAllProjects: function(){
        return new Promise( function(resolve, reject){
            client.projects.findAll({team:tlsVars.TEAM_TLSMEDIA}).then( function(projectList){
                resolve(projectList.data);
            });
        });
    },

    /**
    * switches from the current tag to a new tag
    *
    * @param taskID the id of the task that you'd like to switch
    * @param oldTag the tagID from tlsConstants that you'd like to switch from
    * @param newTag the tagID from tlsConstants that you'd like to switch to
    * @return {promise} A promise containing the task information after change
    */
    switchTag: function(taskID, oldTag, newTag){
        let tlsAsana = this;

        let promiseArray = [
            this.getTagIDByName(oldTag),
            this.getTagIDByName(newTag)
        ];

        return Promise.all(promiseArray).then(IDresponses => {
            return new Promise( function(resolve, reject){
                client.tasks.removeTag(taskID, {tag: IDresponses[0] }).then(response => {
                    client.tasks.addTag(taskID, {tag: IDresponses[1] }).then(response => {
                        tlsAsana.updateTasks(); //update the local task cache if we changed the tags associated with a task
                        resolve(response);
                    });
                }).catch(reason => { //catch any errors from the call to Asana
                    console.log(reason);
                    reject(reason);
                });
            });
        }).catch(reason => { //catch any errors from the Promise.all promise
            console.log(reason);
            reject(reason);
        });
    },

    /**
     * Create new task
     */
    //createTask: function(projectID, name, description, due_date, dataObj){
    createTask: function(name, dataObj){

        //1. Have to handle assignee here...have to make a function to
        //   look at assignee data and get an id by a name or something

        //2. Just have to quick test the due_date to make sure thats what the
        //   API wants----may also have to do some JS date formatting

        console.log('data submitted to createTask func')
        console.log(dataObj);

        return client.tasks.create({
                'name': name,
                'description': 'description',
                'assignee': {'id': '170705266868499'},
                'workspace': 36641419235321,
                'projects': projectID,
                'external': {
                    'data': JSON.stringify(dataObj)
                }
            }
        );

    }

}
<commit_msg>Adds typechecking for projectID string<commit_after>"use strict";

var _ = require('lodash');

var asana = require('asana');
var tlsVars = require('./tlsConstants.js')
var asanaKey = process.env.ASANAKEY;
let client = undefined;
let projectID = undefined;

let tlsUsers = {
    pendingPromise: null
};

let autoCacheTimeout = 15000;
let pageLimit = 100;

let tlsTagNames = {
    name: 'tlsTagNames',
    deferredFunctions: [],
    pendingPromise: null,
    refreshTime: 120000
};

let tlsTasks = {
    name: 'tlsTasks',
    data: [],
    deferredFunctions: [],
    pendingPromise: null,
    refreshTime: 30000
};

//stores the static info associated with the tag and task
//requests so that we don't have to pass a million parameters
//when there are multiple pages of data
let asanaRequestDetails = {
    tags: {
        apiFunction: 'findByWorkspace',
        identifier: tlsVars.WORKSPACE_TLS
    },
    tasks: {
        apiFunction: 'findByProject',
        identifier: projectID
    }
}

module.exports = {

    /**
     * Always needs to be run first to startup the connection between node and asana.
     * Everything else uses this connection to run.
     *
     * @param {String} requestedProjectID The id of the project that all other functions will refer to
     * @return {Object} The connection to the Asana server
     **/
    connect: function (requestedProjectID) {
        let tlsAsana = this;

        if( !(typeof requestedProjectID == "string") ){
            throw new TypeError('Requested project ID parameter must be a string') ;
        }
        else {
            projectID = requestedProjectID;
        }

        return new Promise(function(resolve, reject){
            try {
                client = asana.Client.create().useAccessToken(asanaKey);
                if (client) {
                    tlsAsana.updateTagNames();
                    tlsAsana.updateTasks();
                    tlsAsana.autoCacheCheck(autoCacheTimeout);
                    resolve(client);
                }
            }
            catch (err) {
                reject(err);
            }
        });
    },

    /**
     * Gets all the users that we are authorized access to with the current API key.
     * Sets a property within tlsUsers that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with user data
     */
    updateUsers: function() {
        tlsUsers.pendingPromise = new Promise( function(resolve, reject){
            client.users.findByWorkspace(36641419235321, {'opt_fields': 'id,name,email'}).then(response => {
                tlsUsers.data = response.data;
                tlsUsers.lastUpdated = Date.now();
                resolve(response);
            });
        });

        return tlsUsers.pendingPromise;
    },

    /**
     * Sets the tlsTagNames variable with the tags currently stored in Asana for quick (cached) reference later.
     * Sets a property within tlsTagNames that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with tag data
     */
    updateTagNames: function() {
        let tlsAsana = this;

        tlsTagNames.pendingPromise = new Promise( function(resolve, reject){
            client.tags.findByWorkspace(tlsVars.WORKSPACE_TLS, {limit: pageLimit}).then(function(response) {
                if( response != undefined) {
                    //hayden..if there are more pages let get the other pages of responses
                    if(response._response.next_page){
                        tlsAsana.combinePaginatedData('tags', response).then(function(response){
                            updateTlsTagCache(response);
                            resolve(tlsTagNames);
                        });
                    }
                    else {
                        updateTlsTagCache(response.data);
                        resolve(tlsTagNames);
                    }
                }
                else{
                    resolve(false);
                }

                function updateTlsTagCache(fullTagData){
                    _.forEach(fullTagData, function(value, key){
                        tlsTagNames[value.name] = value.id;
                    });

                    tlsTagNames['lastUpdated'] = Date.now();
                }
            });
        });

        return tlsTagNames.pendingPromise;
    },

    /**
     * Sets the tlsTasks variable with the tasks currently stored in Asana for quick (cached) reference later.
     * Sets a property within tlsTasks that represents the last promise that was created that may or may not be fulfilled.
     *
     * @return {Promise} Promise returned by Asana API, fulfilled with task data
     */
    updateTasks: function(){
        let tlsAsana = this;

        tlsTasks.pendingPromise = new Promise( function(resolve, reject){
            client.tasks.findByProject(projectID, {limit: pageLimit, opt_fields: 'id,name,projects,assignee,external,created_at,tags.name,tags.color'}).then(function(response){
                if(response != undefined){
                    //hayden..if there are more pages let get the other pages of responses
                    if(response._response.next_page){
                        tlsAsana.combinePaginatedData('tasks', response).then(function(response){
                            updateTlsTaskCache(response);
                            resolve(tlsTasks);
                        });
                    }
                    else {
                        updateTlsTaskCache(response.data);
                        resolve(tlsTasks);
                    }
                }
                else{
                    resolve(false);
                }

                function updateTlsTaskCache(fullTaskData){
                    tlsTasks.data = [];
                    _.forEach(fullTaskData, function(value, key){
                        tlsTasks.data.push(value);
                    });

                    tlsTasks['lastUpdated'] = Date.now();
                }
            });
        });

        return tlsTasks.pendingPromise;
    },

    /**
     * Concatonates data arrays -- for now it is the tag names and ids, but I think I can use it for
     * tasks as well. Will change the name if I can use it for tasks also.
     *
     * @param {String} type Request type from Asana API (currently tags or tasks)
     * @param {Object} previousResponse Full Asana response that was paginated
     * @return {Promise} An array of data objects
     */
    combinePaginatedData: function(type, previousResponse){
        let tlsAsana = this;
        let offsetHash = previousResponse._response.next_page.offset;

        //Asana API function needed to get paginated data
        let apiFunction = asanaRequestDetails[type].apiFunction;

        //Name of id used with Asana API function (workspaceId or projectId currently)
        let identifier = asanaRequestDetails[type].identifier;

        return new Promise( function(resolve, reject){
            client[type][apiFunction](identifier, {limit: pageLimit, offset: offsetHash}).then(function(response){
                if(response._response.next_page){
                    tlsAsana.combinePaginatedData(type, response).then(function(response){
                        //combine the previous page's data with the current page
                        let combinedTagData = previousResponse.data.concat(response);
                        resolve(combinedTagData);
                    });
                }else{
                    //combine last page of data with the previous pages' data
                    let combinedTagData = previousResponse.data.concat(response.data);
                    resolve(combinedTagData);
                }
            });
        });
    },

    /**
     * Checks when a cache was last updated and sees if it needs to be refreshed
     *
     * @param {Object} cache - Local cache that may need to be updated
     * @param {Function} updateFunc - Name of the function that will be called if update is necessary
     * @return {Promise} Promise from the cache function that could be finished or in progress
     *                   (cache.pendingPromise), or just being created (updateFunc)
     */
    checkLastCacheUpdate: function(cache, updateFunc){
        //If cache has never been updated see if we can access the pending
        //update promise-if not, explicitly update this cache
        if(!cache.lastUpdated){
            if(cache.pendingPromise){
                return cache.pendingPromise;
            }
            else {
                return updateFunc();
            }
        }
        else if( ( Date.now() - cache.lastUpdated ) >= cache.refreshTime ) {
            //console.log( cache.name + ' cache age X, it is ' + (Date.now() - cache.lastUpdated) + 'ms old --- !!!');
            return updateFunc();
        }
        else {
            //console.log( cache.name + ' cache age $, it is ' + (Date.now() - cache.lastUpdated) + 'ms old');
            return cache.pendingPromise;
        }
    },

    /**
     * Simplifies the tag cache check function call because it is repeated frequently
     */
    checkTagCache: function(){
        return this.checkLastCacheUpdate(tlsTagNames, this.updateTagNames);
    },

    /**
     * Simplifies the task cache check function call because it is repeated frequently
     */
    checkTaskCache: function(){
        return this.checkLastCacheUpdate(tlsTasks, this.updateTasks);
    },

    /**
     * Simplifies the call to both the tag and task cache check function calls because
     * they are repeated frequently
     */
    checkBothCaches: function(){
        let promiseArray = [
            this.checkLastCacheUpdate(tlsTagNames, this.updateTagNames),
            this.checkLastCacheUpdate(tlsTasks, this.updateTasks)
        ];

        return Promise.all(promiseArray);
    },

    /**
     *
     */
    autoCacheCheck: function(timeout){
        let tlsAsana = this;

        return new Promise(function(resolve, reject){
            setTimeout(function(){
                resolve(tlsAsana.checkBothCaches());
            }, timeout);
        }).then(() => {
            return tlsAsana.autoCacheCheck(timeout);
        });
    },

    /**
     * Check the age of the task cache and then gets a list of all of the cached
     * tasks that have a tag with the passed ID
     *
     * @param {Number} tag Tag Id number
     * @return {Array} Array containing all task objects with a specific tag in Asana
     **/
    getTasksByTag: function (tag) {
        return this.checkTaskCache().then(function(){
            return _.filter(tlsTasks.data, function(x){
                return _.find(x.tags, {'id': tag});
            });
        });
    },

    /**
     * Looks for a the local tag cache for a plain english tag name and returns the corresponding
     * Asana tag ID.
     *
     * @param tagName The name of the tag you are looking up in plain english (the Asana tag name)
     * @returns {String} the Asana id that represents the tagName you've passed in. Note that this is a cached tag.
     */
    getTagIDByName: function(tagName){
        return this.checkTagCache().then(function(){
            if(tlsTagNames[tagName]){
                return tlsTagNames[tagName];
            }
            else{
                throw new Error('Error, no tag exists in the cache with that name');
            }
        });
    },

    /**
     * Checks the task cache age and returns information about a specific task
     *
     * @param taskID - the id of the cached task we are interested in
     * @return {Object} Information about a specific task in the task cache
     **/
    getTaskInfoByID: function (taskID) {
        return this.checkTaskCache().then(function(){
            return _.find(tlsTasks.data, function(x){
                return x.id == taskID;
            })
        });
    },

    /**
     * Check the tag and task cache ages and then returns all of the tasks that are unassigned
     *
     * @return {Array} An array containing the task objects that have an unassigned tag
     **/
    getUnassignedTasks: function () {
        var tlsAsana = this;

        return this.checkBothCaches().then(function(){
            return tlsAsana.getTasksByTag( tlsTagNames.captioning_unassigned );
        });
    },

    /**
     * Returns all of the new requests
     *
     * @return {Promise} A promise containing only the new requests in Asana
     **/
    getNewTasks: function () {
        var tlsAsana = this;

        return this.checkBothCaches().then(function(){
            return tlsAsana.getTasksByTag( tlsTagNames['New Request'] );
        });
    },

    /**
    * Returns a list of all of the projects currently in Asana
    *
    * @return {Promise} A promise containing a list of all of the projects
    */
    getAllProjects: function(){
        return new Promise( function(resolve, reject){
            client.projects.findAll({team:tlsVars.TEAM_TLSMEDIA}).then( function(projectList){
                resolve(projectList.data);
            });
        });
    },

    /**
    * switches from the current tag to a new tag
    *
    * @param taskID the id of the task that you'd like to switch
    * @param oldTag the tagID from tlsConstants that you'd like to switch from
    * @param newTag the tagID from tlsConstants that you'd like to switch to
    * @return {promise} A promise containing the task information after change
    */
    switchTag: function(taskID, oldTag, newTag){
        let tlsAsana = this;

        let promiseArray = [
            this.getTagIDByName(oldTag),
            this.getTagIDByName(newTag)
        ];

        return Promise.all(promiseArray).then(IDresponses => {
            return new Promise( function(resolve, reject){
                client.tasks.removeTag(taskID, {tag: IDresponses[0] }).then(response => {
                    client.tasks.addTag(taskID, {tag: IDresponses[1] }).then(response => {
                        tlsAsana.updateTasks(); //update the local task cache if we changed the tags associated with a task
                        resolve(response);
                    });
                }).catch(reason => { //catch any errors from the call to Asana
                    console.log(reason);
                    reject(reason);
                });
            });
        }).catch(reason => { //catch any errors from the Promise.all promise
            console.log(reason);
            reject(reason);
        });
    },

    /**
     * Create new task
     */
    //createTask: function(projectID, name, description, due_date, dataObj){
    createTask: function(name, dataObj){

        //1. Have to handle assignee here...have to make a function to
        //   look at assignee data and get an id by a name or something

        //2. Just have to quick test the due_date to make sure thats what the
        //   API wants----may also have to do some JS date formatting

        console.log('data submitted to createTask func')
        console.log(dataObj);

        return client.tasks.create({
                'name': name,
                'description': 'description',
                'assignee': {'id': '170705266868499'},
                'workspace': 36641419235321,
                'projects': projectID,
                'external': {
                    'data': JSON.stringify(dataObj)
                }
            }
        );

    }

}
<|endoftext|>