<commit_before>/*global document, console */

var GithubUsers = (function () {

    var xmlHttp = null;
    var BASEURL = 'https://api.github.com/search/users?q=';
    var USERSTOSHOW = 16;

    var _showSeachResult = function (info) {
        //'use strict';
        this.info = info;
        var countSearchResult = this.info.total_count;

        document.getElementById("items-found").innerHTML = countSearchResult;

        if (countSearchResult > USERSTOSHOW) {
            this.usersToShow = USERSTOSHOW;
        } else {
            this.usersToShow = countSearchResult;
        }
        var searchResult = document.getElementById("search-result"),
            resultUserInfo = document.getElementById("result-user-info"),
            i;

        searchResult.removeChild(resultUserInfo);

        var newResultUserInfo = document.createElement("div");
        newResultUserInfo.setAttribute('id', 'result-user-info');
        newResultUserInfo.setAttribute('class', "col-md-12 result-user-info");
        searchResult.appendChild(newResultUserInfo);

        var ulElement = document.createElement("ul");

        for (i = 0; i < this.usersToShow; i += 1) {
            var liElement = document.createElement("li");
            ulElement.appendChild(liElement);

            var userResult = document.createElement("div");
            userResult.setAttribute('class', 'user-result');

            var imgElement = document.createElement("img");
            imgElement.setAttribute('id', this.info.items[i].login);
            imgElement.setAttribute('alt', 'Identicon');
            imgElement.setAttribute('src', this.info.items[i].avatar_url);

            var pElement = document.createElement("p");

            var userLogin = document.createTextNode(this.info.items[i].login.slice(0, 14));

            pElement.appendChild(userLogin);

            userResult.appendChild(imgElement);
            userResult.appendChild(pElement);
            liElement.appendChild(userResult);
        }
        newResultUserInfo.appendChild(ulElement);
    };

    var _eventInputSearch = function (event) {
        if (event.target.value.length >= 3) {
            _httpGet(BASEURL + event.target.value);
        }
    };

    var _httpGet = function (theUrl) {
        xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = _ProcessRequest;
        xmlHttp.open("GET", theUrl, true);
        xmlHttp.send(null);
    };

    var _ProcessRequest = function () {
    if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
        if (xmlHttp.responseText == "Not found") {
            document.getElementById("raw-items-found").value = "Not found";
            document.getElementById("raw-result").value = "";
        } else {
            var info = eval ( "(" + xmlHttp.responseText + ")" );

            _showSeachResult(info);

            document.getElementById("raw-items-found").value = info.total_count;
            document.getElementById("raw-result").value = xmlHttp.responseText;
            }
        }
    };

    var initialize = function () {
        userSearchOnChange = document.getElementById('github-user-onchange');
        userSearchOnChange.addEventListener('change', _eventInputSearch, false);
        userSearchOnInput = document.getElementById('github-user-oninput');
        userSearchOnInput.addEventListener('input', _eventInputSearch, false);
        console.log("Initialize: Ok");
    };

    return {
        initialize: initialize
    };

})();
<commit_msg>Add some SRP refactor<commit_after>/*global document, console */

var GithubUsers = (function () {

    var xmlHttp = null;
    var BASEURL = 'https://api.github.com/search/users?q=';
    var USERSTOSHOW = 16;

    var _showSeachResult = function (info) {
        //'use strict';
        this.info = info;
        var countSearchResult = this.info.total_count;

        document.getElementById("items-found").innerHTML = countSearchResult;

        if (countSearchResult > USERSTOSHOW) {
            this.usersToShow = USERSTOSHOW;
        } else {
            this.usersToShow = countSearchResult;
        }
        var searchResult = document.getElementById("search-result"),
            resultUserInfo = document.getElementById("result-user-info"),
            i;

        searchResult.removeChild(resultUserInfo);

        var newResultUserInfo = document.createElement("div");
        newResultUserInfo.setAttribute('id', 'result-user-info');
        newResultUserInfo.setAttribute('class', "col-md-12 result-user-info");
        searchResult.appendChild(newResultUserInfo);

        var ulElement = document.createElement("ul");

        for (i = 0; i < this.usersToShow; i += 1) {
            var liElement = document.createElement("li");
            ulElement.appendChild(liElement);

            var userResult = document.createElement("div");
            userResult.setAttribute('class', 'user-result');

            var imgElement = document.createElement("img");
            imgElement.setAttribute('id', this.info.items[i].login);
            imgElement.setAttribute('alt', 'Identicon');
            imgElement.setAttribute('src', this.info.items[i].avatar_url);

            var pElement = document.createElement("p");

            var userLogin = document.createTextNode(this.info.items[i].login.slice(0, 14));

            pElement.appendChild(userLogin);

            userResult.appendChild(imgElement);
            userResult.appendChild(pElement);
            liElement.appendChild(userResult);
        }
        newResultUserInfo.appendChild(ulElement);
    };

    var _urlToSearch = function (user) {
        _httpGet(BASEURL + user);
    };

    var _triggerNormalizer = function (user) {
        this.user = user;
        if (this.user.length >= 3) {
            _urlToSearch(this.user);
        }
    };

    var _eventInputNormalizer = function (event) {
        var user = event.target.value;
        _triggerNormalizer(user);
    };

    var _httpGet = function (theUrl) {
        xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = _ProcessRequest;
        xmlHttp.open("GET", theUrl, true);
        xmlHttp.send(null);
    };

    var _ProcessRequest = function () {
    if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
        if (xmlHttp.responseText == "Not found") {
            document.getElementById("raw-items-found").value = "Not found";
            document.getElementById("raw-result").value = "";
        } else {
            var info = eval ( "(" + xmlHttp.responseText + ")" );

            _showSeachResult(info);

            document.getElementById("raw-items-found").value = info.total_count;
            document.getElementById("raw-result").value = xmlHttp.responseText;
            }
        }
    };

    var initialize = function () {
        userSearchOnChange = document.getElementById('github-user-onchange');
        userSearchOnChange.addEventListener('change', _eventInputNormalizer, false);
        userSearchOnInput = document.getElementById('github-user-oninput');
        userSearchOnInput.addEventListener('input', _eventInputNormalizer, false);
        console.log("Initialize: Ok");
    };

    return {
        initialize: initialize
    };

})();
<|endoftext|>


<commit_before>/*
 *      This file is part of GPaste.
 *
 *      Copyright 2014-2015 Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
 *
 *      GPaste is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      GPaste is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with GPaste.  If not, see <http://www.gnu.org/licenses/>.
 */
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */

const Lang = imports.lang;

const PopupMenu = imports.ui.popupMenu;

const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const St = imports.gi.St;

const GPaste = imports.gi.GPaste;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();

const DeleteItemPart = Me.imports.deleteItemPart;

const GPasteItem = new Lang.Class({
    Name: 'GPasteItem',
    Extends: PopupMenu.PopupMenuItem,

    _init: function(client, size, index) {
        this.parent("");

        this._client = client;

        if (index <= 10) {
            this._indexLabel = new St.Label({
                text: index + ': '
            });
            this._indexLabelVisible = false;
        }

        this.connect('activate', Lang.bind (this, this._onActivate));
        this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressed));

        this._deleteItem = new DeleteItemPart.GPasteDeleteItemPart(client, index);
        this.actor.add(this._deleteItem.actor, { expand: true, x_align: St.Align.END });

        this.label.clutter_text.ellipsize = Pango.EllipsizeMode.END;
        this.setTextSize(size);

        this.setIndex(index);
    },

    showIndex: function(state) {
        if (state) {
            if (!this._indexLabelVisible) {
                this.actor.insert_child_at_index(this._indexLabel, 1);
            }
        } else if (this._indexLabelVisible) {
            this.actor.remove_child(this._indexLabel);
        }
        this._indexLabelVisible = state;
    },

    refresh: function() {
        this.setIndex(this._index);
    },

    setIndex: function(index) {
        let oldIndex = this._index || -1;
        this._index = index;

        if (index == 0) {
            this.label.set_style("font-weight: bold;");
        } else if (oldIndex == 0) {
            this.label.set_style(null);
        }

        this._deleteItem.setIndex(index);

        if (index != -1) {
            this._client.get_element(index, Lang.bind(this, function(client, result) {
                let text = client.get_element_finish(result).replace(/[\t\n\r]/g, '');
                if (text == this.label.get_text()) {
                    return;
                }
                this.label.clutter_text.set_text(text);
                if (oldIndex == -1) {
                    this.actor.show();
                }
            }));
        } else {
            this.label.clutter_text.set_text(null);
            this.actor.hide();
        }
    },

    setTextSize: function(size) {
        this.label.clutter_text.max_length = size;
    },

    _onActivate: function(actor, event) {
        this._client.select(this._index, null);
    },

    _onKeyPressed: function(actor, event) {
        let symbol = event.get_key_symbol();
        if (symbol == Clutter.KEY_BackSpace || symbol == Clutter.KEY_Delete) {
            this._client.delete(this._index, null);
            return Clutter.EVENT_STOP;
        }
        return Clutter.EVENT_PROPAGATE;
    }
});
<commit_msg>gnome-shell: cosmetic tweak<commit_after>/*
 *      This file is part of GPaste.
 *
 *      Copyright 2014-2015 Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
 *
 *      GPaste is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      GPaste is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with GPaste.  If not, see <http://www.gnu.org/licenses/>.
 */
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */

const Lang = imports.lang;

const PopupMenu = imports.ui.popupMenu;

const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const St = imports.gi.St;

const GPaste = imports.gi.GPaste;

const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();

const DeleteItemPart = Me.imports.deleteItemPart;

