<commit_before>var placeholder = "Search, drag and drop video, or paste its URL...";

var playImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/media-play-4x.png";
var removeImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/x-4x.png";

var videoUrl;
var videoName;
var videoTime = null;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;

var videoPaused;
var stayPaused;
var backRestart;

var timer;

function Timer(callback, delay) {
  var timerId, start, remaining = delay;

  this.pause = function() {
      window.clearTimeout(timerId);
      remaining -= new Date() - start;
  };

  this.resume = function() {
      start = new Date();
      window.clearTimeout(timerId);
      timerId = window.setTimeout(callback, remaining);
  };

  this.resume();
}

function msConversion(millis) {
  var minutes = Math.floor(millis / 60000);
  var seconds = ((millis % 60000) / 1000).toFixed(0);
  return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}

function highlight(i) {
  $("tr:nth-child(" + i + ")").attr("id", "newSelected");
  $("tr.selected").removeClass("selected");
  $("#newSelected").addClass("selected");
  $("#newSelected").removeAttr("id");
}

function addVideoToList(name, time) {
  name = decodeURIComponent(name);
  $("#videosTable").append("
" + name + "<button class=\"tableButton removeButton\" onclick=\"actionRemoveVideo(this);\"></button>" +
  "<button class=\"tableButton playButton\" onclick=\"actionPlayVideo(this);\"></button>	" + time + "
");
}

function playVideo() {
  highlight(videoIteration);
  document.title = "Streamly - " + decodeURIComponent(videos[videoIteration]["name"]);
  var embedUrl = videos[videoIteration]["url"];

  var autoplay = "";
  if (!stayPaused) {
    autoplay = "?autoplay=1";
  }

  if (embedUrl.search(/file:\/\//i) == -1) {
    embedUrl = "https://www.youtube.com/embed/" + videos[videoIteration]["url"] + autoplay;
  }
  $("#youtube").attr("src", embedUrl);

  backRestart = false;
  window.setTimeout(function() {
    backRestart = true;
  }, 3000);
}

function loopVideo() {
  videoIteration++;
  playVideo();
  timer = new Timer(function() {
    if (videoIteration < videoCounter) {
      loopVideo();
    }
    else {
      timer.pause();
      timer = 0;
      $("#youtube").attr("src", "");
      document.title = "Streamly";
    }
  }, videos[videoIteration]["time"] + 2000);
  if (stayPaused) {
    timer.pause();
  }
}

function pauseVideo() {
  if (!videoPaused) {
    timer.pause();
    videoPaused = true;
  }
  else {
    timer.resume();
    videoPaused = false;
    stayPaused = false;
  }
  $("#pauseOverlay").css("display", "none");
  setTimeout(function(){
    $("#pauseOverlay").css("display", "block");
    $("#youtube").blur();
  }, 500);
}

function forwardVideo() {
  if (videoIteration + 1 <= videoCounter) {
    if (timer != 0) {
      timer.pause();
    }
    timer = 0;

    if (videoPaused) {
      stayPaused = true;
    }
    loopVideo();
  }
}

function backVideo() {
  if (!backRestart) {
    if (videoIteration - 2 > -1) {
      videoIteration = videoIteration - 2;
      if (timer != 0) {
        timer.pause();
      }
      timer = 0;

      if (videoPaused) {
        stayPaused = true;
      }
      loopVideo();
    }
  }
  else {
    videoIteration = videoIteration - 1;
    if (timer != 0) {
      timer.pause();
    }
    timer = 0;
    loopVideo();
  }
}

function setPlaylist() {
  if (videos.length > 1) {
    var playlist = JSON.stringify(videos);
    playlist = window.btoa(playlist);
    playlist = encodeURIComponent(playlist);
    window.location.hash = playlist;
  }
  else {
    window.location.hash = "";
  }
}

function getPlaylist() {
  if (window.location.hash.substr(1) !== "") {
    var playlist = window.location.hash.substr(1);
    playlist = decodeURIComponent(playlist);
    playlist = window.atob(playlist);
    playlist = JSON.parse(playlist);
    videos = playlist;

    if (videos[0] != undefined) {
      $("#playlistNameBox").val(decodeURIComponent(videos[0]));
    }

    for (i = 1; i < videos.length; i++) {
      videoCounter = i;
      var printTime = msConversion(videos[videoCounter]["time"]);
      addVideoToList(videos[videoCounter]["name"], printTime);
    }
    loopVideo();
  }
}

function getVideoData() {
  $.ajax({
    url: videoUrl,
    type: 'GET',
    success: function(res) {
      var data = $(res.responseText);
      try {
        videoName = data.find("span#eow-title");
        videoName = videoName[0].textContent;
        videoName = $("
").html(videoName).text();
        videoName = videoName.trim();
      } catch(err) {
        videoName = prompt("Please enter the name of the video", "");
      }
      videoName = encodeURIComponent(videoName).replace(/%20/g, " ");
      try {
        videoTime = null;
        for (iteration in data) {
          var str = data[iteration].innerHTML;
          if (videoTime == null && typeof str != "undefined") {
            videoTime = str.match(/,"length_seconds":"\d+",/g);
          }
        }
        videoTime = videoTime[0];
        videoTime = videoTime.replace(/,"length_seconds":"/g, "").replace(/",/g, "");
        videoTime = +videoTime * 1000;
      } catch(err) {
        videoTime = prompt("Please enter the length of the video", "3:00");
        videoTime = videoTime.split(":");
        videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
        videoTime = videoTime * 1000;
      }
    },
    error: function(jqXHR, textStatus, errorThrown) {
      videoName = prompt("Please enter the name of the video", "");
      videoTime = prompt("Please enter the length of the video", "3:00");
    }
  });
}

function addVideo() {
  videoCounter++;
  var video = {};
  video["name"] = videoName;
  video["time"] = videoTime;
  video["url"] = videoUrl.replace(/^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=/i, "");
  videos[videoCounter] = video;

  var printTime = msConversion(videos[videoCounter]["time"]);

  addVideoToList(videoName, printTime);

  setPlaylist();

  if (videoCounter == 1 || timer == 0) {
    loopVideo();
  }
}

function actionPlayVideo(element) {
  var index = $(".playButton").index(element);
  videoIteration = index;
  if (timer != 0) {
    timer.pause();
  }
  timer = 0;
  loopVideo();
}

function actionRemoveVideo(element) {
  var index = $(".removeButton").index(element) + 1;
  if (index == videoIteration) {
    if (videoIteration + 1 <= videoCounter) {
      forwardVideo();
      videoIteration--;
    }
    else {
      if (timer != 0) {
        timer.pause();
      }
      timer = 0;
      $("#youtube").attr("src", "");
      document.title = "Streamly";
      videoIteration--;
    }
  }
  else if (index < videoIteration) {
    videoIteration--;
  }
  videoCounter--;
  videos.splice(index, 1);
  $("tr:nth-child(" + index + ")").remove();
  setPlaylist();
}

function urlValidate(url) {
  var isValidYouTube = /^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=.+$/i;
  var isValidFile = /^file:\/\/.+$/i;

  url = url.trim();
  url = url.replace(/&list=.+/g, "");

  if (url.search(isValidYouTube) > -1 || url.search(isValidFile) > -1) {
    return url;
  }
  else {
    return false;
  }
}

function input(type) {
  var inputBox = $("#inputBox").val();
  var playlistNameBox = $("#playlistNameBox").val();
  switch (type) {
    case 0:
      if (inputBox != "") {
        window.open("https://www.youtube.com/results?search_query=" + inputBox.replace(/ /g, "+"));
        $("#inputBox").val("").attr("placeholder", placeholder);
      }
      break;
    case 1:
      if (inputBox != "") {
        inputBox = urlValidate(inputBox);
        if (inputBox) {
          videoUrl = inputBox;
          $("#inputBox").val("").attr("placeholder", "Loading video data from YouTube...");
          getVideoData();
        }
        else {
          alert("That video's URL seems broken\n\nTry copying it again, or drag and drop the video directly");
        }
      }
      break;
    case 2:
      if (playlistNameBox != "") {
        videos[0] = encodeURIComponent(playlistNameBox).replace(/%20/g, " ");
        setPlaylist();
      }
      else {
        videos[0] = undefined;
      }
      break;
  }
}

$(document).ajaxStop(function() {
  $("#inputBox").val("").attr("placeholder", placeholder);
  addVideo();
});

document.addEventListener("drop", function(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData("URL");

  $("#inputBox").val(data);
  input(1);
});

document.addEventListener("dragover", function(event) {
  event.preventDefault();
});
<commit_msg>forgot to do pre-processing on time<commit_after>var placeholder = "Search, drag and drop video, or paste its URL...";

var playImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/media-play-4x.png";
var removeImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/x-4x.png";

var videoUrl;
var videoName;
var videoTime = null;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;

var videoPaused;
var stayPaused;
var backRestart;

var timer;

function Timer(callback, delay) {
  var timerId, start, remaining = delay;

  this.pause = function() {
      window.clearTimeout(timerId);
      remaining -= new Date() - start;
  };

  this.resume = function() {
      start = new Date();
      window.clearTimeout(timerId);
      timerId = window.setTimeout(callback, remaining);
  };

  this.resume();
}

function msConversion(millis) {
  var minutes = Math.floor(millis / 60000);
  var seconds = ((millis % 60000) / 1000).toFixed(0);
  return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}

function highlight(i) {
  $("tr:nth-child(" + i + ")").attr("id", "newSelected");
  $("tr.selected").removeClass("selected");
  $("#newSelected").addClass("selected");
  $("#newSelected").removeAttr("id");
}

function addVideoToList(name, time) {
  name = decodeURIComponent(name);
  $("#videosTable").append("
" + name + "<button class=\"tableButton removeButton\" onclick=\"actionRemoveVideo(this);\"></button>" +
  "<button class=\"tableButton playButton\" onclick=\"actionPlayVideo(this);\"></button>	" + time + "
");
}

function playVideo() {
  highlight(videoIteration);
  document.title = "Streamly - " + decodeURIComponent(videos[videoIteration]["name"]);
  var embedUrl = videos[videoIteration]["url"];

  var autoplay = "";
  if (!stayPaused) {
    autoplay = "?autoplay=1";
  }

  if (embedUrl.search(/file:\/\//i) == -1) {
    embedUrl = "https://www.youtube.com/embed/" + videos[videoIteration]["url"] + autoplay;
  }
  $("#youtube").attr("src", embedUrl);

  backRestart = false;
  window.setTimeout(function() {
    backRestart = true;
  }, 3000);
}

function loopVideo() {
  videoIteration++;
  playVideo();
  timer = new Timer(function() {
    if (videoIteration < videoCounter) {
      loopVideo();
    }
    else {
      timer.pause();
      timer = 0;
      $("#youtube").attr("src", "");
      document.title = "Streamly";
    }
  }, videos[videoIteration]["time"] + 2000);
  if (stayPaused) {
    timer.pause();
  }
}

function pauseVideo() {
  if (!videoPaused) {
    timer.pause();
    videoPaused = true;
  }
  else {
    timer.resume();
    videoPaused = false;
    stayPaused = false;
  }
  $("#pauseOverlay").css("display", "none");
  setTimeout(function(){
    $("#pauseOverlay").css("display", "block");
    $("#youtube").blur();
  }, 500);
}

function forwardVideo() {
  if (videoIteration + 1 <= videoCounter) {
    if (timer != 0) {
      timer.pause();
    }
    timer = 0;

    if (videoPaused) {
      stayPaused = true;
    }
    loopVideo();
  }
}

function backVideo() {
  if (!backRestart) {
    if (videoIteration - 2 > -1) {
      videoIteration = videoIteration - 2;
      if (timer != 0) {
        timer.pause();
      }
      timer = 0;

      if (videoPaused) {
        stayPaused = true;
      }
      loopVideo();
    }
  }
  else {
    videoIteration = videoIteration - 1;
    if (timer != 0) {
      timer.pause();
    }
    timer = 0;
    loopVideo();
  }
}

function setPlaylist() {
  if (videos.length > 1) {
    var playlist = JSON.stringify(videos);
    playlist = window.btoa(playlist);
    playlist = encodeURIComponent(playlist);
    window.location.hash = playlist;
  }
  else {
    window.location.hash = "";
  }
}

function getPlaylist() {
  if (window.location.hash.substr(1) !== "") {
    var playlist = window.location.hash.substr(1);
    playlist = decodeURIComponent(playlist);
    playlist = window.atob(playlist);
    playlist = JSON.parse(playlist);
    videos = playlist;

    if (videos[0] != undefined) {
      $("#playlistNameBox").val(decodeURIComponent(videos[0]));
    }

    for (i = 1; i < videos.length; i++) {
      videoCounter = i;
      var printTime = msConversion(videos[videoCounter]["time"]);
      addVideoToList(videos[videoCounter]["name"], printTime);
    }
    loopVideo();
  }
}

function getVideoData() {
  $.ajax({
    url: videoUrl,
    type: 'GET',
    success: function(res) {
      var data = $(res.responseText);
      try {
        videoName = data.find("span#eow-title");
        videoName = videoName[0].textContent;
        videoName = $("
").html(videoName).text();
        videoName = videoName.trim();
      } catch(err) {
        videoName = prompt("Please enter the name of the video", "");
      }
      videoName = encodeURIComponent(videoName).replace(/%20/g, " ");
      try {
        videoTime = null;
        for (iteration in data) {
          var str = data[iteration].innerHTML;
          if (videoTime == null && typeof str != "undefined") {
            videoTime = str.match(/,"length_seconds":"\d+",/g);
          }
        }
        videoTime = videoTime[0];
        videoTime = videoTime.replace(/,"length_seconds":"/g, "").replace(/",/g, "");
        videoTime = +videoTime * 1000;
      } catch(err) {
        videoTime = prompt("Please enter the length of the video", "3:00");
        videoTime = videoTime.split(":");
        videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
        videoTime = videoTime * 1000;
      }
    },
    error: function(jqXHR, textStatus, errorThrown) {
      videoName = prompt("Please enter the name of the video", "");

      videoTime = prompt("Please enter the length of the video", "3:00");
      videoTime = videoTime.split(":");
      videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
      videoTime = videoTime * 1000;
    }
  });
}

function addVideo() {
  videoCounter++;
  var video = {};
  video["name"] = videoName;
  video["time"] = videoTime;
  video["url"] = videoUrl.replace(/^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=/i, "");
  videos[videoCounter] = video;

  var printTime = msConversion(videos[videoCounter]["time"]);

  addVideoToList(videoName, printTime);

  setPlaylist();

  if (videoCounter == 1 || timer == 0) {
    loopVideo();
  }
}

function actionPlayVideo(element) {
  var index = $(".playButton").index(element);
  videoIteration = index;
  if (timer != 0) {
    timer.pause();
  }
  timer = 0;
  loopVideo();
}

function actionRemoveVideo(element) {
  var index = $(".removeButton").index(element) + 1;
  if (index == videoIteration) {
    if (videoIteration + 1 <= videoCounter) {
      forwardVideo();
      videoIteration--;
    }
    else {
      if (timer != 0) {
        timer.pause();
      }
      timer = 0;
      $("#youtube").attr("src", "");
      document.title = "Streamly";
      videoIteration--;
    }
  }
  else if (index < videoIteration) {
    videoIteration--;
  }
  videoCounter--;
  videos.splice(index, 1);
  $("tr:nth-child(" + index + ")").remove();
  setPlaylist();
}

function urlValidate(url) {
  var isValidYouTube = /^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=.+$/i;
  var isValidFile = /^file:\/\/.+$/i;

  url = url.trim();
  url = url.replace(/&list=.+/g, "");

  if (url.search(isValidYouTube) > -1 || url.search(isValidFile) > -1) {
    return url;
  }
  else {
    return false;
  }
}

function input(type) {
  var inputBox = $("#inputBox").val();
  var playlistNameBox = $("#playlistNameBox").val();
  switch (type) {
    case 0:
      if (inputBox != "") {
        window.open("https://www.youtube.com/results?search_query=" + inputBox.replace(/ /g, "+"));
        $("#inputBox").val("").attr("placeholder", placeholder);
      }
      break;
    case 1:
      if (inputBox != "") {
        inputBox = urlValidate(inputBox);
        if (inputBox) {
          videoUrl = inputBox;
          $("#inputBox").val("").attr("placeholder", "Loading video data from YouTube...");
          getVideoData();
        }
        else {
          alert("That video's URL seems broken\n\nTry copying it again, or drag and drop the video directly");
        }
      }
      break;
    case 2:
      if (playlistNameBox != "") {
        videos[0] = encodeURIComponent(playlistNameBox).replace(/%20/g, " ");
        setPlaylist();
      }
      else {
        videos[0] = undefined;
      }
      break;
  }
}

$(document).ajaxStop(function() {
  $("#inputBox").val("").attr("placeholder", placeholder);
  addVideo();
});

document.addEventListener("drop", function(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData("URL");

  $("#inputBox").val(data);
  input(1);
});

document.addEventListener("dragover", function(event) {
  event.preventDefault();
});
<|endoftext|>


<commit_before>const AWS = require('aws-sdk');
const async = require('async');
const argv = require('minimist')(process.argv.slice(2));

AWS.config.update({ region: 'us-east-1' });

if (argv._.length < 2) {
  console.error('Usage: node post_queue.js <QUEUE_URL> <ITEM...>');
  process.exit(1);
}

const sqs = new AWS.SQS();

const queueUrl = argv._[0];
const messages = argv._.slice(1);

async.each(messages, (message, cb) => {
  sqs.sendMessage({
    QueueUrl: queueUrl,
    MessageBody: message
  }, (err) => {
    if (!err) {
      console.log(`Posted '${message}' to queue URL ${queueUrl}.`);
    }
    cb(err);
  });
}, (err) => {
  if (err) {
    console.log(err);
  }
});
<commit_msg>Fix number posting issue<commit_after>const AWS = require('aws-sdk');
const async = require('async');
const argv = require('minimist')(process.argv.slice(2));

AWS.config.update({ region: 'us-east-1' });

if (argv._.length < 2) {
  console.error('Usage: node post_queue.js <QUEUE_URL> <ITEM...>');
  process.exit(1);
}

const sqs = new AWS.SQS();

const queueUrl = argv._[0];
const messages = argv._.slice(1);

async.each(messages, (message, cb) => {
  sqs.sendMessage({
    QueueUrl: queueUrl,
    MessageBody: String(message)
  }, (err) => {
    if (!err) {
      console.log(`Posted '${message}' to queue URL ${queueUrl}.`);
    }
    cb(err);
  });
}, (err) => {
  if (err) {
    console.log(err);
  }
});
<|endoftext|>


<commit_before>'use strict';

angular.module('einJahrGroKo.services', [])
    .factory('DataService', ['$q', '$http', 'dataSourceUrl',
        function($q, $http, dataSourceUrl) {
            /**
             * This is the data provider for all controllers etc. that depends
             * on the data. The first time the service is used the data gets
             * retrieved and cached. All next calls use the cached data.
             * A promise is returned in either case. So no matter what,
             * DataService.getData().then() is mandatory.
             */

            /**
             * Retrieve data from server and return promise
             * @return {Object} promise that resolves data on success and
             * rejects on failure with returned status (wrapped in a message)
             */
            function getData() {
                var defer = $q.defer();

                // first time ever called: retrieve data and hand over to promise
                // after finishing the retrieval
                $http.get(dataSourceUrl, {
                    'cached': true,
                    'headers': {
                        'Accept-Encoding': 'gzip'
                    }
                })
                    .success(function(data) {
                        // hand data over to the promise
                        defer.resolve(data);
                    })
                    .error(function(data, status) {
                        defer.reject('status ' + status + ' returned');
                    });

                return defer.promise;
            }

            // API for this service
            return {
                getData: getData
            };
        }
    ])
    .factory('RandomNumberService', function() {
        /**
         * Return random integer between min and max (both inclusive)
         * @param  {int} min minimal value
         * @param  {int} max maximal value
         * @return {int}     random int from `[min, max]`
         */
        function getRandomNumber(min, max) {
            return Math.floor(((Math.random() * (max - min) + 1) + min) + 1);
        }

        // API for this service
        return {
            getRandomNumber: getRandomNumber
        };
    })
    .factory('QuoteService', ['$http', '$q', 'RandomNumberService', 'DataService', 'QuoteHistoryService',
        function($http, $q, RandomNumberService, DataService, QuoteHistoryService) {
            /**
             * Calculate size of returned data
             * @param  {Object} data
             * @return {Integer} size of data
             */
            function getDataSize(data) {
                var size = 0,
                    key = null;

                for (key in data) {
                    // only count attributes (not functions)
                    if (data.hasOwnProperty(key)) {
                        size++;
                    }
                }

                return size;
            }

            /**
             * Remove
 and
 from text
             * @param  {String} text to strip p tags from
             * @return {String}      stripped text
             */
            function stripParTag(text) {
                return text.replace('
', '').replace('
', '');
            }

            /**
             * Convert markdown to html
             *
             * @discussion If the quote was already converted the `isHtml`
             * attribute is `true` and will be returned immediately. Otherwise
             * the quote will beconverted and marked the same way.
             *
             * @param  {Object} quote to convert
             * @return {Object}       converted quote
             */
            function toHtml(quote) {
                if (quote.isHtml) {
                    return quote;
                } else {
                    var converter = new Markdown.Converter();

                    return {
                        'author': quote.author,
                        'title': quote.title,
                        'text': stripParTag(converter.makeHtml(quote.quote)),
                        /* jshint camelcase:false */
                        'source': stripParTag(converter.makeHtml(quote.quote_src)),
                        'isHtml': true,
                        'id': quote.id
                    };
                }
            }

            /**
             * Get quote. There are three possibilities on what quote will be
             * returned. This depends on the QuoteHistoryService status and
             * whether or not `id` is null
             *
             * 1.  `id` is set: return quote with given id if possible.
             *     Note: Promise rejects if quote with id was not found
             *
             * 2.  `id` is null and QuoteHistoryService's head is at the latest
             *     quote: random quote will be returned and added to the history
             *
             * 3.  `id` is null and QuoteHistoryService's head is not the latest
             *     quote: return next quote in history (the one following the
             *     now-head). The head will be moved to the quote
             *
             * @see     QuoteHistoryService
             * @param   {Integer}   `id` of quote or null for random quote or
             * next in history
             * @return  {Object}    Promise that resolves quote or rejects with
             * error message
             */
            function getQuote(id) {
                var defer = $q.defer();

                DataService.getData().then(function(data) { // jshint unused:false
                    /*
                        please note that when rej and res are set, rej has a
                        higher precedence and the promise rejects with `rej`
                     */
                    var res = null,
                        rej = null;

                    if (id) {
                        // return specific quote
                        var key;

                        for (key in data) {
                            if (data.hasOwnProperty(key) && data[key].id == id) {
                                // convert markdown to html
                                res = toHtml(data[key]);
                                break;
                            }
                        }

                        // add quote to history
                        if (res) {
                            QuoteHistoryService.addObjectToHistory(res);
                        }

                        rej = res ? null : 'no quote with id ' + id;
                    } else {
                        /*
                            return random quote or next in history
                            if history is at head, null will be returned. thus
                            a random quote will be resolved
                        */
                        res = QuoteHistoryService.getNext();

                        if (!res) {
                            var dataSize = getDataSize(data);
                            var randID = RandomNumberService.getRandomNumber(0,
                                dataSize - 1);
                            // convert markdown to html
                            res = toHtml(data[randID]);
                            QuoteHistoryService.addObjectToHistory(res);
                        }
                    }

                    if (rej) {
                        defer.reject(rej);
                    } else {
                        defer.resolve(res);
                    }

                }, function(rej) {
                    defer.reject(rej);
                });

                return defer.promise;
            }

            // API for this service
            return {
                getQuote: getQuote
            };
        }
    ])
    .factory('QuoteHistoryService', ['$location',
        function($location) {
            var history = [];
            var histPntr = -1;

            /**
             * Check if there are previous quotes
             * @return {Boolean}
             */
            function hasPrevious() {
                return (histPntr > 0) ? true : false;
            }

            /**
             * Add quote to history anbd change browser location accordingly
             * @param {[type]} id  of quote
             * @param {[type]} obj quote
             */
            function addObjectToHistory(obj) {
                history.push(obj);
                histPntr++;

                // set hash in the browsers location bar
                $location.hash(id);
            }

            /**
             * Get predecessor of the current head quote
             * @return {Object} quote or null if there is no predecessor
             */
            function getPrevious() {
                window.history.back();

                if (histPntr > 0) {
                    histPntr--;

                    console.log('returned getPrevious ' + history[histPntr].id + '; moved pntr to ' + histPntr);
                    return history[histPntr];
                }

                return null; // no more items in history
            }

            /**
             * Get successor of current quote
             * @return {Object} quote or null if there is no successor
             */
            function getNext() {
                var out;

                if (histPntr < (history.length - 1)) {
                    out = history[histPntr];
                    histPntr++;

                    console.log('returned getNext ' + out.id + '; moved pntr to ' + histPntr);

                    // set hash in the browser location
                    if (out) {
                        $location.hash(out.id);
                    }
                } else {
                    out = null;
                }

                return out;
            }

            // API for this service
            return {
                addObjectToHistory: addObjectToHistory,
                getNext: getNext,
                getPrevious: getPrevious,
                hasPrevious: hasPrevious
            };
        }
    ]);
<commit_msg>set object id hash<commit_after>'use strict';

angular.module('einJahrGroKo.services', [])
    .factory('DataService', ['$q', '$http', 'dataSourceUrl',
        function($q, $http, dataSourceUrl) {
            /**
             * This is the data provider for all controllers etc. that depends
             * on the data. The first time the service is used the data gets
             * retrieved and cached. All next calls use the cached data.
             * A promise is returned in either case. So no matter what,
             * DataService.getData().then() is mandatory.
             */

            /**
             * Retrieve data from server and return promise
             * @return {Object} promise that resolves data on success and
             * rejects on failure with returned status (wrapped in a message)
             */
            function getData() {
                var defer = $q.defer();

                // first time ever called: retrieve data and hand over to promise
                // after finishing the retrieval
                $http.get(dataSourceUrl, {
                    'cached': true,
                    'headers': {
                        'Accept-Encoding': 'gzip'
                    }
                })
                    .success(function(data) {
                        // hand data over to the promise
                        defer.resolve(data);
                    })
                    .error(function(data, status) {
                        defer.reject('status ' + status + ' returned');
                    });

                return defer.promise;
            }

            // API for this service
            return {
                getData: getData
            };
        }
    ])
    .factory('RandomNumberService', function() {
        /**
         * Return random integer between min and max (both inclusive)
         * @param  {int} min minimal value
         * @param  {int} max maximal value
         * @return {int}     random int from `[min, max]`
         */
        function getRandomNumber(min, max) {
            return Math.floor(((Math.random() * (max - min) + 1) + min) + 1);
        }

        // API for this service
        return {
            getRandomNumber: getRandomNumber
        };
    })
    .factory('QuoteService', ['$http', '$q', 'RandomNumberService', 'DataService', 'QuoteHistoryService',
        function($http, $q, RandomNumberService, DataService, QuoteHistoryService) {
            /**
             * Calculate size of returned data
             * @param  {Object} data
             * @return {Integer} size of data
             */
            function getDataSize(data) {
                var size = 0,
                    key = null;

                for (key in data) {
                    // only count attributes (not functions)
                    if (data.hasOwnProperty(key)) {
                        size++;
                    }
                }

                return size;
            }

            /**
             * Remove
 and
 from text
             * @param  {String} text to strip p tags from
             * @return {String}      stripped text
             */
            function stripParTag(text) {
                return text.replace('
', '').replace('
', '');
            }

            /**
             * Convert markdown to html
             *
             * @discussion If the quote was already converted the `isHtml`
             * attribute is `true` and will be returned immediately. Otherwise
             * the quote will beconverted and marked the same way.
             *
             * @param  {Object} quote to convert
             * @return {Object}       converted quote
             */
            function toHtml(quote) {
                if (quote.isHtml) {
                    return quote;
                } else {
                    var converter = new Markdown.Converter();

                    return {
                        'author': quote.author,
                        'title': quote.title,
                        'text': stripParTag(converter.makeHtml(quote.quote)),
                        /* jshint camelcase:false */
                        'source': stripParTag(converter.makeHtml(quote.quote_src)),
                        'isHtml': true,
                        'id': quote.id
                    };
                }
            }

            /**
             * Get quote. There are three possibilities on what quote will be
             * returned. This depends on the QuoteHistoryService status and
             * whether or not `id` is null
             *
             * 1.  `id` is set: return quote with given id if possible.
             *     Note: Promise rejects if quote with id was not found
             *
             * 2.  `id` is null and QuoteHistoryService's head is at the latest
             *     quote: random quote will be returned and added to the history
             *
             * 3.  `id` is null and QuoteHistoryService's head is not the latest
             *     quote: return next quote in history (the one following the
             *     now-head). The head will be moved to the quote
             *
             * @see     QuoteHistoryService
             * @param   {Integer}   `id` of quote or null for random quote or
             * next in history
             * @return  {Object}    Promise that resolves quote or rejects with
             * error message
             */
            function getQuote(id) {
                var defer = $q.defer();

                DataService.getData().then(function(data) { // jshint unused:false
                    /*
                        please note that when rej and res are set, rej has a
                        higher precedence and the promise rejects with `rej`
                     */
                    var res = null,
                        rej = null;

                    if (id) {
                        // return specific quote
                        var key;

                        for (key in data) {
                            if (data.hasOwnProperty(key) && data[key].id == id) {
                                // convert markdown to html
                                res = toHtml(data[key]);
                                break;
                            }
                        }

                        // add quote to history
                        if (res) {
                            QuoteHistoryService.addObjectToHistory(res);
                        }

                        rej = res ? null : 'no quote with id ' + id;
                    } else {
                        /*
                            return random quote or next in history
                            if history is at head, null will be returned. thus
                            a random quote will be resolved
                        */
                        res = QuoteHistoryService.getNext();

                        if (!res) {
                            var dataSize = getDataSize(data);
                            var randID = RandomNumberService.getRandomNumber(0,
                                dataSize - 1);
                            // convert markdown to html
                            res = toHtml(data[randID]);
                            QuoteHistoryService.addObjectToHistory(res);
                        }
                    }

                    if (rej) {
                        defer.reject(rej);
                    } else {
                        defer.resolve(res);
                    }

                }, function(rej) {
                    defer.reject(rej);
                });

                return defer.promise;
            }

            // API for this service
            return {
                getQuote: getQuote
            };
        }
    ])
    .factory('QuoteHistoryService', ['$location',
        function($location) {
            var history = [];
            var histPntr = -1;

            /**
             * Check if there are previous quotes
             * @return {Boolean}
             */
            function hasPrevious() {
                return (histPntr > 0) ? true : false;
            }

            /**
             * Add quote to history anbd change browser location accordingly
             * @param {[type]} id  of quote
             * @param {[type]} obj quote
             */
            function addObjectToHistory(obj) {
                history.push(obj);
                histPntr++;

                // set hash in the browsers location bar
                $location.hash(obj.id);
            }

            /**
             * Get predecessor of the current head quote
             * @return {Object} quote or null if there is no predecessor
             */
            function getPrevious() {
                window.history.back();

                if (histPntr > 0) {
                    histPntr--;

                    console.log('returned getPrevious ' + history[histPntr].id + '; moved pntr to ' + histPntr);
                    return history[histPntr];
                }

                return null; // no more items in history
            }

            /**
             * Get successor of current quote
             * @return {Object} quote or null if there is no successor
             */
            function getNext() {
                var out;

                if (histPntr < (history.length - 1)) {
                    out = history[histPntr];
                    histPntr++;

                    console.log('returned getNext ' + out.id + '; moved pntr to ' + histPntr);

                    // set hash in the browser location
                    if (out) {
                        $location.hash(out.id);
                    }
                } else {
                    out = null;
                }

                return out;
            }

            // API for this service
            return {
                addObjectToHistory: addObjectToHistory,
                getNext: getNext,
                getPrevious: getPrevious,
                hasPrevious: hasPrevious
            };
        }
    ]);
<|endoftext|>


<commit_before>exports = module.exports = PauseQueue;

function PauseQueue (worker, concurrency) {

	if (typeof concurrency === 'undefined') { concurrency = 1; }

	var pending = 0,
		queue = {
			tasks : [],
			concurrency : concurrency,
			drain : null,
			nothing : null,
			paused : false,

			push : function (task, priority, callback) {
				if (typeof priority === 'function') {
					callback = priority;
					priority = false;
				}

				queue.tasks.push({
					data : task,
					callback : (typeof callback === 'function') ? callback : null
				});

				process.nextTick(queue.run);
			},

			run : function () {
                if (pending == 0 && queue.pausedCb) { queue.pausedCb(); delete queue.pausedCb; };

				if (!queue.paused && pending < queue.concurrency && queue.tasks.length) {
					var task = queue.tasks.shift();
					pending += 1;

					var next = function () {
						pending -= 1;

						if (task.callback) {
							task.callback.apply(task, arguments);
						}

						if (queue.drain && queue.tasks.length + pending === 0) { queue.drain(); }
						queue.run();
					};

					worker(task.data, next);
				}

				if (queue.nothing && queue.tasks.length + pending === 0) { queue.nothing(); }

			},

			pause : function (cb) {
				queue.paused = true;
                queue.pausedCb = cb;
				queue.run();
			},

			resume : function () {
				queue.paused = false;
				queue.run();
			},

			length : function () {
				return queue.tasks.length;
			}
		};

	return queue;
}
<commit_msg>Fixed indentation<commit_after>exports = module.exports = PauseQueue;

function PauseQueue (worker, concurrency) {

	if (typeof concurrency === 'undefined') { concurrency = 1; }

	var pending = 0,
		queue = {
			tasks : [],
			concurrency : concurrency,
			drain : null,
			nothing : null,
			paused : false,

			push : function (task, priority, callback) {
				if (typeof priority === 'function') {
					callback = priority;
					priority = false;
				}

				queue.tasks.push({
					data : task,
					callback : (typeof callback === 'function') ? callback : null
				});

				process.nextTick(queue.run);
			},

			run : function () {
				if (pending == 0 && queue.pausedCb) { queue.pausedCb(); delete queue.pausedCb; };

				if (!queue.paused && pending < queue.concurrency && queue.tasks.length) {
					var task = queue.tasks.shift();
					pending += 1;

					var next = function () {
						pending -= 1;

						if (task.callback) {
							task.callback.apply(task, arguments);
						}

						if (queue.drain && queue.tasks.length + pending === 0) { queue.drain(); }
						queue.run();
					};

					worker(task.data, next);
				}

				if (queue.nothing && queue.tasks.length + pending === 0) { queue.nothing(); }

			},

			pause : function (cb) {
				queue.paused = true;
                queue.pausedCb = cb;
				queue.run();
			},

			resume : function () {
				queue.paused = false;
				queue.run();
			},

			length : function () {
				return queue.tasks.length;
			}
		};

	return queue;
}
<|endoftext|>


<commit_before>/* eslint unicorn/filename-case: "off", func-names: "off", camelcase: "off", no-unused-vars: "off" */

module.exports = function (charName, obj, iface) {
    const {acc, settings, subtype} = obj;
    const {mqttStatus, mqttPub, mqttSub, Characteristic, log} = iface;

    if (!Characteristic[charName]) {
        throw new Error('Unknown Characteristic ' + charName);
    }

    const setTopic = 'set' + charName;
    const statusTopic = 'status' + charName.replace(/^Status/, '');

    const service = acc.getService(subtype);
    const characteristic = service.getCharacteristic(Characteristic[charName]);

    if (settings.props && settings.props[charName]) {
        characteristic.setProps(settings.props[charName]);
    }

    const {props, eventOnlyCharacteristic} = characteristic;

    /* istanbul ignore else */
    if (props.perms.includes(Characteristic.Perms.PAIRED_READ) && settings.topic[statusTopic]) {
        mqttSub(settings.topic[statusTopic], val => {
            log.debug('> hap update', settings.name, charName, val);
            service.updateCharacteristic(Characteristic[charName], val);
        });

        /* istanbul ignore else */
        if (!eventOnlyCharacteristic) {
            characteristic.on('get', callback => {
                log.debug('< hap get', settings.name, charName);
                log.debug('> hap re_get', settings.name, charName, mqttStatus[settings.topic[statusTopic]]);
                callback(null, mqttStatus[settings.topic[statusTopic]]);
            });
        }
    }

    /* istanbul ignore else */
    if (props.perms.includes(Characteristic.Perms.PAIRED_WRITE) && settings.topic[setTopic]) {
        characteristic.on('set', (value, callback) => {
            log.debug('< hap set', settings.name, charName, value);
            mqttPub(settings.topic[setTopic], value);
            callback();
        });
    }
};
<commit_msg>fix short topic names, add mqttPublishOptions<commit_after>/* eslint unicorn/filename-case: "off", func-names: "off", camelcase: "off", no-unused-vars: "off" */

module.exports = function (charName, obj, iface) {
    const {acc, settings, subtype} = obj;
    const {mqttStatus, mqttPub, mqttSub, Characteristic, log} = iface;

    if (!Characteristic[charName]) {
        throw new Error('Unknown Characteristic ' + charName);
    }

    let setTopic = 'set' + charName;
    let statusTopic = 'status' + charName;
    const topicShort = charName.replace(/^Set|^Status/, '');
    const setTopicShort = 'set' + topicShort;
    const statusTopicShort = 'status' + topicShort;

    if (setTopic !== setTopicShort && settings.topic[setTopicShort]) {
        setTopic = setTopicShort;
    }

    if (statusTopic !== statusTopicShort && settings.topic[statusTopicShort]) {
        statusTopic = statusTopicShort;
    }

    const service = acc.getService(subtype);
    const characteristic = service.getCharacteristic(Characteristic[charName]);

    if (settings.props && settings.props[charName]) {
        characteristic.setProps(settings.props[charName]);
    }

    const {props, eventOnlyCharacteristic} = characteristic;

    /* istanbul ignore else */
    if (props.perms.includes(Characteristic.Perms.PAIRED_READ) && settings.topic[statusTopic]) {
        mqttSub(settings.topic[statusTopic], val => {
            log.debug('> hap update', settings.name, charName, val);
            service.updateCharacteristic(Characteristic[charName], val);
        });

        /* istanbul ignore else */
        if (!eventOnlyCharacteristic) {
            characteristic.on('get', callback => {
                log.debug('< hap get', settings.name, charName);
                log.debug('> hap re_get', settings.name, charName, mqttStatus[settings.topic[statusTopic]]);
                callback(null, mqttStatus[settings.topic[statusTopic]]);
            });
        }
    }

    /* istanbul ignore else */
    if (props.perms.includes(Characteristic.Perms.PAIRED_WRITE) && settings.topic[setTopic]) {
        characteristic.on('set', (value, callback) => {
            log.debug('< hap set', settings.name, charName, value);
            mqttPub(settings.topic[setTopic], value, settings.mqttPublishOptions);
            callback();
        });
    }
};
<|endoftext|>


<commit_before>/**
 * Track API errors.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { trackEvent } from './';

/**
 *
 * @param {Object} args            The requst arguments.
 * @param {Object} args.method     The request method.
 * @param {Object} args.type       The request type.
 * @param {Object} args.identifier The request identifier.
 * @param {Object} args.datapoint  The request datapoint.
 * @param {Object} args.error      The request error.
 *
 */
export async function trackAPIError( { method, type, identifier, datapoint, error } ) {
	// Exclude certain errors from tracking based on error code.
	const excludedErrorCodes = [
		'fetch_error', // Client failed to fetch from WordPress.
	];
	if ( excludedErrorCodes.indexOf( error.code ) >= 0 ) {
		return;
	}

	await trackEvent(
		'api_error',
		`${ method }:${ type }/${ identifier }/data/${ datapoint }`,
		`${ error.message } (code: ${ error.code }${ error.data?.reason ? ', reason: ' + error.data.reason : '' })`,
		error.data?.status || error.code
	);
}
<commit_msg>Move excludedErrorCodes outside function.<commit_after>/**
 * Track API errors.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { trackEvent } from './';

const excludedErrorCodes = [
	'fetch_error', // Client failed to fetch from WordPress.
];
/**
 * Tracks API errors.
 *
 * @since n.e.x.t
 *
 * @param {Object} args            The requst arguments.
 * @param {Object} args.method     The request method.
 * @param {Object} args.type       The request type.
 * @param {Object} args.identifier The request identifier.
 * @param {Object} args.datapoint  The request datapoint.
 * @param {Object} args.error      The request error.
 */
export async function trackAPIError( { method, type, identifier, datapoint, error } ) {
	// Exclude certain errors from tracking based on error code.

	if ( excludedErrorCodes.indexOf( error.code ) >= 0 ) {
		return;
	}

	await trackEvent(
		'api_error',
		`${ method }:${ type }/${ identifier }/data/${ datapoint }`,
		`${ error.message } (code: ${ error.code }${ error.data?.reason ? ', reason: ' + error.data.reason : '' })`,
		error.data?.status || error.code
	);
}
<|endoftext|>


<commit_before>
var laeh = require('laeh2').leanStacks(true);
var _e = laeh._e;
var _x = laeh._x;

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var marked = require('marked');
var highlight = require('highlight.js');
var _ = require('underscore');
var fs = require('fs');
var utilz = require('utilz');
var optimist = require('optimist');
var tmp = require('temporary');

var phantom_sync = require('phantom-sync')
var phantom = phantom_sync.phantom
var sync = phantom_sync.sync

var pkgJson = require('./package.json');

function cb(err, msg) {
    console.log(err ? (err.stack || err) : msg || 'done');
}

var argv = optimist
    .usage('\nGithub Flavored Markdown Server.\nRun in your project\'s root directory.\nUsage: $0')
    .demand('p')
    .alias('p', 'port')
    .describe('p', 'Port number to listen at.')
    .alias('h', 'host')
    .describe('h', 'Host address to bind to.')
    .default('h', 'localhost')
    .describe('proxy', 'if behind a proxy, proxy url.')
    .argv;

var rootUrl = 'http://' + argv.h + ':' + argv.p + '/'

var pub = __dirname + '/public';
var views = __dirname + '/views';
app.set('views', views);
app.set('view engine', 'jade');
app.set('view options', { layout: false });

app.use(express.static(pub));

function basename(fn) {
    var m = fn.match(/.*?([^\/]+)\/?$/);
    return m ? m[1] : fn;
}

function is_markdown(v) {
    return v.match(/.*?(?:\.md|\.markdown)$/) ? true : false;
}

function is_image(v) {
    return v.match(/.*?(?:\.png|\.jpg|\.gif|\.svg)$/) ? true : false;
}

function is_sourcecode(v) {
    var matched = v.match(/.*?(?:(\.js|\.php|\.php5|\.py|\.sql))$/, 'i');

    if (matched) {
        return matched[1].substring(1).toLowerCase();
    }

    return false;
}

app.get('*', function(req, res, next) {

    if ('pdf' in req.query) {
        var urlToRender = rootUrl + req.path + '?printerFriendly'

        var tmpFileBase = new tmp.File()
        var tmpFilePdfPath = tmpFileBase + '.pdf'

        sync(function() {
            var ph = phantom.create()
            var page = ph.createPage()
            page.set("paperSize", { format: "A4", orientation: 'portrait', margin: '0.6cm' });
            page.viewPortSize = { width: 1366, height: 768 };
            page.open(urlToRender)

            page.render(tmpFilePdfPath)

            var pdfFileContents = fs.readFileSync(tmpFilePdfPath)
            tmpFileBase.unlink()
            fs.unlink(tmpFilePdfPath)

            ph.exit();
            res.send(200, pdfFileContents);
        })

        res.set('Content-Type', 'application/pdf');
        return
    }

    var styles = ('printerFriendly' in req.query) ? ['/print.css'] : []

    if(req.path.indexOf('/styles/') === 0) {
        var style = styles[req.path];
        if(!style) {
            res.send(404);
        }
        else {
            res.set('Content-Type', 'text/css');
            // res.set('ETag', utilz.randomString());
            return res.send(200, style);
        }
    }

    var base = req.path.replace('..', 'DENIED').replace(/\/$/, '');
    var query = req.query || {};
    var dir = decodeURI(process.cwd() + base);
    var lang = "";

    var stat;
    try {
        stat = fs.statSync(dir);
    }
    catch(e) {
        return next();
    }

    if(stat.isDirectory()) {
        renderDir(base, dir, styles, res)
    } else if(is_markdown(dir)) {
        renderFile(dir, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));
    }
    else if(is_image(dir)) {
        renderImageFile(base, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));

    }
    else if(lang = is_sourcecode(dir)) {
        renderSourceCode(dir, lang, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));
    }

    else
        return next();
});

function renderDir(base, dir, styles, res) {
    // stat
    var files = _.chain(fs.readdirSync(dir)).map(function(v) {
        return { name: v, stat: fs.statSync(dir + '/' + v) }
    })

    // show only docs
    files = files.filter(function(fileDesc) {
        return fileDesc.stat.isDirectory() || (fileDesc.stat.isFile() && (is_markdown(fileDesc.name) || is_image(fileDesc.name)));
    })

    // sort
    files = files.sortBy(function(entry) { return !entry.stat.isDirectory() })

    // prepare file list for jade template
    files = files.map(function(fileDesc) {
        return {
            url: base + '/' + fileDesc.name,
            name: fileDesc.name,
            type: fileDesc.stat.isDirectory() ? 'directory' : 'text'
        };
    })

    files = files.value();

    res.render('directory', {
        files: files,
        dir: dir,
        baseDir: base ? base : '/',
        styles: styles,
        title: basename(dir)
    });
}

function renderFile(file, cb) { // cb(err, res)
    var contents = fs.readFileSync(file, 'utf8');
    renderWithMarked(contents, _x(cb, true, cb));
}

function renderImageFile(file, cb) { // cb(err, res)
    var html = '

';
    cb(null, html);
}

function renderSourceCode(file, lang, cb) { // cb(err, res)
    var contents = "```" + lang + "\n" + fs.readFileSync(file, 'utf8') + "\n```";
    renderWithMarked(contents, _x(cb, true, cb));
}

function renderWithMarked(contents, cb) { // cb(err, res)
    marked.setOptions({
      gfm: true,
      tables: true,
      smartLists: true,
      breaks: true,
      highlight: function (code, lang) {
        if (lang) {
            return highlight.highlight(lang, code, true).value;
        } else {
            code
        }
      }
    });

    var html = marked(contents);

    cb(null, html);
}

process.on('SIGINT', function() {
    console.log('\nGFMS exit.');
    return process.exit();
});

_x(cb, false, function() {
        server.listen(argv.p, argv.h);
        console.log('GFMS ' + pkgJson.version + ' serving ' + process.cwd() + ' at ' + rootUrl + ' - press CTRL+C to exit.');
})();
<commit_msg>Directory listing displays parent directory entry<commit_after>
var laeh = require('laeh2').leanStacks(true);
var _e = laeh._e;
var _x = laeh._x;

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var marked = require('marked');
var highlight = require('highlight.js');
var _ = require('underscore');
var fs = require('fs');
var utilz = require('utilz');
var optimist = require('optimist');
var tmp = require('temporary');

var phantom_sync = require('phantom-sync')
var phantom = phantom_sync.phantom
var sync = phantom_sync.sync

var pkgJson = require('./package.json');

function cb(err, msg) {
    console.log(err ? (err.stack || err) : msg || 'done');
}

var argv = optimist
    .usage('\nGithub Flavored Markdown Server.\nRun in your project\'s root directory.\nUsage: $0')
    .demand('p')
    .alias('p', 'port')
    .describe('p', 'Port number to listen at.')
    .alias('h', 'host')
    .describe('h', 'Host address to bind to.')
    .default('h', 'localhost')
    .describe('proxy', 'if behind a proxy, proxy url.')
    .argv;

var rootUrl = 'http://' + argv.h + ':' + argv.p + '/'

var pub = __dirname + '/public';
var views = __dirname + '/views';
app.set('views', views);
app.set('view engine', 'jade');
app.set('view options', { layout: false });

app.use(express.static(pub));

function basename(fn) {
    var m = fn.match(/.*?([^\/]+)\/?$/);
    return m ? m[1] : fn;
}

function is_markdown(v) {
    return v.match(/.*?(?:\.md|\.markdown)$/) ? true : false;
}

function is_image(v) {
    return v.match(/.*?(?:\.png|\.jpg|\.gif|\.svg)$/) ? true : false;
}

function is_sourcecode(v) {
    var matched = v.match(/.*?(?:(\.js|\.php|\.php5|\.py|\.sql))$/, 'i');

    if (matched) {
        return matched[1].substring(1).toLowerCase();
    }

    return false;
}

app.get('*', function(req, res, next) {

    if ('pdf' in req.query) {
        var urlToRender = rootUrl + req.path + '?printerFriendly'

        var tmpFileBase = new tmp.File()
        var tmpFilePdfPath = tmpFileBase + '.pdf'

        sync(function() {
            var ph = phantom.create()
            var page = ph.createPage()
            page.set("paperSize", { format: "A4", orientation: 'portrait', margin: '0.6cm' });
            page.viewPortSize = { width: 1366, height: 768 };
            page.open(urlToRender)

            page.render(tmpFilePdfPath)

            var pdfFileContents = fs.readFileSync(tmpFilePdfPath)
            tmpFileBase.unlink()
            fs.unlink(tmpFilePdfPath)

            ph.exit();
            res.send(200, pdfFileContents);
        })

        res.set('Content-Type', 'application/pdf');
        return
    }

    var styles = ('printerFriendly' in req.query) ? ['/print.css'] : []

    if(req.path.indexOf('/styles/') === 0) {
        var style = styles[req.path];
        if(!style) {
            res.send(404);
        }
        else {
            res.set('Content-Type', 'text/css');
            // res.set('ETag', utilz.randomString());
            return res.send(200, style);
        }
    }

    var base = req.path.replace('..', 'DENIED').replace(/\/$/, '');
    var query = req.query || {};
    var dir = decodeURI(process.cwd() + base);
    var lang = "";

    var stat;
    try {
        stat = fs.statSync(dir);
    }
    catch(e) {
        return next();
    }

    if(stat.isDirectory()) {
        renderDir(base, dir, styles, res)
    } else if(is_markdown(dir)) {
        renderFile(dir, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));
    }
    else if(is_image(dir)) {
        renderImageFile(base, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));

    }
    else if(lang = is_sourcecode(dir)) {
        renderSourceCode(dir, lang, _x(next, true, function(err, rendered) {
            res.render('file', {
                file: rendered,
                title: basename(dir),
                styles: styles,
                fullname: dir
            });
        }));
    }

    else
        return next();
});

function renderDir(base, dir, styles, res) {
    // stat
    var files = _.chain(fs.readdirSync(dir)).map(function(v) {
        return { name: v, stat: fs.statSync(dir + '/' + v) }
    })

    // show only docs
    files = files.filter(function(fileDesc) {
        return fileDesc.stat.isDirectory() || (fileDesc.stat.isFile() && (is_markdown(fileDesc.name) || is_image(fileDesc.name)));
    })

    // sort
    files = files.sortBy(function(entry) { return !entry.stat.isDirectory() })

    // prepare file list for jade template
    files = files.map(function(fileDesc) {
        return {
            url: base + '/' + fileDesc.name,
            name: fileDesc.name,
            type: fileDesc.stat.isDirectory() ? 'directory' : 'text'
        };
    })

    files = files.value();
    // add parent directory
    if (base.length > '/'.length) {
        files.unshift({
            url: base.slice(0, base.lastIndexOf('/')) || '/',
            name: '..',
            type: 'directory'
        })
    }

    res.render('directory', {
        files: files,
        dir: dir,
        baseDir: base ? base : '/',
        styles: styles,
        title: basename(dir)
    });
}

function renderFile(file, cb) { // cb(err, res)
    var contents = fs.readFileSync(file, 'utf8');
    renderWithMarked(contents, _x(cb, true, cb));
}

function renderImageFile(file, cb) { // cb(err, res)
    var html = '

';
    cb(null, html);
}

function renderSourceCode(file, lang, cb) { // cb(err, res)
    var contents = "```" + lang + "\n" + fs.readFileSync(file, 'utf8') + "\n```";
    renderWithMarked(contents, _x(cb, true, cb));
}

function renderWithMarked(contents, cb) { // cb(err, res)
    marked.setOptions({
      gfm: true,
      tables: true,
      smartLists: true,
      breaks: true,
      highlight: function (code, lang) {
        if (lang) {
            return highlight.highlight(lang, code, true).value;
        } else {
            code
        }
      }
    });

    var html = marked(contents);

    cb(null, html);
}

process.on('SIGINT', function() {
    console.log('\nGFMS exit.');
    return process.exit();
});

_x(cb, false, function() {
        server.listen(argv.p, argv.h);
        console.log('GFMS ' + pkgJson.version + ' serving ' + process.cwd() + ' at ' + rootUrl + ' - press CTRL+C to exit.');
})();
<|endoftext|>


<commit_before>'use strict';

const concat = require('lodash/concat');
const isNil = require('lodash/isNil');
const each = require('lodash/each');
const join = require('lodash/join');
const keys = require('lodash/keys');
const difference = require('lodash/difference');
const first = require('lodash/first');
const includes = require('lodash/includes');
const map = require('lodash/map');
const assign = require('lodash/assign');
const last = require('lodash/last');
const dropRight = require('lodash/dropRight');

const WatsonsError = require('./lib/WatsonsError');
const formatKeyPath = require('./lib/formatKeyPath');

const validators = {};

const dependencies = {};

let config = {
  checkDeps: true
};

class ChainedValidator extends Object {
  constructor(validators) {
    super();
    this.validators = validators;
    if (config.checkDeps) {
      this.checkDeps();
    }
  }

  checkDeps() {
    let validatorName = last(this.validators).name;
    let requiredDeps = dependencies[validatorName];
    if (requiredDeps) {
      let chained = map(dropRight(this.validators), 'name');
      let unfulfilledDeps = difference(requiredDeps, chained);
      if (unfulfilledDeps.length !== 0) {
        throw new WatsonsError(`Unfulfilled validator dependencies ${join(unfulfilledDeps, ', ')} for validator ${validatorName}.`);
      }
    }
  }
}

const watsons = {
  config: function(newConfig) {
    config = assign({}, config, newConfig);
  },
  addValidator: function(name, validator, acceptParams, deps) {
    if (watsons[name] && !this.hasValidator(name)) {
      throw new WatsonsError(`Invalid validator name '${name}'.`);
    } else if (this.hasValidator(name)) {
      throw new WatsonsError(`Validator '${name}' redefined.`);
    }
    if (deps) {
      dependencies[name] = deps;
    }
    if (!acceptParams) {
      watsons[name] = new ChainedValidator([{name: name}]);
      validators[name] = validator;
      Object.defineProperty(ChainedValidator.prototype, name, {
        get: function() {
          return new ChainedValidator(concat(this.validators, {name: name}));
        }
      });
    } else {
      watsons[name] = function(params) {
        return new ChainedValidator([{name: name, params: params}]);
      };
      validators[name] = validator;

      Object.defineProperty(ChainedValidator.prototype, name, {
        get: function() {
          return function(params) {
            return new ChainedValidator(
              concat(this.validators, {name: name, params: params}));
          };
        }
      });
    }
  },
  hasValidator: function(name) {
    return validators.hasOwnProperty(name);
  },

  validate: function(object, schema, validator = watsons.shape(schema), keyPath = [], root = object) {
    each(validator.validators, function(v) {
      validators[v.name](object, keyPath, root, v.params);
    });
  }
};

// See https://github.com/facebook/prop-types/blob/155f4cc27ae7e566bb2825edb9f4467ed1d0d2b2/factoryWithTypeCheckers.js#L459
function isSymbol(t, v) {
  if (v === null) {
    return false;
  }
  // Native Symbol.
  if (t === 'symbol') {
    return true;
  }
  // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
  if (v['@@toStringTag'] === 'Symbol') {
    return true;
  }
  // Fallback for non-spec compliant Symbols which are polyfilled.
  if (typeof Symbol === 'function' && v instanceof Symbol) {
    return true;
  }
  return false;
}

// TODO: handle string, number objects
function getPrimitiveType(v) {
  if (v === null) {
    return 'null';
  }
  let type = typeof v;
  if ((type === 'object') && Array.isArray(v)) {
    return 'array';
  }
  if (isSymbol(type, v)) {
    return 'symbol';
  }
  if (v instanceof Date) {
    return 'date';
  }
  if (v instanceof RegExp) {
    return 'regexp';
  }
  if (v === null) {
    return null;
  }
  return type;
}

watsons.addValidator("shape", function(object, keyPath, root, validators) {
  if (object === undefined) return;
  let unallowedKey = first(difference(keys(object), keys(validators)));
  if (unallowedKey) {
    throw new WatsonsError(`Unallowed key '${unallowedKey}' at key path \
'${formatKeyPath(keyPath)}'.`);
  }
  each(validators, function(validator, k){
    let value = object[k];
    watsons.validate(value, undefined, validator, concat(keyPath, k), root);
  });
}, true);

each(['array', 'object'], function(collection) {
  watsons.addValidator(`${collection}Of`, function(value, keyPath, root, validator) {
    if (value === undefined) return;
    watsons.validate(value, undefined, watsons[collection], keyPath, root);
    each(value, function(v, i) {
      watsons.validate(v, undefined, validator, concat(keyPath, i), root);
    });
  }, true);
});

watsons.addValidator("instanceOf", function(value, keyPath, root, kls) {
  if (!value instanceof kls) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be instance of ${kls.name}.`);
  }
}, true);

// TODO: validator dependency,
//for example, watsons.date.before(tomorrow), before requires date to be prepended.
each(['array', 'bool', 'func', 'number', 'object', 'string', 'symbol', 'date', 'regexp', 'null'], function(expectedType){
  watsons.addValidator(expectedType, function(value, keyPath, root) {
    // Keep API simple and adjective by keeping in sync with prop-types, thus using 'func'.
    if (expectedType === 'func') expectedType = 'function';
    if (expectedType === 'bool') expectedType = 'boolean';
    if (value === undefined) return;
    if (getPrimitiveType(value) !== expectedType) {
      throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be '${expectedType}'.`);
    }
  });
});

