<commit_before>angular.module('starter', ['ionic', 'ngCordova', 'app.AppControl', 'app.AchievementCtrl', 'app.MainCtrl', 'app.AIControl', 'app.skillTreeController', 'app.helloWorldController', 'app.quizController', 'app.reviewController', 'app.dayController', 'starter.controllers', 'starter.services', 'hc.marked', 'ionic.rating', 'tabSlideBox', 'jett.ionic.filter.bar', 'pascalprecht.translate'])
  .run(function ($ionicPlatform) {
    $ionicPlatform.ready(function () {
      if (typeof analytics !== 'undefined') {
        analytics.startTrackerWithId('UA-71907748-1');
        analytics.trackView('Growth')
      } else {
        console.log("Google Analytics plugin could not be loaded.")
      }
      if (window.cordova && window.cordova.plugins.Keyboard) {
        cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
        cordova.plugins.Keyboard.disableScroll(true);

      }
      if (window.StatusBar) {
        // org.apache.cordova.statusbar required
        //StatusBar.styleDefault();
        StatusBar.backgroundColorByHexString("#387ef5");
      }
    });
  })
  .config(function ($stateProvider, $urlRouterProvider, $translateProvider) {

    $translateProvider.translations('en', SIDE_MENU['en']);
    $translateProvider.translations('en', MAIN_VIEW_MENU['en']);
    $translateProvider.translations('en', PAGE_TITLE['en']);
    $translateProvider.translations('en', DAY_TITLE['en']);
    $translateProvider.translations('zh-cn', DAY_TITLE['zh-cn']);
    $translateProvider.translations('zh-cn', SIDE_MENU['zh-cn']);
    $translateProvider.translations('zh-cn', MAIN_VIEW_MENU['zh-cn']);
    $translateProvider.translations('zh-cn', PAGE_TITLE['zh-cn']);

    $translateProvider.preferredLanguage('zh-cn');
    var language = window.localStorage.getItem('language');
      if (language !== undefined) {
      $translateProvider.preferredLanguage(language);
    }
    $translateProvider.fallbackLanguage('en');
  })
  .config(['markedProvider', function (markedProvider) {
    marked.Lexer.rules.gfm.heading = marked.Lexer.rules.normal.heading;
    marked.Lexer.rules.tables.heading = marked.Lexer.rules.normal.heading;

    markedProvider.setOptions({
      gfm: true,
      tables: true,
      breaks: false,
      pedantic: false,
      sanitize: true,
      smartLists: true,
      smartypants: false,
      highlight: function (code, lang) {
        if (lang) {
          return hljs.highlight(lang, code, true).value;
        } else {
          return hljs.highlightAuto(code).value;
        }
      }
    });
    markedProvider.setRenderer({
      heading: function (text, level) {
        var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
        return '<h' + level + '>' +
          text + '</h' + level + '>';
      },
      image: function (href) {
        return "";
      }
    });
  }])
  .config(function ($stateProvider, $urlRouterProvider) {
    $stateProvider

      .state('app', {
        url: '/app',
        abstract: true,
        templateUrl: 'templates/menu.html',
        controller: 'AppCtrl'
      })

      .state('app.main', {
        url: '/main',
        views: {
          'menuContent': {
            templateUrl: 'templates/main.html',
            controller: 'MainCtrl'
          }
        }
      })

      .state('app.wiki', {
        url: "/wiki",
        views: {
          'menuContent': {
            templateUrl: "templates/game/wiki.html",
            controller: 'WikiCtrl'
          }
        }
      })
      .state('app.language', {
        url: "/language/:language_info",
        views: {
          'menuContent': {
            templateUrl: "templates/game/wiki_detail.html",
            controller: 'WikiDetailCtrl'
          }
        }
      })
      .state('app.levelSelect', {
        url: "/level",
        views: {
          'menuContent': {
            templateUrl: "templates/game/level.html",
            controller: 'LevelSelectCtrl'
          }
        }
      })

      .state('app.single', {
        url: "/level/:level",
        views: {
          'menuContent': {
            templateUrl: "templates/game/level_quiz.html",
            controller: 'QuizCtrl'
          }
        }
      })

      .state('app.solution', {
        url: "/solution",
        views: {
          'menuContent': {
            templateUrl: "templates/solution.html",
            controller: 'SolutionCtrl'
          }
        }
      })

      .state('app.stack', {
        url: "/stack/:stack",
        views: {
          'menuContent': {
            templateUrl: "templates/skills/stack.html",
            controller: 'StackCtrl'
          }
        }
      })

      .state('app.about', {
        url: '/about',
        views: {
          'menuContent': {
            templateUrl: 'templates/about.html',
            controller: 'AboutCtrl'
          }
        }
      })

      .state('app.help', {
        url: '/help',
        views: {
          'menuContent': {
            templateUrl: 'templates/help.html'
          }
        }
      })

      .state('app.setting', {
        url: '/setting',
        views: {
          'menuContent': {
            templateUrl: 'templates/setting.html',
            controller: 'SettingCtrl'
          }
        }
      })

      .state('app.skilltree', {
        url: '/skilltree',
        views: {
          'menuContent': {
            templateUrl: 'templates/skilltree.html',
            controller: 'skillTreeControl'
          }
        }
      })

      .state('app.ai', {
        url: '/ai',
        views: {
          'menuContent': {
            templateUrl: 'templates/skills/ai.html',
            controller: 'AIControl'
          }
        }
      })

      .state('app.achievement', {
        url: '/achievement',
        views: {
          'menuContent': {
            templateUrl: 'templates/skills/achievement.html',
            controller: 'AchievementCtrl'
          }
        }
      })

      .state('app.article', {
        url: '/article/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/article-detail.html',
            controller: 'ArticleCtrl'
          }
        }
      })

      .state('app.articles', {
        url: '/articles',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/article-list.html',
            controller: 'ArticleListCtrl'
          }
        }
      })

      .state('app.review', {
        url: '/review/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/review-detail.html',
            controller: 'ReviewCtrl'
          }
        }
      })

      .state('app.reviews', {
        url: '/reviews',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/review-list.html',
            controller: 'ReviewListCtrl'
          }
        }
      })

      .state('app.book', {
        url: '/book',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/book.html'
          }
        }
      })

      .state('app.seven', {
        url: '/seven',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/seven.html'
          }
        }
      })

      .state('app.faq', {
        url: '/faq',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/faq.html'
          }
        }
      })

      .state('app.feedback', {
        url: '/feedback',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/feedback.html',
            controller: 'FeedbackCtrl'
          }
        }
      })

      .state('app.exam', {
        url: '/exam',
        views: {
          'menuContent': {
            templateUrl: 'templates/exam.html'
          }
        }
      })

      .state('app.day0', {
        url: '/day/0',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day0.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day1', {
        url: '/day/1',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day1.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day2', {
        url: '/day/2',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day2.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day3', {
        url: '/day/3',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day3.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day4', {
        url: '/day/4',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day4.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day5', {
        url: '/day/5',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day5.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day6', {
        url: '/day/6',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day6.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day7', {
        url: '/day/7',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day7.html',
            controller: 'DayCtrl'
          }
        }
      })

      .state('app.prog', {
        url: '/books/prog',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/prog.html'
          }
        }
      })
      .state('app.arch', {
        url: '/books/arch',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/arch.html'
          }
        }
      })
      .state('app.method', {
        url: '/books/method',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/method.html'
          }
        }
      })
      .state('app.think', {
        url: '/books/think',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/think.html'
          }
        }
      })
      .state('app.bookfe', {
        url: '/books/fe',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/fe.html'
          }
        }
      })

      .state('app.quiz', {
        url: '/quiz/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/game/quiz.html',
            controller: 'AllQuizCtrl'
          }
        }
      })
      .state('app.advancedQuiz', {
        url: '/advance-quiz/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/game/advance-quiz.html',
            controller: 'AdvancedQuizCtrl'
          }
        }
      })
    ;

    $urlRouterProvider.otherwise('/app/main');
  });