const GPasteItem = new Lang.Class({
    Name: 'GPasteItem',
    Extends: PopupMenu.PopupMenuItem,

    _init: function(client, size, index) {
        this.parent("");

        this._client = client;

        if (index <= 10) {
            this._indexLabel = new St.Label({
                text: index + ': '
            });
            this._indexLabelVisible = false;
        }

        this.connect('activate', Lang.bind (this, this._onActivate));
        this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressed));

        this._deleteItem = new DeleteItemPart.GPasteDeleteItemPart(client, index);
        this.actor.add(this._deleteItem.actor, { expand: true, x_align: St.Align.END });

        this.label.clutter_text.ellipsize = Pango.EllipsizeMode.END;
        this.setTextSize(size);

        this.setIndex(index);
    },

    showIndex: function(state) {
        if (state) {
            if (!this._indexLabelVisible) {
                this.actor.insert_child_at_index(this._indexLabel, 1);
            }
        } else if (this._indexLabelVisible) {
            this.actor.remove_child(this._indexLabel);
        }
        this._indexLabelVisible = state;
    },

    refresh: function() {
        this.setIndex(this._index);
    },

    setIndex: function(index) {
        let oldIndex = this._index || -1;
        this._index = index;

        if (index == 0) {
            this.label.set_style("font-weight: bold;");
        } else if (oldIndex == 0) {
            this.label.set_style(null);
        }

        this._deleteItem.setIndex(index);

        if (index != -1) {
            this._client.get_element(index, Lang.bind(this, function(client, result) {
                let text = client.get_element_finish(result).replace(/[\t\n\r]/g, ' ');
                if (text == this.label.get_text()) {
                    return;
                }
                this.label.clutter_text.set_text(text);
                if (oldIndex == -1) {
                    this.actor.show();
                }
            }));
        } else {
            this.label.clutter_text.set_text(null);
            this.actor.hide();
        }
    },

    setTextSize: function(size) {
        this.label.clutter_text.max_length = size;
    },

    _onActivate: function(actor, event) {
        this._client.select(this._index, null);
    },

    _onKeyPressed: function(actor, event) {
        let symbol = event.get_key_symbol();
        if (symbol == Clutter.KEY_BackSpace || symbol == Clutter.KEY_Delete) {
            this._client.delete(this._index, null);
            return Clutter.EVENT_STOP;
        }
        return Clutter.EVENT_PROPAGATE;
    }
});
<|endoftext|>


<commit_before>var user = require('./util/user.js');

Parse.Cloud.define("getSkin", function(request, response) {
	console.log("getSkin installationId=" + request.params.installationId);
  try {
	  Parse.Cloud.useMasterKey()
	  var query = new Parse.Query("_Installation");
	  query.equalTo("installationId", request.params.installationId);
	  query.include("skin").include("user").include("user.skin");
	  query.find({
		success: function(results) {
			var result = results[0];
			var installationSkin = result.get("skin");
			if (!installationSkin)
				installationSkin = result.get("user").get("skin");
			console.log(JSON.stringify(installationSkin));
			response.success(installationSkin);
		},
		error: function(error) {
			console.log(error);
		}
	  });
  }
  catch (e) {
	console.error(e);
  }
});

Parse.Cloud.define("iosPush", function(request, response) {
  try {
	  var params = request.params;
	  var pushQuery = new Parse.Query(Parse.Installation);
	  pushQuery.equalTo('deviceType', 'ios'); // targeting iOS devices only
	  var user = new Parse.User();
	  user.id = params.toUser;
	  pushQuery.equalTo('user', user)
	  delete params.toUser;
	  Parse.Cloud.useMasterKey()
	  var query = new Parse.Query("_Installation");
	  query.equalTo("installationId", params.installationId);
	  query.find({
		success: function(results) {
			try {
				var result = results[0];
		  if (params.badge == "Increment") {
			result.increment("badge");
			params.badge = result.get("badge");
		  }
		  else
			result.set("badge", params.badge);
		  delete params.installationId;
		  result.save();
		  Parse.Push.send({
			where: pushQuery, // Set our Installation query
			data: params
		  }, { success: function() {
			  console.log("#### PUSH OK");
		  }, error: function(error) {
			  console.log("#### PUSH ERROR" + error.message);
		  }, useMasterKey: true});
		  } catch(e){console.error(e);}
		},
		error: function(error) {
			console.log(error);
		}
	  });
	  response.success('success');
  }
  catch (e) {
  	console.error(e);
  }
});

function getObject(className, userID, completionBlock) {
	var installation = Parse.Object.extend("_Installation");
	var query = new Parse.Query(Parse.Object.extend("_Installation"));
	query.get(userID, {
  		success: function(user) {
  			completionBlock(user)
		},
  		error: function(object, error) {
  		  console.log(className + "/" + userID + ": " + JSON.stringify(error))
  		  completionBlock(null)
		}
	});
}<commit_msg>Fixed error handling in getSkin<commit_after>var user = require('./util/user.js');

Parse.Cloud.define("getSkin", function(request, response) {
	console.log("getSkin installationId=" + request.params.installationId);
  try {
	  Parse.Cloud.useMasterKey()
	  var query = new Parse.Query("_Installation");
	  query.equalTo("installationId", request.params.installationId);
	  query.include("skin").include("user").include("user.skin");
	  query.find({
		success: function(results) {
			if (results.length > 0) {
				var result = results[0];
				var installationSkin = result.get("skin");
				if (!installationSkin)
					installationSkin = result.get("user").get("skin");
				console.log(JSON.stringify(installationSkin));
				response.success(installationSkin);
			}
			else
				response.error("No skin found");
		},
		error: function(error) {
			console.log(error);
			response.error(error);
		}
	  });
  }
  catch (e) {
	console.error(e);
	response.error(e);
  }
});

Parse.Cloud.define("iosPush", function(request, response) {
  try {
	  var params = request.params;
	  var pushQuery = new Parse.Query(Parse.Installation);
	  pushQuery.equalTo('deviceType', 'ios'); // targeting iOS devices only
	  var user = new Parse.User();
	  user.id = params.toUser;
	  pushQuery.equalTo('user', user)
	  delete params.toUser;
	  Parse.Cloud.useMasterKey()
	  var query = new Parse.Query("_Installation");
	  query.equalTo("installationId", params.installationId);
	  query.find({
		success: function(results) {
			try {
				var result = results[0];
		  if (params.badge == "Increment") {
			result.increment("badge");
			params.badge = result.get("badge");
		  }
		  else
			result.set("badge", params.badge);
		  delete params.installationId;
		  result.save();
		  Parse.Push.send({
			where: pushQuery, // Set our Installation query
			data: params
		  }, { success: function() {
			  console.log("#### PUSH OK");
		  }, error: function(error) {
			  console.log("#### PUSH ERROR" + error.message);
		  }, useMasterKey: true});
		  } catch(e){console.error(e);}
		},
		error: function(error) {
			console.log(error);
		}
	  });
	  response.success('success');
  }
  catch (e) {
  	console.error(e);
  }
});

function getObject(className, userID, completionBlock) {
	var installation = Parse.Object.extend("_Installation");
	var query = new Parse.Query(Parse.Object.extend("_Installation"));
	query.get(userID, {
  		success: function(user) {
  			completionBlock(user)
		},
  		error: function(object, error) {
  		  console.log(className + "/" + userID + ": " + JSON.stringify(error))
  		  completionBlock(null)
		}
	});
}<|endoftext|>


<commit_before>import dedent from 'dedent-js';
import { fetchOverallStats } from '../services/fetchOverallStats';
import { fetchAverageStats } from '../services/fetchAverageStats';
import { fetchBestStats } from '../services/fetchBestStats';
import { MSG_PARSE_MODE } from '../constants';

export default class Command {
  constructor() {}

  sendHint(message, bot, command) {
    bot.sendMessage(message.chat.id, `Use ${command} <Username>-<Battle ID>.\nE.g. ${command} LastBastion-12345`);
  }

  sendSearching(message, bot, battletag) {
    bot.sendMessage(message.chat.id, `Hold on while I search for ${battletag}`);
  }

  getOverallStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/overallstats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(13, 18) === '_comp';
      fetchOverallStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getAverageStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/averagestats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(13, 18) === '_comp';
      fetchAverageStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getBestStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/beststats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(10, 15) === '_comp';
      // console.log()
      fetchBestStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getHelp(message, bot) {
    const reply = dedent`*Help*
    Usage: <command> <Username>-<Battle ID>
    E.g. /overallstats LastBastion-12345

    *Commands*
    Quick Play Stats
    /overallstats
    /averagestats
    /beststats

    Competitive Stats
    /overallstats_comp
    /averagestats_comp
    /beststats_comp`;
    bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
  }
}
<commit_msg>Fix bug where messages cannot use underscores<commit_after>import dedent from 'dedent-js';
import { fetchOverallStats } from '../services/fetchOverallStats';
import { fetchAverageStats } from '../services/fetchAverageStats';
import { fetchBestStats } from '../services/fetchBestStats';
import { MSG_PARSE_MODE } from '../constants';

export default class Command {
  constructor() {}

  sendHint(message, bot, command) {
    bot.sendMessage(message.chat.id, `Use ${command} <Username>-<Battle ID>.\nE.g. ${command} LastBastion-12345`);
  }

  sendSearching(message, bot, battletag) {
    bot.sendMessage(message.chat.id, `Hold on while I search for ${battletag}`);
  }

  getOverallStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/overallstats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(13, 18) === '_comp';
      fetchOverallStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getAverageStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/averagestats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(13, 18) === '_comp';
      fetchAverageStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getBestStats(message, bot) {
    let messageParts = message.text.split(' ');
    messageParts = messageParts.filter(part => /\S/.test(part));

    if (messageParts.length === 1) {
      this.sendHint(message, bot, '/beststats');
    } else {
      const battletag = messageParts[1];
      this.sendSearching(message, bot, battletag);

      const competitive = messageParts[0].substring(10, 15) === '_comp';
      fetchBestStats(battletag, competitive)
        .then(reply => {
          bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
        })
    }
  }

  getHelp(message, bot) {
    const reply = dedent`*Help*
    Usage: <command> <Username>-<Battle ID>
    E.g. /overallstats LastBastion-12345

    *Commands*
    Quick Play Stats
    \`\`\`
    /overallstats
    /averagestats
    /beststats
    \`\`\`

    Competitive Stats
    \`\`\`
    /overallstats_comp
    /averagestats_comp
    /beststats_comp
    \`\`\``;
    bot.sendMessage(message.chat.id, reply, MSG_PARSE_MODE);
  }
}
<|endoftext|>


<commit_before>var _ = require("underscore");

var MAX_ALBUMS = 2
var MAX_PHOTOS_PER_ALBUM = 2

Parse.Cloud.define("newUser", function(request, response) {
	var thisUser = request.user;
	var locations = [];
	console.log("newUser photo count=" + request.params.roll.length);
	// find all the locations in the camera roll, count the photos at each location, find length of time at location
	// { id: unique_id, location: location_string, date: time_taken }
	var count = 0;
	for (var i=0; i < request.params.roll.length; i++) {
		(function(i) {
			reverseGeocode(request.params.roll[i].location, function(geo) { request.params.roll[i].reverseLocation = geo.name; if (++count >= request.params.roll.length) geoDone(); });
		})(i);
	}
	function geoDone() {
		var albums = _.groupBy(request.params.roll, function(a) { return a.reverseLocation })
		albums = _.sortBy(albums, function(b) { return -b.length });
		if (albums.length > MAX_ALBUMS)
			albums.length = MAX_ALBUMS;
		_.each(albums, function(albumContents) {
			console.log("Album: " + albumContents[0].reverseLocation + " " + albumContents.length + " photos");
			// sort by date earliest to latest
			albumContents = _.sortBy(albumContents, function(a) { a.date });
			var Album = Parse.Object.extend("Album");
			var album = new Album();
			var worldACL = new Parse.ACL();
			worldACL.setPublicReadAccess(true);
			worldACL.setPublicWriteAccess(true);
			album.set("type", "album");
			album.set("comments", 0);
			album.set("createdBy", thisUser);
			album.set("backgroundPersistentID", albumContents[0].id);
			var albumTitle = makeAlbumTitle(albumContents);
			album.set("title", albumTitle);
			album.setACL(worldACL);
			(function(reverseLocation) {
				album.save(null, {
					success: function(album) {
					console.log("******* album saved, length = " + albumContents.length);
						if (albumContents.length > MAX_PHOTOS_PER_ALBUM)
							albumContents.length = MAX_PHOTOS_PER_ALBUM;
						_.each(albumContents, function(albumPost) {
							try {
								console.log(JSON.stringify(albumPost));
								console.log("saving photo: " + albumPost.id + " album: " + reverseLocation);
								var Post = Parse.Object.extend("Post");
								var post = new Post();
								post.set("type", "post");
								post.set("title", reverseLocation);
								post.set("views", 0);
								post.set("comments", 0);
								post.set("likes", 0);
								post.set("createdBy", thisUser);
								post.set("postedAt", albumPost.date);
								post.set("persistentID", albumPost.id);
								post.setACL(worldACL);
								post.set("location", new GeoPoint(latitude: albumPost.location.latitude, longitude: albumPost.location.longitude));
								var relation = post.relation("albums");
								relation.add(album);
								post.save();
							}
							catch (e) {
								console.error(e);
							}
						});
					},
					error: function(album, error) {
						console.error("************ newUser: error creating album: " + JSON.stringify(error));
					}
				});
			})(albumTitle);
		});
	}
	// now join the new user to the groups that are owned by the admin user
	var Album = Parse.Object.extend("Album");
	var query = new Parse.Query(Album);
	var owner = new Parse.User();
	owner.id = "EM0YoC7bp3";
	query.equalTo("type", "group").equalTo("createdBy", owner);
	query.find({
  		success: function(groups) {
  			for (var i=0; i < groups.length; i++) {
  				var group = groups[i];
				var Follow = Parse.Object.extend("Follow");
				var follow = new Follow();
				var worldACL = new Parse.ACL();
				worldACL.setPublicReadAccess(true);
				worldACL.setPublicWriteAccess(true);
				follow.setACL(worldACL);
				follow.set("type", "ag");
				follow.set("from", owner);
				follow.set("to", thisUser);
				follow.set("toAlbumGroup", group);
				console.log("Sharing group: " + group.get("title"));
				follow.save();
			}
		},
  		error: function(object, error) {
  		  console.log(error)
		}
	});
	response.success("Success");
});

var geocoder = require('./util/geocoder')({ database: __dirname + "/data/geocode.db" });

function reverseGeocode(location, callback) {
	geocoder.reverse(location.latitude, location.longitude).then(function(result) { callback(result) });
}

function makeAlbumTitle(album) {
	// album is already sorted earliest to latest
	var location = album[0].reverseLocation;
	try {
		var timeStart = new Date(album[0].date.iso);
		var timeEnd = new Date(album[album.length -1].date.iso);
		var hourDiff = timeEnd - timeStart;
		var secDiff = hourDiff / 1000; //in s
		var minDiff = hourDiff / 60 / 1000; //in minutes
		var hDiff = hourDiff / 3600 / 1000; //in hours
		var day = timeStart.getDay();
		var month = timeStart.getMonth();
		var year = timeStart.getYear();
		var startHour = timeStart.getHours();
		// holidays, thanksgiving, New Years, christmas July 4th etc, birthday
		var holidays = [
			{ name: "July 4th", start: "7/4", duration: 1 },
			{ name: "Christmas", start: "12/24", duration: 7 },
			{ name: "New Year", start: "12/31", duration: 2 },
		];
		var holiday = _.filter(holidays, function(h) {
			return day >= h.start && day < h.start + h.duration;
		});
		if (holiday.length > 0) {
			return holiday[0].name + " " + year;
		}
		// todo: variable holidays: Memorial Day, Easter, Labor Day, Thanksgiving
		if (startHour >= 6 && startHour + hDiff < 12)
			return "A morning in " + location;
		if (startHour >= 12 && startHour + hDiff < 18)
			return "An afternoon in " + location;
		if (startHour >= 18 && hDiff < 6)
			return "An evening in " + location;
		if (startHour >= 18 && hDiff < 12)
			return "A night in " + location;
		if (hDiff > 6 && hDiff < 24)
			return "A day in " + location;
		if (hDiff > 4*24 && hDiff < 10*24)
			return "A week in " + location;
		if (hDiff > 21*24 && hDiff < 42*24)
			return "A month in " + location;
	}
	catch (e) {
		console.error(e);
	}
	return location;
}

<commit_msg>Reverse geocoding<commit_after>var _ = require("underscore");

var MAX_ALBUMS = 2
var MAX_PHOTOS_PER_ALBUM = 2

Parse.Cloud.define("newUser", function(request, response) {
	var thisUser = request.user;
	var locations = [];
	console.log("newUser photo count=" + request.params.roll.length);
	// find all the locations in the camera roll, count the photos at each location, find length of time at location
	// { id: unique_id, location: location_string, date: time_taken }
	var count = 0;
	for (var i=0; i < request.params.roll.length; i++) {
		(function(i) {
			reverseGeocode(request.params.roll[i].location, function(geo) { request.params.roll[i].reverseLocation = geo.name; if (++count >= request.params.roll.length) geoDone(); });
		})(i);
	}
	function geoDone() {
		var albums = _.groupBy(request.params.roll, function(a) { return a.reverseLocation })
		albums = _.sortBy(albums, function(b) { return -b.length });
		if (albums.length > MAX_ALBUMS)
			albums.length = MAX_ALBUMS;
		_.each(albums, function(albumContents) {
			console.log("Album: " + albumContents[0].reverseLocation + " " + albumContents.length + " photos");
			// sort by date earliest to latest
			albumContents = _.sortBy(albumContents, function(a) { a.date });
			var Album = Parse.Object.extend("Album");
			var album = new Album();
			var worldACL = new Parse.ACL();
			worldACL.setPublicReadAccess(true);
			worldACL.setPublicWriteAccess(true);
			album.set("type", "album");
			album.set("comments", 0);
			album.set("createdBy", thisUser);
			album.set("backgroundPersistentID", albumContents[0].id);
			var albumTitle = makeAlbumTitle(albumContents);
			album.set("title", albumTitle);
			album.setACL(worldACL);
			(function(reverseLocation) {
				album.save(null, {
					success: function(album) {
					console.log("******* album saved, length = " + albumContents.length);
						if (albumContents.length > MAX_PHOTOS_PER_ALBUM)
							albumContents.length = MAX_PHOTOS_PER_ALBUM;
						_.each(albumContents, function(albumPost) {
							try {
								console.log(JSON.stringify(albumPost));
								console.log("saving photo: " + albumPost.id + " album: " + reverseLocation);
								var Post = Parse.Object.extend("Post");
								var post = new Post();
								post.set("type", "post");
								post.set("title", reverseLocation);
								post.set("views", 0);
								post.set("comments", 0);
								post.set("likes", 0);
								post.set("createdBy", thisUser);
								post.set("postedAt", albumPost.date);
								post.set("persistentID", albumPost.id);
								post.setACL(worldACL);
								post.set("location", new Parse.GeoPoint(latitude: albumPost.location.latitude, longitude: albumPost.location.longitude));
								var relation = post.relation("albums");
								relation.add(album);
								post.save();
							}
							catch (e) {
								console.error(e);
							}
						});
					},
					error: function(album, error) {
						console.error("************ newUser: error creating album: " + JSON.stringify(error));
					}
				});
			})(albumTitle);
		});
	}
	// now join the new user to the groups that are owned by the admin user
	var Album = Parse.Object.extend("Album");
	var query = new Parse.Query(Album);
	var owner = new Parse.User();
	owner.id = "EM0YoC7bp3";
	query.equalTo("type", "group").equalTo("createdBy", owner);
	query.find({
  		success: function(groups) {
  			for (var i=0; i < groups.length; i++) {
  				var group = groups[i];
				var Follow = Parse.Object.extend("Follow");
				var follow = new Follow();
				var worldACL = new Parse.ACL();
				worldACL.setPublicReadAccess(true);
				worldACL.setPublicWriteAccess(true);
				follow.setACL(worldACL);
				follow.set("type", "ag");
				follow.set("from", owner);
				follow.set("to", thisUser);
				follow.set("toAlbumGroup", group);
				console.log("Sharing group: " + group.get("title"));
				follow.save();
			}
		},
  		error: function(object, error) {
  		  console.log(error)
		}
	});
	response.success("Success");
});

