<commit_before>/**
 This Source Code is licensed under the MIT license. If a copy of the
 MIT-license was not distributed with this file, You can obtain one at:
 http://opensource.org/licenses/mit-license.html.

 @author: Hans van den Akker (mysim1)
 @license MIT
 @copyright Bizboard, 2015

 */

import {Provide}                    from 'di.js';
import {ObjectHelper}               from 'arva-utils/ObjectHelper';
import {DataSource}                 from '../core/DataSource';
import {SharePointSnapshot}         from './SharePoint/SharePointSnapshot';
import {SharePoint}                 from 'SPSoapAdapter/SharePoint';

@Provide(DataSource)
export class SharePointSoapDataSource extends DataSource {

    /** @param {String} path **/
    constructor(path, selector = null) {
        super(path);

        this._dataReference = null;
        this._onValueCallback = null;
        this._onAddCallback = null;
        this._onChangeCallback = null;
        this._onMoveCallback = null;
        this._onRemoveCallback = null;
        this._orginialPath = path;
        this._selector = selector;

        /* Bind all local methods to the current object instance, so we can refer to "this"
         * in the methods as expected, even when they're called from event handlers.        */
        ObjectHelper.bindAllMethods(this, this);

        /* Hide all private properties (starting with '_') and methods from enumeration,
         * so when you do for( in ), only actual data properties show up. */
        ObjectHelper.hideMethodsAndPrivatePropertiesFromObject(this);

        /* Hide the priority field from enumeration, so we don't save it to the dataSource. */
        ObjectHelper.hidePropertyFromObject(Object.getPrototypeOf(this), 'length');

        // don't initialize this datasource when there is no path selected to
        // retrieve data from.
        if (this.key().length>0) {

            // bind the soap adapter against the datasource with configuration
            this._dataReference = new SharePoint({
                endPoint: this._orginialPath,
                listName: this.key()
            });
        }
    }

    _notifyOnValue(snapshot) {
        if(this._onValueCallback) {
            this._onValueCallback(snapshot);
        }
    }

    _ParseSelector(path, endPoint) {

    }

    _ParsePath(path, endPoint) {

        var url = UrlParser(path);
        if (!url) console.log("Invalid datasource path provided!");

        var pathParts = url.path.split('/');
        var newPath = url.protocol + "://" + url.host + "/";
        for(var i=0;i<pathParts.length;i++)
            newPath += pathParts[i] + "/";
        newPath += endPoint;
        return newPath;
    };

    /**
     * Indicate that the DataSource can be inherited when instantiating a list of models.
     * @returns {boolean}
     */
    get inheritable() { return true; }

    /**
     * Returns a datasource reference to the given child branch of the current datasouce.
     * @param {String} childName
     */
    child(childName) {
        // the selector will be interpreted at each level and is used to address the correct endpoints relative from the original path
        let newSelector = this._selector?this._selector+ '/' + childName: childName;
        return new SharePointSoapDataSource(this._orginialPath, newSelector);
    }

    root() {
        return this._orginialPath;
    }

    /**
     * Returns the full URL to the path on the datasource.
     */
    path() {
        return this._orginialPath;
    }

    toString() {
        return this._orginialPath;
    }

    /**
     * Returns the name of the current branch in the path on the datasource.
     */
    key() {

        // process the selector
        if (this._selector) {
            let parts = this._selector.split('/');
            if (parts.length>0) {
                return parts[parts.length-1];
            }
        }
        return '';

    }

    /**
     * Writes newData to the path this dataSource was constructed with.
     * @param {Object} newData
     */
    set(newData) {
        this._dataReference.set(newData);
    }

    /**
     * Removes the object and all underlying children that this dataSource points to.
     */
    remove(object) {
        this._dataReference.remove(newData);
    }

    /**
     * Writes newData to the path this dataSource was constructed with, appended by a random UID generated by
     * the dataSource.
     * @param {Object} newData
     */
    push(newData) {
        return this.set(newData);
    }

    /**
     * Writes newData with given priority (ordering) to the path this dataSource was constructed with.
     * @param {Object} newData
     * @param {String|Number} priority
     */
    setWithPriority(newData, priority) {
        newData.priority = priority;
        this.set(newData);
    }

    /**
     * Sets the priority (ordering) of an object on a given dataSource.
     * @param {String|Number} newPriority
     */
    setPriority(newPriority) { }

    /** Sets the callback triggered when dataSource updates the data.
     *  @param {Function} callback **/
    setValueChangedCallback(callback){
        this._onValueCallback = callback;
        this._dataReference.on('value', this._onValueCallback);
    }

    /** Removes the callback set to trigger when dataSource updates the data. **/
    removeValueChangedCallback() {
        if(this._onValueCallback) {
            this._dataReference.off('value', this._onValueCallback);
            this._onValueCallback = null;
        }
    }

    /** Set the callback triggered when dataSource adds a data element.
     * @param {Function} callback **/
    setChildAddedCallback(callback) {
        this._onAddCallback = callback;
        this._dataReference.on('child_added', this._onAddCallback);
    }

    /** Removes the callback set to trigger when dataSource adds a data element. **/
    removeChildAddedCallback() {
        if(this._onAddCallback) {
            this._dataReference.off('child_added', this._onAddCallback);
            this._onAddCallback = null;
        }
    }

    /** Set the callback triggered when dataSource changes a data element.
     * @param {Function} callback **/
    setChildChangedCallback(callback) {
        this._onChangeCallback = callback;
        this._dataReference.on('child_changed', this._onChangeCallback);
    }

    /** Removes the callback set to trigger when dataSource changes a data element. **/
    removeChildChangedCallback() {
        if(this._onChangeCallback) {
            this._dataReference.off('child_changed', this._onChangeCallback);
            this._onChangeCallback = null;
        }
    }

    /** Set the callback triggered when dataSource moves a data element.
     * @param {Function} callback **/
    setChildMovedCallback(callback) {
    }

    /** Removes the callback set to trigger when dataSource moves a data element. **/
    removeChildMovedCallback() {
    }

    /** Set the callback triggered when dataSource adds a data element.
     * @param {Function} callback **/
    setChildRemovedCallback(callback) {
        this._onRemoveCallback = callback;
        this._dataReference.on('child_removed', this._onRemoveCallback);
    }

    /** Removes the callback set to trigger when dataSource adds a data element. **/
    removeChildRemovedCallback() {
        if(this._onRemoveCallback) {
            this._dataReference.off('child_removed', this._onRemoveCallback);
            this._onRemoveCallback = null;
        }
    }
}<commit_msg>no message<commit_after>/**
 This Source Code is licensed under the MIT license. If a copy of the
 MIT-license was not distributed with this file, You can obtain one at:
 http://opensource.org/licenses/mit-license.html.

 @author: Hans van den Akker (mysim1)
 @license MIT
 @copyright Bizboard, 2015

 */

import {Provide}                    from 'di.js';
import {ObjectHelper}               from 'arva-utils/ObjectHelper';
import {DataSource}                 from '../core/DataSource';
import {SharePointSnapshot}         from './SharePoint/SharePointSnapshot';
import {SharePoint}                 from 'SPSoapAdapter/SharePoint';

@Provide(DataSource)
export class SharePointDataSource extends DataSource {

    /** @param {String} path **/
    constructor(path, selector = null) {
        super(path);

        this._dataReference = null;
        this._onValueCallback = null;
        this._onAddCallback = null;
        this._onChangeCallback = null;
        this._onMoveCallback = null;
        this._onRemoveCallback = null;
        this._orginialPath = path;
        this._selector = selector;

        /* Bind all local methods to the current object instance, so we can refer to "this"
         * in the methods as expected, even when they're called from event handlers.        */
        ObjectHelper.bindAllMethods(this, this);

        /* Hide all private properties (starting with '_') and methods from enumeration,
         * so when you do for( in ), only actual data properties show up. */
        ObjectHelper.hideMethodsAndPrivatePropertiesFromObject(this);

        /* Hide the priority field from enumeration, so we don't save it to the dataSource. */
        ObjectHelper.hidePropertyFromObject(Object.getPrototypeOf(this), 'length');

        // don't initialize this datasource when there is no path selected to
        // retrieve data from.
        if (this.key().length>0) {

            // bind the soap adapter against the datasource with configuration
            this._dataReference = new SharePoint({
                endPoint: this._orginialPath,
                listName: this.key()
            });
        }
    }

    _notifyOnValue(snapshot) {
        if(this._onValueCallback) {
            this._onValueCallback(snapshot);
        }
    }

    _ParseSelector(path, endPoint) {

    }

    _ParsePath(path, endPoint) {

        var url = UrlParser(path);
        if (!url) console.log("Invalid datasource path provided!");

        var pathParts = url.path.split('/');
        var newPath = url.protocol + "://" + url.host + "/";
        for(var i=0;i<pathParts.length;i++)
            newPath += pathParts[i] + "/";
        newPath += endPoint;
        return newPath;
    };

    /**
     * Indicate that the DataSource can be inherited when instantiating a list of models.
     * @returns {boolean}
     */
    get inheritable() { return true; }

    /**
     * Returns a datasource reference to the given child branch of the current datasouce.
     * @param {String} childName
     */
    child(childName) {
        // the selector will be interpreted at each level and is used to address the correct endpoints relative from the original path
        let newSelector = this._selector?this._selector+ '/' + childName: childName;
        return new SharePointSoapDataSource(this._orginialPath, newSelector);
    }

    root() {
        return this._orginialPath;
    }

    /**
     * Returns the full URL to the path on the datasource.
     */
    path() {
        return this._orginialPath;
    }

    toString() {
        return this._orginialPath;
    }

    /**
     * Returns the name of the current branch in the path on the datasource.
     */
    key() {

        // process the selector
        if (this._selector) {
            let parts = this._selector.split('/');
            if (parts.length>0) {
                return parts[parts.length-1];
            }
        }
        return '';

    }

    /**
     * Writes newData to the path this dataSource was constructed with.
     * @param {Object} newData
     */
    set(newData) {
        this._dataReference.set(newData);
    }

    /**
     * Removes the object and all underlying children that this dataSource points to.
     */
    remove(object) {
        this._dataReference.remove(newData);
    }

    /**
     * Writes newData to the path this dataSource was constructed with, appended by a random UID generated by
     * the dataSource.
     * @param {Object} newData
     */
    push(newData) {
        return this.set(newData);
    }

    /**
     * Writes newData with given priority (ordering) to the path this dataSource was constructed with.
     * @param {Object} newData
     * @param {String|Number} priority
     */
    setWithPriority(newData, priority) {
        newData.priority = priority;
        this.set(newData);
    }