<commit_msg>align title center<commit_after>angular.module('starter', ['ionic', 'ngCordova', 'app.AppControl', 'app.AchievementCtrl', 'app.MainCtrl', 'app.AIControl', 'app.skillTreeController', 'app.helloWorldController', 'app.quizController', 'app.reviewController', 'app.dayController', 'starter.controllers', 'starter.services', 'hc.marked', 'ionic.rating', 'tabSlideBox', 'jett.ionic.filter.bar', 'pascalprecht.translate'])
  .run(function ($ionicPlatform) {
    $ionicPlatform.ready(function () {
      if (typeof analytics !== 'undefined') {
        analytics.startTrackerWithId('UA-71907748-1');
        analytics.trackView('Growth')
      } else {
        console.log("Google Analytics plugin could not be loaded.")
      }
      if (window.cordova && window.cordova.plugins.Keyboard) {
        cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
        cordova.plugins.Keyboard.disableScroll(true);

      }
      if (window.StatusBar) {
        // org.apache.cordova.statusbar required
        //StatusBar.styleDefault();
        StatusBar.backgroundColorByHexString("#387ef5");
      }
    });
  })
  .config(function($ionicConfigProvider) {
    $ionicConfigProvider.navBar.alignTitle('center');
  })
  .config(function ($stateProvider, $urlRouterProvider, $translateProvider) {
    $translateProvider.translations('en', SIDE_MENU['en']);
    $translateProvider.translations('en', MAIN_VIEW_MENU['en']);
    $translateProvider.translations('en', PAGE_TITLE['en']);
    $translateProvider.translations('en', DAY_TITLE['en']);
    $translateProvider.translations('zh-cn', DAY_TITLE['zh-cn']);
    $translateProvider.translations('zh-cn', SIDE_MENU['zh-cn']);
    $translateProvider.translations('zh-cn', MAIN_VIEW_MENU['zh-cn']);
    $translateProvider.translations('zh-cn', PAGE_TITLE['zh-cn']);

    $translateProvider.preferredLanguage('zh-cn');
    var language = window.localStorage.getItem('language');
      if (language !== undefined) {
      $translateProvider.preferredLanguage(language);
    }
    $translateProvider.fallbackLanguage('en');
  })
  .config(['markedProvider', function (markedProvider) {
    marked.Lexer.rules.gfm.heading = marked.Lexer.rules.normal.heading;
    marked.Lexer.rules.tables.heading = marked.Lexer.rules.normal.heading;

    markedProvider.setOptions({
      gfm: true,
      tables: true,
      breaks: false,
      pedantic: false,
      sanitize: true,
      smartLists: true,
      smartypants: false,
      highlight: function (code, lang) {
        if (lang) {
          return hljs.highlight(lang, code, true).value;
        } else {
          return hljs.highlightAuto(code).value;
        }
      }
    });
    markedProvider.setRenderer({
      heading: function (text, level) {
        var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
        return '<h' + level + '>' + text + '</h' + level + '>';
      },
      image: function (href) {
        return "";
      }
    });
  }])
  .config(function ($stateProvider, $urlRouterProvider) {
    $stateProvider

      .state('app', {
        url: '/app',
        abstract: true,
        templateUrl: 'templates/menu.html',
        controller: 'AppCtrl'
      })

      .state('app.main', {
        url: '/main',
        views: {
          'menuContent': {
            templateUrl: 'templates/main.html',
            controller: 'MainCtrl'
          }
        }
      })

      .state('app.wiki', {
        url: "/wiki",
        views: {
          'menuContent': {
            templateUrl: "templates/game/wiki.html",
            controller: 'WikiCtrl'
          }
        }
      })
      .state('app.language', {
        url: "/language/:language_info",
        views: {
          'menuContent': {
            templateUrl: "templates/game/wiki_detail.html",
            controller: 'WikiDetailCtrl'
          }
        }
      })
      .state('app.levelSelect', {
        url: "/level",
        views: {
          'menuContent': {
            templateUrl: "templates/game/level.html",
            controller: 'LevelSelectCtrl'
          }
        }
      })

      .state('app.single', {
        url: "/level/:level",
        views: {
          'menuContent': {
            templateUrl: "templates/game/level_quiz.html",
            controller: 'QuizCtrl'
          }
        }
      })

      .state('app.solution', {
        url: "/solution",
        views: {
          'menuContent': {
            templateUrl: "templates/solution.html",
            controller: 'SolutionCtrl'
          }
        }
      })

      .state('app.stack', {
        url: "/stack/:stack",
        views: {
          'menuContent': {
            templateUrl: "templates/skills/stack.html",
            controller: 'StackCtrl'
          }
        }
      })

      .state('app.about', {
        url: '/about',
        views: {
          'menuContent': {
            templateUrl: 'templates/about.html',
            controller: 'AboutCtrl'
          }
        }
      })

      .state('app.help', {
        url: '/help',
        views: {
          'menuContent': {
            templateUrl: 'templates/help.html'
          }
        }
      })

      .state('app.setting', {
        url: '/setting',
        views: {
          'menuContent': {
            templateUrl: 'templates/setting.html',
            controller: 'SettingCtrl'
          }
        }
      })

      .state('app.skilltree', {
        url: '/skilltree',
        views: {
          'menuContent': {
            templateUrl: 'templates/skilltree.html',
            controller: 'skillTreeControl'
          }
        }
      })

      .state('app.ai', {
        url: '/ai',
        views: {
          'menuContent': {
            templateUrl: 'templates/skills/ai.html',
            controller: 'AIControl'
          }
        }
      })

      .state('app.achievement', {
        url: '/achievement',
        views: {
          'menuContent': {
            templateUrl: 'templates/skills/achievement.html',
            controller: 'AchievementCtrl'
          }
        }
      })

      .state('app.article', {
        url: '/article/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/article-detail.html',
            controller: 'ArticleCtrl'
          }
        }
      })

      .state('app.articles', {
        url: '/articles',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/article-list.html',
            controller: 'ArticleListCtrl'
          }
        }
      })

      .state('app.review', {
        url: '/review/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/review-detail.html',
            controller: 'ReviewCtrl'
          }
        }
      })

      .state('app.reviews', {
        url: '/reviews',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/review-list.html',
            controller: 'ReviewListCtrl'
          }
        }
      })

      .state('app.book', {
        url: '/book',
        views: {
          'menuContent': {
            templateUrl: 'templates/read/book.html'
          }
        }
      })

      .state('app.seven', {
        url: '/seven',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/seven.html'
          }
        }
      })

      .state('app.faq', {
        url: '/faq',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/faq.html'
          }
        }
      })

      .state('app.feedback', {
        url: '/feedback',
        views: {
          'menuContent': {
            templateUrl: 'templates/more/feedback.html',
            controller: 'FeedbackCtrl'
          }
        }
      })

      .state('app.exam', {
        url: '/exam',
        views: {
          'menuContent': {
            templateUrl: 'templates/exam.html'
          }
        }
      })

      .state('app.day0', {
        url: '/day/0',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day0.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day1', {
        url: '/day/1',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day1.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day2', {
        url: '/day/2',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day2.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day3', {
        url: '/day/3',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day3.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day4', {
        url: '/day/4',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day4.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day5', {
        url: '/day/5',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day5.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day6', {
        url: '/day/6',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day6.html',
            controller: 'DayCtrl'
          }
        }
      })
      .state('app.day7', {
        url: '/day/7',
        views: {
          'menuContent': {
            templateUrl: 'templates/days/day7.html',
            controller: 'DayCtrl'
          }
        }
      })

      .state('app.prog', {
        url: '/books/prog',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/prog.html'
          }
        }
      })
      .state('app.arch', {
        url: '/books/arch',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/arch.html'
          }
        }
      })
      .state('app.method', {
        url: '/books/method',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/method.html'
          }
        }
      })
      .state('app.think', {
        url: '/books/think',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/think.html'
          }
        }
      })
      .state('app.bookfe', {
        url: '/books/fe',
        views: {
          'menuContent': {
            templateUrl: 'templates/books/fe.html'
          }
        }
      })

      .state('app.quiz', {
        url: '/quiz/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/game/quiz.html',
            controller: 'AllQuizCtrl'
          }
        }
      })
      .state('app.advancedQuiz', {
        url: '/advance-quiz/:slug',
        views: {
          'menuContent': {
            templateUrl: 'templates/game/advance-quiz.html',
            controller: 'AdvancedQuizCtrl'
          }
        }
      })
    ;

    $urlRouterProvider.otherwise('/app/main');
  });
<|endoftext|>


<commit_before><commit_msg>test injectInElement<commit_after><|endoftext|>


<commit_before>/*******************
 * Helper functions
 ******************/<commit_msg>global handlebar helper loggedIn<commit_after>/*******************
 * Helper functions
 ******************/

/*******************
 * Handlebar Helper functions
 ******************/

Handlebars.registerHelper('loggedIn', function () {
    return Meteor.userId();
});<|endoftext|>


<commit_before><commit_msg>disable failing vuepress test, which is unimportant ATM<commit_after><|endoftext|>


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

function createHREF( id ){
    var domain = 'tournaments';
    return 'http://localhost:8080/api/v0/' + domain + '/' + id;
}