var geocoder = require('./util/geocoder')({ database: __dirname + "/data/geocode.db" });

function reverseGeocode(location, callback) {
	geocoder.reverse(location.latitude, location.longitude).then(function(result) { callback(result) });
}

function makeAlbumTitle(album) {
	// album is already sorted earliest to latest
	var location = album[0].reverseLocation;
	try {
		var timeStart = new Date(album[0].date.iso);
		var timeEnd = new Date(album[album.length -1].date.iso);
		var hourDiff = timeEnd - timeStart;
		var secDiff = hourDiff / 1000; //in s
		var minDiff = hourDiff / 60 / 1000; //in minutes
		var hDiff = hourDiff / 3600 / 1000; //in hours
		var day = timeStart.getDay();
		var month = timeStart.getMonth();
		var year = timeStart.getYear();
		var startHour = timeStart.getHours();
		// holidays, thanksgiving, New Years, christmas July 4th etc, birthday
		var holidays = [
			{ name: "July 4th", start: "7/4", duration: 1 },
			{ name: "Christmas", start: "12/24", duration: 7 },
			{ name: "New Year", start: "12/31", duration: 2 },
		];
		var holiday = _.filter(holidays, function(h) {
			return day >= h.start && day < h.start + h.duration;
		});
		if (holiday.length > 0) {
			return holiday[0].name + " " + year;
		}
		// todo: variable holidays: Memorial Day, Easter, Labor Day, Thanksgiving
		if (startHour >= 6 && startHour + hDiff < 12)
			return "A morning in " + location;
		if (startHour >= 12 && startHour + hDiff < 18)
			return "An afternoon in " + location;
		if (startHour >= 18 && hDiff < 6)
			return "An evening in " + location;
		if (startHour >= 18 && hDiff < 12)
			return "A night in " + location;
		if (hDiff > 6 && hDiff < 24)
			return "A day in " + location;
		if (hDiff > 4*24 && hDiff < 10*24)
			return "A week in " + location;
		if (hDiff > 21*24 && hDiff < 42*24)
			return "A month in " + location;
	}
	catch (e) {
		console.error(e);
	}
	return location;
}

<|endoftext|>


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

var argv = require('optimist')
    .usage('\nUpdate AWS security groups with cloudfront IP\'s.\n\nUsage: $0 arg1..argn')
    .demand(1)
    .describe('arg1..argn', 'One or more security group ID\'s')
    .demand('r')
    .alias('r', 'region')
    .describe('r', 'The AWS Region (i.e. eu-west-1, etc)')
    .alias('k', 'accesskey')
    .describe('k', 'The AWS Access key; omit to retrieve from default AWS config')
    .alias('s', 'secret')
    .describe('s', 'The AWS Access key secret; omit to retrieve from default AWS config')
    .demand('p')
    .alias('p', 'port')
    .default('p', [80, 443])
    .describe('p', 'The ports to open for Cloudfront')
    .boolean('u')
    .alias('u', 'update')
    .default('u', false)
    .describe('u', 'set flag to actually update the security groups')
    .argv;

var Seq = require('seq');
var AWS = require('aws-sdk');

if (argv.port.constructor !== Array) {
    argv.port = [argv.port];
}

// Set your region and further aws credentials for uture requests
AWS.config.update({
    region: argv.region,
    accessKeyId: argv.accesskey,
    secretAccessKey: argv.secret
});
var EC2 = new AWS.EC2({apiVersion: '2015-10-01'});