    /**
     * Sets the priority (ordering) of an object on a given dataSource.
     * @param {String|Number} newPriority
     */
    setPriority(newPriority) { }

    /** Sets the callback triggered when dataSource updates the data.
     *  @param {Function} callback **/
    setValueChangedCallback(callback){
        this._onValueCallback = callback;
        this._dataReference.on('value', this._onValueCallback);
    }

    /** Removes the callback set to trigger when dataSource updates the data. **/
    removeValueChangedCallback() {
        if(this._onValueCallback) {
            this._dataReference.off('value', this._onValueCallback);
            this._onValueCallback = null;
        }
    }

    /** Set the callback triggered when dataSource adds a data element.
     * @param {Function} callback **/
    setChildAddedCallback(callback) {
        this._onAddCallback = callback;
        this._dataReference.on('child_added', this._onAddCallback);
    }

    /** Removes the callback set to trigger when dataSource adds a data element. **/
    removeChildAddedCallback() {
        if(this._onAddCallback) {
            this._dataReference.off('child_added', this._onAddCallback);
            this._onAddCallback = null;
        }
    }

    /** Set the callback triggered when dataSource changes a data element.
     * @param {Function} callback **/
    setChildChangedCallback(callback) {
        this._onChangeCallback = callback;
        this._dataReference.on('child_changed', this._onChangeCallback);
    }

    /** Removes the callback set to trigger when dataSource changes a data element. **/
    removeChildChangedCallback() {
        if(this._onChangeCallback) {
            this._dataReference.off('child_changed', this._onChangeCallback);
            this._onChangeCallback = null;
        }
    }

    /** Set the callback triggered when dataSource moves a data element.
     * @param {Function} callback **/
    setChildMovedCallback(callback) {
    }

    /** Removes the callback set to trigger when dataSource moves a data element. **/
    removeChildMovedCallback() {
    }

    /** Set the callback triggered when dataSource adds a data element.
     * @param {Function} callback **/
    setChildRemovedCallback(callback) {
        this._onRemoveCallback = callback;
        this._dataReference.on('child_removed', this._onRemoveCallback);
    }

    /** Removes the callback set to trigger when dataSource adds a data element. **/
    removeChildRemovedCallback() {
        if(this._onRemoveCallback) {
            this._dataReference.off('child_removed', this._onRemoveCallback);
            this._onRemoveCallback = null;
        }
    }
}<|endoftext|>


<commit_before>/* Function to show game detail for selected game */
function showGameDetails(gameID) {
	// Clear the div
	document.getElementById("detailContainer").innerHTML = "";

	// return if marker is being added
	if ( gameID == 'Marker' ) {
		return;
	}

	// Get game details from database
	$.getJSON('/api/getGameDetails',
    {
      ID: gameID
    },function(data) {

		// Get the game detail container
		var detailContainer = document.getElementById('detailContainer');
		var linebreak = document.createElement('BR');

		// Make a label for the sport
		var sportLabel = document.createTextNode('Sport: ' + data[0].sport);
		detailContainer.appendChild(sportLabel);
		detailContainer.appendChild(linebreak);

		// Make a label for the creator
		var creatorLabel = document.createTextNode('Creator: ' + data[0].creator);
		detailContainer.appendChild(creatorLabel);

		// Make img for creator
		var creatorImage = document.createElement("img");
		creatorImage.setAttribute('src', 'https://graph.facebook.com/'+data[0].creatorID+'/picture')
		//detailContainer.appendChild(creatorImage);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Make a label for the time
		var timeLabel = document.createTextNode('time: ' );
		detailContainer.appendChild(timeLabel);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Make a label for the description
		var description = document.createTextNode('description: ' + data[0].description);
		detailContainer.appendChild(description);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Add the button and player list
		addButton(gameID);
	});
}
<commit_msg>Added function to display the "IM IN" button<commit_after>/* Function to show game detail for selected game */
function showGameDetails(gameID) {
	// Clear the div
	document.getElementById("detailContainer").innerHTML = "";

	// return if marker is being added
	if ( gameID == 'Marker' ) {
		return;
	}

	// Get game details from database
	$.getJSON('/api/getGameDetails',
    {
      ID: gameID
    },function(data) {

		// Get the game detail container
		var detailContainer = document.getElementById('detailContainer');
		var linebreak = document.createElement('BR');

		// Make a label for the sport
		var sportLabel = document.createTextNode('Sport: ' + data[0].sport);
		detailContainer.appendChild(sportLabel);
		detailContainer.appendChild(linebreak);

		// Make a label for the creator
		var creatorLabel = document.createTextNode('Creator: ' + data[0].creator);
		detailContainer.appendChild(creatorLabel);

		// Make img for creator
		var creatorImage = document.createElement("img");
		creatorImage.setAttribute('src', 'https://graph.facebook.com/'+data[0].creatorID+'/picture')
		//detailContainer.appendChild(creatorImage);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Make a label for the time
		var timeLabel = document.createTextNode('time: ' );
		detailContainer.appendChild(timeLabel);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Make a label for the description
		var description = document.createTextNode('description: ' + data[0].description);
		detailContainer.appendChild(description);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);
		linebreak = document.createElement('BR');
		detailContainer.appendChild(linebreak);

		// Add the button and player list
		addButton(gameID);
	});
}

/* Function to display button on the game detail form */
function addButton(gameID) {
	// Get user info
	FB.api('/me', {fields: 'name,first_name'}, function(response) {
		$.getJSON('/api/getUserInGame',
	    {
	      gameID: gameID,
	      userID: response.id
	    },function(data) {
	    	// Make the im in button
			var button = document.createElement("button");

	    	// See if the user is already in the game
	    	if ( data.length == 0 ) {
	    		button.innerHTML = "I'm In!";
				button.addEventListener('click', function(){ imin(gameID); });
	    	}else{
	    		button.innerHTML = "Leave Game";
				button.addEventListener('click', function(){ leaveGame(gameID); });
	    	}

	    	// Add the button to the page
	    	detailContainer.appendChild(button);

	    	// Add the list of palyers
	    	addPlayerList(gameID);
	    });
	});
}
<|endoftext|>


<commit_before>var getFileExtension = function(filename) {
  return filename.split('.').pop().toLowerCase();
}

var getMediaType = function(url) {
  // imgur album
  if (url.indexOf('imgur.com/a/') > -1) {
    return "imgur-album";
  }

  // Some common sources don't use file extensions in the url, but still serve a plain ol' image file.
  if (url.indexOf('500px.org') > -1) {
    return "image";
  }

  switch (getFileExtension(url)) {
    case "jpg":
    case "jpeg":
    case "png":
    case "gif":
      return "image";
      break;
  }
}

var processUrl = function(url) {
  var newUrl = url;

  // convert imgur page url into direct image url
  if ((parseUrl(url).hostname == "imgur.com") &&
      (url.indexOf("gallery") == -1) &&
      (url.indexOf("/a/") == -1) &&
      (url.indexOf("gifv") == -1)) {
    newUrl = url + ".jpg"; // any suffix is ok
  }

  return newUrl;
}

var addImgurAlbum = function(url) {
  var id = url.split('/a/')[1];
  $.ajax({
    url: "https://api.imgur.com/3/album/" + id,
    dataType: "json",
    beforeSend: function(xhr) {
      xhr.setRequestHeader("Authorization", "Client-ID ddf12e5f849636a");
    },
    success: function(resp) {
      var data = resp.data;
      var albumTemplate = require("../templates/imgur-album.hbs");
      var html = albumTemplate(data);
      $(html).appendTo("#wrapper");
    }
  });
}

// http://stackoverflow.com/a/6644749
function parseUrl(url) {
  var a = document.createElement('a');
  a.href = url;
  return a;
}

module.exports = {
  getFileExtension: getFileExtension,
  getMediaType: getMediaType,
  processUrl: processUrl,
  addImgurAlbum: addImgurAlbum,
  parseUrl: parseUrl
}
<commit_msg>Handle gifv urls<commit_after>var getFileExtension = function(filename) {
  return filename.split('.').pop().toLowerCase();
}

var getMediaType = function(url) {
  // imgur album
  if (url.indexOf('imgur.com/a/') > -1) {
    return "imgur-album";
  }

  // Some common sources don't use file extensions in the url, but still serve a plain ol' image file.
  if (url.indexOf('500px.org') > -1) {
    return "image";
  }

  switch (getFileExtension(url)) {
    case "jpg":
    case "jpeg":
    case "png":
    case "gif":
      return "image";
      break;
  }
}

var processUrl = function(url) {
  var newUrl = url;

  // convert imgur page url into direct image url
  if ((parseUrl(url).hostname == "imgur.com") &&
      (url.indexOf("gallery") == -1) &&
      (url.indexOf("/a/") == -1) &&
      (url.indexOf(".gifv") == -1)) {
    newUrl = url + ".jpg"; // any suffix is ok
  }

  // convert imgur gifv url into gif url by slicing off the final v
  if (url.indexOf(".gifv") > -1) {
    newUrl = url.slice(0, -1);
  }

  return newUrl;
}

var addImgurAlbum = function(url) {
  var id = url.split('/a/')[1];
  $.ajax({
    url: "https://api.imgur.com/3/album/" + id,
    dataType: "json",
    beforeSend: function(xhr) {
      xhr.setRequestHeader("Authorization", "Client-ID ddf12e5f849636a");
    },
    success: function(resp) {
      var data = resp.data;
      var albumTemplate = require("../templates/imgur-album.hbs");
      var html = albumTemplate(data);
      $(html).appendTo("#wrapper");
    }
  });
}

// http://stackoverflow.com/a/6644749
function parseUrl(url) {
  var a = document.createElement('a');
  a.href = url;
  return a;
}

module.exports = {
  getFileExtension: getFileExtension,
  getMediaType: getMediaType,
  processUrl: processUrl,
  addImgurAlbum: addImgurAlbum,
  parseUrl: parseUrl
}
<|endoftext|>


<commit_before>const express = require('express')
const fallback = require('express-history-api-fallback')
const staticGzip = require('express-static-gzip')
const proxy = require('http-proxy-middleware')
const morgan = require('morgan')
const path = require('path')
const os = require('os')
const colors = require('colors/safe')