module.exports = [
    {
        'type': 'POST',
        'name': 'tournaments',
        'response': function (req, res) {

            var responseBody = {};

            var requiredProperties = ['name'];

            if ( !requestValidator.validate( req, requiredProperties )){
                responseBody = {message: 'Missing request body properties. Check the API documentation.'};
                res.status(400).send(responseBody);
                return;
            }

            var APIKey = req.get('APIKey');

            if (!APIKey) {
                responseBody = {message: 'Missing APIKey header'};
                res.status(403).send(responseBody);
                return;
            }

            var tournamentPromise = storage.addTournamentAsync( req.body, APIKey );

            var successCallback = function(tournament){
                tournament.href = createHREF(tournament._id);
                res.status(201).send(tournament);
            };

            var errorCallback = function(error){
                responseBody = {message: error};
                res.status(403).send(responseBody);
            };

            tournamentPromise.then(successCallback, errorCallback);
        }
    },
    {
        'type': 'GET',
        'name': 'tournaments/:id?',
        'response': function (req, res) {
            var responseBody = {};

            var tournamentPromise = storage.getTournamentsAsync(req.params.id);

            var successCallback = function(tournamentsList){
                if( tournamentsList ){
                    for( var i in tournamentsList ){
                        tournamentsList[i].href = createHREF(tournamentsList[i]._id);
                    }
                    res.status(200).send(tournamentsList);
                } else {
                    responseBody = {message: 'Could not find tournament/tournaments'};
                    res.status(404).send(responseBody);
                }
            };

            var errorCallback = function(error){
                responseBody = {message: error};
                res.status(500).send(responseBody);
            };

            tournamentPromise.then(successCallback, errorCallback);
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/registerUsers',
        'response': function (req, res) {
            var responseBody = {};
            if ( !req.params.id || !req.body || !req.body.usersList){
                responseBody = {message: 'Bad request. Check the API documentation.'};
                res.status(400).send(responseBody);
                return;
            }

            storage.registerUsers( req.params.id, req.body.usersList )
            .then( function(registration){
                if( registration ){
                   res.status(200).send(registration);
                } else {
                   res.status(500).send(registration);
                }
            }, function(message){
                res.status(500).send( {message: message} );
            });
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/beginTournament',
        'response': function (req, res) {
            var responseBody = {};
            res.status(501).send({message: 'beginTournament service is not available yet'});
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/concludeTournament',
        'response': function (req, res) {
            var responseBody = {};
            res.status(501).send({message: 'concludeTournament service is not available yet'});
        }
    }
];
<commit_msg>Refactoring<commit_after>var storage = require('./storage.js');
var requestValidator = require('./requestValidator.js');

function createHREF( id ){
    var domain = 'tournaments';
    return 'http://localhost:8080/api/v0/' + domain + '/' + id;
}

module.exports = [
    {
        'type': 'POST',
        'name': 'tournaments',
        'response': function (req, res) {

            var responseBody = {};

            var requiredProperties = ['name'];

            if ( !requestValidator.validate( req, requiredProperties )){
                responseBody = {message: 'Missing request body properties. Check the API documentation.'};
                res.status(400).send(responseBody);
                return;
            }

            var APIKey = req.get('APIKey');

            if (!APIKey) {
                responseBody = {message: 'Missing APIKey header'};
                res.status(403).send(responseBody);
                return;
            }

            storage.addTournamentAsync( req.body, APIKey ).then( function(tournament){
                tournament.href = createHREF(tournament._id);
                res.status(201).send(tournament);
            }, function(error){
                responseBody = {message: error};
                res.status(403).send(responseBody);
            });
        }
    },
    {
        'type': 'GET',
        'name': 'tournaments/:id?',
        'response': function (req, res) {
            var responseBody = {};

            storage.getTournamentsAsync(req.params.id).then( function(tournamentsList){
                if( tournamentsList ){
                    for( var i in tournamentsList ){
                        tournamentsList[i].href = createHREF(tournamentsList[i]._id);
                    }
                    res.status(200).send(tournamentsList);
                } else {
                    responseBody = {message: 'Could not find tournament/tournaments'};
                    res.status(404).send(responseBody);
                }
            },  function(error){
                responseBody = {message: error};
                res.status(500).send(responseBody);
            });
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/registerUsers',
        'response': function (req, res) {
            var responseBody = {};
            if ( !req.params.id || !req.body || !req.body.usersList){
                responseBody = {message: 'Bad request. Check the API documentation.'};
                res.status(400).send(responseBody);
                return;
            }

            storage.registerUsers( req.params.id, req.body.usersList ).then( function(registration){
                if( registration ){
                   res.status(200).send(registration);
                } else {
                   res.status(500).send(registration);
                }
            }, function(message){
                res.status(500).send( {message: message} );
            });
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/beginTournament',
        'response': function (req, res) {
            var responseBody = {};
            res.status(501).send({message: 'beginTournament service is not available yet'});
        }
    },
    {
        'type': 'POST',
        'name': 'tournaments/:id/concludeTournament',
        'response': function (req, res) {
            var responseBody = {};
            res.status(501).send({message: 'concludeTournament service is not available yet'});
        }
    }
];
<|endoftext|>


<commit_before>
var Parser = require('html5').Parser;

module.exports = function (html, callback) {
	var parser = new Parser();
	parser.parse(html);
	callback();
};
<commit_msg>updated html5 wrapper<commit_after>
var Parser = require('html5').SAXParser;

module.exports = function (html, callback) {
	var parser = new Parser();
	var noop = function() {};
	parser.contentHandler = {
		startDocument: noop,
		endDocument: noop,
		startElement: noop,
		endElement: noop,
		characters: noop
	};
	parser.parse(html);
	callback();
};
<|endoftext|>


<commit_before>var Lab = require('lab');
var VM = require('../lib/vm');
var assert  = require('chai').assert;

var lab = exports.lab = Lab.script();

lab.experiment('VM', function() {

  var vm = new VM();

  lab.test('.rejectEmpty()', function(done) {
    assert.deepEqual(
      vm.rejectEmpty(['a', null, 'b', '', 'c']),
      ['a', 'b', 'c']
    );
    done();
  });

  lab.test('.flatten()', function(done) {
    assert.deepEqual(
      vm.flatten([1, [2, 3], [4, [5, [6, 7]]]]),
      ['1', '2', '3', '4', '5', '6', '7']
    );

    assert.deepEqual(
      vm.flatten([1, 2, [3], [4, [5, 6], 7], [8, 9]]),
      ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    );

    assert.deepEqual(
      vm.flatten([1, 2, [], [3, [4, 5, []], 6]]),
      ['1', '2', '3', '4', '5', '6']
    );
    done();
  });

  lab.test('.escape()', function(done) {
    assert.deepEqual(vm.escape(), '');
    assert.deepEqual(vm.escape(null), '');
    assert.deepEqual(vm.escape(' '), ' ');
    assert.deepEqual(vm.escape('<'), '<');
    assert.deepEqual(vm.escape('>'), '>');
    assert.deepEqual(vm.escape('"'), '"');
    assert.deepEqual(vm.escape('&'), '&');
    assert.deepEqual(vm.escape('<javascript>alert("alert!")</javascript>'), '<javascript>alert("alert!")</javascript>');

    done();
  });

  lab.test('.safe()', function(done) {
    assert.deepEqual(vm.escape(vm.safe('<javascript>alert("alert!")</javascript>')), '<javascript>alert("alert!")</javascript>');
    assert.deepEqual(vm.escape(vm.safe('')), '');
    assert.deepEqual(vm.escape(vm.safe()), '');
    assert.deepEqual(vm.escape(vm.safe(null)), '');

    done();
  });
});
<commit_msg>Migrate vm tests<commit_after>var VM = require('../lib/vm');

describe('VM', function() {

  var vm = new VM();

  it('.rejectEmpty()', function() {
    expect(vm.rejectEmpty(['a', null, 'b', '', 'c'])).toEqual(['a', 'b', 'c']);
  });

  it('.flatten()', function() {
    expect(vm.flatten([1, [2, 3], [4, [5, [6, 7]]]]))
    .toEqual(['1', '2', '3', '4', '5', '6', '7']);

    expect(vm.flatten([1, 2, [3], [4, [5, 6], 7], [8, 9]]))
    .toEqual(['1', '2', '3', '4', '5', '6', '7', '8', '9']);

    expect(vm.flatten([1, 2, [], [3, [4, 5, []], 6]]))
    .toEqual(['1', '2', '3', '4', '5', '6']);
  });

  it('.escape()', function() {
    expect(vm.escape()).toEqual('');
    expect(vm.escape(null)).toEqual('');
    expect(vm.escape(' ')).toEqual(' ');
    expect(vm.escape('<')).toEqual('<');
    expect(vm.escape('>')).toEqual('>');
    expect(vm.escape('"')).toEqual('"');
    expect(vm.escape('&')).toEqual('&');
    expect(vm.escape('<javascript>alert("alert!")</javascript>'))
      .toEqual('<javascript>alert("alert!")</javascript>');
  });

  it('.safe()', function() {
    expect(vm.escape(vm.safe('<javascript>alert("alert!")</javascript>'))).toEqual('<javascript>alert("alert!")</javascript>');
    expect(vm.escape(vm.safe(''))).toEqual('');
    expect(vm.escape(vm.safe())).toEqual('');
    expect(vm.escape(vm.safe(null))).toEqual('');
  });
});
<|endoftext|>


<commit_before>'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();
const IceCream = require('../model/icecream');

const iceCreamRouter = module.exports = exports = express.Router();

iceCreamRouter.get('/', (req, res, next) => {
  IceCream.find({}, (err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.get('/:id', (req, res, next) => {
  IceCream.find({_id: req.params.id}, (err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.post('/', jsonParser, (req, res, next) => {
  let newIceCream = new IceCream(req.body);
  newIceCream.save((err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.put('/:id', jsonParser, (req, res, next) => {
  let _id = req.params.id;
  console.log('looking for id and req.body', _id, req.body);
  IceCream.findOneAndUpdate({_id: _id}, req.body, (err, icecream) => {
    console.log('data from findOneAndUpdate',icecream);
    let message = 'successfully updated';
    res.json({message:message, data:icecream});
  });
});

iceCreamRouter.delete('/:id', (req, res, next) => {
  let _id = req.params.id;
  IceCream.findOneAndRemove({_id: _id}, (err, icecream) => {
    if(err) return next(err);
    let message = 'successfully deleted';
    res.json({message:message, data:icecream});
  });
});
<commit_msg>fix err handling<commit_after>'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json();
const IceCream = require('../model/icecream');

const iceCreamRouter = module.exports = exports = express.Router();

iceCreamRouter.get('/', (req, res, next) => {
  IceCream.find({}, (err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.get('/:id', (req, res, next) => {
  IceCream.find({_id: req.params.id}, (err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.post('/', jsonParser, (req, res, next) => {
  let newIceCream = new IceCream(req.body);
  newIceCream.save((err, icecream) => {
    if(err) return next(err);
    res.json(icecream);
  });
});

iceCreamRouter.put('/:id', jsonParser, (req, res, next) => {
  let _id = req.params.id;
  console.log('looking for id and req.body', _id, req.body);
  IceCream.findOneAndUpdate({_id: _id}, req.body, (err, icecream) => {
    if(err) return next(err);
    let message = 'successfully updated';
    res.json({message:message, data:icecream});
  });
});

iceCreamRouter.delete('/:id', (req, res, next) => {
  let _id = req.params.id;
  IceCream.findOneAndRemove({_id: _id}, (err, icecream) => {
    if(err) return next(err);
    let message = 'successfully deleted';
    res.json({message:message, data:icecream});
  });
});
<|endoftext|>


<commit_before>var tpl = {

    // Hash of preloaded templates for the app
    templates:{},

    // Recursively pre-load all the templates for the app.
    // This implementation should be changed in a production environment. All the template files should be
    // concatenated in a single file.
    loadTemplates:function (names, callback) {

        var that = this;

        var loadTemplate = function (index) {
            var name = names[index];
            console.log('Loading template: ' + name + ', index: ' + index);
            $.get('templates/en/' + name + '.html', function (data) {
                that.templates[name] = data;
                index++;
                if (index < names.length) {
                    loadTemplate(index);
                } else {
                    callback();
                }
            });
        };

        loadTemplate(0);
    },

    // Get template by name from hash of preloaded templates
    get:function (name) {
        return this.templates[name];
    }

};

(function (FMS, Backbone, _, $) {
    _.extend(FMS, {
        templates: [
            'home', 'around', 'offline', 'save_offline', 'reports', 'address_search', 'existing', 'photo', 'details', 'submit', 'submit_email', 'submit_name', 'submit_password', 'sent'
        ],

        isOffline: 0,
        initialized: 0,
        users: new FMS.Users(),
        currentUser: null,
        currentLocation: null,
        currentPosition: null,

        currentDraft: new FMS.Draft(),
        allDrafts: new FMS.Drafts(),

        reportToView: null,

        online: function() {
            FMS.isOffline = 0;
        },

        offline: function() {
            FMS.isOffline = 1;
        },

        saveCurrentDraft: function() {
            FMS.router.pause();
            FMS.allDrafts.add( FMS.currentDraft );
            FMS.currentDraft.save();
            localStorage.currentDraftID = FMS.currentDraft.id;
        },

        loadCurrentDraft: function() {
            if ( localStorage.currentDraftID && localStorage.currentDraftID != 'null' ) {
                var r = FMS.allDrafts.get( localStorage.currentDraftID );
                if ( r ) {
                    FMS.currentDraft = r;
                }
            }
            localStorage.currentDraftID = null;
            if ( navigator && navigator.connection && ( navigator.connection.type == Connection.NONE ||
                    navigator.connection.type == Connection.UNKNOWN ) ) {
                FMS.offline();
            }
        },

        removeDraft: function(draftID, removePhoto) {
            console.log( draftID );
            var draft = FMS.allDrafts.get(draftID);
            console.log( draft );
            var uri = draft.get('file');
            FMS.allDrafts.remove(draft);
            draft.destroy();

            if ( removePhoto && uri ) {
                return FMS.files.deleteURI( uri );
            }
            var p = $.Deferred();
            p.resolve();
            return p;
        },

        initialize: function () {
            if ( this.initialized == 1 ) {
                return this;
            }
            FMS.initialized = 1;
            tpl.loadTemplates( FMS.templates, function() {
                _.extend(FMS, {
                    router: new FMS.appRouter(),
                    locator: new FMS.Locate()
                });
                _.extend( FMS.locator, Backbone.Events );

                // we only ever have the details of one user
                FMS.users.fetch();
                if ( FMS.users.length > 0 ) {
                    FMS.currentUser = FMS.users.get(1);
                }
                if ( FMS.currentUser === null ) {
                    FMS.currentUser = new FMS.User({id: 1});
                }

                document.addEventListener('pause', function() { FMS.saveCurrentDraft(); }, false);
                document.addEventListener('resume', function() { FMS.loadCurrentDraft(); }, false);
                document.addEventListener('backbutton', function() { FMS.router.back(); }, true);
                document.addEventListener('offline', function() { FMS.offline(); }, true);
                document.addEventListener('online', function() { FMS.online(); }, true);

                FMS.allDrafts.comparator = function(a,b) { var a_date = a.get('created'), b_date = b.get('created'); return a_date === b_date ? 0 : a_date < b_date ? 1 : -1; };
                FMS.allDrafts.fetch();
                FMS.loadCurrentDraft();

                Backbone.history.start();
                navigator.splashscreen.hide();
            });
        }
    });
})(FMS, Backbone, _, $);

var androidStartUp = function() {
    // deviceready does not fire on some android versions very reliably so
    // we do this instead

    if (FMS.initialized === 1) {
        return;
    }

    if ( typeof device != 'undefined' ) {
        if ( device.platform == 'Android' ) {
            FMS.initialize();
        }
    } else {
        window.setTimeout( androidStartUp, 1000 );
    }
};

document.addEventListener('deviceready', FMS.initialize, false);
window.setTimeout( androidStartUp, 2000 );
<commit_msg>display standard jquery mobile busy spinner when we are making an ajax request<commit_after>var tpl = {

    // Hash of preloaded templates for the app
    templates:{},

    // Recursively pre-load all the templates for the app.
    // This implementation should be changed in a production environment. All the template files should be
    // concatenated in a single file.
    loadTemplates:function (names, callback) {

        var that = this;

        var loadTemplate = function (index) {
            var name = names[index];
            console.log('Loading template: ' + name + ', index: ' + index);
            $.get('templates/en/' + name + '.html', function (data) {
                that.templates[name] = data;
                index++;
                if (index < names.length) {
                    loadTemplate(index);
                } else {
                    callback();
                }
            });
        };

        loadTemplate(0);
    },

    // Get template by name from hash of preloaded templates
    get:function (name) {
        return this.templates[name];
    }

};

(function (FMS, Backbone, _, $) {
    _.extend(FMS, {
        templates: [
            'home', 'around', 'offline', 'save_offline', 'reports', 'address_search', 'existing', 'photo', 'details', 'submit', 'submit_email', 'submit_name', 'submit_password', 'sent'
        ],

        isOffline: 0,
        initialized: 0,
        users: new FMS.Users(),
        currentUser: null,
        currentLocation: null,
        currentPosition: null,

        currentDraft: new FMS.Draft(),
        allDrafts: new FMS.Drafts(),

        reportToView: null,

        online: function() {
            FMS.isOffline = 0;
        },

        offline: function() {
            FMS.isOffline = 1;
        },

        saveCurrentDraft: function() {
            FMS.router.pause();
            FMS.allDrafts.add( FMS.currentDraft );
            FMS.currentDraft.save();
            localStorage.currentDraftID = FMS.currentDraft.id;
        },

        loadCurrentDraft: function() {
            if ( localStorage.currentDraftID && localStorage.currentDraftID != 'null' ) {
                var r = FMS.allDrafts.get( localStorage.currentDraftID );
                if ( r ) {
                    FMS.currentDraft = r;
                }
            }
            localStorage.currentDraftID = null;
            if ( navigator && navigator.connection && ( navigator.connection.type == Connection.NONE ||
                    navigator.connection.type == Connection.UNKNOWN ) ) {
                FMS.offline();
            }
        },

        removeDraft: function(draftID, removePhoto) {
            console.log( draftID );
            var draft = FMS.allDrafts.get(draftID);
            console.log( draft );
            var uri = draft.get('file');
            FMS.allDrafts.remove(draft);
            draft.destroy();

            if ( removePhoto && uri ) {
                return FMS.files.deleteURI( uri );
            }
            var p = $.Deferred();
            p.resolve();
            return p;
        },

        initialize: function () {
            if ( this.initialized == 1 ) {
                return this;
            }
            FMS.initialized = 1;
            tpl.loadTemplates( FMS.templates, function() {
                _.extend(FMS, {
                    router: new FMS.appRouter(),
                    locator: new FMS.Locate()
                });
                _.extend( FMS.locator, Backbone.Events );

                // we only ever have the details of one user
                FMS.users.fetch();
                if ( FMS.users.length > 0 ) {
                    FMS.currentUser = FMS.users.get(1);
                }
                if ( FMS.currentUser === null ) {
                    FMS.currentUser = new FMS.User({id: 1});
                }

                document.addEventListener('pause', function() { FMS.saveCurrentDraft(); }, false);
                document.addEventListener('resume', function() { FMS.loadCurrentDraft(); }, false);
                document.addEventListener('backbutton', function() { FMS.router.back(); }, true);
                document.addEventListener('offline', function() { FMS.offline(); }, true);
                document.addEventListener('online', function() { FMS.online(); }, true);

                $(document).on('ajaxStart', function() { console.log('ajax on'); $.mobile.loading('show'); } );
                $(document).on('ajaxStop', function() { console.log('ajax off'); $.mobile.loading('hide'); } );

                FMS.allDrafts.comparator = function(a,b) { var a_date = a.get('created'), b_date = b.get('created'); return a_date === b_date ? 0 : a_date < b_date ? 1 : -1; };
                FMS.allDrafts.fetch();
                FMS.loadCurrentDraft();

                Backbone.history.start();
                navigator.splashscreen.hide();
            });
        }
    });
})(FMS, Backbone, _, $);

var androidStartUp = function() {
    // deviceready does not fire on some android versions very reliably so
    // we do this instead

    if (FMS.initialized === 1) {
        return;
    }

    if ( typeof device != 'undefined' ) {
        if ( device.platform == 'Android' ) {
            FMS.initialize();
        }
    } else {
        window.setTimeout( androidStartUp, 1000 );
    }
};

document.addEventListener('deviceready', FMS.initialize, false);
window.setTimeout( androidStartUp, 2000 );
<|endoftext|>


<commit_before>/*
 Tomloprod Modal 1.0.0

 The MIT License (MIT)

 Copyright (c) 2015 by Tomás López.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

var TomloprodModal=function(){"use strict";function h(a,b,c){[].forEach.call(a,function(a){a.style[b]=c})}function i(a){var b=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css",c.styleSheet?c.styleSheet.cssText=a:c.appendChild(document.createTextNode(a)),b.appendChild(c)}function j(a,b){return a.classList?a.classList.contains(b):new RegExp("(^| )"+b+"( |$)","gi").test(a.className)}function k(a,b){a.classList?a.classList.add(b):a.className+=" "+b}function l(a,b){var c=0,d=a.length;for(c=0;c<d;c+=1)if(a[c].toString()===b.toString())return c;return-1}function m(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(new RegExp("(^|\\b)"+b.split(" ").join("|")+"(\\b|$)","gi")," ")}function n(a,b,c){a.style.left=b+"px",a.style.top=c+"px",f&&console.info("TomloprodModal: Dragging. Coord X: "+b+"px | Coord Y: "+c+"px")}function o(a){a=a||window.event,27===a.keyCode&&TomloprodModal.closeModal()}var a=null,b=!0,c=!0,d=!1,e={},f=!1,g=".tm-avoidSelection{-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}";return{modal:[],isOpen:!1,openModal:function(e){TomloprodModal.isOpen&&TomloprodModal.closeModal(),TomloprodModal.modal=document.getElementById(e),TomloprodModal.modal?(c&&j(TomloprodModal.modal,"tm-draggable")&&(TomloprodModal.modal.setAttribute("onmousedown","TomloprodModal.startDragging(this,event);"),TomloprodModal.modal.setAttribute("onmouseup","TomloprodModal.stopDragging(this);")),k(TomloprodModal.modal,"tm-showModal"),a=TomloprodModal.modal.querySelector(".tm-closeButton"),a.addEventListener("click",TomloprodModal.closeModal,!1),d&&document.querySelector(".tm-overlay").addEventListener("click",TomloprodModal.closeModal,!1),b&&(document.onkeyup=o),TomloprodModal.isOpen=!0,TomloprodModal.fire("opened")):f&&console.error("TomloprodModal: Cannot find the indicated modal window.")},registerHandler:function(a,b){var c=!0;e[a]?l(e[a],b)===-1?e[a].push(b):(c=!1,console.error("TomloprodModal: The event ''"+a+"'' already contain one handler with the next function:\n\n "+b)):e[a]=[b],f&&c&&console.info("TomloprodModal: There are one new handler registered to the event ''"+a+"'':\n\n "+b+". \n\nTotal handlers of ''"+a+"'' event: "+e[a].length)},removeHandler:function(a,b){if(!e[a])return!1;if(b=b||!1){var c=l(e[a],b);return c>-1&&(e[a].splice(c,1),f&&console.info("TomloprodModal: The handlers with the name ''"+a+"'' have been deleted successfully. ("+b+")"),!0)}delete e[a],f&&console.info("TomloprodModal: The handler ''"+a+"'' has been deleted successfully. ("+b+")")},fire:function(a){if(!e[a])return f&&console.info("TomloprodModal: There aren't any handlers registered with that name."),!1;var b;for(b=0;b<e[a].length;b+=1)e[a][b].apply(window,Array.prototype.slice.call(arguments,1))},start:function(a){i(g);var e=null;if(void 0!==a)for(e in a)if(void 0!==a[e])switch(e){case"draggable":c=a[e];break;case"bgColor":h(document.getElementsByClassName("tm-wrapper"),"backgroundColor",a[e]);break;case"textColor":h(document.getElementsByClassName("tm-wrapper"),"color",a[e]),h(document.getElementsByClassName("tm-content"),"color",a[e]);break;case"closeOnOverlay":d=a[e];break;case"overlayColor":document.querySelector(".tm-overlay").style.backgroundColor=a[e];break;case"removeOverlay":a[e]&&document.querySelector(".tm-overlay").parentNode.removeChild(document.querySelector(".tm-overlay"));break;case"showMessages":f=a[e];break;case"closeOnEsc":b=a[e];break;case"idMainContainer":k(document.getElementById(a[e]),"tm-MainContainer")}document.onclick=function(a){a=a||window.event,j(a.target,"tm-trigger")&&(TomloprodModal.openModal(a.target.getAttribute("data-tm-modal")),a.preventDefault())};for(var l=document.getElementsByTagName("A"),m=0;m<l.length;m++){var n=l[m];j(n,"tm-trigger")&&(n.onclick=function(a){a=a||window.event,TomloprodModal.openModal(this.getAttribute("data-tm-modal")),a.preventDefault()})}},stop:function(){document.onclick=null;for(var a=document.getElementsByTagName("A"),b=0;b<a.length;b++){var c=a[b];c.onclick=null}},closeModal:function(b){void 0!==b&&b.stopPropagation(),m(TomloprodModal.modal,"tm-showModal"),a.removeEventListener("click",TomloprodModal.closeModal,!1);var c=TomloprodModal.modal.querySelectorAll(".tm-emptyOnClose"),d=0;for(d=0;d<c.length;d+=1)"INPUT"===c[d].tagName?c[d].value="":c[d].innerHTML="";TomloprodModal.isOpen=!1,TomloprodModal.fire("closed")},startDragging:function(a,b){b=b||window.event,a.style.cursor="move";var c=a.offsetTop,d=a.offsetLeft,e=TomloprodModal.modal.offsetWidth/2,f=TomloprodModal.modal.offsetHeight/2,g=parseInt(window.innerWidth,10),h=parseInt(window.innerHeight,10),i=b.clientX-d,j=b.clientY-c;document.onmousemove=function(b){b=b||window.event;var c=b.clientX-i,d=b.clientY-j;c<e&&(c=e),c+e>g&&(c=g-e),d<f&&(d=f),d+f>h&&(d=h-f),k(document.getElementsByTagName("body")[0],"tm-avoidSelection"),k(TomloprodModal.modal,"tm-avoidSelection"),n(a,c,d)}},stopDragging:function(a){a.style.cursor="default",m(document.getElementsByTagName("body")[0],"tm-avoidSelection"),m(TomloprodModal.modal,"tm-avoidSelection"),TomloprodModal.fire("stopDragging"),document.onmousemove=function(){}}}}();
<commit_msg>Added border-radius parameter<commit_after>/*
 Tomloprod Modal 1.0.0

 The MIT License (MIT)

 Copyright (c) 2015 by Tomás López.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

var TomloprodModal=function(){"use strict";function h(a,b,c){[].forEach.call(a,function(a){a.style[b]=c})}function i(a){var b=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css",c.styleSheet?c.styleSheet.cssText=a:c.appendChild(document.createTextNode(a)),b.appendChild(c)}function j(a,b){return a.classList?a.classList.contains(b):new RegExp("(^| )"+b+"( |$)","gi").test(a.className)}function k(a,b){a.classList?a.classList.add(b):a.className+=" "+b}function l(a,b){var c=0,d=a.length;for(c=0;c<d;c+=1)if(a[c].toString()===b.toString())return c;return-1}function m(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(new RegExp("(^|\\b)"+b.split(" ").join("|")+"(\\b|$)","gi")," ")}function n(a,b,c){a.style.left=b+"px",a.style.top=c+"px",f&&console.info("TomloprodModal: Dragging. Coord X: "+b+"px | Coord Y: "+c+"px")}function o(a){a=a||window.event,27===a.keyCode&&TomloprodModal.closeModal()}var a=null,b=!0,c=!0,d=!1,e={},f=!1,g=".tm-avoidSelection{-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}";return{modal:[],isOpen:!1,openModal:function(e){TomloprodModal.isOpen&&TomloprodModal.closeModal(),TomloprodModal.modal=document.getElementById(e),TomloprodModal.modal?(c&&j(TomloprodModal.modal,"tm-draggable")&&(TomloprodModal.modal.setAttribute("onmousedown","TomloprodModal.startDragging(this,event);"),TomloprodModal.modal.setAttribute("onmouseup","TomloprodModal.stopDragging(this);")),k(TomloprodModal.modal,"tm-showModal"),a=TomloprodModal.modal.querySelector(".tm-closeButton"),a.addEventListener("click",TomloprodModal.closeModal,!1),d&&document.querySelector(".tm-overlay").addEventListener("click",TomloprodModal.closeModal,!1),b&&(document.onkeyup=o),TomloprodModal.isOpen=!0,TomloprodModal.fire("opened")):f&&console.error("TomloprodModal: Cannot find the indicated modal window.")},registerHandler:function(a,b){var c=!0;e[a]?l(e[a],b)===-1?e[a].push(b):(c=!1,console.error("TomloprodModal: The event ''"+a+"'' already contain one handler with the next function:\n\n "+b)):e[a]=[b],f&&c&&console.info("TomloprodModal: There are one new handler registered to the event ''"+a+"'':\n\n "+b+". \n\nTotal handlers of ''"+a+"'' event: "+e[a].length)},removeHandler:function(a,b){if(!e[a])return!1;if(b=b||!1){var c=l(e[a],b);return c>-1&&(e[a].splice(c,1),f&&console.info("TomloprodModal: The handlers with the name ''"+a+"'' have been deleted successfully. ("+b+")"),!0)}delete e[a],f&&console.info("TomloprodModal: The handler ''"+a+"'' has been deleted successfully. ("+b+")")},fire:function(a){if(!e[a])return f&&console.info("TomloprodModal: There aren't any handlers registered with that name."),!1;var b;for(b=0;b<e[a].length;b+=1)e[a][b].apply(window,Array.prototype.slice.call(arguments,1))},start:function(a){i(g);var e=null;if(void 0!==a)for(e in a)if(void 0!==a[e])switch(e){case"draggable":c=a[e];break;case"bgColor":h(document.getElementsByClassName("tm-wrapper"),"backgroundColor",a[e]);break;case"borderRadius":h(document.getElementsByClassName("tm-wrapper"),"-webkit-border-radius",a[e]),h(document.getElementsByClassName("tm-wrapper"),"-moz-border-radius",a[e]),h(document.getElementsByClassName("tm-wrapper"),"border-radius",a[e]);break;case"textColor":h(document.getElementsByClassName("tm-wrapper"),"color",a[e]),h(document.getElementsByClassName("tm-content"),"color",a[e]);break;case"closeOnOverlay":d=a[e];break;case"overlayColor":document.querySelector(".tm-overlay").style.backgroundColor=a[e];break;case"removeOverlay":a[e]&&document.querySelector(".tm-overlay").parentNode.removeChild(document.querySelector(".tm-overlay"));break;case"showMessages":f=a[e];break;case"closeOnEsc":b=a[e];break;case"idMainContainer":k(document.getElementById(a[e]),"tm-MainContainer")}document.onclick=function(a){a=a||window.event,j(a.target,"tm-trigger")&&(TomloprodModal.openModal(a.target.getAttribute("data-tm-modal")),a.preventDefault())};for(var l=document.getElementsByTagName("A"),m=0;m<l.length;m++){var n=l[m];j(n,"tm-trigger")&&(n.onclick=function(a){a=a||window.event,TomloprodModal.openModal(this.getAttribute("data-tm-modal")),a.preventDefault()})}},stop:function(){document.onclick=null;for(var a=document.getElementsByTagName("A"),b=0;b<a.length;b++){var c=a[b];c.onclick=null}},closeModal:function(b){void 0!==b&&b.stopPropagation(),m(TomloprodModal.modal,"tm-showModal"),a.removeEventListener("click",TomloprodModal.closeModal,!1);var c=TomloprodModal.modal.querySelectorAll(".tm-emptyOnClose"),d=0;for(d=0;d<c.length;d+=1)"INPUT"===c[d].tagName?c[d].value="":c[d].innerHTML="";TomloprodModal.isOpen=!1,TomloprodModal.fire("closed")},startDragging:function(a,b){b=b||window.event,a.style.cursor="move";var c=a.offsetTop,d=a.offsetLeft,e=TomloprodModal.modal.offsetWidth/2,f=TomloprodModal.modal.offsetHeight/2,g=parseInt(window.innerWidth,10),h=parseInt(window.innerHeight,10),i=b.clientX-d,j=b.clientY-c;document.onmousemove=function(b){b=b||window.event;var c=b.clientX-i,d=b.clientY-j;c<e&&(c=e),c+e>g&&(c=g-e),d<f&&(d=f),d+f>h&&(d=h-f),k(document.getElementsByTagName("body")[0],"tm-avoidSelection"),k(TomloprodModal.modal,"tm-avoidSelection"),n(a,c,d)}},stopDragging:function(a){a.style.cursor="default",m(document.getElementsByTagName("body")[0],"tm-avoidSelection"),m(TomloprodModal.modal,"tm-avoidSelection"),TomloprodModal.fire("stopDragging"),document.onmousemove=function(){}}}}();
<|endoftext|>


<commit_before>import { Mongo } from 'meteor/mongo';

export const Builds = new Mongo.Collection('builds');

function addBuild(id) {
  console.log(id);

  let obj = {
    id: id,
    revision: id.substr(id.length - 40),
    owner: id.substr(0, id.length - 41),
    location: 'Necko:Try-' + id.replace('.', '_'),
    created_at: new Date()
  };

  Builds.insert(obj, (err, _id) => {
    if (err) {
      console.log(err);
    } else {
      console.log(_id);
    }
  });
}

Router.route('/api/build/add', {
  where: 'server',
  action: function() {
    this.response.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8',
      'Access-Control-Allow-Origin': '*'
    });

    let id = decodeURIComponent(this.params.query.id);
    let url = Meteor.settings.public.build_archive + encodeURIComponent(id) + '/';
    console.log(url);

    let obj = Builds.findOne({id: id});
    if (obj) {
      this.response.end(id + ' exists');
      return;
    }

    HTTP.get(url, {}, (err, resp) => {
      if (err || resp.statusCode != 200) {
        this.response.end('invalid id: ' + id);
      } else {
        addBuild(id);
        this.response.end('OK');
      }
    });
  }
});

Router.route('/api/builds', {
  where: 'server',
  action: function() {
    this.response.writeHead(200, {
      'Content-Type': 'application/json; charset=utf-8',
      'Access-Control-Allow-Origin': '*'
    });

    let builds = Builds.find({}, { sort: { created_at: 1 } }).fetch();
    let responses = [];

    for (let build of builds) {
      responses.push({
        id: build.id,
        revision: build.revision,
        owner: build.owner,
        location: build.location,
        created_at: build.created_at
      });
    }

    this.response.end(JSON.stringify(responses));
  }
});
<commit_msg>use timestamp as created time<commit_after>import { Mongo } from 'meteor/mongo';

export const Builds = new Mongo.Collection('builds');

function addBuild(id) {
  console.log(id);

  let obj = {
    id: id,
    revision: id.substr(id.length - 40),
    owner: id.substr(0, id.length - 41),
    location: 'Necko:Try-' + id.replace('.', '_'),
    created_at: Math.floor(Date.now() / 1000)
  };

  Builds.insert(obj, (err, _id) => {
    if (err) {
      console.log(err);
    } else {
      console.log(_id);
    }
  });
}

Router.route('/api/build/add', {
  where: 'server',
  action: function() {
    this.response.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8',
      'Access-Control-Allow-Origin': '*'
    });

    let id = decodeURIComponent(this.params.query.id);
    let url = Meteor.settings.public.build_archive + encodeURIComponent(id) + '/';
    console.log(url);

    let obj = Builds.findOne({id: id});
    if (obj) {
      this.response.end(id + ' exists');
      return;
    }

    HTTP.get(url, {}, (err, resp) => {
      if (err || resp.statusCode != 200) {
        this.response.end('invalid id: ' + id);
      } else {
        addBuild(id);
        this.response.end('OK');
      }
    });
  }
});

Router.route('/api/builds', {
  where: 'server',
  action: function() {
    this.response.writeHead(200, {
      'Content-Type': 'application/json; charset=utf-8',
      'Access-Control-Allow-Origin': '*'
    });

    let builds = Builds.find({}, { sort: { created_at: 1 } }).fetch();
    let responses = [];

    for (let build of builds) {
      responses.push({
        id: build.id,
        revision: build.revision,
        owner: build.owner,
        location: build.location,
        created_at: build.created_at
      });
    }

    this.response.end(JSON.stringify(responses));
  }
});
<|endoftext|>


<commit_before>YUI().use(function(Y) {
//BEGIN Y closure
var Watcher = YUI.namespace('Themer.Watcher');

Watcher.processes = [];
// Watcher.sockets = [];

//Initialize all watchers on startup
Watcher.init = function(app) {

    app.shops.each(function(shop) {
        var themes = new Themer.themeList();
        themes.parent_id = shop.get('id');
        themes.load();

        themes.each(function(theme) {
            Watcher.watch(shop, theme);
        });

    });
};

//Will find an open port to spin up the server on
//Looks between 40000 - 50000 range
//If you know a better way to do this, please, let me know!
Watcher.getPort = function() {

};

Watcher.watch = function(shop, theme) {

    //Need to send in port as a string, else 'd' appended to it: ie: 40000 becomes 40000d
    console.log('Watch '+theme.get('id'));
    var port = '40003';

    var process = Titanium.Process.createProcess({
        args: ["/Users/mitch/src/shopify-theme2/Resources/lib/watch_server.rb",port],
        env: {'PATH': '/usr/bin:/bin'}
    });

    process.launch();
    Watcher.processes.push(process);

    //@todo check if we get a race condition where process isn't running, but we try to establish socket
    console.log('Watch process launched: '+ process.getPID());
    console.log('Watch process running: '+ process.isRunning());
    //Give server a second to spinup
    setTimeout(function() {
        Watcher.connect(shop, theme, port);
    }, 1000);

};

Watcher.connect = function(shop, theme, port, attempt) {
    console.log('Connecting socket theme: '+theme.get('id') +  ' on port '+ port);
    attempt = attempt || 0;
    //port needs to be an int
    var socket = Titanium.Network.createTCPSocket('127.0.0.1', parseInt(port, 10));

    socket.onError(function(e) {
        console.log('Error with socket');
        console.log(e);
        if(attempt < 3) {
            setTimeout(function() {
                Watcher.connect(shop, theme, port, (attempt+1));
            }, 1000);
        } else {
            console.log('too many attempts');
        }
    });
    socket.onTimeout(function(e) {
        console.log('Timeout with socket');
        // console.log(e);
    });
    socket.onRead(function(e) {
        console.log('Read');
        console.log(e.toString());
    });
    socket.onReadComplete(function(e) {
        console.log('ReadComplete');
    });
    socket.connect();
    // Watcher.sockets.push(socket);
    console.log('Socket is closed? '+ socket.isClosed());
};

//Clean up watchers on exit.
Ti.API.addEventListener(Titanium.APP_EXIT, function() {
    Titanium.API.warn('Exiting...');
    Watcher.processes.forEach(function(p) {

        Titanium.API.warn('Killing '+ p.getPID());
        if(p.isRunning()) {
            p.kill();
        }
    });
});

//end closure
});
<commit_msg>Watcher now spins up on random port, connects<commit_after>YUI().use(function(Y) {
//BEGIN Y closure
var Watcher = YUI.namespace('Themer.Watcher');

Watcher.processes = [];
// Watcher.sockets = [];

//Initialize all watchers on startup
Watcher.init = function(app) {

    app.shops.each(function(shop) {
        var themes = new Themer.themeList();
        themes.parent_id = shop.get('id');
        themes.load();

        themes.each(function(theme) {
            Watcher.start(shop, theme);
        });

    });
};

//Will find an open port to spin up server on
//Looks between 40000 - 50000 range
//If you know a better way to do this, please, let me know!
Watcher.start = function(shop, theme) {
    var port = random(40000, 50000);

    var portProc = Titanium.Process.createProcess({
        args: ["lsof", "-i", ":"+port],
        env: {'PATH': '/usr/sbin:/usr/bin:/bin'}
    });

    portProc.setOnExit(function(e) {
        //code 0 == port not avail
        // code 1 == port available
        // console.log("Exit Code:" + e.getTarget().getExitCode());
        if(e.getTarget().getExitCode() == 1) {
            //Port avail, start
            console.log('Port Available. Starting Watcher...');
            Watcher.watch(shop, theme, port);
        }
        else {
            console.log("Exit Code:" + e.getTarget().getExitCode());
            Watcher.start(shop, theme);
        }
    });

    portProc.launch();

};

Watcher.watch = function(shop, theme, port) {
    console.log('Watch Theme: '+theme.get('id') + ' on port: '+port);

    //Need to send in port as a string, else 'd' appended to it: ie: 40000 becomes 40000d
    var process = Titanium.Process.createProcess({
        args: ["/Users/mitch/src/shopify-theme2/Resources/lib/watch_server.rb",port.toString()],
        env: {'PATH': '/usr/bin:/bin'}
    });

    process.launch();
    Watcher.processes.push(process);

    //@todo check if we get a race condition where process isn't running, but we try to establish socket
    console.log('Watch process launched: '+ process.getPID());
    console.log('Watch process running: '+ process.isRunning());
    //Give server a second to spinup
    setTimeout(function() {
        Watcher.connect(shop, theme, port);
    }, 1000);

};

Watcher.connect = function(shop, theme, port, attempt) {
    console.log('Connecting socket theme: '+theme.get('id') +  ' on port '+ port);
    attempt = attempt || 0;
    //port needs to be an int
    var socket = Titanium.Network.createTCPSocket('127.0.0.1', parseInt(port, 10));

    socket.onError(function(e) {
        console.log('Error with socket');
        console.log(e);
        if(attempt < 3) {
            setTimeout(function() {
                Watcher.connect(shop, theme, port, (attempt+1));
            }, 1000);
        } else {
            console.log('too many attempts');
        }
    });
    socket.onTimeout(function(e) {
        console.log('Timeout with socket');
        // console.log(e);
    });
    socket.onRead(function(e) {
        console.log('Read');
        console.log(e.toString());
    });
    socket.onReadComplete(function(e) {
        console.log('ReadComplete');
    });
    socket.connect();
    // Watcher.sockets.push(socket);
    console.log('Socket is closed? '+ socket.isClosed());
};

//Clean up watchers on exit.
Ti.API.addEventListener(Titanium.APP_EXIT, function() {
    Titanium.API.warn('Exiting...');
    Watcher.processes.forEach(function(p) {

        Titanium.API.warn('Killing '+ p.getPID());
        if(p.isRunning()) {
            p.kill();
        }
    });
});

//end closure
});
<|endoftext|>


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

let url;
const info = require('../package');
const chalk = require('chalk');
const opts = require('commander')
  .version(info.version)
  .arguments('<url>')
  .action((a) => { url = a; })
  .option('-q, --quality <ITAG>',
    'Video quality to download, default: highest')
  .option('-r, --range <INT>..<INT>',
    'Byte range to download, ie 10355705-12452856')
  .option('-b, --begin <INT>', 'Time to begin video, format by 1:30.123 and 1m30s')
  .option('-o, --output <FILE>', 'Save to file, template by {prop}, default: stdout')
  .option('--filter <STR>',
    'Can be video, videoonly, audio, audioonly',
    /^(video|audio)(only)?$/)
  .option('--filter-container <REGEXP>', 'Filter in format container')
  .option('--unfilter-container <REGEXP>', 'Filter out format container')
  .option('--filter-resolution <REGEXP>', 'Filter in format resolution')
  .option('--unfilter-resolution <REGEXP>', 'Filter out format resolution')
  .option('--filter-encoding <REGEXP>', 'Filter in format encoding')
  .option('--unfilter-encoding <REGEXP>', 'Filter out format encoding')
  .option('-i, --info', 'Print video info without downloading')
  .option('-j, --info-json', 'Print video info as JSON without downloading')
  .option('--print-url', 'Print direct download URL')
  .option('--no-cache', 'Skip file cache for html5player')
  .option('--debug', 'Print debug information')
  .parse(process.argv)
  ;

if (!url) {
  opts.outputHelp((help) => {
    return chalk.red('\n  url argument is required\n') + help;
  });
  process.exit(1);
}

const path         = require('path');
const fs           = require('fs');
const ytdl         = require('ytdl-core');
const homedir      = require('homedir');
const util         = require('../lib/util');
const sanitizeName = require('sanitize-filename');

const label = chalk.bold.gray;

if (opts.cache !== false) {
  // Keep cache in file.
  const cachefile = path.resolve(homedir(), '.ytdl-cache.json');
  let cache = {};
  fs.readFile(cachefile, (err, contents) => {
    if (err) return;
    try {
      cache = JSON.parse(contents);
    } catch (err) {
      console.error(`Badly formatted cachefile (${cachefile}): ${err.message}`);
    }
  });

  ytdl.cache.sig.get = key => cache[key];
  ytdl.cache.sig.set = (key, value) => {
    cache[key] = value;
    fs.writeFile(cachefile,
      JSON.stringify(cache, null, 2), () => {});
  };
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log(label('title: ') + info.title);
  console.log(label('author: ') + info.author.name);
  console.log(label('average rating: ') + info.avg_rating);
  console.log(label('view count: ') + info.view_count);
  console.log(label('length: ') + util.toHumanTime(info.length_seconds));
}

if (opts.infoJson) {
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }
    console.log(JSON.stringify(info));
  });
} else if (opts.info) {
  const cliff = require('cliff');
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    const cols = [
      'itag',
      'container',
      'resolution',
      'video enc',
      'audio bitrate',
      'audio enc'
    ];
    info.formats.forEach((format) => {
      format['video enc']     = format.encoding;
      format['audio bitrate'] = format.audioBitrate;
      format['audio enc']     = format.audioEncoding;
      cols.forEach((col) => {
        format[col] = format[col] || '';
      });
    });
    console.log(label('formats:'));
    const colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
  });

} else {
  let output = opts.output;
  let ext = (output || '').match(/(\.\w+)?$/)[1];

  if (output) {
    if (ext && !opts.quality && !opts.filterContainer) {
      opts.filterContainer = '^' + ext.slice(1) + '$';
    }
  }

  const ytdlOptions = {};
  ytdlOptions.quality = /,/.test(opts.quality) ?
    opts.quality.split(',') : opts.quality;
  if (opts.range) {
    let s = opts.range.split('-');
    ytdlOptions.range = { start: s[0], end: s[1] };
  }
  ytdlOptions.begin = opts.begin;

  // Create filters.
  const filters = [];

  /**
   * @param {String} field
   * @param {String} regexpStr
   * @param {Boolean|null} negated
   */
  const createFilter = (field, regexpStr, negated) => {
    let regexp;
    try {
      regexp = new RegExp(regexpStr, 'i');
    } catch (err) {
      console.error(err.message);
      process.exit(1);
    }

    filters.push(format => negated !== regexp.test(format[field]));
  };

  ['container', 'resolution', 'encoding'].forEach((field) => {
    let key = 'filter' + field[0].toUpperCase() + field.slice(1);
    if (opts[key]) {
      createFilter(field, opts[key], false);
    }

    key = 'un' + key;
    if (opts[key]) {
      createFilter(field, opts[key], true);
    }
  });

  // Support basic ytdl-core filters manually, so that other
  // cli filters are supported when used together.
  switch (opts.filter) {
    case 'video':
      filters.push(format => format.bitrate);
      break;

    case 'videoonly':
      filters.push(format => format.bitrate && !format.audioBitrate);
      break;

    case 'audio':
      filters.push(format => format.audioBitrate);
      break;

    case 'audioonly':
      filters.push(format => !format.bitrate && format.audioBitrate);
      break;
  }

  ytdlOptions.filter = (format) => {
    return filters.every(filter => filter(format));
  };

  if (opts.printUrl) {
    ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
      if (err) {
        console.error(err.message);
        process.exit(1);
        return;
      }
      let format = ytdl.chooseFormat(info.formats, ytdlOptions);
      if (format instanceof Error) {
        console.error(format.message);
        process.exit(1);
        return;
      }
      console.log(format.url);
    });

  } else {
    const readStream = ytdl(url, ytdlOptions);
    const stdoutMutable = process.stdout && process.stdout.cursorTo && process.stdout.clearLine;
    let liveBroadcast = false;

    readStream.on('info', (info, format) => {
      if (!output) {
        readStream.pipe(process.stdout).on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });
        return;
      }

      output = util.tmpl(output, [info, format]);
      if (!ext && format.container) {
        output += '.' + format.container;
      }

      // Parses & sanitises output filename for any illegal characters
      let parsedOutput = path.parse(output);
      output = path.format({
        dir: parsedOutput.dir,
        base: sanitizeName(parsedOutput.base)
      });

      readStream.pipe(fs.createWriteStream(output))
        .on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });

      // Print information about the video if not streaming to stdout.
      printVideoInfo(info);

      console.log(label('container: ') + format.container);
      console.log(label('resolution: ') + format.resolution);
      console.log(label('encoding: ') + format.encoding);

      liveBroadcast = format.live;
      if (!liveBroadcast) { return; }

      const throttle = require('lodash.throttle');
      let dataRead = 0;
      const updateProgress = throttle(() => {
        process.stdout.cursorTo(0);
        process.stdout.clearLine(1);
        process.stdout.write(label('size: ') + util.toHumanSize(dataRead) +
                             ' (' + dataRead +' bytes)');
      }, 500);

      readStream.on('data', (data) => {
        dataRead += data.length;
        if (stdoutMutable) {
          updateProgress();
        }
      });

      readStream.on('end', () => {
        if (stdoutMutable) {
          console.log(label('downloaded: ') + util.toHumanSize(dataRead));
        }
        console.log();
      });
    });

    readStream.on('response', (res) => {
      if (!output || liveBroadcast) { return; }

      // Print information about the format we're downloading.
      const size = parseInt(res.headers['content-length'], 10);
      console.log(label('size: ') + util.toHumanSize(size) +
                  ' (' + size +' bytes)');
      console.log(label('output: ') + output);
      console.log();
      if (!stdoutMutable) { return; }

      // Create progress bar.
      const bar = require('progress-bar').create(process.stdout, 50);
      const throttle = require('lodash.throttle');
      bar.format = '$bar; $percentage;%';

      let lastPercent = null;
      let updateBar = () => {
        let percent = dataRead / size;
        let newPercent = Math.floor(percent * 100);
        if (newPercent != lastPercent) {
          lastPercent = newPercent;
          bar.update(percent);
        }
      };
      let updateBarThrottled = throttle(updateBar, 100, { trailing: false });

      // Keep track of progress.
      let dataRead = 0;
      readStream.on('data', (data) => {
        dataRead += data.length;
        if (dataRead === size) {
          updateBar();
        } else {
          updateBarThrottled();
        }
      });

      readStream.on('end', () => {
        console.log();
      });
    });

    readStream.on('error', (err) => {
      console.error(err.message);
      process.exit(1);
    });

    process.on('SIGINT', () => {
      console.log();
      process.exit();
    });
  }
}
<commit_msg>fix: remove ytdl cache timeout<commit_after>#!/usr/bin/env node

let url;
const info = require('../package');
const chalk = require('chalk');
const opts = require('commander')
  .version(info.version)
  .arguments('<url>')
  .action((a) => { url = a; })
  .option('-q, --quality <ITAG>',
    'Video quality to download, default: highest')
  .option('-r, --range <INT>..<INT>',
    'Byte range to download, ie 10355705-12452856')
  .option('-b, --begin <INT>', 'Time to begin video, format by 1:30.123 and 1m30s')
  .option('-o, --output <FILE>', 'Save to file, template by {prop}, default: stdout')
  .option('--filter <STR>',
    'Can be video, videoonly, audio, audioonly',
    /^(video|audio)(only)?$/)
  .option('--filter-container <REGEXP>', 'Filter in format container')
  .option('--unfilter-container <REGEXP>', 'Filter out format container')
  .option('--filter-resolution <REGEXP>', 'Filter in format resolution')
  .option('--unfilter-resolution <REGEXP>', 'Filter out format resolution')
  .option('--filter-encoding <REGEXP>', 'Filter in format encoding')
  .option('--unfilter-encoding <REGEXP>', 'Filter out format encoding')
  .option('-i, --info', 'Print video info without downloading')
  .option('-j, --info-json', 'Print video info as JSON without downloading')
  .option('--print-url', 'Print direct download URL')
  .option('--no-cache', 'Skip file cache for html5player')
  .option('--debug', 'Print debug information')
  .parse(process.argv)
  ;

if (!url) {
  opts.outputHelp((help) => {
    return chalk.red('\n  url argument is required\n') + help;
  });
  process.exit(1);
}

const path         = require('path');
const fs           = require('fs');
const ytdl         = require('ytdl-core');
const homedir      = require('homedir');
const util         = require('../lib/util');
const sanitizeName = require('sanitize-filename');

const label = chalk.bold.gray;

ytdl.cache.info.timeout = 0;
if (opts.cache !== false) {
  // Keep cache in file.
  const cachefile = path.resolve(homedir(), '.ytdl-cache.json');
  let cache = {};
  fs.readFile(cachefile, (err, contents) => {
    if (err) return;
    try {
      cache = JSON.parse(contents);
    } catch (err) {
      console.error(`Badly formatted cachefile (${cachefile}): ${err.message}`);
    }
  });

  ytdl.cache.sig.get = key => cache[key];
  ytdl.cache.sig.set = (key, value) => {
    cache[key] = value;
    fs.writeFile(cachefile,
      JSON.stringify(cache, null, 2), () => {});
  };
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log(label('title: ') + info.title);
  console.log(label('author: ') + info.author.name);
  console.log(label('average rating: ') + info.avg_rating);
  console.log(label('view count: ') + info.view_count);
  console.log(label('length: ') + util.toHumanTime(info.length_seconds));
}

if (opts.infoJson) {
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }
    console.log(JSON.stringify(info));
  });
} else if (opts.info) {
  const cliff = require('cliff');
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    const cols = [
      'itag',
      'container',
      'resolution',
      'video enc',
      'audio bitrate',
      'audio enc'
    ];
    info.formats.forEach((format) => {
      format['video enc']     = format.encoding;
      format['audio bitrate'] = format.audioBitrate;
      format['audio enc']     = format.audioEncoding;
      cols.forEach((col) => {
        format[col] = format[col] || '';
      });
    });
    console.log(label('formats:'));
    const colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
  });

} else {
  let output = opts.output;
  let ext = (output || '').match(/(\.\w+)?$/)[1];

  if (output) {
    if (ext && !opts.quality && !opts.filterContainer) {
      opts.filterContainer = '^' + ext.slice(1) + '$';
    }
  }

  const ytdlOptions = {};
  ytdlOptions.quality = /,/.test(opts.quality) ?
    opts.quality.split(',') : opts.quality;
  if (opts.range) {
    let s = opts.range.split('-');
    ytdlOptions.range = { start: s[0], end: s[1] };
  }
  ytdlOptions.begin = opts.begin;

  // Create filters.
  const filters = [];

  /**
   * @param {String} field
   * @param {String} regexpStr
   * @param {Boolean|null} negated
   */
  const createFilter = (field, regexpStr, negated) => {
    let regexp;
    try {
      regexp = new RegExp(regexpStr, 'i');
    } catch (err) {
      console.error(err.message);
      process.exit(1);
    }

    filters.push(format => negated !== regexp.test(format[field]));
  };

  ['container', 'resolution', 'encoding'].forEach((field) => {
    let key = 'filter' + field[0].toUpperCase() + field.slice(1);
    if (opts[key]) {
      createFilter(field, opts[key], false);
    }

    key = 'un' + key;
    if (opts[key]) {
      createFilter(field, opts[key], true);
    }
  });

  // Support basic ytdl-core filters manually, so that other
  // cli filters are supported when used together.
  switch (opts.filter) {
    case 'video':
      filters.push(format => format.bitrate);
      break;

    case 'videoonly':
      filters.push(format => format.bitrate && !format.audioBitrate);
      break;

    case 'audio':
      filters.push(format => format.audioBitrate);
      break;

    case 'audioonly':
      filters.push(format => !format.bitrate && format.audioBitrate);
      break;
  }

  ytdlOptions.filter = (format) => {
    return filters.every(filter => filter(format));
  };

  if (opts.printUrl) {
    ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
      if (err) {
        console.error(err.message);
        process.exit(1);
        return;
      }
      let format = ytdl.chooseFormat(info.formats, ytdlOptions);
      if (format instanceof Error) {
        console.error(format.message);
        process.exit(1);
        return;
      }
      console.log(format.url);
    });

  } else {
    const readStream = ytdl(url, ytdlOptions);
    const stdoutMutable = process.stdout && process.stdout.cursorTo && process.stdout.clearLine;
    let liveBroadcast = false;

    readStream.on('info', (info, format) => {
      if (!output) {
        readStream.pipe(process.stdout).on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });
        return;
      }

      output = util.tmpl(output, [info, format]);
      if (!ext && format.container) {
        output += '.' + format.container;
      }

      // Parses & sanitises output filename for any illegal characters
      let parsedOutput = path.parse(output);
      output = path.format({
        dir: parsedOutput.dir,
        base: sanitizeName(parsedOutput.base)
      });

      readStream.pipe(fs.createWriteStream(output))
        .on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });

      // Print information about the video if not streaming to stdout.
      printVideoInfo(info);

      console.log(label('container: ') + format.container);
      console.log(label('resolution: ') + format.resolution);
      console.log(label('encoding: ') + format.encoding);

      liveBroadcast = format.live;
      if (!liveBroadcast) { return; }

      const throttle = require('lodash.throttle');
      let dataRead = 0;
      const updateProgress = throttle(() => {
        process.stdout.cursorTo(0);
        process.stdout.clearLine(1);
        process.stdout.write(label('size: ') + util.toHumanSize(dataRead) +
                             ' (' + dataRead +' bytes)');
      }, 500);

      readStream.on('data', (data) => {
        dataRead += data.length;
        if (stdoutMutable) {
          updateProgress();
        }
      });

      readStream.on('end', () => {
        if (stdoutMutable) {
          console.log(label('downloaded: ') + util.toHumanSize(dataRead));
        }
        console.log();
      });
    });

    readStream.on('response', (res) => {
      if (!output || liveBroadcast) { return; }

      // Print information about the format we're downloading.
      const size = parseInt(res.headers['content-length'], 10);
      console.log(label('size: ') + util.toHumanSize(size) +
                  ' (' + size +' bytes)');
      console.log(label('output: ') + output);
      console.log();
      if (!stdoutMutable) { return; }

      // Create progress bar.
      const bar = require('progress-bar').create(process.stdout, 50);
      const throttle = require('lodash.throttle');
      bar.format = '$bar; $percentage;%';

      let lastPercent = null;
      let updateBar = () => {
        let percent = dataRead / size;
        let newPercent = Math.floor(percent * 100);
        if (newPercent != lastPercent) {
          lastPercent = newPercent;
          bar.update(percent);
        }
      };
      let updateBarThrottled = throttle(updateBar, 100, { trailing: false });

      // Keep track of progress.
      let dataRead = 0;
      readStream.on('data', (data) => {
        dataRead += data.length;
        if (dataRead === size) {
          updateBar();
        } else {
          updateBarThrottled();
        }
      });

      readStream.on('end', () => {
        console.log();
      });
    });

    readStream.on('error', (err) => {
      console.error(err.message);
      process.exit(1);
    });

    process.on('SIGINT', () => {
      console.log();
      process.exit();
    });
  }
}
<|endoftext|>


<commit_before><commit_msg>race condition in test<commit_after><|endoftext|>


<commit_before>jest.unmock('../src/DatabaseDriver');
jest.mock('rethinkdb');
import DatabaseDriver from '../src/DatabaseDriver';
import rethinkdb from 'rethinkdb';

describe('DatabaseDriver', () => {
  it('does exist', () => {
    expect(DatabaseDriver).not.toEqual({});
  });

  it('does initialize database', (done) => {
    const rethinkdbConfig = {
      config: {
        host: 'localhost',
        port: 28015,
        db: 'someDb',
      },
    };
    const databaseDriver = new DatabaseDriver(rethinkdbConfig);
    databaseDriver.init().then(() => {
      expect(databaseDriver.connection.use).toBeCalledWith(rethinkdbConfig.config.db);
      expect(rethinkdb.init).toBeCalledWith(rethinkdbConfig.config, undefined);
      done();
    });
  });
});
<commit_msg>more db init tests<commit_after>jest.unmock('../src/DatabaseDriver');
jest.mock('rethinkdb');
import DatabaseDriver from '../src/DatabaseDriver';
import rethinkdb from 'rethinkdb';

describe('DatabaseDriver', () => {
  it('does exist', () => {
    expect(DatabaseDriver).not.toEqual({});
  });

  it('does initialize database', (done) => {
    const rethinkdbConfig = {
      config: {
        host: 'localhost',
        port: 28015,
        db: 'someDb',
      },
    };
    const databaseDriver = new DatabaseDriver(rethinkdbConfig);
    databaseDriver.init().then(() => {
      expect(databaseDriver.connection.use).toBeCalledWith(rethinkdbConfig.config.db);
      expect(rethinkdb.init).toBeCalledWith(rethinkdbConfig.config, undefined);
      done();
    });
  });

  it('does handle database connection errors', (done) => {
    const rethinkdbConfig = {
      config: {
        host: 'badhost',
        port: 28015,
      },
    };
    const databaseDriver = new DatabaseDriver(rethinkdbConfig);
    databaseDriver.init()
    .then(() => {
      throw new Error('Expecting connection to be invalid');
    })
    .catch((err) => {
      expect(err).toBe('bad host detected');
      done();
    });
  });

  it('does init db with tables and indexes', (done) => {
    const rethinkdbConfig = {
      config: {
        host: 'localhost',
        port: 28015,
        db: 'someDb',
      },
      tableConfig: [
        'a',
        'b',
      ],
    };
    const databaseDriver = new DatabaseDriver(rethinkdbConfig);
    databaseDriver.init().then(() => {
      expect(rethinkdb.init).toBeCalledWith(rethinkdbConfig.config, rethinkdbConfig.tableConfig);
      done();
    });
  });
});
<|endoftext|>