Seq()
    .seq(function () {
        this.vars.cloudFrontIps = [];
        this.vars.securityGroupIds = argv._;
        this.vars.securityGroups = [];
        this.vars.ports = argv.port;
        this.vars.dryrun = !argv.update;

        console.log('');
        console.log('Update AWS security groups %s with cloudfront IP\'s for ports %s', this.vars.securityGroupIds.join(', '), this.vars.ports.join(', '));
        console.log(this.vars.dryrun ? 'Running in DRYRUN mode' : 'Running in UPDATE mode');
        console.log('');

        this();
    })
    // load cloudfront ips
    .seq(function () {
        var _self = this;
        var request = require("request");
        request('https://ip-ranges.amazonaws.com/ip-ranges.json', function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var awsIps = JSON.parse(response.body);
                for (var prefixIndex in awsIps.prefixes) {
                    var prefix = awsIps.prefixes[prefixIndex];
                    if (prefix.service == 'CLOUDFRONT') {
                        _self.vars.cloudFrontIps.push(prefix.ip_prefix);
                    }
                }
                console.log('loaded AWS Cloudfront IPs:' + _self.vars.cloudFrontIps.join(', '));
                _self();
            } else {
                _self("Couldn't load AWS IPS");
            }
        })
    })
    // load security groups
    .empty()
    .par(function () {
        var _self = this;
        var params = {
            DryRun: false,
            GroupIds: _self.vars.securityGroupIds
        };
        EC2.describeSecurityGroups(params, function (err, data) {
            if (err) {
                _self(err);
            }
            for (var j in data.SecurityGroups) {
                var securityGroup = data.SecurityGroups[j];
                securityGroup.hasIngressPermission = function (protocol, ip, fromPort, toPort) {
                    for (var j in this.IpPermissions) {
                        var ipPermissions = this.IpPermissions[j];
                        if (ipPermissions.IpProtocol == protocol && ipPermissions.FromPort == fromPort && ipPermissions.ToPort == toPort) {
                            for (var k in ipPermissions.IpRanges) {
                                if (ipPermissions.IpRanges[k].CidrIp == ip) {
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                };
                _self.vars.securityGroups.push(securityGroup);
                console.log('loaded description of security group ' + securityGroup.GroupId);
            }
            _self(null, _self.vars.securityGroups);
        });
    })
    .flatten()
    .seqFilter(function (securityGroup) {
        var _self = this;
        var rulesAdded = 0;
        var groupID = securityGroup.GroupId;
        console.log('\nupdating security group %s with %d ip ranges', groupID,_self.vars.cloudFrontIps.length);
        var params = {
            DryRun: this.vars.dryrun,
            GroupId: groupID,
            IpPermissions: []
        };
        // add allowances for each ports
        for (var pI in this.vars.ports) {
            var port = this.vars.ports[pI];
            console.log('adding %d rules for security group %s for port %d', _self.vars.cloudFrontIps.length,groupID, port);
            var permissions = {
                FromPort: port,
                ToPort: port,
                IpProtocol: 'TCP',
                IpRanges: []
            };
            for (var ipPrefix in _self.vars.cloudFrontIps) {
                if (securityGroup.hasIngressPermission('tcp', _self.vars.cloudFrontIps[ipPrefix], port, port)) {
                    // skip ingress permission
                } else {
                    permissions.IpRanges.push({
                        CidrIp: _self.vars.cloudFrontIps[ipPrefix]
                    });
                    console.log('adding rule to security group: ALLOW TCP for port %s to IP Range %s', port, _self.vars.cloudFrontIps[ipPrefix]);
                    rulesAdded++;
                }
            }
            if (permissions.IpRanges.length > 0) {
                params.IpPermissions.push(permissions);
            }
        }
        if (rulesAdded > 0) {
            console.log("Adding %d rules to security group %s", rulesAdded, groupID);
            EC2.authorizeSecurityGroupIngress(params, function (err, data) {
                if (err) {
                    if (err.code!='DryRunOperation') {
                        console.error(err);
                        _self();
                    } else {
                        // dryrun
                        console.log('skipped - dryrun mode; ' + err.message);
                        _self();
                    }
                } else {
                    console.log('OK');
                    _self();
                }
            });
        } else {
            console.log('nothing to do for security group %s, all ip ranges present.', groupID);
            this();
        }
    }).seq(function () {
        console.log('');
        console.log('done');
    }).catch(function (err) {
        console.error(err.stack ? err.stack : err)
    });
// end<commit_msg>cloudfront-sg-njs-8 force option<commit_after>#!/usr/bin/env node

var argv = require('optimist')
    .usage('\nUpdate AWS security groups with cloudfront IP\'s.\n\nUsage: $0 arg1..argn')
    .demand(1)
    .describe('arg1..argn', 'One or more security group ID\'s')
    .demand('r')
    .alias('r', 'region')
    .describe('r', 'The AWS Region (i.e. eu-west-1, etc)')
    .alias('k', 'accesskey')
    .describe('k', 'The AWS Access key; omit to retrieve from default AWS config')
    .alias('s', 'secret')
    .describe('s', 'The AWS Access key secret; omit to retrieve from default AWS config')
    .demand('p')
    .alias('p', 'port')
    .default('p', [80, 443])
    .describe('p', 'The ports to open for Cloudfront')
    .boolean('u')
    .alias('u', 'update')
    .default('u', false)
    .describe('u', 'set flag to actually update the security groups')
    .boolean('force')
    .default('force', false)
    .describe('force', 'skip interactive and confirmation questions')
    .argv;

var Seq = require('seq');
var AWS = require('aws-sdk');
var RL = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
});
RL.proceed = function(success,error) {
    this.question('Proceed?',function(answer) {
        console.log(answer);
        if (answer == 'Y' || answer == 'y' || answer == 'YES' || answer == 'yes') {
             success();
        } else {
            error();
        }
    });
};

if (argv.port.constructor !== Array) {
    argv.port = [argv.port];
}

// Set your region and further aws credentials for uture requests
AWS.config.update({
    region: argv.region,
    accessKeyId: argv.accesskey,
    secretAccessKey: argv.secret
});
var EC2 = new AWS.EC2({apiVersion: '2015-10-01', maxRetries: 2});

Seq()
    .seq(function () {
        var _self = this;
        this.vars.cloudFrontIps = [];
        this.vars.securityGroupIds = argv._;
        this.vars.securityGroups = [];
        this.vars.ports = argv.port;
        this.vars.dryrun = !argv.update;
        this.vars.hasError = false;
        this.vars.force = argv.force;

        console.log('');
        console.log('Update AWS security groups %s with cloudfront IP\'s for ports %s', this.vars.securityGroupIds.join(', '), this.vars.ports.join(', '));
        console.log(this.vars.dryrun ? 'Running in DRYRUN mode' : 'Running in UPDATE mode');
        console.log('');

        if (!this.vars.force) {
            RL.proceed(function() {
                _self();
            }, function() {
                _self('aborted');
            });
        } else {
            _self();
        }

    })
    // load cloudfront ips
    .seq(function () {
        var _self = this;
        var request = require("request");
        request('https://ip-ranges.amazonaws.com/ip-ranges.json', function (error, response, body) {
            if (!error && response.statusCode == 200) {
                var awsIps = JSON.parse(response.body);
                for (var prefixIndex in awsIps.prefixes) {
                    var prefix = awsIps.prefixes[prefixIndex];
                    if (prefix.service == 'CLOUDFRONT') {
                        _self.vars.cloudFrontIps.push(prefix.ip_prefix);
                    }
                }
                console.log('loaded AWS Cloudfront IPs:' + _self.vars.cloudFrontIps.join(', '));
                _self();
            } else {
                _self("Couldn't load AWS IPS");
            }
        })
    })
    // load security groups
    .empty()
    .par(function () {
        var _self = this;
        var params = {
            DryRun: false,
            GroupIds: _self.vars.securityGroupIds
        };
        EC2.describeSecurityGroups(params, function (err, data) {
            if (err) {
                _self(err);
            }
            for (var j in data.SecurityGroups) {
                var securityGroup = data.SecurityGroups[j];
                securityGroup.hasIngressPermission = function (protocol, ip, fromPort, toPort) {
                    for (var j in this.IpPermissions) {
                        var ipPermissions = this.IpPermissions[j];
                        if (ipPermissions.IpProtocol == protocol && ipPermissions.FromPort == fromPort && ipPermissions.ToPort == toPort) {
                            for (var k in ipPermissions.IpRanges) {
                                if (ipPermissions.IpRanges[k].CidrIp == ip) {
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                };
                _self.vars.securityGroups.push(securityGroup);
                console.log('loaded description of security group ' + securityGroup.GroupId);
            }
            _self(null, _self.vars.securityGroups);
        });
    })
    .flatten()
    .seqFilter(function (securityGroup) {
        var _self = this;
        var rulesAdded = 0;
        var groupID = securityGroup.GroupId;
        console.log('\nupdating security group %s with %d ip ranges', groupID,_self.vars.cloudFrontIps.length);

        var params = {
            DryRun: this.vars.dryrun,
            GroupId: groupID,
            IpPermissions: []
        };
        // add allowances for each ports
        for (var pI in this.vars.ports) {
            var port = this.vars.ports[pI];
            console.log('adding %d rules for security group %s for port %d', _self.vars.cloudFrontIps.length,groupID, port);
            var permissions = {
                FromPort: port,
                ToPort: port,
                IpProtocol: 'TCP',
                IpRanges: []
            };
            for (var ipPrefix in _self.vars.cloudFrontIps) {
                if (securityGroup.hasIngressPermission('tcp', _self.vars.cloudFrontIps[ipPrefix], port, port)) {
                    // skip ingress permission
                } else {
                    permissions.IpRanges.push({
                        CidrIp: _self.vars.cloudFrontIps[ipPrefix]
                    });
                    console.log('adding rule to security group: ALLOW TCP for port %s to IP Range %s', port, _self.vars.cloudFrontIps[ipPrefix]);
                    rulesAdded++;
                }
            }
            if (permissions.IpRanges.length > 0) {
                params.IpPermissions.push(permissions);
            }
        }
        if (rulesAdded > 0) {
            console.log("Adding %d rules to security group %s", rulesAdded, groupID);

            var apply = function() {
                EC2.authorizeSecurityGroupIngress(params, function (err, data) {
                    if (err) {
                        if (err.code != 'DryRunOperation') {
                            console.error('Error: %s', err.message);
                            _self.vars.hasError = true;
                            _self();
                        } else {
                            // dryrun
                            console.log('skipped - dryrun mode; ' + err.message);
                            _self();
                        }
                    } else {
                        console.log('OK');
                        _self();
                    }
                });
            };

            if (!this.vars.force) {
                RL.proceed(function() {
                    apply();
                }, function() {
                    _self();
                });
            } else {
                apply();
            }

        } else {
            console.log('nothing to do for security group %s, all ip ranges present.', groupID);
            this();
        }
    }).seq(function () {
        if (this.vars.hasError) {
            this('An error occurred');
        } else {
            console.log('');
            console.log('done.');
            RL.close();
        }
    }).catch(function (err) {
        console.error(err.stack ? err.stack : err);
        RL.close();
    });

// end
<|endoftext|>


<commit_before>(function (angular) {

    'use strict';

    var Node = function (fromState, toState) {
        this.from = fromState;
        this.to = [];

        if (toState) {
            this.to.push(toState);
        }
    };

    angular.module('template-prefetch', ['ui.router'])
        .provider('TemplatePrefetch', [function () {

            var routeMap = {};

            var from = function (fromState) {
                var node = routeMap[fromState] || new Node(fromState);
                return {
                    to: to(node)
                };
            };

            var to = function (node) {
                return function (toState) {
                    node.to.push(toState);
                    if (!routeMap[node.from]) {
                        routeMap[node.from] = node;
                    }
                    return {
                        to: to(node),
                        from: from
                    };
                };
            };

            this.$get = ['$rootScope', '$state', '$templateCache', '$http', function ($rootScope, $state, $templateCache, $http) {

                var prefetch = function (toState) {
                    var node = routeMap[toState];
                    if (!node) {
                        return;
                    }

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

                        var toStateName = node.to[i];
                        var toStateObj = $state.get(toStateName);
                        var url;

                        if (!toStateObj.templateUrl && toStateObj.views) {
                            for (var viewName in toStateObj.views) {
                                var view = toStateObj.views[viewName];
                                if (view.templateUrl) {
                                    url = view.templateUrl;
                                    $http.get(url).success(handleResponse(url));
                                }
                            }
                        } else {
                            url = toStateObj.templateUrl;
                            $http.get(url).success(handleResponse(url));
                        }
                    }
                };

                function fetchIncludes(data) {
                    var pattern = /ng-include=('"|"')(.+?)('"|"')/g;
                    var match;
                    while (match = pattern.exec(data)) {
                        // Second capture group of regex;
                        var url = match[2];
                        $http.get(url).success(handleResponse(url));
                    }
                }

                var handleResponse = function (url) {
                    return function (data) {
                        fetchIncludes(data);
                        $templateCache.put(url, data);
                    };
                };

                prefetch($state.current.name);

                $rootScope.$on('$stateChangeSuccess', function (event, toState) {
                    prefetch(toState.name);
                });

                return {};
            }];

            this.from = from;

            this.getRoutesFor = function (fromState) {
                return routeMap[fromState].to;
            };
        }]);
}(angular));<commit_msg>Added logging<commit_after>(function (angular) {

    'use strict';

    var Node = function (fromState, toState) {
        this.from = fromState;
        this.to = [];

        if (toState) {
            this.to.push(toState);
        }
    };

    angular.module('template-prefetch', ['ui.router'])
        .provider('TemplatePrefetch', [function () {

            var routeMap = {};

            var from = function (fromState) {
                var node = routeMap[fromState] || new Node(fromState);
                return {
                    to: to(node)
                };
            };

            var to = function (node) {
                return function (toState) {
                    node.to.push(toState);
                    if (!routeMap[node.from]) {
                        routeMap[node.from] = node;
                    }
                    return {
                        to: to(node),
                        from: from
                    };
                };
            };

            this.$get = ['$rootScope', '$state', '$templateCache', '$http', function ($rootScope, $state, $templateCache, $http, $log) {

                $log.debug('TemplatePrefetch: Instantiated');

                var prefetch = function (toState) {

                    $log.debug('TemplatePrefetch: called with toState: ' + toState);

                    var node = routeMap[toState];
                    if (!node) {
                        return;
                    }

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

                        var toStateName = node.to[i];
                        var toStateObj = $state.get(toStateName);
                        var url;

                        if (!toStateObj.templateUrl && toStateObj.views) {
                            $log.debug('TemplatePrefetch: No templateUrl for ' + toStateName + ', checking views...');
                            for (var viewName in toStateObj.views) {
                                var view = toStateObj.views[viewName];
                                if (view.templateUrl) {
                                    url = view.templateUrl;
                                    $log.debug('TemplatePrefetch: Fetching view template ' + url);
                                    $http.get(url).success(handleResponse(url));
                                }
                            }
                        } else {
                            url = toStateObj.templateUrl;
                            $log.debug('TemplatePrefetch: Fetching template ' + url);
                            $http.get(url).success(handleResponse(url));
                        }
                    }
                };

                function fetchIncludes(data) {
                    var pattern = /ng-include=('"|"')(.+?)('"|"')/g;
                    var match;
                    while (match = pattern.exec(data)) {
                        // Second capture group of regex;
                        var url = match[2];
                        $http.get(url).success(handleResponse(url));
                    }
                }

                var handleResponse = function (url) {
                    return function (data) {
                        fetchIncludes(data);
                        $templateCache.put(url, data);
                    };
                };

                prefetch($state.current.name);

                $rootScope.$on('$stateChangeSuccess', function (event, toState) {
                    prefetch(toState.name);
                });

                return {};
            }];

            this.from = from;

            this.getRoutesFor = function (fromState) {
                return routeMap[fromState].to;
            };
        }]);
}(angular));<|endoftext|>


<commit_before>import React from 'react';
import moment from 'moment';
import { createMuiTheme } from 'material-ui/styles';
import yellow from 'material-ui/colors/yellow';
import Slide from 'material-ui/transitions/Slide';
import $ from 'jquery';

// = = = = B A C K E N D = = = = =

// for local testing against staging backend
const ajaxTarget = window.location.href.indexOf('rablabla.mybluemix.net') !== -1 ? '' : 'https://rablabla-staging.mybluemix.net';

const getParams = (args) => {
  const params = {};
  const pStrings = args.split('&');
  Object.keys(pStrings).forEach((param) => {
    const kvStrings = pStrings[param].split('=');
    params[kvStrings[0]] = kvStrings[1];
  });
  return params;
};

const getICSLink = (url, success, error) => {
  const deSuffix = '.de/rapla?';
  const baseURL = url.substring(0, url.indexOf(deSuffix) + deSuffix.length);
  const params = getParams(url.substring(url.indexOf(deSuffix) + deSuffix.length));
  if (params.key) {
    $.ajax({
      url: `${ajaxTarget}/Rablabla?url=${url}`,
      type: 'POST',
      success,
      error,
    });
    return 'Accessing calendar file...';
  } else if (params.user && params.file) {
    console.log(baseURL);
    success(`${baseURL}page=ical&user=${params.user}&file=${params.file}`);
  } else {
    console.error(`Yearly calendar not supported for url: ${url}`);
  }
  return 'Request denied.';
};

const getAppointments = (url, mmt, success, error, pre) => {
  pre(mmt);
  // backend uses monday as first day of the week
  // we use en locale so we make an exception for sundays
  $.ajax({
    url: `${ajaxTarget}/Rablabla?url=${encodeURIComponent(url)}&day=${mmt.day() > 0 ? mmt.date() : mmt.day(1).date()}&month=${mmt.month() + 1}&year=${mmt.year()}`,
    type: 'GET',
    success,
    error,
  });
  return 'Accessing appointments...';
};

const parseDates = (events) => {
  events.forEach((el) => {
    const dateElements = el.date.split('.');
    el.Date = moment().date(dateElements[0]).month(dateElements[1] - 1).year(dateElements[2]);
  });
  return events;
};

// check if there's a collision between the events a and b
const intersects = (a, b) => {
  const startTimeWrapperA = a.startTime.split(':');
  const endTimeWrapperA = a.endTime.split(':');
  const startMinA = parseInt(startTimeWrapperA[0]) * 60 + parseInt(startTimeWrapperA[1]);
  const endMinA = parseInt(endTimeWrapperA[0]) * 60 + parseInt(endTimeWrapperA[1]);

  const startTimeWrapperB = b.startTime.split(':');
  const endTimeWrapperB = b.endTime.split(':');
  const startMinB = parseInt(startTimeWrapperB[0]) * 60 + parseInt(startTimeWrapperB[1]);
  const endMinB = parseInt(endTimeWrapperB[0]) * 60 + parseInt(endTimeWrapperB[1]);

  return (startMinA <= startMinB && endMinA >= endMinB) // a contains(equals) b
    || (startMinA >= startMinB && endMinA <= endMinB) // b contains(equals) a
    || (startMinA < startMinB && endMinA < endMinB && endMinA > startMinB) // a intersects b
    || (startMinA > startMinB && endMinA > endMinB && startMinA < endMinB) // b intersects a
  ;
};

/* divides a list of events into the maximum-non-colliding list of events and the rest
const splitGreedy = (eventStack) => {
  const filterFalse = [];
  let done = false;
  do {
    // count the intersections of each event
    eventStack.forEach((ev) => {
      ev.intersectionCount = 0;
      eventStack.filter(otherEvent => ev !== otherEvent).forEach((otherEvent) => {
        if (intersects(ev, otherEvent)) {
          ev.intersectionCount++;
        }
      });
    });

    // sort for intersection count
    eventStack.sort((a, b) => a.intersectionCount - b.intersectionCount);

    // if collisions remaining -> repeat without the max intersects element
    if (eventStack.filter(ev => ev.intersectionCount > 0).length > 0) {
      filterFalse.push(eventStack.pop());
    } else {
      done = true;
    }
  } while (!done);

  return { filterTrue: eventStack, filterFalse };
}; */

const splitterSearch = (possibleSolutions, todo, current) => {
  // get every event without collision to current
  todo.filter((testEv) => {
    return current.filter(safeEv => intersects(safeEv, testEv)).length === 0;
  }).forEach((semiSafeEv) => {
    const newSolution = current.concat([semiSafeEv]);
    possibleSolutions.push(newSolution);
    const remaining = todo.filter(el => el !== semiSafeEv);
    splitterSearch(possibleSolutions, remaining, newSolution);
  });
};

// same as splitGreedy() but more intelligent
const splitter = (eventStack) => {
  const safe = [], todo = [];
  // count the intersections of each event
  eventStack.forEach((ev) => {
    ev.intersectionCount = 0;
    eventStack.filter(otherEvent => ev !== otherEvent).forEach((otherEvent) => {
      if (intersects(ev, otherEvent)) {
        ev.intersectionCount++;
      }
    });
  });

  // divide into safe and colliding
  eventStack.forEach((ev) => {
    (ev.intersectionCount > 0 ? todo : safe).push(ev);
  });

  const possibleSolutions = [];
  let filterTrue = safe;
  // if there are colliding elements
  if (todo.length > 0) {
    splitterSearch(possibleSolutions, todo, []);
    // search for biggest solution
    possibleSolutions.sort((arr1, arr2) => arr2.length - arr1.length);
    filterTrue = safe.concat(possibleSolutions[0]);
  }
  // merge with safe ones
  return {
    filterTrue,
    filterFalse: eventStack.filter(ev => filterTrue.indexOf(ev) === -1),
  };
};

const makeDays = (events) => {
  /* console.log(splitter([
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '14:00',
      course: 'Webducksign',
      persons: 'Daisy Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '14:00',
      course: 'Ducktales Introduction',
      persons: 'Donald Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '16:00',
      endTime: '18:00',
      course: 'Mousorithms',
      persons: 'Micky Mouse',
      resources: 'STG-INF42X',
    },
  ])); */
  const dailyEvents = [[
    // block 0
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '06:00',
      endTime: '06:30',
      course: 'Financing',
      persons: 'Dagobert Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '06:30',
      endTime: '07:30',
      course: 'Webducksign',
      persons: 'Daisy Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '06:30',
      endTime: '07:30',
      course: 'Ducktales Introduction',
      persons: 'Donald Duck',
      resources: 'STG-INF42X',
    },
    // block 1
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '08:30',
      course: 'Mousorithms',
      persons: 'Micky Mouse',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:30',
      endTime: '09:00',
      course: 'Dark Things',
      persons: 'Severus Snape',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '09:00',
      course: 'Appearance Changing',
      persons: 'Donald Mouse',
      resources: 'STG-INF42X',
    },
    // block 2
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '09:15',
      endTime: '10:15',
      course: 'Entry Maps',
      persons: 'Dumbledoor',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '09:15',
      endTime: '09:45',
      course: 'Health Care',
      persons: 'Harry Potter',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '09:45',
      endTime: '10:15',
      course: 'Muggle Tech',
      persons: 'Ron Weasly',
      resources: 'STG-INF42X',
    },
    // block 3
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '10:30',
      endTime: '11:00',
      course: 'Business 1',
      persons: 'Max Mustermann',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '10:45',
      endTime: '11:15',
      course: 'Business 2',
      persons: 'Maxime Musterfrau',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:00',
      endTime: '11:30',
      course: 'Storages',
      persons: 'Neville Longbottom',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:15',
      endTime: '11:45',
      course: 'Hat Language',
      persons: 'McGonagle',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:40',
      endTime: '12:00',
      course: 'Cognitive Bio Tech',
      persons: 'Sproud',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:45',
      endTime: '12:15',
      course: 'Augmented Reality',
      persons: 'McAlister',
      resources: 'STG-INF42X',
    },
  ], [], [], [], [], [], []];
  events.forEach((el) => {
    dailyEvents[el.Date.day()].push(el);
  });

  dailyEvents.forEach((day) => {
    const todoStack = [day];
    const doneStack = [];

    // execute algorithm until no collisions remaining
    while (todoStack.length > 0) {
      const divison = splitter(todoStack.pop());
      if (divison.filterFalse.length > 0) todoStack.push(divison.filterFalse);
      doneStack.push(divison.filterTrue);
    }

    // assign the col values
    doneStack.forEach((colLevel, i) => {
      colLevel.forEach((el) => {
        el.col = i;
      });
    });
  });

  console.log(dailyEvents);

  return dailyEvents;
};