const port = 3000
const wwwroot = path.join(__dirname, 'wwwroot')
const ifaces = os.networkInterfaces()
const app = express()
const backendProxy = proxy({
  target: 'http://localhost:5000/',
  logLevel: 'debug',
  logProvider: () => {
    return {
      log: (message) => console.log(colors.gray(message)),
      debug: (message) => console.log(colors.gray(message)),
      info: (message) => console.log(colors.gray(message)),
      warn: (message) => console.log(colors.yellow(message)),
      error: (message) => console.log(colors.red(message))
    }
  }
})

app.use(morgan('dev'))
app.use('/api', backendProxy)
app.use('/', staticGzip(wwwroot))
app.use(fallback('index.html', {root: wwwroot}))

console.log(colors.yellow('Starting express web server.'))
console.log('Listening on port ' + colors.magenta(port) + ', serving ' + colors.cyan(wwwroot))
app.listen(port, '0.0.0.0', () => {
  console.log('Available on')
  Object.keys(ifaces).forEach(function (dev) {
    ifaces[dev].forEach(function (details) {
      if (details.family === 'IPv4') {
        console.log('  ' + colors.cyan('http://' + details.address + ':' + port))
      }
    })
  })
  console.log('Hit ' + colors.cyan('CTRL-C') + ' to stop the server')
})

process.on('SIGINT', function () {
  console.log(colors.yellow(' express web server stopped.'))
  process.exit()
})

process.on('SIGTERM', function () {
  console.log(colors.yellow(' express web server stopped.'))
  process.exit()
})
<commit_msg>Formatting.<commit_after>const express = require('express')
const fallback = require('express-history-api-fallback')
const staticGzip = require('express-static-gzip')
const proxy = require('http-proxy-middleware')
const morgan = require('morgan')
const path = require('path')
const os = require('os')
const colors = require('colors/safe')

const port = 3000
const wwwroot = path.join(__dirname, 'wwwroot')
const ifaces = os.networkInterfaces()
const app = express()
const backendProxy = proxy({
  target: 'http://localhost:5000/',
  logLevel: 'debug',
  logProvider: () => {
    return {
      log: (message) => console.log(colors.gray(message)),
      debug: (message) => console.log(colors.gray(message)),
      info: (message) => console.log(colors.gray(message)),
      warn: (message) => console.log(colors.yellow(message)),
      error: (message) => console.log(colors.red(message))
    }
  }
})

app.use(morgan('dev'))
app.use('/api', backendProxy)
app.use('/', staticGzip(wwwroot))
app.use(fallback('index.html', { root: wwwroot }))

console.log(colors.yellow('Starting express web server.'))
console.log('Listening on port ' + colors.magenta(port) + ', serving ' + colors.cyan(wwwroot))
app.listen(port, '0.0.0.0', () => {
  console.log('Available on')
  Object.keys(ifaces).forEach(function (dev) {
    ifaces[dev].forEach(function (details) {
      if (details.family === 'IPv4') {
        console.log('  ' + colors.cyan('http://' + details.address + ':' + port))
      }
    })
  })
  console.log('Hit ' + colors.cyan('CTRL-C') + ' to stop the server')
})

process.on('SIGINT', function () {
  console.log(colors.yellow(' express web server stopped.'))
  process.exit()
})

process.on('SIGTERM', function () {
  console.log(colors.yellow(' express web server stopped.'))
  process.exit()
})
<|endoftext|>


<commit_before>// whatever javascript files you place in this iFEF `folder will be concatenated to a single file in the js library

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

var AV = {};

AV.routes = Backbone.Router.extend({

	routes: {
		'': 'index'
	},
	initialize:function(){
		test('init');
	},
	index: function(){
		this.model = new AV.model();
		this.model({

			name: 'test',
			type: 'txt',
			content: 'test'
		});
		this.model.save({
			success:function(d){
				test('success');
			},
			error:function(d){
				test('error');
			}
		});
	}
});

AV.model = Backbone.Model.extend({
	url: 'localhost:8182/juxta/source',
	name: '',
	type: '',
	content: ''
});

AV.view = Backbone.View.extend({});

var readysetgo = new AV.routes();

$(function(){
  Backbone.history.start();
});
<commit_msg>changed the url in scripts<commit_after>// whatever javascript files you place in this iFEF `folder will be concatenated to a single file in the js library

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

Backbone.emulateHTTP = true;
var AV = {};

AV.routes = Backbone.Router.extend({

	routes: {
		'': 'index'
	},
	initialize:function(){
		test('init');
	},
	index: function(){
		test("Inside index");
		this.model = new AV.model(
		{
			name: 'test',
			type: 'txt',
			content: 'test'
		});
		this.model.save({
			success:function(d){
				test('success');
			},
			error:function(d){
				test('error');
			}
		});
	}
});

AV.model = Backbone.Model.extend({
	url: 'http://54.88.3.200:8182/juxta/source',
	name: '',
	type: '',
	content: ''
});

AV.view = Backbone.View.extend({});

var readysetgo = new AV.routes();