watsons.addValidator("required", function(value, keyPath, root) {
  if (value === undefined) {
    throw new WatsonsError(`Required value at key path \
'${formatKeyPath(keyPath)}'.`);
  }
});

watsons.addValidator("any", function(value, keyPath, root) {});

watsons.addValidator("oneOf", function(value, keyPath, root, list) {
  if (value === undefined) return;
  if (!includes(list, value)) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be one of [${join(list, ",")}], but it is '${value}'.`);
  }
}, true);

watsons.addValidator("oneOfType", function(value, keyPath, root, validators) {
  if (value === undefined) return;
  let passFlag = false;
  each(validators, function(v) {
    if (!passFlag) {
      try {
        watsons.validate(value, undefined, v, keyPath, root);
        passFlag = true;
      } catch(e) {
      }
    }
  });
  if (!passFlag) {
    let types = join(map(validators, "validators.0.name"), ", ");
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be one of type [${types}].`);
  }
}, true);

watsons.addValidator("validateWith", function(value, keyPath, root, func) {
  if (!func(value, keyPath, root)) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
not passing custom validator function.`);
  }
}, true);

module.exports = watsons;
<commit_msg>'rule' and 'rules' validator.<commit_after>'use strict';

const concat = require('lodash/concat');
const isNil = require('lodash/isNil');
const each = require('lodash/each');
const join = require('lodash/join');
const keys = require('lodash/keys');
const difference = require('lodash/difference');
const first = require('lodash/first');
const includes = require('lodash/includes');
const map = require('lodash/map');
const assign = require('lodash/assign');
const last = require('lodash/last');
const dropRight = require('lodash/dropRight');

const WatsonsError = require('./lib/WatsonsError');
const formatKeyPath = require('./lib/formatKeyPath');

const validators = {};

const dependencies = {};

let config = {
  checkDeps: true
};

class ChainedValidator extends Object {
  constructor(validators) {
    super();
    this.validators = validators;
    if (config.checkDeps) {
      this.checkDeps();
    }
  }

  checkDeps() {
    let validatorName = last(this.validators).name;
    let requiredDeps = dependencies[validatorName];
    if (requiredDeps) {
      let chained = map(dropRight(this.validators), 'name');
      let unfulfilledDeps = difference(requiredDeps, chained);
      if (unfulfilledDeps.length !== 0) {
        throw new WatsonsError(`Unfulfilled validator dependencies ${join(unfulfilledDeps, ', ')} for validator ${validatorName}.`);
      }
    }
  }
}

const watsons = {
  config: function(newConfig) {
    config = assign({}, config, newConfig);
  },
  addValidator: function(name, validator, acceptParams, deps) {
    if (watsons[name] && !this.hasValidator(name)) {
      throw new WatsonsError(`Invalid validator name '${name}'.`);
    } else if (this.hasValidator(name)) {
      throw new WatsonsError(`Validator '${name}' redefined.`);
    }
    if (deps) {
      dependencies[name] = deps;
    }
    if (!acceptParams) {
      watsons[name] = new ChainedValidator([{name: name}]);
      validators[name] = validator;
      Object.defineProperty(ChainedValidator.prototype, name, {
        get: function() {
          return new ChainedValidator(concat(this.validators, {name: name}));
        }
      });
    } else {
      watsons[name] = function(params) {
        return new ChainedValidator([{name: name, params: params}]);
      };
      validators[name] = validator;

      Object.defineProperty(ChainedValidator.prototype, name, {
        get: function() {
          return function(params) {
            return new ChainedValidator(
              concat(this.validators, {name: name, params: params}));
          };
        }
      });
    }
  },
  hasValidator: function(name) {
    return validators.hasOwnProperty(name);
  },

  validate: function(object, schema, validator = watsons.shape, keyPath = [], root = object) {
    if (typeof validator === 'function') {
      validator = validator(schema);
    }
    each(validator.validators, function(v) {
      validators[v.name](object, keyPath, root, v.params);
    });
  }
};

// See https://github.com/facebook/prop-types/blob/155f4cc27ae7e566bb2825edb9f4467ed1d0d2b2/factoryWithTypeCheckers.js#L459
function isSymbol(t, v) {
  if (v === null) {
    return false;
  }
  // Native Symbol.
  if (t === 'symbol') {
    return true;
  }
  // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
  if (v['@@toStringTag'] === 'Symbol') {
    return true;
  }
  // Fallback for non-spec compliant Symbols which are polyfilled.
  if (typeof Symbol === 'function' && v instanceof Symbol) {
    return true;
  }
  return false;
}

// TODO: handle string, number objects
function getPrimitiveType(v) {
  if (v === null) {
    return 'null';
  }
  let type = typeof v;
  if ((type === 'object') && Array.isArray(v)) {
    return 'array';
  }
  if (isSymbol(type, v)) {
    return 'symbol';
  }
  if (v instanceof Date) {
    return 'date';
  }
  if (v instanceof RegExp) {
    return 'regexp';
  }
  if (v === null) {
    return null;
  }
  return type;
}

watsons.addValidator("shape", function(object, keyPath, root, validators) {
  if (object === undefined) return;
  let unallowedKey = first(difference(keys(object), keys(validators)));
  if (unallowedKey) {
    throw new WatsonsError(`Unallowed key '${unallowedKey}' at key path \
'${formatKeyPath(keyPath)}'.`);
  }
  each(validators, function(validator, k){
    let value = object[k];
    watsons.validate(value, undefined, validator, concat(keyPath, k), root);
  });
}, true);

each(['array', 'object'], function(collection) {
  watsons.addValidator(`${collection}Of`, function(value, keyPath, root, validator) {
    if (value === undefined) return;
    watsons.validate(value, undefined, watsons[collection], keyPath, root);
    each(value, function(v, i) {
      watsons.validate(v, undefined, validator, concat(keyPath, i), root);
    });
  }, true);
});

watsons.addValidator("instanceOf", function(value, keyPath, root, kls) {
  if (!value instanceof kls) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be instance of ${kls.name}.`);
  }
}, true);