// = = = = T H E M E = = = = =

const dhbwtimetablepalette = {
  50: '#f7e7e7',
  100: '#eac3c3',
  200: '#dd9c9c',
  300: '#cf7474',
  400: '#c45656',
  500: '#ba3838',
  600: '#b33232',
  700: '#ab2b2b',
  800: '#a32424',
  900: '#941717',
  A100: '#ffc9c9',
  A200: '#ff9696',
  A400: '#ff6363',
  A700: '#ff4a4a',
  contrastDefaultColor: 'light',
};

const slidingTransition = props => <Slide direction="up" {...props} />;

const theme = createMuiTheme({
  palette: {
    primary: dhbwtimetablepalette,
    secondary: {
      ...dhbwtimetablepalette,
      A400: 'white', // Accent color
    },
    error: yellow,
  },
});

module.exports = {
  getParams,
  slidingTransition,
  theme,
  parseDates,
  makeDays,
  getAppointments,
  getICSLink,
  ajaxTarget,
};
<commit_msg>Shifted sample data<commit_after>import React from 'react';
import moment from 'moment';
import { createMuiTheme } from 'material-ui/styles';
import yellow from 'material-ui/colors/yellow';
import Slide from 'material-ui/transitions/Slide';
import $ from 'jquery';

// = = = = B A C K E N D = = = = =