$(function(){
  Backbone.history.start();
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
//
// Node.js based HTTP proxy to rewrite the Location: and non-relative
// urls used in the HomeMatic WebUI of HTTP requests coming from
// Home-Assistent UI so that the Ingress-based HA UI is able to embed
// the WebUI.
//
// Copyright (c) 2021 Jens Maus <mail@jens-maus.de>
//
// Apache 2.0 License applies
//

const express = require('express');
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
const ipaddr = require('ipaddr.js');

const apiProxy = createProxyMiddleware('/', {
  target: 'http://127.0.0.1:80',
  changeOrigin: true, // for vhosted sites,
  //logLevel: 'debug',
  selfHandleResponse: true,
  timeout: 1200000, // max 20 min
  onProxyRes: responseInterceptor(async (responseBody, proxyRes, req, res) => {
    // modify Location: response header if present
    if(typeof(proxyRes.headers.location) !== 'undefined') {
      var redirect = proxyRes.headers.location;
      redirect = req.headers['x-ingress-path'] + redirect;
      res.append("location", redirect);
    }

    // modifying textual response bodies
    if(proxyRes.headers['content-type'] &&
       (
        proxyRes.headers['content-type'].includes('text/') ||
        proxyRes.headers['content-type'].includes('application/javascript') ||
        proxyRes.headers['content-type'].includes('application/json')
       )
      ) {

      var body;

      // if this a textual response body we make sure to prepend the ingress path
      if(proxyRes.headers['content-type'].toLowerCase().includes('utf-8')) {
        body = responseBody.toString('utf8');
      } else {
        body = responseBody.toString('latin1');
      }

      body = body.replace(/(?<=["'=\\u0027 \(\\])\/(api|webui|ise|pda|config|pages|jpages|esp|upnp|tools|addons)(\\?\/)(?!hassio_ingress)/g,
                          req.headers['x-ingress-path']+'/$1$2');
      body = body.replace(/(?<=["'])\/(index|login|logout)\.htm/g,
                          req.headers['x-ingress-path']+'/$1.htm');
      body = body.replace(/window\.location\.href='\/'/g,
                          'window.location.href=\'' + req.headers['x-ingress-path'] + '/\'');
      body = body.replace(/window\.location\.href='\/index\.htm'/g,
                          'window.location.href=\'' + req.headers['x-ingress-path'] + '/index.htm\'');

      // convert back to a Buffer in the right character encoding
      if(typeof(req.headers['content-type']) === 'undefined') {
        return new Buffer.from(body, 'latin1');
      } else {
        return new Buffer.from(body, 'utf8');
      }
    } else {
      return responseBody;
    }
  }),
});

const app = express();
app.use((req, res, next) => {
  //Get whitelisted range
  let whitelisted_range = ipaddr.parseCIDR(process.env.HM_HAPROXY_SRC);
  //Get source IP
  let source_ip = ipaddr.parse(req.ip.split(':').pop());
  //Check if source IP in whitelisted range
  if(source_ip.match(whitelisted_range)) {
    // allowed, forward to next middleware (proxy)
    next();
  } else {
    // abort request with "403 Forbidden"
    res.status(403).end();
  }
}, apiProxy);
app.listen(8099);
<commit_msg>integrated a fix for /bin/ha-proxy.js which moves the '\u0027' string out of the character class (where it was wrong). This should integrate a further fix for getting the general file upload via fileupload.ccc running correctly in a HA add-on environment. This refs #1368.<commit_after>#!/usr/bin/env node
//
// Node.js based HTTP proxy to rewrite the Location: and non-relative
// urls used in the HomeMatic WebUI of HTTP requests coming from
// Home-Assistent UI so that the Ingress-based HA UI is able to embed
// the WebUI.
//
// Copyright (c) 2021 Jens Maus <mail@jens-maus.de>
//
// Apache 2.0 License applies
//

const express = require('express');
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
const ipaddr = require('ipaddr.js');

const apiProxy = createProxyMiddleware('/', {
  target: 'http://127.0.0.1:80',
  changeOrigin: true, // for vhosted sites,
  //logLevel: 'debug',
  selfHandleResponse: true,
  timeout: 1200000, // max 20 min
  onProxyRes: responseInterceptor(async (responseBody, proxyRes, req, res) => {
    // modify Location: response header if present
    if(typeof(proxyRes.headers.location) !== 'undefined') {
      var redirect = proxyRes.headers.location;
      redirect = req.headers['x-ingress-path'] + redirect;
      res.append("location", redirect);
    }

    // modifying textual response bodies
    if(proxyRes.headers['content-type'] &&
       (
        proxyRes.headers['content-type'].includes('text/') ||
        proxyRes.headers['content-type'].includes('application/javascript') ||
        proxyRes.headers['content-type'].includes('application/json')
       )
      ) {

      var body;

      // if this a textual response body we make sure to prepend the ingress path
      if(proxyRes.headers['content-type'].toLowerCase().includes('utf-8')) {
        body = responseBody.toString('utf8');
      } else {
        body = responseBody.toString('latin1');
      }

      body = body.replace(/(?<=["'= \(\\]|\\u0027)\/(api|webui|ise|pda|config|pages|jpages|esp|upnp|tools|addons)(\\?\/)(?!hassio_ingress)/g,
                          req.headers['x-ingress-path']+'/$1$2');
      body = body.replace(/(?<=["'])\/(index|login|logout)\.htm/g,
                          req.headers['x-ingress-path']+'/$1.htm');
      body = body.replace(/window\.location\.href='\/'/g,
                          'window.location.href=\'' + req.headers['x-ingress-path'] + '/\'');
      body = body.replace(/window\.location\.href='\/index\.htm'/g,
                          'window.location.href=\'' + req.headers['x-ingress-path'] + '/index.htm\'');

      // convert back to a Buffer in the right character encoding
      if(typeof(req.headers['content-type']) === 'undefined') {
        return new Buffer.from(body, 'latin1');
      } else {
        return new Buffer.from(body, 'utf8');
      }
    } else {
      return responseBody;
    }
  }),
});

const app = express();
app.use((req, res, next) => {
  //Get whitelisted range
  let whitelisted_range = ipaddr.parseCIDR(process.env.HM_HAPROXY_SRC);
  //Get source IP
  let source_ip = ipaddr.parse(req.ip.split(':').pop());
  //Check if source IP in whitelisted range
  if(source_ip.match(whitelisted_range)) {
    // allowed, forward to next middleware (proxy)
    next();
  } else {
    // abort request with "403 Forbidden"
    res.status(403).end();
  }
}, apiProxy);
app.listen(8099);
<|endoftext|>


<commit_before>/*  ============================================================================

 Copyright (C) 2006-2018 Talend Inc. - www.talend.com

 This source code is available under agreement available at
 https://github.com/Talend/data-prep/blob/master/LICENSE

 You should have received a copy of the agreement
 along with this program; if not, write to Talend SA
 9 rue Pages 92150 Suresnes, France

 ============================================================================*/

export const LIVE_LOCATION_TYPE = 'job';

const DATASTORE_SUBMIT_SELECTOR = '#datastore-form [type="submit"]';

/**
 * @ngdoc controller
 * @name data-prep.dataset-import:DatasetImportCtrl
 * @description Dataset Import controller
 */
export default class DatasetImportCtrl {
	constructor($document, $timeout, $translate, DatasetService, MessageService, ImportService, UploadWorkflowService) {
		'ngInject';

		this.$document = $document;
		this.$timeout = $timeout;
		this.$translate = $translate;

		this.importService = ImportService;
		this.messageService = MessageService;
		this.uploadWorkflowService = UploadWorkflowService;

		this.onDatastoreFormChange = this.onDatastoreFormChange.bind(this);
		this.onDatastoreFormSubmit = this.onDatastoreFormSubmit.bind(this);
		this._getDatastoreFormActions = this._getDatastoreFormActions.bind(this);
		this.onDatasetFormChange = this.onDatasetFormChange.bind(this);
		this.onDatasetFormSubmit = this.onDatasetFormSubmit.bind(this);
		this._getDatasetFormActions = this._getDatasetFormActions.bind(this);

		this._create = this._create.bind(this);
		this._edit = this._edit.bind(this);
		this._reset = this._reset.bind(this);
		this._simulateDatastoreSubmit = this._simulateDatastoreSubmit.bind(this);
	}

	$onChanges(changes) {
		const item = changes.item && changes.item.currentValue;
		const locationType = (changes.locationType && changes.locationType.currentValue) || LIVE_LOCATION_TYPE;
		if (item) {
			this.importService
				.getFormsByDatasetId(this.item.id)
				.then(({ data }) => {
					const { dataStoreFormData, dataSetFormData } = data;
					const { properties } = dataStoreFormData;
					this.datastoreForm = null;
					this.datasetForm = null;
					this._getDatastoreFormActions(properties);
					this._getDatasetFormActions();
					this.$timeout(() => {
						this.datastoreForm = dataStoreFormData;
						this.datasetForm = dataSetFormData;
					});
				})
				.catch(this._reset);
		}
		else if (locationType) {
			this.importService
				.importParameters(locationType)
				.then(({ data }) => {
					const { properties } = data;
					this.datastoreForm = null;
					this._getDatastoreFormActions(properties);
					this.$timeout(() => {
						this.datastoreForm = data;
					});
					return properties;
				})
				.then((formData) => {
					const hasHiddenTestConnectionBtn = formData && !formData.tdp_isTestConnectionEnabled;
					if (hasHiddenTestConnectionBtn) {
						return this._initDatasetForm(formData);
					}
				})
				.catch(this._reset);
		}
	}

	/**
	 * @ngdoc method
	 * @name _initDatasetForm
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Initialize dataset form from datastore form data
	 * @param formData Datastore form data
	 * @returns {Promise}
	 * @private
	 */
	_initDatasetForm(formData) {
		return this.importService
			.getDatasetForm(formData)
			.then(({ data }) => {
				this.datasetForm = null;
				this._getDatasetFormActions();
				this.$timeout(() => {
					this.datasetForm = data;
				});
			});
	}

	/**
	 * @ngdoc method
	 * @name _getDatastoreFormActions
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Populates datastore form actions if they don't exist
	 */
	_getDatastoreFormActions(properties) {
		if (!this.datastoreFormActions) {
			this.datastoreFormActions = [{
				style: `info ${properties && !properties.tdp_isTestConnectionEnabled && 'sr-only'}`,
				type: 'submit',
				label: this.$translate.instant('DATASTORE_TEST_CONNECTION'),
			}];
		}
	}

	/**
	 * @ngdoc method
	 * @name _getDatasetFormActions
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Populates dataset form actions if they don't exist
	 */
	_getDatasetFormActions() {
		if (!this.datasetFormActions) {
			this.datasetFormActions = [
				{
					style: 'default',
					type: 'button',
					onClick: this._reset,
					label: this.$translate.instant('CANCEL'),
				},
				{
					style: 'success',
					type: 'submit',
					label: this.$translate.instant(this.item ? 'EDIT_DATASET' : 'IMPORT_DATASET'),
				},
			];
		}
	}

	/**
	 * @ngdoc method
	 * @name onDatastoreFormChange
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Datastore form change handler
	 * @param formData All data as form properties
	 * @param definitionName ID attached to the form
	 * @param propertyName Property which has triggered change handler
	 */
	onDatastoreFormChange(formData, definitionName = (this.locationType || LIVE_LOCATION_TYPE), propertyName) {
		this.importService
			.refreshForm(propertyName, formData)
			.then(({ data }) => {
				this.datastoreForm = null;
				this.$timeout(() => {
					this.datastoreForm = data;
				});
			});
	}

	/**
	 * @ngdoc method
	 * @name onDatastoreFormSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Datastore form change handler
	 * @param event Original event
	 * @param changes Form changes
	 */
	onDatastoreFormSubmit(event, changes) {
		const { formData, definitionName = (this.locationType || this.item.location.componentType || LIVE_LOCATION_TYPE) } = changes;
		if (this.submitLock) {
			const formsData = {
				dataStoreProperties: formData,
				dataSetProperties: this.datasetFormData,
			};
			let controlledSubmitPromise;
			// Dataset form change
			if (this.currentPropertyName) {
				controlledSubmitPromise = this.importService
					.refreshForms(this.currentPropertyName, formsData)
					.then(({ data }) => {
						this.datasetForm = null;
						this.$timeout(() => {
							this.datasetForm = data;
						});
					});
			}
			// Dataset form submit
			else {
				const action = this.item ? this._edit : this._create;
				controlledSubmitPromise = action(formsData)
					.then(this.uploadWorkflowService.openDataset)
					.then(this._reset);
			}
			controlledSubmitPromise.finally(() => {
				this.currentPropertyName = null;
				this.submitLock = false;
			});
		}
		// Datastore form submit without submit button
		else if (this.datastoreForm && this.datastoreForm.properties && !this.datastoreForm.properties.tdp_isTestConnectionEnabled) {
			// From datastore form submit (i.e. submit with keyboard)
			return false;
		}
		// Datastore form submit
		else {
			this.importService
				.testConnection(definitionName, formData)
				.then(() => this.messageService.success(
					'DATASTORE_TEST_CONNECTION',
					'DATASTORE_CONNECTION_SUCCESSFUL'
				))
				.then(() => {
					if (!this.datasetForm) {
						if (this.item && this.item.id) {
							formData.datasetId = this.item.id;
						}
						return this._initDatasetForm(formData);
					}
				});
		}
	}

	/**
	 * @ngdoc method
	 * @name onDatasetFormChange
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Dataset form change handler
	 * @param formData All data as form properties
	 * @param definitionName ID attached to the form
	 * @param propertyName Property which has triggered change handler
	 */
	onDatasetFormChange(formData, definitionName, propertyName) {
		this.currentPropertyName = propertyName;
		this._simulateDatastoreSubmit(formData);
	}

	/**
	 * @ngdoc method
	 * @name onDatasetFormSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Dataset form submit handler
	 * @see onDatastoreFormSubmit
	 * @param event Original event
	 * @param changes Form changes
	 */
	onDatasetFormSubmit(event, changes) {
		const { formData } = changes;
		this._simulateDatastoreSubmit(formData);
	}

	/**
	 * @ngdoc method
	 * @name _simulateDatastoreSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Simulate datastore form submit after saving dataset form data
	 * Both forms need to be submitted so we have to put a latch in order to submit data store and data set forms data
	 * One way to do that, it's to trigger onClick event on data store form submit button
	 *  1. Second form submit -> save second form data
	 *  2. Trigger click event on first form submit button -> save first form data
	 *  3. Second form submit -> aggregate both forms data and send it
	 * @private
	 */
	_simulateDatastoreSubmit(formData) {
		this.submitLock = true;
		const $datastoreFormSubmit = this.$document.find(DATASTORE_SUBMIT_SELECTOR).eq(0);
		if ($datastoreFormSubmit.length) {
			this.datasetFormData = formData;
			const datastoreFormSubmitElm = $datastoreFormSubmit[0];
			datastoreFormSubmitElm.click();
		}
		else {
			this.submitLock = false;
		}
	}

	/**
	 * @ngdoc method
	 * @name _reset
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Reset state after submit
	 * @private
	 */
	_reset() {
		this.$timeout(() => {
			this.datastoreForm = null;
			this.datasetForm = null;
			this.datasetFormData = null;
			this.submitLock = false;
			this.currentPropertyName = null;
			this.importService.StateService.hideImport();
			this.importService.StateService.setCurrentImportItem(null);
		});
	}

	/**
	 * @ngdoc method
	 * @name _create
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Create dataset with both forms data
	 * @param formsData Datastore and dataset properties
	 * @private
	 */
	_create(formsData) {
		return this.importService
			.createDataset((this.locationType || LIVE_LOCATION_TYPE), formsData)
			.then(({ data }) => {
				const { dataSetId } = data;
				// temp dataset object to read its id
				return { id: dataSetId };
			});
	}

	/**
	 * @ngdoc method
	 * @name _edit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Edit dataset with both forms data
	 * @param formsData Datastore and dataset properties
	 * @private
	 */
	_edit(formsData) {
		const itemId = this.item.id;
		return this.importService
			.editDataset(itemId, formsData)
			.then(() => this.item);
	}
}
<commit_msg>fix(TDP-5947): datasets listing has performance degradation (#1609)<commit_after>/*  ============================================================================

 Copyright (C) 2006-2018 Talend Inc. - www.talend.com

 This source code is available under agreement available at
 https://github.com/Talend/data-prep/blob/master/LICENSE

 You should have received a copy of the agreement
 along with this program; if not, write to Talend SA
 9 rue Pages 92150 Suresnes, France

 ============================================================================*/

export const LIVE_LOCATION_TYPE = 'job';

const DATASTORE_SUBMIT_SELECTOR = '#datastore-form [type="submit"]';

/**
 * @ngdoc controller
 * @name data-prep.dataset-import:DatasetImportCtrl
 * @description Dataset Import controller
 */
export default class DatasetImportCtrl {
	constructor($document, $timeout, $translate, DatasetService, MessageService, ImportService, UploadWorkflowService) {
		'ngInject';

		this.$document = $document;
		this.$timeout = $timeout;
		this.$translate = $translate;

		this.importService = ImportService;
		this.messageService = MessageService;
		this.uploadWorkflowService = UploadWorkflowService;

		this.onDatastoreFormChange = this.onDatastoreFormChange.bind(this);
		this.onDatastoreFormSubmit = this.onDatastoreFormSubmit.bind(this);
		this._getDatastoreFormActions = this._getDatastoreFormActions.bind(this);
		this.onDatasetFormChange = this.onDatasetFormChange.bind(this);
		this.onDatasetFormSubmit = this.onDatasetFormSubmit.bind(this);
		this._getDatasetFormActions = this._getDatasetFormActions.bind(this);

		this._create = this._create.bind(this);
		this._edit = this._edit.bind(this);
		this._reset = this._reset.bind(this);
		this._simulateDatastoreSubmit = this._simulateDatastoreSubmit.bind(this);
	}

	$onChanges(changes) {
		const item = changes.item && changes.item.currentValue;
		const locationType = (changes.locationType && changes.locationType.currentValue) || LIVE_LOCATION_TYPE;
		if (item) {
			this.importService
				.getFormsByDatasetId(this.item.id)
				.then(({ data }) => {
					const { dataStoreFormData, dataSetFormData } = data;
					const { properties } = dataStoreFormData;
					this.datastoreForm = null;
					this.datasetForm = null;
					this._getDatastoreFormActions(properties);
					this._getDatasetFormActions();
					this.$timeout(() => {
						this.datastoreForm = dataStoreFormData;
						this.datasetForm = dataSetFormData;
					});
				})
				.catch(this._reset);
		}
		else if (locationType) {
			this.importService
				.importParameters(locationType)
				.then(({ data }) => {
					const { properties } = data;
					this.datastoreForm = null;
					this._getDatastoreFormActions(properties);
					this.$timeout(() => {
						this.datastoreForm = data;
					});
					return properties;
				})
				.then((formData) => {
					const hasHiddenTestConnectionBtn = formData && !formData.tdp_isTestConnectionEnabled;
					if (hasHiddenTestConnectionBtn) {
						return this._initDatasetForm(formData);
					}
				})
				.catch(this._reset);
		}
	}

	/**
	 * @ngdoc method
	 * @name _initDatasetForm
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Initialize dataset form from datastore form data
	 * @param formData Datastore form data
	 * @returns {Promise}
	 * @private
	 */
	_initDatasetForm(formData) {
		return this.importService
			.getDatasetForm(formData)
			.then(({ data }) => {
				this.datasetForm = null;
				this._getDatasetFormActions();
				this.$timeout(() => {
					this.datasetForm = data;
				});
			});
	}

	/**
	 * @ngdoc method
	 * @name _getDatastoreFormActions
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Populates datastore form actions if they don't exist
	 */
	_getDatastoreFormActions(properties) {
		if (!this.datastoreFormActions) {
			this.datastoreFormActions = [{
				style: `info ${properties && !properties.tdp_isTestConnectionEnabled && 'sr-only'}`,
				type: 'submit',
				label: this.$translate.instant('DATASTORE_TEST_CONNECTION'),
			}];
		}
	}

	/**
	 * @ngdoc method
	 * @name _getDatasetFormActions
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Populates dataset form actions if they don't exist
	 */
	_getDatasetFormActions() {
		if (!this.datasetFormActions) {
			this.datasetFormActions = [
				{
					style: 'default',
					type: 'button',
					onClick: this._reset,
					label: this.$translate.instant('CANCEL'),
				},
				{
					style: 'success',
					type: 'submit',
					label: this.$translate.instant(this.item ? 'EDIT_DATASET' : 'IMPORT_DATASET'),
				},
			];
		}
	}

	/**
	 * @ngdoc method
	 * @name onDatastoreFormChange
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Datastore form change handler
	 * @param formData All data as form properties
	 * @param definitionName ID attached to the form
	 * @param propertyName Property which has triggered change handler
	 */
	onDatastoreFormChange(formData, definitionName = (this.locationType || LIVE_LOCATION_TYPE), propertyName) {
		this.importService
			.refreshForm(propertyName, formData)
			.then(({ data }) => {
				this.datastoreForm = null;
				this.$timeout(() => {
					this.datastoreForm = data;
				});
			});
	}

	/**
	 * @ngdoc method
	 * @name onDatastoreFormSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Datastore form change handler
	 * @param event Original event
	 * @param changes Form changes
	 */
	onDatastoreFormSubmit(event, changes) {
		// Get item type from its mime type
		const itemType = this.item && this.item.type && this.item.type.split('.').reverse()[0];
		const { formData, definitionName = (this.locationType || itemType || LIVE_LOCATION_TYPE) } = changes;
		if (this.submitLock) {
			const formsData = {
				dataStoreProperties: formData,
				dataSetProperties: this.datasetFormData,
			};
			let controlledSubmitPromise;
			// Dataset form change
			if (this.currentPropertyName) {
				controlledSubmitPromise = this.importService
					.refreshForms(this.currentPropertyName, formsData)
					.then(({ data }) => {
						this.datasetForm = null;
						this.$timeout(() => {
							this.datasetForm = data;
						});
					});
			}
			// Dataset form submit
			else {
				const action = this.item ? this._edit : this._create;
				controlledSubmitPromise = action(formsData)
					.then(this.uploadWorkflowService.openDataset)
					.then(this._reset);
			}
			controlledSubmitPromise.finally(() => {
				this.currentPropertyName = null;
				this.submitLock = false;
			});
		}
		// Datastore form submit without submit button
		else if (this.datastoreForm && this.datastoreForm.properties && !this.datastoreForm.properties.tdp_isTestConnectionEnabled) {
			// From datastore form submit (i.e. submit with keyboard)
			return false;
		}
		// Datastore form submit
		else {
			this.importService
				.testConnection(definitionName, formData)
				.then(() => this.messageService.success(
					'DATASTORE_TEST_CONNECTION',
					'DATASTORE_CONNECTION_SUCCESSFUL'
				))
				.then(() => {
					if (!this.datasetForm) {
						if (this.item && this.item.id) {
							formData.datasetId = this.item.id;
						}
						return this._initDatasetForm(formData);
					}
				});
		}
	}

	/**
	 * @ngdoc method
	 * @name onDatasetFormChange
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Dataset form change handler
	 * @param formData All data as form properties
	 * @param definitionName ID attached to the form
	 * @param propertyName Property which has triggered change handler
	 */
	onDatasetFormChange(formData, definitionName, propertyName) {
		this.currentPropertyName = propertyName;
		this._simulateDatastoreSubmit(formData);
	}

	/**
	 * @ngdoc method
	 * @name onDatasetFormSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Dataset form submit handler
	 * @see onDatastoreFormSubmit
	 * @param event Original event
	 * @param changes Form changes
	 */
	onDatasetFormSubmit(event, changes) {
		const { formData } = changes;
		this._simulateDatastoreSubmit(formData);
	}

	/**
	 * @ngdoc method
	 * @name _simulateDatastoreSubmit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Simulate datastore form submit after saving dataset form data
	 * Both forms need to be submitted so we have to put a latch in order to submit data store and data set forms data
	 * One way to do that, it's to trigger onClick event on data store form submit button
	 *  1. Second form submit -> save second form data
	 *  2. Trigger click event on first form submit button -> save first form data
	 *  3. Second form submit -> aggregate both forms data and send it
	 * @private
	 */
	_simulateDatastoreSubmit(formData) {
		this.submitLock = true;
		const $datastoreFormSubmit = this.$document.find(DATASTORE_SUBMIT_SELECTOR).eq(0);
		if ($datastoreFormSubmit.length) {
			this.datasetFormData = formData;
			const datastoreFormSubmitElm = $datastoreFormSubmit[0];
			datastoreFormSubmitElm.click();
		}
		else {
			this.submitLock = false;
		}
	}

	/**
	 * @ngdoc method
	 * @name _reset
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Reset state after submit
	 * @private
	 */
	_reset() {
		this.$timeout(() => {
			this.datastoreForm = null;
			this.datasetForm = null;
			this.datasetFormData = null;
			this.submitLock = false;
			this.currentPropertyName = null;
			this.importService.StateService.hideImport();
			this.importService.StateService.setCurrentImportItem(null);
		});
	}

	/**
	 * @ngdoc method
	 * @name _create
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Create dataset with both forms data
	 * @param formsData Datastore and dataset properties
	 * @private
	 */
	_create(formsData) {
		return this.importService
			.createDataset((this.locationType || LIVE_LOCATION_TYPE), formsData)
			.then(({ data }) => {
				const { dataSetId } = data;
				// temp dataset object to read its id
				return { id: dataSetId };
			});
	}

	/**
	 * @ngdoc method
	 * @name _edit
	 * @methodOf data-prep.dataset-import:DatasetImportCtrl
	 * @description Edit dataset with both forms data
	 * @param formsData Datastore and dataset properties
	 * @private
	 */
	_edit(formsData) {
		const itemId = this.item.id;
		return this.importService
			.editDataset(itemId, formsData)
			.then(() => this.item);
	}
}
<|endoftext|>


<commit_before>function readInput(id) {
  	var input = document.getElementById(id).value;
  	return input;
}

function createDetails() {

	var details = {

		"title" : readInput('inputTitle'),
		"URL" : readInput('inputURL'),
		"text" : readInput('inputText'),
		"startDate": readInput('inputStartDate'),
		"endDate": readInput('inputEndDate'),
		"rating": readInput('ratingComment')

	};

	return details;
}

function validateURL(url) {

	return (url.match(/http:\/\/[A-Za-z0-9\.-]{3,}\.[A-Za-z]{3}/) != null && url.length != 0);
}

function validateDateFormat(date) {

	if(date === '') {

		return true;
	}

	else {

		// from formValidator-plugin
		var mask = regex = 'dd/mm/yyyy';
		var matches = day = month = year = null;

		regex = regex.replace('mm', '[01][0-9]');
		regex = regex.replace('m', '[1]?[0-9]');
		regex = regex.replace('dd', '[0123][0-9]');
		regex = regex.replace('d', '[0123]?[0-9]');
		regex = regex.replace('yyyy', '[0-9]{4}');
		regex = regex.replace('yy', '[0-9]{2}');
		var pattern = '^' + regex + '$';
		var re = new RegExp(pattern, '');

		return (!!date.match(re));
	}
}

function validateDatesRelation (startDate, endDate) {

	var dateStart = startDate.split("/");
	var dateEnd = endDate.split("/");

	if(startDate === '' & endDate === '') {
		return true;
	}

	else if(startDate === '' & endDate != '') {
		return false;
	}

	else if(dateStart[2] > dateEnd[2]) {
		return false;
	}

	else if((dateStart[1] > dateEnd[1]) & (dateStart[2] === dateEnd[2])) {
		return false;
	}

	else if((dateStart[0] >= dateEnd[0]) & (dateStart[1] === dateEnd[1])) {
		return false;
	}

	else {
		return true;
	}
}<commit_msg>Change input-reading, delete validateDateForm<commit_after>function createDetails() {

	var details = {

		"title" : $("#inputTitle").val(),
		"URL" : $("#inputURL").val(),
		"text" : $("#inputText").val(),
		"startDate": $("#inputStartDate").val(),
		"endDate": $("#inputEndDate").val(),
		"rating": $("#ratingComment").val()

	};

	return details;
}

function validateURL(url) {

	return (url.match(/http:\/\/[A-Za-z0-9\.-]{3,}\.[A-Za-z]{3}/) != null && url.length != 0);
}

function validateDatesRelation (startDate, endDate) {

	var dateStart = startDate.split("/");
	var dateEnd = endDate.split("/");

	if(startDate === '' & endDate === '') {
		return true;
	}

	else if(startDate === '' & endDate != '') {
		return false;
	}

	else if(startDate != '' & endDate === '') {
		return false;
	}

	else if(dateStart[2] > dateEnd[2]) {
		return false;
	}

	else if((dateStart[1] > dateEnd[1]) & (dateStart[2] === dateEnd[2])) {
		return false;
	}

	else if((dateStart[0] >= dateEnd[0]) & (dateStart[1] === dateEnd[1])) {
		return false;
	}

	else {
		return true;
	}
}<|endoftext|>


<commit_before>  'use strict';

angular.module('sqwiggle-feed.system').controller('FeedController', ['$scope', '$http', function ($scope, $http) {
	$scope.messages = [];
	$scope.users = [];
	$scope.menuactive = false;
	$scope.page = 1;
	$scope.limit = 15;
	$scope.togglemenu = function(){
		$scope.menuactive = !$scope.menuactive;
	}
	$scope.getMessages = function() {
		$http.get('/resources/api.php', {
    		params: {
    			endpoint: 'messages',
    			page: $scope.page,
    			limit: $scope.limit
    		},
    	}).success(function(e) {
    		for(var i in e) {
    			var message = e[i];
    			$scope.messages.push(message);
    		}
    	});
	}
	$scope.getUsers = function() {
		$http.get('resources/api.php', {
    		params: {
    			endpoint: 'users'
    		}

    	}).success(function(e) {
    		$scope.users = e;
    	});
	}
	$scope.loadMore = function(){
		$scope.page ++;
		$scope.getMessages();
	}

	$scope.postMessage = function() {
		var payload = {
			endpoint: 'messages',
			data: $scope.formData
		};

		$http({
	        method  : 'POST',
	        url     : 'resources/api.php',
	        data    : $.param(payload),
	        headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
	    }).success(function(e) {
	    	$scope.messages.unshift(e);
        });
	};
}]);<commit_msg>changed from absolute api path to relative<commit_after>  'use strict';

angular.module('sqwiggle-feed.system').controller('FeedController', ['$scope', '$http', function ($scope, $http) {
	$scope.messages = [];
	$scope.users = [];
	$scope.menuactive = false;
	$scope.page = 1;
	$scope.limit = 15;
	$scope.togglemenu = function(){
		$scope.menuactive = !$scope.menuactive;
	}
	$scope.getMessages = function() {
		$http.get('resources/api.php', {
    		params: {
    			endpoint: 'messages',
    			page: $scope.page,
    			limit: $scope.limit
    		},
    	}).success(function(e) {
    		for(var i in e) {
    			var message = e[i];
    			$scope.messages.push(message);
    		}
    	});
	}
	$scope.getUsers = function() {
		$http.get('resources/api.php', {
    		params: {
    			endpoint: 'users'
    		}

    	}).success(function(e) {
    		$scope.users = e;
    	});
	}
	$scope.loadMore = function(){
		$scope.page ++;
		$scope.getMessages();
	}

	$scope.postMessage = function() {
		var payload = {
			endpoint: 'messages',
			data: $scope.formData
		};

		$http({
	        method  : 'POST',
	        url     : 'resources/api.php',
	        data    : $.param(payload),
	        headers : { 'Content-Type': 'application/x-www-form-urlencoded' }  // set the headers so angular passing info as form data (not request payload)
	    }).success(function(e) {
	    	$scope.messages.unshift(e);
        });
	};
}]);<|endoftext|>


<commit_before>var Tarantula = require('tarantula'),
    fs = require('fs');

/*var start_page = 'https://wiki.piratenpartei.de/BE:Gebietsversammlungen/Friedrichshain-Kreuzberg/Antragsportal',
	path = '/BE:Gebietsversammlungen/Friedrichshain-Kreuzberg/Antragsportal/',
    event = 'GVFK2012.1';*/

var start_page = 'http://wiki.piratenpartei.de/BE:Gebietsversammlungen/Treptow-K%C3%B6penick/Antragsportal',
    path = '/BE:Gebietsversammlungen/Treptow-K%C3%B6penick/Antragsportal/',
    event = 'GVTK2013.1';

RegExp.quote = function(str) {
    return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
};

var Motion = function() {
    return {
        id: undefined,
        title: undefined,
        summary: undefined,
        text: undefined,
        topic: undefined,
        type: undefined,
        tags: undefined,
        url: undefined,
        remarks: undefined,
        author: undefined
    }
}

var motions = [],
    motionsIDs = [],
	brain = {

    politeness: 200,

    shouldVisit: function(uri) {
    	var re = new RegExp(RegExp.quote(path+event),"");
        return uri.match(re);
    },

    visit : function(request, response, body, $) {
        console.log(request.uri);
        if(request.uri != start_page) {
            var motion = new Motion(),
                idRegEx = new RegExp(RegExp.quote(event)+"\/(.*?)_","");

            motion.url = request.uri;
            match = request.uri.match(idRegEx);
            motion.id = match ? match[1] : 'fail';
            match = body.match(/\s*?[\s\S]*?<\/span><\/h3>\s*?
([\s\S]*?)\n<\/p>\s*?(?=
)/m);
            motion.title = match ? match[1] : 'fail';
            match = body.match(/\s*?[\s\S]*?<\/span><\/h3>\s*?
([\s\S]*?)\n<\/p>\s*?(?=
)/m);
            motion.author = match ? match[1] : 'fail';
            match = body.match(/\s*?[\s\S]*?<\/span><\/h3>\s*?
([\s\S]*?)\n<\/p>\s*?(?=
)/m);
            motion.type = match ? match[1] : 'fail';
            match = body.match(/\s*?[\s\S]*?<\/span><\/h3>\s*?
\n([\s\S]*?)?\n<\/div>\n\s*?(?=
)/m);
            motion.text = match ? match[1] : 'fail';
            console.log(motion.text);
            match = body.match(/\s*?[\s\S]*?<\/span><\/h3>\s*?([\s\S]*?)?\n\s*?(?=
)/m);
            motion.remarks = match ? match[1] : 'fail';

            if(motionsIDs.indexOf(motion.id) == -1) {
                motions.push(motion);
                motionsIDs.push(motion.id);
            }

        }
        //console.log(body);

        //var matches = body.match(/===(.*)===[\s\S]*?(.*)^==/);

    },

    debug: false
};

var tarantula = new Tarantula(brain);

tarantula.on('done', function() {
    console.log('done, found '+ motions.length + ' motions for #'+event);

    // export as json
    var json = JSON.stringify(motions);
    fs.writeFile('out/'+event+'-'+Math.floor(Date.now() / 1000)+'.json', json, function(err) {
    if(err) {
        console.log(err);
    } else {
        console.log("The file was saved!");
    }
});

});

tarantula.start([start_page]);<commit_msg>extrude config<commit_after>var Tarantula = require('tarantula'),
    fs = require('fs');

/* helper */

RegExp.quote = function(str) {
    str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
    str.replace(/\s/g, "\\s");
    str.replace(/\S/g, "\\S");
    str.replace(/\n/g, "\\n");
    return str;
};

/* config */

/*var start_page = 'https://wiki.piratenpartei.de/BE:Gebietsversammlungen/Friedrichshain-Kreuzberg/Antragsportal',
	path = '/BE:Gebietsversammlungen/Friedrichshain-Kreuzberg/Antragsportal/',
    event = 'GVFK2012.1';*/

var start_page = 'http://wiki.piratenpartei.de/BE:Gebietsversammlungen/Treptow-K%C3%B6penick/Antragsportal',
    path = '/BE:Gebietsversammlungen/Treptow-K%C3%B6penick/Antragsportal/',
    event = 'GVTK2013.1',
    regexID         = RegExp.quote(event)+"\/(.*?)_",
    regexTitle      = '\\s*?[\\s\\S]*?
\\s*?
([\\s\\S]*?)\\n
\\s*?(?=
)',
    regexAuthor     = '\\s*?[\\s\\S]*?
\\s*?
([\\s\\S]*?)\\n
\\s*?(?=
)',
    regexType       = '\\s*?[\\s\\S]*?
\\s*?
([\\s\\S]*?)\\n
\\s*?(?=
)',
    regexText       = '\\s*?[\\s\\S]*?
\\s*?
\\n([\\s\\S]*?)?\\n
\\n\\s*?(?=
)',
    regexRemarks    = '\\s*?[\\s\\S]*?
\\s*?([\\s\\S]*?)?\\n\\s*?(?=
)';

var Motion = function() {
    return {
        id: undefined,
        title: undefined,
        summary: undefined,
        text: undefined,
        topic: undefined,
        type: undefined,
        tags: undefined,
        url: undefined,
        remarks: undefined,
        author: undefined
    };
};

var motions = [],
    motionsIDs = [],
	brain = {

    politeness: 200,

    shouldVisit: function(uri) {
    	var re = new RegExp(RegExp.quote(path+event), "");
        return uri.match(re);
    },

    visit : function(request, response, body, $) {
        console.log(request.uri);
        if(request.uri != start_page) {
            var motion = new Motion(),
                idRegEx = new RegExp(regexID, "");

            motion.url = request.uri;
            match = request.uri.match(idRegEx);
            motion.id = match ? match[1] : 'fail';

            match = body.match(new RegExp(RegExp.quote(regexTitle), 'm'));
            motion.title = match ? match[1] : 'fail';

            match = body.match(new RegExp(regexAuthor, 'm'));
            motion.author = match ? match[1] : 'fail';

            match = body.match(new RegExp(regexType, 'm'));
            motion.type = match ? match[1] : 'fail';

            match = body.match(new RegExp(regexText, 'm'));
            motion.text = match ? match[1] : 'fail';

            match = body.match(new RegExp(regexRemarks, 'm'));
            motion.remarks = match ? match[1] : 'fail';

            if(motionsIDs.indexOf(motion.id) == -1) {
                motions.push(motion);
                motionsIDs.push(motion.id);
                console.log(motion);
            }

        }

    },

    debug: false
};

var tarantula = new Tarantula(brain);

tarantula.on('done', function() {
    console.log('done, found '+ motions.length + ' motions for #'+event);

    // export as json
    var json = JSON.stringify(motions);
    fs.writeFile('out/'+event+'-'+Math.floor(Date.now() / 1000)+'.json', json, function(err) {
    if(err) {
        console.log(err);
    } else {
        console.log("The file was saved!");
    }
});

});

tarantula.start([start_page]);<|endoftext|>


<commit_before>/*global
  $, async, debug, cog
*/

(function(window, document) {

  var log = debug('cog-web:page:history');
  var submit = $('button#submit').ladda();

  var uuid = null;
  var admin = false;

  $(document).ready(function() {
    log('page initialization process started');
    var select = $('select#assignment');

    async.waterfall([
      function(callback) {
        log('requesting unique identifier for current session from server');
        cog.getMyUniqueId(function(err, data) {
          callback(err, data.useruuid);
        });
      }, function(uuid, callback) {
        log('requesting user administrator state from server');
        cog.getMyIsadmin(function(err, data) {
          callback(err, { uuid, admin: data.isadmin });
        });
      }
    ], function(err, result) {
      uuid = result.uuid;
      admin = result.admin;

      if (admin) {
        log('user identified as administrator, showing `user` form field');
        $('#form_user').slideDown(300);

        // this field will cause errors if it marked `required` when hidden
        $('select#user').prop('required', true);
      }

      // fetch all the submittable assignments from the server
      cog.getAssignmentsSubmittable(function(err, data) {
        // now we have an array of assignment UUIDs
        var assignments = data.assignments;
        log('loaded %d assignment identifier(s) from the server', assignments.length);

        // inform the user if no assignments can be currently submitted
        if (!assignments.length) {
          var option = $('<option>').text('No Assignments Available');
          // only on initial load, no empty required
          select.append(option);
          return;
        }

        log('fetching metadata for individual assignments');
        async.map(assignments, cog.getAssignment.bind(cog), function(err, results) {
          log('received all assignment metadata from server');

          // after receiving all the assignment objects, clear the selector
          select.empty();
          log('populating assignment listing with received entries');
          populateAssignmentList(results);
        });
      });

    });
  });

  $('select#assignment').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();

    var select = $('select#test');
    var users = $('select#user');

    log('assignment selector changed to `%s` (%s)', text, uuid.substring(0, 8));
    cog.getAssignmentTests(uuid, function(err, data) {
      // array of test UUIDs
      var tests = data.tests;

      log('loaded %d test options for assignment `%s`', tests.length, text);

      // inform the user if no tests are available
      if (!tests.length) {
        var option = $('<option>').text('No Tests Available');
        // empty previous assignment selection
        select.empty();
        select.append(option);
        // disable the test selector
        select.prop('disabled', true);

        // empty all previously loaded usernames
        users.empty();
        // disable the user selector
        users.prop('disabled', true);

        // remove the max score, as there is no specified test
        $('span#max_score').text(0);
        // disable the submit button
        $('button#submit').prop('disabled', true);
        return;
      }

      log('fetching metadata for individual tests');
      async.map(tests, cog.getTest.bind(cog), function(err, results) {
        log('received all test metadata from server');

        // after receiving all the test objects, clear the selector
        select.empty();
        log('populating test listing with received entries');
        populateTestList(results);
      });
    });
  });

  $('select#test').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();
    log('test selector changed to `%s` (%s)', text, uuid.substring(0, 8));

    cog.getTest(uuid, function(err, data) {
      var keys = Object.keys(data);
      var uuid = keys[0];
      var test = data[uuid];

      // update the maximum possible score indicator
      $('span#max_score').text(test.maxscore);
      // enable the submit button
      $('button#submit').prop('disabled', false);

      // for non-administrators, stop execution here
      if (!admin) {
      	// if(util.getHashParameter('search')) $("#submitform").submit();
      	return;
      }
      log('current user is of type administrator, loading usernames');

      cog.getUsersNamelist(function(err, data) {
        var usernames = data.usernames;
        var uuids = Object.keys(usernames);
        log('loaded %d username(s) from the server', uuids.length);

        populateUserList(usernames);
      });

    });
  });

  $('select#user').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();
    log('user selector changed to `%s` (%s)', text, uuid.substring(0, 8));
	if(util.getHashParameter('search')) $("#submitform").submit();
  });

  $('form#submitform').submit(function(event) {
    event.preventDefault();

    // start the loading ticker and indicate that a search is in progress
    submit.ladda('start');
    $('button#submit').children('span.ladda-label').html('Searching...');

    var assignment = $('select#assignment').val();
    var user = $('select#user').val();

    // lock all form fields
    $('select#assignment').prop('disabled', true);
    $('select#test').prop('disabled', true);
    $('select#user').prop('disabled', true);

    // clear all entries loaded from previous queries
    $('#history-table tbody tr').remove();

    var getAssignmentSubmissions = admin ? cog.getUserAssignmentSubmissions.bind(cog, user)
                                         : cog.getMyAssignmentSubmissions.bind(cog);
    var getSubmissionRuns = admin ? cog.getUserSubmissionRuns.bind(cog, user)
                                  : cog.getMySubmissionRuns.bind(cog);

    if (admin) {
      log('currently viewing runs as administrator for user: `%s`', user.substring(0, 8));
    }

    log('requesting assignment submissions for assignment: %s', assignment.substring(0, 8));
    getAssignmentSubmissions(assignment, function(err, data) {
      // array of submission UUIDs
      var submissions = data.submissions;

      log('received %d submissions for assignment `%s`', submissions.length, assignment.substring(0, 8));

      if (!submissions.length) {
        submit.ladda('stop');
        $('button#submit').children('span.ladda-label').html('Search');

        $('select#assignment').prop('disabled', false);
        $('select#test').prop('disabled', false);
        $('select#user').prop('disabled', false);
        return;
      }

      log('fetching run listings for individual submissions (%d total)', submissions.length);
      async.map(submissions, getSubmissionRuns, function(err, results) {
        log('received all submission run listings from server');

        log('flattening all runs into single listing');
        var filter = results.filter(function(entry) {
          return entry.runs.length > 0;
        }).map(function(entry) {
          return entry.runs;
        });

        var runs = [].concat.apply([], filter);

        log('fetching metadata for individual run entries (%d total)', runs.length);
        async.map(runs, cog.getRun.bind(cog), function(err, results) {
          log('received all test metadata from server (took %s requests)', submissions.length + runs.length);

          // filter submissions by test UUID
          // this should really be done on the server side, but it's not
          var test = $('select#test').val();
          results = results.filter(function(entry) {
            var key = Object.keys(entry)[0];
            return entry[key].test === test;
          });

          log('populating results table with received entries');
          populateResultTable(results);
        });
      });

    });
  });

  function populateAssignmentList(list) {
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];
      var option = $('<option>', { value: uuid }).text(meta.name);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#assignment');
    select.html(str);
    select.prop('disabled', false);

    // select the last entry, as per old behavior
    // select.find('option:last').attr('selected', 'selected');
    // select.val(select.children('option:last').val());
    var asn_uuid = util.getHashParameter('asn');
    log('attempting to fetch run result record for %s', asn_uuid);

    if (asn_uuid == null) {
    	select.val(select.children('option:last').val());
    }
    else {
	    select.val(asn_uuid);
    }
    select.change();
  }

  function populateTestList(list) {
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];
      var option = $('<option>', { value: uuid }).text(meta.name);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#test');
    select.html(str);
    select.prop('disabled', false);

    // select the last entry (assumed most recent)
    select.val(select.children('option:last').val());
    var tst_uuid = util.getHashParameter('tst');

    if (tst_uuid == null) {
    	select.val(select.children('option:last').val());
    }
    else {
		select.val(tst_uuid);
		if(select.val() == null) {
			select.val(select.children('option:last').val());
		}
    }
    select.change();
  }

  function populateUserList(map) {
    var elements = [];

    Object.keys(map).forEach(function(uuid) {
      var username = map[uuid];
      var option = $('<option>', { value: uuid }).text(username);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#user');
    select.html(str);
    select.prop('disabled', false);

    // select the currently logged in user
    var usr_uuid = util.getHashParameter('usr');
    log('attempting to fetch run result record for %s', usr_uuid);

    if (usr_uuid == null) {
    	select.val(uuid);
    }
    else {
	    select.val(usr_uuid);
    }
    select.change();
  }

  function populateResultTable(list) {
  	location.hash = "asn=" + $('select#assignment').val() + "&tst=" +
  					 $('select#test').val() + "&usr=" + $('select#user').val()
  					 + "&search=1";
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];

      elements.push({
        uuid,
        submission: meta.submission,
        assignment: meta.assignment,
        mtime: new Date(meta.modified_time * 1000),
        score: meta.score,
        status: meta.status,
        retcode: meta.retcode
      });
    });

    elements.sort(function(a, b) {
      return a.mtime - b.mtime;
    });

    var colors = {
      success: 'text-success',
      warning: 'text-warning',
      exception: 'text-danger',
      error: 'text-danger'
    };

    var str = elements.map(function(ele) {
      var submission = 'Submission';
      var run = 'Run';

      var sub = ele.status.split('-');
      var color = (sub.length > 1) ? colors[sub[1]] : colors.success;

      return [
        '
' + ele.mtime.toLocaleString() + '	',
        '' + ele.score + '	',
        '' + ele.retcode + '	',
        '' + ele.status + '	',
        '' + submission + ' or ' + run + '
'
      ].join('');
    }).join('');

    $('#history-table').append(str);
    submit.ladda('stop');
    $('button#submit').children('span.ladda-label').html('Search');

    $('select#assignment').prop('disabled', false);
    $('select#test').prop('disabled', false);
    $('select#user').prop('disabled', false);
  }

})(window, document);
<commit_msg>Fix hash attribute linking.<commit_after>/*global
  $, async, debug, cog, util
*/

(function(window, document) {

  var log = debug('cog-web:page:history');
  var submit = $('button#submit').ladda();

  var uuid = null;
  var admin = false;

  $(document).ready(function() {
    log('page initialization process started');
    var select = $('select#assignment');

    async.waterfall([
      function(callback) {
        log('requesting unique identifier for current session from server');
        cog.getMyUniqueId(function(err, data) {
          callback(err, data.useruuid);
        });
      }, function(uuid, callback) {
        log('requesting user administrator state from server');
        cog.getMyIsadmin(function(err, data) {
          callback(err, { uuid, admin: data.isadmin });
        });
      }
    ], function(err, result) {
      uuid = result.uuid;
      admin = result.admin;

      if (admin) {
        log('user identified as administrator, showing `user` form field');
        $('#form_user').slideDown(300);

        // this field will cause errors if it marked `required` when hidden
        $('select#user').prop('required', true);
      }

      // fetch all the submittable assignments from the server
      cog.getAssignmentsSubmittable(function(err, data) {
        // now we have an array of assignment UUIDs
        var assignments = data.assignments;
        log('loaded %d assignment identifier(s) from the server', assignments.length);

        // inform the user if no assignments can be currently submitted
        if (!assignments.length) {
          var option = $('<option>').text('No Assignments Available');
          // only on initial load, no empty required
          select.append(option);
          return;
        }

        log('fetching metadata for individual assignments');
        async.map(assignments, cog.getAssignment.bind(cog), function(err, results) {
          log('received all assignment metadata from server');

          // after receiving all the assignment objects, clear the selector
          select.empty();
          log('populating assignment listing with received entries');
          populateAssignmentList(results);
        });
      });

    });
  });

  $('select#assignment').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();

    var select = $('select#test');
    var users = $('select#user');

    log('assignment selector changed to `%s` (%s)', text, uuid.substring(0, 8));
    cog.getAssignmentTests(uuid, function(err, data) {
      // array of test UUIDs
      var tests = data.tests;

      log('loaded %d test options for assignment `%s`', tests.length, text);

      // inform the user if no tests are available
      if (!tests.length) {
        var option = $('<option>').text('No Tests Available');
        // empty previous assignment selection
        select.empty();
        select.append(option);
        // disable the test selector
        select.prop('disabled', true);

        // empty all previously loaded usernames
        users.empty();
        // disable the user selector
        users.prop('disabled', true);

        // remove the max score, as there is no specified test
        $('span#max_score').text(0);
        // disable the submit button
        $('button#submit').prop('disabled', true);
        return;
      }

      log('fetching metadata for individual tests');
      async.map(tests, cog.getTest.bind(cog), function(err, results) {
        log('received all test metadata from server');

        // after receiving all the test objects, clear the selector
        select.empty();
        log('populating test listing with received entries');
        populateTestList(results);
      });
    });
  });

  $('select#test').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();
    log('test selector changed to `%s` (%s)', text, uuid.substring(0, 8));

    cog.getTest(uuid, function(err, data) {
      var keys = Object.keys(data);
      var uuid = keys[0];
      var test = data[uuid];

      // update the maximum possible score indicator
      $('span#max_score').text(test.maxscore);
      // enable the submit button
      $('button#submit').prop('disabled', false);

      // for non-administrators, stop execution here
      if (!admin) return;
      log('current user is of type administrator, loading usernames');

      cog.getUsersNamelist(function(err, data) {
        var usernames = data.usernames;
        var uuids = Object.keys(usernames);
        log('loaded %d username(s) from the server', uuids.length);

        populateUserList(usernames);
      });

    });
  });

  $('select#user').change(function() {
    var sel = $(this).find(':selected');
    var uuid = sel.val();
    var text = sel.text();
    log('user selector changed to `%s` (%s)', text, uuid.substring(0, 8));
  });

  $('form#submitform').submit(function(event) {
    event.preventDefault();

    // start the loading ticker and indicate that a search is in progress
    submit.ladda('start');
    $('button#submit').children('span.ladda-label').html('Searching...');

    var assignment = $('select#assignment').val();
    var test = $('select#test').val();
    var user = $('select#user').val();

    // create a attribute link for this search
    var hash = 'asn=' + assignment + '&tst=' + test + '&usr=' + user + '&search=1';
    window.location.hash = hash;

    // lock all form fields
    $('select#assignment').prop('disabled', true);
    $('select#test').prop('disabled', true);
    $('select#user').prop('disabled', true);

    // clear all entries loaded from previous queries
    $('#history-table tbody tr').remove();

    var getAssignmentSubmissions = admin ? cog.getUserAssignmentSubmissions.bind(cog, user)
                                         : cog.getMyAssignmentSubmissions.bind(cog);
    var getSubmissionRuns = admin ? cog.getUserSubmissionRuns.bind(cog, user)
                                  : cog.getMySubmissionRuns.bind(cog);

    if (admin) {
      log('currently viewing runs as administrator for user: `%s`', user.substring(0, 8));
    }

    log('requesting assignment submissions for assignment: %s', assignment.substring(0, 8));
    getAssignmentSubmissions(assignment, function(err, data) {
      // array of submission UUIDs
      var submissions = data.submissions;

      log('received %d submissions for assignment `%s`', submissions.length, assignment.substring(0, 8));

      if (!submissions.length) {
        submit.ladda('stop');
        $('button#submit').children('span.ladda-label').html('Search');

        $('select#assignment').prop('disabled', false);
        $('select#test').prop('disabled', false);
        $('select#user').prop('disabled', false);
        return;
      }

      log('fetching run listings for individual submissions (%d total)', submissions.length);
      async.map(submissions, getSubmissionRuns, function(err, results) {
        log('received all submission run listings from server');

        log('flattening all runs into single listing');
        var filter = results.filter(function(entry) {
          return entry.runs.length > 0;
        }).map(function(entry) {
          return entry.runs;
        });

        var runs = [].concat.apply([], filter);

        log('fetching metadata for individual run entries (%d total)', runs.length);
        async.map(runs, cog.getRun.bind(cog), function(err, results) {
          log('received all test metadata from server (took %s requests)', submissions.length + runs.length);

          // filter submissions by test UUID
          // this should really be done on the server side, but it's not
          var test = $('select#test').val();
          results = results.filter(function(entry) {
            var key = Object.keys(entry)[0];
            return entry[key].test === test;
          });

          log('populating results table with received entries');
          populateResultTable(results);
        });
      });

    });
  });

  function populateAssignmentList(list) {
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];
      var option = $('<option>', { value: uuid }).text(meta.name);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#assignment');
    select.html(str);
    select.prop('disabled', false);

    // select the last entry, as per old behavior
    // select.find('option:last').attr('selected', 'selected');
    // select.val(select.children('option:last').val());

    log('attempting to fetch run result record for %s', asn);
    // use the hash parameter if it's given
    var asn = util.getHashParameter('asn') || select.children('option:last').val();
    select.val(asn);
    select.change();
  }

  function populateTestList(list) {
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];
      var option = $('<option>', { value: uuid }).text(meta.name);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#test');
    select.html(str);
    select.prop('disabled', false);

    // select the last entry (assumed most recent)
    // select.val(select.children('option:last').val());

    // use the hash parameter if provided, otherwise use the last one
    var test = util.getHashParameter('tst') || select.children('option:last').val();
    select.val(test);
    select.change();
  }

  function populateUserList(map) {
    var elements = [];

    Object.keys(map).forEach(function(uuid) {
      var username = map[uuid];
      var option = $('<option>', { value: uuid }).text(username);
      elements.push(option);
    });

    elements.sort(function(a, b) {
      var c = a.text().toLowerCase();
      var d = b.text().toLowerCase();

      if (c < d) return -1;
      if (c > d) return 1;
      return 0;
    });

    var str = elements.map(function(ele) {
      return ele.prop('outerHTML');
    }).join('');

    var select = $('select#user');
    select.html(str);
    select.prop('disabled', false);

    // select the currently logged in user, or as specified by hash
    var usr = util.getHashParameter('usr') || uuid;
    log('attempting to fetch run result record for %s', usr);

    select.val(usr);
    select.change();

    // if the search attribute is set, submit immediately
    if (util.getHashParameter('search') == 1) $('#submit').click();
  }

  function populateResultTable(list) {
    var elements = [];

    list.forEach(function(entry) {
      var uuid = Object.keys(entry)[0];
      var meta = entry[uuid];

      elements.push({
        uuid,
        submission: meta.submission,
        assignment: meta.assignment,
        mtime: new Date(meta.modified_time * 1000),
        score: meta.score,
        status: meta.status,
        retcode: meta.retcode
      });
    });

    elements.sort(function(a, b) {
      return a.mtime - b.mtime;
    });

    var colors = {
      success: 'text-success',
      warning: 'text-warning',
      exception: 'text-danger',
      error: 'text-danger'
    };

    var str = elements.map(function(ele) {
      var submission = 'Submission';
      var run = 'Run';

      var sub = ele.status.split('-');
      var color = (sub.length > 1) ? colors[sub[1]] : colors.success;

      return [
        '
' + ele.mtime.toLocaleString() + '	',
        '' + ele.score + '	',
        '' + ele.retcode + '	',
        '' + ele.status + '	',
        '' + submission + ' or ' + run + '
'
      ].join('');
    }).join('');

    $('#history-table').append(str);
    submit.ladda('stop');
    $('button#submit').children('span.ladda-label').html('Search');

    $('select#assignment').prop('disabled', false);
    $('select#test').prop('disabled', false);
    $('select#user').prop('disabled', false);
  }

})(window, document);
<|endoftext|>