// TODO: validator dependency,
//for example, watsons.date.before(tomorrow), before requires date to be prepended.
each(['array', 'bool', 'func', 'number', 'object', 'string', 'symbol', 'date', 'regexp', 'null'], function(expectedType){
  watsons.addValidator(expectedType, function(value, keyPath, root) {
    // Keep API simple and adjective by keeping in sync with prop-types, thus using 'func'.
    if (expectedType === 'func') expectedType = 'function';
    if (expectedType === 'bool') expectedType = 'boolean';
    if (value === undefined) return;
    if (getPrimitiveType(value) !== expectedType) {
      throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be '${expectedType}'.`);
    }
  });
});

watsons.addValidator("required", function(value, keyPath, root) {
  if (value === undefined) {
    throw new WatsonsError(`Required value at key path \
'${formatKeyPath(keyPath)}'.`);
  }
});

watsons.addValidator("any", function(value, keyPath, root) {});

watsons.addValidator("oneOf", function(value, keyPath, root, list) {
  if (value === undefined) return;
  if (!includes(list, value)) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be one of [${join(list, ",")}], but it is '${value}'.`);
  }
}, true);

watsons.addValidator("oneOfType", function(value, keyPath, root, validators) {
  if (value === undefined) return;
  let passFlag = false;
  each(validators, function(v) {
    if (!passFlag) {
      try {
        watsons.validate(value, undefined, v, keyPath, root);
        passFlag = true;
      } catch(e) {
      }
    }
  });
  if (!passFlag) {
    let types = join(map(validators, "validators.0.name"), ", ");
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
should be one of type [${types}].`);
  }
}, true);

watsons.addValidator("validateWith", function(value, keyPath, root, func) {
  if (!func(value, keyPath, root)) {
    throw new WatsonsError(`Value at key path '${formatKeyPath(keyPath)}' \
not passing custom validator function.`);
  }
}, true);

watsons.addValidator("rule", function(value, keyPath, root, rule) {
  console.log("HERE RUNS");
  let [checker, message] = rule;
  console.log("CHECKER");
  console.log(checker);
  console.log("message");
  console.log(message);
  try {
    watsons.validate(value, undefined, checker);
  } catch(e) {
    throw new WatsonsError(message);
  }
}, true);

watsons.addValidator("rules", function(value, keyPath, root, rules) {
  each(rules, (rule) => {
    watsons.validate(value, rule, watsons.rule);
  });
}, true);

module.exports = watsons;
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var EOL = require('os').EOL;

var through = require('through2');
var gutil = require('gulp-util');
var rev = require('gulp-rev');

module.exports = function (options) {
  options = options || {}; // cssmin, htmlmin, jsmin

  var SECTION_START_REGEX = /<!--\s*build:(css|js)(?:\(([^\)]+?)\))?\s+(\/?([^\s]+?))\s*-->/gim;
  var SECTION_END_REGEX   = /<!--\s*endbuild\s*-->/gim;
  var SECTION_JS_REGEX    = /<\s*script\s+.*?src\s*=\s*"([^"]+?)".*?><\s*\/\s*script\s*>/gi;
  var SECTION_CSS_REGEX   = /<\s*link\s+.*?href\s*=\s*"([^"]+)".*?>/gi;

  var section_regex = {
    js : SECTION_JS_REGEX,
    css: SECTION_CSS_REGEX
  }

  function createSection(section) {
    return {
      original     : section[0], // ? always empty?
      fileType     : section[1], // x
      alternatePath: section[2], // x
      outName      : section[3], // ?
      outName      : section[4], // ?
      content      : section[5]  // x
    }
  }

  // function createFile(name, content, asset) {
  //  var filepath = path.join(path.relative(basePath, mainPath), name)

  //  if (asset === true && options.assetsDir)
  //  {
  //    filepath = path.relative(basePath,path.join(options.assetsDir,filepath));
  //  }

  //  return new gutil.File({
  //    path: filepath,
  //    contents: new Buffer(content)
  //  });
  // }

  // function concat(content, reg, delimiter) {
  //  var paths = [];
  //  var buffer = [];

  //  content
  //    .replace(/<!--(?:(?:.|\r|\n)*?)-->/gim, '')
  //    .replace(reg, function (a, b) {
  //      paths.push(path.resolve(path.join(alternatePath || mainPath, b)));
  //    });

  //  for (var i = 0, l = paths.length; i < l; ++i)
  //    buffer.push(fs.readFileSync(paths[i]));

  //  return buffer.join(delimiter);
  // }

  // function write(files, processor, callback) {
  //  if (processor) {
  //    processor.on('data', callback);

  //    files.forEach(function(file) {
  //      processor.write(file);
  //    });

  //    processor.removeListener('data', callback);
  //  }
  //  else
  //    files.forEach(callback);
  // }

  function getSectionFiles(section, reg, state) {
    var files = [];

    processFilePath = function(a, b) {
      filePath    = path.join(state.alternatePath || state.mainPath, b)
      fileContent = new Buffer(fs.readFileSync(filePath));

      files.push(new gutil.File({
        path    : b,
        contents: fileContent
      }));
    }

    section.content
      .replace(/<!--(?:(?:.|\r|\n)*?)-->/gim, '')
      .replace(reg, processFilePath)

    return files
  }

  function transformSectionRefs(section, sectionRefs) {
    finalRefs = []

    function onFinalRef(file) {
      finalRefs.push(file)
    }

    options.jsmin.on('data', onFinalRef)

    sectionRefs.forEach(function(file) {
      options.jsmin.write(file);
    })

    options.jsmin.removeListener('on', onFinalRef)
    return finalRefs
  }

  function processHtml(file) {
    var state = {
      basePath: file.base,
      mainPath: path.dirname(file.path),
      mainName: path.basename(file.path),
    }

    var result      = [];
    var content     = String(file.contents);
    var sectionsRaw = content.split(SECTION_END_REGEX);

    for (var i = 0; i < sectionsRaw.length; i++) {

      // Not a valid section, append to result
      if (!sectionsRaw[i].match(SECTION_START_REGEX)) {
        result.push(sectionsRaw[i]);
        continue;
      }

      var sectionRaw  = sectionsRaw[i].split(SECTION_START_REGEX);
      var section     = createSection(sectionRaw);
      var sectionRefs = getSectionFiles(section, section_regex[section.fileType], state)
      var finalRefs   = transformSectionRefs(section, sectionRefs)

      // console.log('Discovered section: ', section.outName)
      // console.log('Section files: ', sectionRefs)
      // console.log('Transformed files: ', finalRefs)

      result.push(section.original)

      for (var l = 0; l < finalRefs.length; l++) {
        result.push('<script src="' + finalRefs[l].path + '"></script>' + EOL);
      }
    }

    // console.log('Final: ', result)

    return new gutil.File({
      path    : path.join(path.relative(state.basePath, state.mainPath), state.mainName),
      contents: new Buffer(result.join(''))
    })
  }

  return through.obj(function (file, enc, callback) {

    if (file.isNull()) {
      this.push(file);
      callback();
      return;
    }

    if (file.isStream()) {
      this.emit('error', new gutil.PluginError('gulp-indexpipe', 'Streams are not supported!'));
      callback();
      return
    }

    var result = processHtml(file);
    this.push(result);
    callback();
  });
};
<commit_msg>Removed unused code<commit_after>var path = require('path');
var fs = require('fs');
var EOL = require('os').EOL;

var through = require('through2');
var gutil = require('gulp-util');
var rev = require('gulp-rev');

module.exports = function (options) {
  options = options || {}; // cssmin, htmlmin, jsmin

  var SECTION_START_REGEX = /<!--\s*build:(css|js)(?:\(([^\)]+?)\))?\s+(\/?([^\s]+?))\s*-->/gim;
  var SECTION_END_REGEX   = /<!--\s*endbuild\s*-->/gim;
  var SECTION_JS_REGEX    = /<\s*script\s+.*?src\s*=\s*"([^"]+?)".*?><\s*\/\s*script\s*>/gi;
  var SECTION_CSS_REGEX   = /<\s*link\s+.*?href\s*=\s*"([^"]+)".*?>/gi;

  var section_regex = {
    js : SECTION_JS_REGEX,
    css: SECTION_CSS_REGEX
  }

  function createSection(section) {
    return {
      original     : section[0], // ? always empty?
      fileType     : section[1], // x
      alternatePath: section[2], // x
      outName      : section[3], // ?
      outName      : section[4], // ?
      content      : section[5]  // x
    }
  }

  function getSectionFiles(section, reg, state) {
    var files = [];

    processFilePath = function(a, b) {
      filePath    = path.join(state.alternatePath || state.mainPath, b)
      fileContent = new Buffer(fs.readFileSync(filePath));

      files.push(new gutil.File({
        path    : b,
        contents: fileContent
      }));
    }

    section.content
      .replace(/<!--(?:(?:.|\r|\n)*?)-->/gim, '')
      .replace(reg, processFilePath)

    return files
  }

  function transformSectionRefs(section, sectionRefs) {
    finalRefs = []

    function onFinalRef(file) {
      finalRefs.push(file)
    }

    options.jsmin.on('data', onFinalRef)

    sectionRefs.forEach(function(file) {
      options.jsmin.write(file);
    })

    options.jsmin.removeListener('on', onFinalRef)
    return finalRefs
  }

  function processHtml(file) {
    var state = {
      basePath: file.base,
      mainPath: path.dirname(file.path),
      mainName: path.basename(file.path),
    }

    var result      = [];
    var content     = String(file.contents);
    var sectionsRaw = content.split(SECTION_END_REGEX);

    for (var i = 0; i < sectionsRaw.length; i++) {

      // Not a valid section, append to result
      if (!sectionsRaw[i].match(SECTION_START_REGEX)) {
        result.push(sectionsRaw[i]);
        continue;
      }

      var sectionRaw  = sectionsRaw[i].split(SECTION_START_REGEX);
      var section     = createSection(sectionRaw);
      var sectionRefs = getSectionFiles(section, section_regex[section.fileType], state)
      var finalRefs   = transformSectionRefs(section, sectionRefs)

      // console.log('Discovered section: ', section.outName)
      // console.log('Section files: ', sectionRefs)
      // console.log('Transformed files: ', finalRefs)

      result.push(section.original)

      for (var l = 0; l < finalRefs.length; l++) {
        result.push('<script src="' + finalRefs[l].path + '"></script>' + EOL);
      }
    }

    // console.log('Final: ', result)

    return new gutil.File({
      path    : path.join(path.relative(state.basePath, state.mainPath), state.mainName),
      contents: new Buffer(result.join(''))
    })
  }

  return through.obj(function (file, enc, callback) {

    if (file.isNull()) {
      this.push(file);
      callback();
      return;
    }

    if (file.isStream()) {
      this.emit('error', new gutil.PluginError('gulp-indexpipe', 'Streams are not supported!'));
      callback();
      return
    }

    var result = processHtml(file);
    this.push(result);
    callback();
  });
};
<|endoftext|>


<commit_before>var apimocker = require("apimocker");

module.exports = {
	start: function(){
		console.log('--------------------');
	}
}<commit_msg>add start function to index.js<commit_after>var apimocker = require("apimocker");

module.exports = {
  start: function (options) {
    if (options == null) {
      options = {};
    }

    apimocker.createServer(options).setConfigFile(options.config).start();
  }
}<|endoftext|>