// for local testing against staging backend
const ajaxTarget = window.location.href.indexOf('rablabla.mybluemix.net') !== -1 ? '' : 'https://rablabla-staging.mybluemix.net';

const getParams = (args) => {
  const params = {};
  const pStrings = args.split('&');
  Object.keys(pStrings).forEach((param) => {
    const kvStrings = pStrings[param].split('=');
    params[kvStrings[0]] = kvStrings[1];
  });
  return params;
};

const getICSLink = (url, success, error) => {
  const deSuffix = '.de/rapla?';
  const baseURL = url.substring(0, url.indexOf(deSuffix) + deSuffix.length);
  const params = getParams(url.substring(url.indexOf(deSuffix) + deSuffix.length));
  if (params.key) {
    $.ajax({
      url: `${ajaxTarget}/Rablabla?url=${url}`,
      type: 'POST',
      success,
      error,
    });
    return 'Accessing calendar file...';
  } else if (params.user && params.file) {
    console.log(baseURL);
    success(`${baseURL}page=ical&user=${params.user}&file=${params.file}`);
  } else {
    console.error(`Yearly calendar not supported for url: ${url}`);
  }
  return 'Request denied.';
};

const getAppointments = (url, mmt, success, error, pre) => {
  pre(mmt);
  // backend uses monday as first day of the week
  // we use en locale so we make an exception for sundays
  $.ajax({
    url: `${ajaxTarget}/Rablabla?url=${encodeURIComponent(url)}&day=${mmt.day() > 0 ? mmt.date() : mmt.day(1).date()}&month=${mmt.month() + 1}&year=${mmt.year()}`,
    type: 'GET',
    success,
    error,
  });
  return 'Accessing appointments...';
};

const parseDates = (events) => {
  events.forEach((el) => {
    const dateElements = el.date.split('.');
    el.Date = moment().date(dateElements[0]).month(dateElements[1] - 1).year(dateElements[2]);
  });
  return events;
};

// check if there's a collision between the events a and b
const intersects = (a, b) => {
  const startTimeWrapperA = a.startTime.split(':');
  const endTimeWrapperA = a.endTime.split(':');
  const startMinA = parseInt(startTimeWrapperA[0]) * 60 + parseInt(startTimeWrapperA[1]);
  const endMinA = parseInt(endTimeWrapperA[0]) * 60 + parseInt(endTimeWrapperA[1]);

  const startTimeWrapperB = b.startTime.split(':');
  const endTimeWrapperB = b.endTime.split(':');
  const startMinB = parseInt(startTimeWrapperB[0]) * 60 + parseInt(startTimeWrapperB[1]);
  const endMinB = parseInt(endTimeWrapperB[0]) * 60 + parseInt(endTimeWrapperB[1]);

  return (startMinA <= startMinB && endMinA >= endMinB) // a contains(equals) b
    || (startMinA >= startMinB && endMinA <= endMinB) // b contains(equals) a
    || (startMinA < startMinB && endMinA < endMinB && endMinA > startMinB) // a intersects b
    || (startMinA > startMinB && endMinA > endMinB && startMinA < endMinB) // b intersects a
  ;
};

/* divides a list of events into the maximum-non-colliding list of events and the rest
const splitGreedy = (eventStack) => {
  const filterFalse = [];
  let done = false;
  do {
    // count the intersections of each event
    eventStack.forEach((ev) => {
      ev.intersectionCount = 0;
      eventStack.filter(otherEvent => ev !== otherEvent).forEach((otherEvent) => {
        if (intersects(ev, otherEvent)) {
          ev.intersectionCount++;
        }
      });
    });

    // sort for intersection count
    eventStack.sort((a, b) => a.intersectionCount - b.intersectionCount);

    // if collisions remaining -> repeat without the max intersects element
    if (eventStack.filter(ev => ev.intersectionCount > 0).length > 0) {
      filterFalse.push(eventStack.pop());
    } else {
      done = true;
    }
  } while (!done);

  return { filterTrue: eventStack, filterFalse };
}; */

const splitterSearch = (possibleSolutions, todo, current) => {
  // get every event without collision to current
  todo.filter((testEv) => {
    return current.filter(safeEv => intersects(safeEv, testEv)).length === 0;
  }).forEach((semiSafeEv) => {
    const newSolution = current.concat([semiSafeEv]);
    possibleSolutions.push(newSolution);
    const remaining = todo.filter(el => el !== semiSafeEv);
    splitterSearch(possibleSolutions, remaining, newSolution);
  });
};

// same as splitGreedy() but more intelligent
const splitter = (eventStack) => {
  const safe = [], todo = [];
  // count the intersections of each event
  eventStack.forEach((ev) => {
    ev.intersectionCount = 0;
    eventStack.filter(otherEvent => ev !== otherEvent).forEach((otherEvent) => {
      if (intersects(ev, otherEvent)) {
        ev.intersectionCount++;
      }
    });
  });

  // divide into safe and colliding
  eventStack.forEach((ev) => {
    (ev.intersectionCount > 0 ? todo : safe).push(ev);
  });

  const possibleSolutions = [];
  let filterTrue = safe;
  // if there are colliding elements
  if (todo.length > 0) {
    splitterSearch(possibleSolutions, todo, []);
    // search for biggest solution
    possibleSolutions.sort((arr1, arr2) => arr2.length - arr1.length);
    filterTrue = safe.concat(possibleSolutions[0]);
  }
  // merge with safe ones
  return {
    filterTrue,
    filterFalse: eventStack.filter(ev => filterTrue.indexOf(ev) === -1),
  };
};

const makeDays = (events) => {
  /* console.log(splitter([
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '14:00',
      course: 'Webducksign',
      persons: 'Daisy Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '14:00',
      course: 'Ducktales Introduction',
      persons: 'Donald Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '16:00',
      endTime: '18:00',
      course: 'Mousorithms',
      persons: 'Micky Mouse',
      resources: 'STG-INF42X',
    },
  ])); */
  const dailyEvents = [[
    /* block 0
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:00',
      endTime: '08:30',
      course: 'Financing',
      persons: 'Dagobert Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:30',
      endTime: '09:30',
      course: 'Webducksign',
      persons: 'Daisy Duck',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '08:30',
      endTime: '09:30',
      course: 'Ducktales Introduction',
      persons: 'Donald Duck',
      resources: 'STG-INF42X',
    },*/
    /* block 1
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '10:00',
      endTime: '10:30',
      course: 'Mousorithms',
      persons: 'Micky Mouse',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '10:30',
      endTime: '11:00',
      course: 'Dark Things',
      persons: 'Severus Snape',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '10:00',
      endTime: '11:00',
      course: 'Appearance Changing',
      persons: 'Donald Mouse',
      resources: 'STG-INF42X',
    },
    // block 2
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:15',
      endTime: '12:15',
      course: 'Entry Maps',
      persons: 'Dumbledoor',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:15',
      endTime: '11:45',
      course: 'Health Care',
      persons: 'Harry Potter',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '11:45',
      endTime: '12:15',
      course: 'Muggle Tech',
      persons: 'Ron Weasly',
      resources: 'STG-INF42X',
    },
    */// block 3
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '12:30',
      endTime: '13:00',
      course: 'Business 1',
      persons: 'Max Mustermann',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '12:45',
      endTime: '13:15',
      course: 'Business 2',
      persons: 'Maxime Musterfrau',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '13:00',
      endTime: '13:30',
      course: 'Storages',
      persons: 'Neville Longbottom',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '13:15',
      endTime: '13:45',
      course: 'Hat Language',
      persons: 'McGonagle',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '13:40',
      endTime: '14:00',
      course: 'Cognitive Bio Tech',
      persons: 'Sproud',
      resources: 'STG-INF42X',
    },
    {
      date: '11.03.2018',
      Date: moment().date(11).month(3).year(2018),
      startTime: '13:45',
      endTime: '14:15',
      course: 'Augmented Reality',
      persons: 'McAlister',
      resources: 'STG-INF42X',
    },
  ], [], [], [], [], [], []];

  console.log(splitter(dailyEvents[0]));
  console.log(splitter(splitter(dailyEvents[0]).filterFalse));

  events.forEach((el) => {
    dailyEvents[el.Date.day()].push(el);
  });

  dailyEvents.forEach((day) => {
    const todoStack = [day];
    const doneStack = [];

    // execute algorithm until no collisions remaining
    while (todoStack.length > 0) {
      const divison = splitter(todoStack.pop());
      if (divison.filterFalse.length > 0) todoStack.push(divison.filterFalse);
      doneStack.push(divison.filterTrue);
    }

    // assign the col values
    doneStack.forEach((colLevel, i) => {
      colLevel.forEach((el) => {
        el.col = i;
      });
    });
  });

  // DEBUG
  console.log(dailyEvents.map(day => day.map((ev) => {
    return {
      _col: ev.col,
      name: ev.course,
      beginTime: ev.startTime,
      endTime: ev.endTime,
    };
  })));

  return dailyEvents;
};

// = = = = T H E M E = = = = =

const dhbwtimetablepalette = {
  50: '#f7e7e7',
  100: '#eac3c3',
  200: '#dd9c9c',
  300: '#cf7474',
  400: '#c45656',
  500: '#ba3838',
  600: '#b33232',
  700: '#ab2b2b',
  800: '#a32424',
  900: '#941717',
  A100: '#ffc9c9',
  A200: '#ff9696',
  A400: '#ff6363',
  A700: '#ff4a4a',
  contrastDefaultColor: 'light',
};

const slidingTransition = props => <Slide direction="up" {...props} />;

const theme = createMuiTheme({
  palette: {
    primary: dhbwtimetablepalette,
    secondary: {
      ...dhbwtimetablepalette,
      A400: 'white', // Accent color
    },
    error: yellow,
  },
});

module.exports = {
  getParams,
  slidingTransition,
  theme,
  parseDates,
  makeDays,
  getAppointments,
  getICSLink,
  ajaxTarget,
};
<|endoftext|>


<commit_before>/**
 * This service makes sure that the rest interactions are executed in a
 * session, enforces user authentication, etc.
 */
kerubApp.factory('$appsession', ['$log', '$http', '$modal', function($log, $http, $modal) {
    $log.info('creating instance of $appsession');

    /**
     * The wrapper class to wrap requests.
     * When authentication is finished
     */
    var SessionReqWrapper = function(method, req, session, url, options) {
        this.onSuccess = [];
        this._session = session;
        this.onError = [];
        this.getMethod = function() {
			return method;
        };
        this.getUrl = function() {
        	return url;
        };
        this.getOptions = function() {
        	return options;
        };
        this.success = function(callback) {
            $log.debug('onsuccess:', callback);
            this.onSuccess.push(callback);
            return this;
        };
        this.error = function(callback) {
            $log.debug('onerror:', callback)
            this.onError.push(callback);
            return this;
        };
        req.success(function(response) {
            $log.info('success', req, response, this.onSuccess);
            for(idx in this.onSuccess) {
                $log.debug('calling onsuccess method');
                this.onSuccess[idx](response)
            }
        }.bind(this));
        req.error(function(error, responseCode) {
            $log.info('error', req, error, responseCode);
            if(responseCode === 401 && error.code === "AUTH1") {
                this._session._openLogin();
                this._session._blockedRequests.push(this);
            }
        }.bind(this));
    };

    /**
     * Session is a wrapper around the $http service,
     * it adds an extra listener to the Unauthorized (401) responses
     */
    var session = {
        loginWindow : null,
        _blockedRequests : [],

        _sendNewRequest : function(bReq) {
        	var method = bReq.getMethod();
        	$log.debug('Sending ' + method)
            switch(method) {
                case "GET":
                    return $http.get(bReq.getUrl());
                case "POST":
                    return $http.post(bReq.getUrl(), bReq.getData());
                case "PUT":
                    return $http.put(bReq.getUrl(), bReq.getData());
                case "DELETE":
                    return $http.delete(bReq.getUrl());
            }
            throw "Unhandled method: " + bReq.method;
        },
        restartRequests : function() {
            $log.info("restarting requests - close window");
            $log.info("restarting requests", session);
            for(var i = 0; i < session._blockedRequests.length; i++) {
                var bReq = session._blockedRequests[i];
                $log.info('restart request',bReq);
                var resp = session._sendNewRequest(bReq);
                resp.success(function(result) {
                    $log.info('result', bReq,result);
                });
                resp.error(function() {
                    //hold!
                });
            }

            session._blockedRequests = [];
        },
        /**
         * session get
         */
        get : function(url, options) {
            var res = $http.get(url, options);
            var wrap = new SessionReqWrapper('GET', res, this, url, options);
            return wrap;
        },
        /**
         * session put
         */
        put : function(url, data) {
            var res = $http.put(url, data);
            var wrap = new SessionReqWrapper('PUT', res, this);
            return wrap;
        },
        _openLogin : function() {
        	if(session.loginWindow != null) {
        		$log.debug("login window already open");
        		return;
        	}
            $log.info("opening login window");
            session.loginWindow = $modal.open({
                templateUrl : 'Login.html',
                controller : Login,
                keyboard : false,
                backdrop : false
                });
        }
    };
    return session;
}]);
<commit_msg>trigger onsuccess methods after a succesfull authentication<commit_after>/**
 * This service makes sure that the rest interactions are executed in a
 * session, enforces user authentication, etc.
 */
kerubApp.factory('$appsession', ['$log', '$http', '$modal', function($log, $http, $modal) {
    $log.info('creating instance of $appsession');

    /**
     * The wrapper class to wrap requests.
     * When authentication is finished
     */
    var SessionReqWrapper = function(method, req, session, url, options) {
        this.onSuccess = [];
        this._session = session;
        this.onError = [];
        this.getMethod = function() {
			return method;
        };
        this.getUrl = function() {
        	return url;
        };
        this.getOptions = function() {
        	return options;
        };
        this.success = function(callback) {
            $log.debug('onsuccess:', callback);
            this.onSuccess.push(callback);
            return this;
        };
        this.error = function(callback) {
            $log.debug('onerror:', callback)
            this.onError.push(callback);
            return this;
        };
        this.runSuccessCallbacks = function(response) {
            for(var idx = 0; idx < this.onSuccess.length; idx++) {
                $log.debug('calling onsuccess method');
                this.onSuccess[idx](response)
            }
        }
        req.success(function(response) {
            $log.info('success', req, response, this.onSuccess);
            this.runSuccessCallbacks(response);
        }.bind(this));
        req.error(function(error, responseCode) {
            $log.info('error', req, error, responseCode);
            if(responseCode === 401 && error.code === "AUTH1") {
                this._session._openLogin();
                this._session._blockedRequests.push(this);
            }
        }.bind(this));
    };

    /**
     * Session is a wrapper around the $http service,
     * it adds an extra listener to the Unauthorized (401) responses
     */
    var session = {
        loginWindow : null,
        _blockedRequests : [],

        _sendNewRequest : function(bReq) {
        	var method = bReq.getMethod();
        	$log.debug('Sending ' + method)
            switch(method) {
                case "GET":
                    return $http.get(bReq.getUrl());
                case "POST":
                    return $http.post(bReq.getUrl(), bReq.getData());
                case "PUT":
                    return $http.put(bReq.getUrl(), bReq.getData());
                case "DELETE":
                    return $http.delete(bReq.getUrl());
            }
            throw "Unhandled method: " + bReq.method;
        },
        restartRequests : function() {
            $log.info("restarting requests - close window");
            $log.info("restarting requests", session);
            for(var i = 0; i < session._blockedRequests.length; i++) {
                var bReq = session._blockedRequests[i];
                $log.info('restart request',bReq);
                var resp = session._sendNewRequest(bReq);
                resp.success(function(result) {
                    $log.info('result', bReq, result);
                    bReq.runSuccessCallbacks(result);
                });
                resp.error(function() {
                    //hold!
                });
            }

            session._blockedRequests = [];
        },
        /**
         * session get
         */
        get : function(url, options) {
            var res = $http.get(url, options);
            var wrap = new SessionReqWrapper('GET', res, this, url, options);
            return wrap;
        },
        /**
         * session put
         */
        put : function(url, data) {
            var res = $http.put(url, data);
            var wrap = new SessionReqWrapper('PUT', res, this);
            return wrap;
        },
        _openLogin : function() {
        	if(session.loginWindow != null) {
        		$log.debug("login window already open");
        		return;
        	}
            $log.info("opening login window");
            session.loginWindow = $modal.open({
                templateUrl : 'Login.html',
                controller : Login,
                keyboard : false,
                backdrop : false
                });
        }
    };
    return session;
}]);
<|endoftext|>