<commit_before>define([
	'jquery',
	'gizmo/superdesk'
], function($, Gizmo) {
    return Gizmo.Collection.extend({
		_timeInterval: 10000,
		_idInterval: 0,
		_stats: {},
		/*!
		 * for auto refresh
		 */
		keep: false,
		init: function(){
			this.autoInit();
		},
		resetStats: function() {
			this._stats = { limit: 2, offset: 0, lastCId: 0, fistOrder: Infinity, total: 0 };
		},
		autoInit: function(){
			var self = this;
			self.resetStats();
			self.model.on('unpublish publish reorder', function(evt, post){
				if((self._stats.lastCId + 1) === parseInt(post.get('CId')))
					self._stats.lastCId++;
			});
			self.on('readauto', function(evt, data, attr){
				// set offset to limit
				self._stats.offset = self._stats.limit;
				// set total from the attributes
				self._stats.total = parseInt(attr.total);
				attr.lastCId = parseInt(attr.lastCId);
				if(attr.lastCId > self._stats.lastCId)
					self._stats.lastCId = attr.lastCId;
			}).on('readauto updateauto update removeingsauto',function(evt, data)
			{
				self.getLastCid(data);
				self.getFirstOrder(data);
			}).on('addingsauto', function(evt, data){
				/*!
				 * If addings ( from getting the auto updates )
				 *   receive we need to increase the total count of the posts and the offset
				 *   with the numbers of posts added
				 */
				self._stats.total += data.length;
				self._stats.offset += data.length;

			}).on('removeingsauto', function(evt, data){
				/*!
				 * If removeings from the collection ( from getting the autou pdates )
				 *   receive we need to decrease the total and the offset for the next page
				 *   with the numbers of posts added
				 */
				self._stats.total -= data.length;
				self._stats.offset -= data.length;

			}).on('addings', function(evt, data){
				/*!
				 * If addings ( from getting the next page )
				 *   receive we need to increase the offset for the next page
				 *   with the numbers of posts added
				 */
				self._stats.offset += data.length;
			});
		},
		destroy: function(){ this.stop(); },
		auto: function(params)
		{
			var self = this;
			ret = this.stop().start(params);
			this._idInterval = setInterval(function(){
				if(self.keepPolling()) {
					self.start(params);
				} else {
					self.stop();
				}
			}, this._timeInterval);
			return ret;
		},
		keepPolling: function(){
			return true;
		},
		start: function(params)
		{
			var self = this;
			params = params || {};
			requestOptions = $.extend(true, {
				data: {'cId.since': this._stats.lastCId, 'order.start': self._stats.fistOrder },
				headers: { 'X-Filter': 'CId, Order, IsPublished, DeletedOn'}
			},params);
			if(self._stats.lastCId === 0) {
				delete requestOptions.data['cId.since'];
			}
			if(self._stats.fistOrder === Infinity) {
				delete requestOptions.data['order.start'];
			}
			if(!this.keep && self.view && !self.view.checkElement())
			{
				self.stop();
				return;
			}
			this.triggerHandler('beforeUpdate');
			return this.autosync(requestOptions);
		},
		stop: function()
		{
			var self = this;
			clearInterval(self._idInterval);
			return this;
		},
		/*!
		 * Get the minim Order value from the post list received.
		 */
		getFirstOrder: function(data)
		{
			for(var i=0, Order, count=data.length; i<count; i++) {
				Order = parseFloat(data[i].get('Order'))
				if( !isNaN(Order) && (this._stats.fistOrder > Order) )
					this._stats.fistOrder = Order;
			}
		},
		/*!
		 * Get the maximum CId value from the post list received.
		 */
		getLastCid: function(data)
		{
			for(var i=0, CId, count=data.length; i<count; i++) {
				var CId = parseInt(data[i].get('CId'))
				//console.log(CId);
				if( !isNaN(CId) && (this._stats.lastCId < CId) )
					this._stats.lastCId = CId;
			}
		},
		autosync: function()
		{
		var self = this;
		return (this.href &&
			this.syncAdapter.request.call(this.syncAdapter, this.href).read(arguments[0]).done(function(data)
			{
				var attr = self.parseAttributes(data), list = self._parse(data), changeset = [], removeings = [], updates = [], addings = [], count = self._list.length;
				// important or it will infiloop
				for( var i=0; i < list.length; i++ )
				{
					var model = false;
					for( var j=0; j<count; j++ ) {
						if( list[i].hash() == self._list[j].hash() )
						{
							model = list[i];
							break;
						}
					}
					if( !model ) {
						//console.log('is model');
						if(self.isCollectionDeleted(list[i])) {
							//console.log('is collection deleted');
							self._list.splice(j,1);
							if( self.hasEvent('removeingsauto') ) {
								removeings.push(list[i]);
							}

						} else if( !list[i].isDeleted() ) {
							//console.log('is not deleted')
							self._list.push(list[i]);
							changeset.push(list[i]);
							if( self.hasEvent('addingsauto') ) {
								addings.push(list[i]);
							}
						} else {
							//console.log('is updated1');
							if( self.hasEvent('updatesauto') ) {
								updates.push(list[i]);
							}
						}
					}
					else {
						if( self.hasEvent('updatesauto') ) {
							//console.log('has event');
							updates.push(model);
						}
						if(self.isCollectionDeleted(model)) {
							self._list.splice(j,1);
							if( self.hasEvent('removeingsauto') ) {
								removeings.push(model);
							}

						} else {
							//console.log('model.isChanged: ',model.isChanged());
							if( model.isDeleted()) {
								model._remove();
							}
							/**
							 * @TODO: remove this dirty hack and find the real problem
							 * 		why is the model not seen as changed after un unpublish
							 * secenarion: admin unpublish an collab1 post the collab1(admin) is republishing the post.
							 */
							else/* if( model.isChanged() )*/{
								changeset.push(model);
							}/*
							else {
								model.on('delete', function(){ self.remove(this.hash()); })
										.on('garbage', function(){ this.desynced = true; });
							}*/
						}
					}
				}
				self.desynced = false;
				/**
				 * If the initial data is empty then trigger READ event
				 * else UPDATE with the changeset if there are some
				 */
				if( ( count === 0) ){
					//console.log('readauto');

					self.triggerHandler('readauto',[self._list,attr]);
				} else {
					/**
					 * Trigger handler with changeset extraparameter as a vector of vectors,
					 * caz jquery will send extraparameters as arguments when calling handler
					 */
					if( updates.length && self.hasEvent('updatesauto') ) {
						self.triggerHandler('updatesauto', [updates,attr]);
					}
					if( addings.length && self.hasEvent('addingsauto') ) {
						self.triggerHandler('addingsauto', [addings,attr]);
					}
					if( removeings.length && self.hasEvent('removeingsauto') ) {
						self.triggerHandler('removeingsauto', [removeings,attr]);
					}
					self.triggerHandler('updateauto', [changeset,attr]);
				}
			}));
		}
	}, { register: 'AutoCollection' } );
});<commit_msg>LB-1163: As an editor, I want to filter posts on chained blog source by verification status and assigned user<commit_after>define([
	'jquery',
	'gizmo/superdesk'
], function($, Gizmo) {
    return Gizmo.Collection.extend({
		_timeInterval: 10000,
		_idInterval: 0,
		_stats: {},
		/*!
		 * for auto refresh
		 */
		keep: false,
		init: function(){
			this.autoInit();
		},
		resetStats: function() {
			this._stats = { limit: 15, offset: 0, lastCId: 0, fistOrder: Infinity, total: 0 };
		},
		autoInit: function(){
			var self = this;
			self.resetStats();
			self.model.on('unpublish publish reorder', function(evt, post){
				if((self._stats.lastCId + 1) === parseInt(post.get('CId')))
					self._stats.lastCId++;
			});
			self.on('readauto', function(evt, data, attr){
				// set offset to limit
				self._stats.offset = self._stats.limit;
				// set total from the attributes
				self._stats.total = parseInt(attr.total);
				attr.lastCId = parseInt(attr.lastCId);
				if(attr.lastCId > self._stats.lastCId)
					self._stats.lastCId = attr.lastCId;
			}).on('readauto updateauto update removeingsauto',function(evt, data)
			{
				self.getLastCid(data);
				self.getFirstOrder(data);
			}).on('addingsauto', function(evt, data){
				/*!
				 * If addings ( from getting the auto updates )
				 *   receive we need to increase the total count of the posts and the offset
				 *   with the numbers of posts added
				 */
				self._stats.total += data.length;
				self._stats.offset += data.length;

			}).on('removeingsauto', function(evt, data){
				/*!
				 * If removeings from the collection ( from getting the autou pdates )
				 *   receive we need to decrease the total and the offset for the next page
				 *   with the numbers of posts added
				 */
				self._stats.total -= data.length;
				self._stats.offset -= data.length;

			}).on('addings', function(evt, data){
				/*!
				 * If addings ( from getting the next page )
				 *   receive we need to increase the offset for the next page
				 *   with the numbers of posts added
				 */
				self._stats.offset += data.length;
			});
		},
		destroy: function(){ this.stop(); },
		auto: function(params)
		{
			var self = this;
			ret = this.stop().start(params);
			this._idInterval = setInterval(function(){
				if(self.keepPolling()) {
					self.start(params);
				} else {
					self.stop();
				}
			}, this._timeInterval);
			return ret;
		},
		keepPolling: function(){
			return true;
		},
		start: function(params)
		{
			var self = this;
			params = params || {};
			requestOptions = $.extend(true, {
				data: {'cId.since': this._stats.lastCId, 'order.start': self._stats.fistOrder },
				headers: { 'X-Filter': 'CId, Order, IsPublished, DeletedOn'}
			},params);
			if(self._stats.lastCId === 0) {
				delete requestOptions.data['cId.since'];
			}
			if(self._stats.fistOrder === Infinity) {
				delete requestOptions.data['order.start'];
			}
			if(!this.keep && self.view && !self.view.checkElement())
			{
				self.stop();
				return;
			}
			this.triggerHandler('beforeUpdate');
			return this.autosync(requestOptions);
		},
		stop: function()
		{
			var self = this;
			clearInterval(self._idInterval);
			return this;
		},
		/*!
		 * Get the minim Order value from the post list received.
		 */
		getFirstOrder: function(data)
		{
			for(var i=0, Order, count=data.length; i<count; i++) {
				Order = parseFloat(data[i].get('Order'))
				if( !isNaN(Order) && (this._stats.fistOrder > Order) )
					this._stats.fistOrder = Order;
			}
		},
		/*!
		 * Get the maximum CId value from the post list received.
		 */
		getLastCid: function(data)
		{
			for(var i=0, CId, count=data.length; i<count; i++) {
				var CId = parseInt(data[i].get('CId'))
				//console.log(CId);
				if( !isNaN(CId) && (this._stats.lastCId < CId) )
					this._stats.lastCId = CId;
			}
		},
		autosync: function()
		{
		var self = this;
		return (this.href &&
			this.syncAdapter.request.call(this.syncAdapter, this.href).read(arguments[0]).done(function(data)
			{
				var attr = self.parseAttributes(data), list = self._parse(data), changeset = [], removeings = [], updates = [], addings = [], count = self._list.length;
				// important or it will infiloop
				for( var i=0; i < list.length; i++ )
				{
					var model = false;
					for( var j=0; j<count; j++ ) {
						if( list[i].hash() == self._list[j].hash() )
						{
							model = list[i];
							break;
						}
					}
					if( !model ) {
						//console.log('is model');
						if(self.isCollectionDeleted(list[i])) {
							//console.log('is collection deleted');
							self._list.splice(j,1);
							if( self.hasEvent('removeingsauto') ) {
								removeings.push(list[i]);
							}

						} else if( !list[i].isDeleted() ) {
							//console.log('is not deleted')
							self._list.push(list[i]);
							changeset.push(list[i]);
							if( self.hasEvent('addingsauto') ) {
								addings.push(list[i]);
							}
						} else {
							//console.log('is updated1');
							if( self.hasEvent('updatesauto') ) {
								updates.push(list[i]);
							}
						}
					}
					else {
						if( self.hasEvent('updatesauto') ) {
							//console.log('has event');
							updates.push(model);
						}
						if(self.isCollectionDeleted(model)) {
							self._list.splice(j,1);
							if( self.hasEvent('removeingsauto') ) {
								removeings.push(model);
							}

						} else {
							//console.log('model.isChanged: ',model.isChanged());
							if( model.isDeleted()) {
								model._remove();
							}
							/**
							 * @TODO: remove this dirty hack and find the real problem
							 * 		why is the model not seen as changed after un unpublish
							 * secenarion: admin unpublish an collab1 post the collab1(admin) is republishing the post.
							 */
							else/* if( model.isChanged() )*/{
								changeset.push(model);
							}/*
							else {
								model.on('delete', function(){ self.remove(this.hash()); })
										.on('garbage', function(){ this.desynced = true; });
							}*/
						}
					}
				}
				self.desynced = false;
				/**
				 * If the initial data is empty then trigger READ event
				 * else UPDATE with the changeset if there are some
				 */
				if( ( count === 0) ){
					//console.log('readauto');

					self.triggerHandler('readauto',[self._list,attr]);
				} else {
					/**
					 * Trigger handler with changeset extraparameter as a vector of vectors,
					 * caz jquery will send extraparameters as arguments when calling handler
					 */
					if( updates.length && self.hasEvent('updatesauto') ) {
						self.triggerHandler('updatesauto', [updates,attr]);
					}
					if( addings.length && self.hasEvent('addingsauto') ) {
						self.triggerHandler('addingsauto', [addings,attr]);
					}
					if( removeings.length && self.hasEvent('removeingsauto') ) {
						self.triggerHandler('removeingsauto', [removeings,attr]);
					}
					self.triggerHandler('updateauto', [changeset,attr]);
				}
			}));
		}
	}, { register: 'AutoCollection' } );
});<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Relay from 'react-relay/classic';
import AboutRoute from '../relay/AboutRoute';

class LanguageSelectorComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    const { project } = this.props;
    const supportedLanguages = JSON.parse(this.props.about.languages_supported);
    const projectLanguages = project.get_languages
      ? JSON.parse(project.get_languages)
      : null;
    if (!projectLanguages) {
      return null;
    }
    return (
      <select onChange={this.props.onChange} defaultValue={this.props.selected}>
        {projectLanguages.map(code =>
          (<option key={code} value={code}>{supportedLanguages[code]}</option>))}
      </select>
    );
  }
}

const LanguageSelectorContainer = Relay.createContainer(LanguageSelectorComponent, {
  fragments: {
    about: () => Relay.QL`
      fragment on About {
        languages_supported
      }
    `,
  },
});

const LanguageSelector = (props) => {
  const route = new AboutRoute();
  return (
    <Relay.RootContainer
      Component={LanguageSelectorContainer}
      route={route}
      renderFetched={data => <LanguageSelectorContainer {...props} {...data} />}
    />
  );
};

export default LanguageSelector;
<commit_msg>Show all languages with project languages at the top<commit_after>import React, { Component } from 'react';
import Relay from 'react-relay/classic';
import AboutRoute from '../relay/AboutRoute';

class LanguageSelectorComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    const { project } = this.props;
    const supportedLanguages = JSON.parse(this.props.about.languages_supported);
    const projectLanguages = project.get_languages
      ? JSON.parse(project.get_languages)
      : null;
    return (
      <select onChange={this.props.onChange} defaultValue={this.props.selected}>
        {(projectLanguages ?
          (projectLanguages.map(code =>
            (<option key={code} value={code}>{supportedLanguages[code]}</option>))
            .concat(<option key="disabled" disabled>──────────</option>))
          : [])
          .concat(Object.keys(supportedLanguages)
            .filter(code => !projectLanguages || !projectLanguages.includes(code))
            .map(code =>
              (<option key={code} value={code}>{supportedLanguages[code]}</option>)))}
      </select>
    );
  }
}

const LanguageSelectorContainer = Relay.createContainer(LanguageSelectorComponent, {
  fragments: {
    about: () => Relay.QL`
      fragment on About {
        languages_supported
      }
    `,
  },
});

const LanguageSelector = (props) => {
  const route = new AboutRoute();
  return (
    <Relay.RootContainer
      Component={LanguageSelectorContainer}
      route={route}
      renderFetched={data => <LanguageSelectorContainer {...props} {...data} />}
    />
  );
};

export default LanguageSelector;
<|endoftext|>


<commit_before>const assert = require("assert");
const CommandRunner = require("../commandrunner");
const MemoryLogger = require("../memorylogger");
const fs = require("fs-extra");

describe("truffle unbox", () => {
  let config;
  const logger = new MemoryLogger();

  beforeEach("set up config for logger", () => {
    config = { working_directory: `${process.cwd()}/test/sources/unbox` };
    config.logger = logger;
  });

  afterEach("clear working_directory", () => {
    fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
  });

  describe("when run without arguments", () => {
    it("unboxes truffle-init-default", done => {
      CommandRunner.run("unbox", config, () => {
        const output = logger.contents();
        assert(output.includes("Unbox successful."));
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/ConvertLib.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/Migrations.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/MetaCoin.sol`
          )
        );
        done();
      });
    }).timeout(20000);
  });

  describe("when run with arguments", () => {
    describe("valid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("full url", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch:path/to/subDir",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox truffle-box/bare-box", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("origin/master#branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master#branch:relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch:path/to/subDir",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("official truffle box", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare#truffle-test-branch", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox bare#truffle-test-branch:path/to/subDir",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("with an invalid git@ ssh", () => {
        it("logs an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch:path/to/subDir",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });
    });

    describe("with invalid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("invalid full url", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-boxing",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("invalid origin/master", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox truffle-box/bare-boxer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid official truffle box", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox barer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid git@ ssh", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("absolutePaths", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox bare:/path/to/subDir", config, () => {
            const output = logger.contents();
            assert(output.includes("not allowed!"));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid box format", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox /bare/", config, () => {
            const output = logger.contents();
            assert(output.includes("invalid format"));
            done();
          });
        }).timeout(20000);
      });
    });
  });
});
<commit_msg>Add --force flag to some unbox commands to bypass the prompt to overwrite files<commit_after>const assert = require("assert");
const CommandRunner = require("../commandrunner");
const MemoryLogger = require("../memorylogger");
const fs = require("fs-extra");

describe("truffle unbox", () => {
  let config;
  const logger = new MemoryLogger();

  beforeEach("set up config for logger", () => {
    config = { working_directory: `${process.cwd()}/test/sources/unbox` };
    config.logger = logger;
  });

  afterEach("clear working_directory", () => {
    fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
  });

  describe("when run without arguments", () => {
    it("unboxes truffle-init-default", done => {
      CommandRunner.run("unbox", config, () => {
        const output = logger.contents();
        assert(output.includes("Unbox successful."));
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/ConvertLib.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/Migrations.sol`
          )
        );
        assert(
          fs.pathExistsSync(
            `${process.cwd()}/test/sources/unbox/contracts/MetaCoin.sol`
          )
        );
        done();
      });
    }).timeout(20000);
  });

  describe("when run with arguments", () => {
    describe("valid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("full url", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("full url + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox truffle-box/bare-box", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("origin/master#branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("origin/master#branch:relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("official truffle box", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run("unbox bare#truffle-test-branch", config, () => {
            const output = logger.contents();
            assert(output.includes("Unbox successful."));
            done();
          });
        }).timeout(20000);
      });

      describe("official truffle box + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox bare#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("with an invalid git@ ssh", () => {
        it("logs an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("git@ ssh + branch + relativePath", () => {
        it("unboxes successfully", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-box#truffle-test-branch:path/to/subDir --force",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("Unbox successful."));
              done();
            }
          );
        }).timeout(20000);
      });
    });

    describe("with invalid input", () => {
      afterEach("clear working_directory", () => {
        fs.emptyDirSync(`${process.cwd()}/test/sources/unbox`);
      });

      describe("invalid full url", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox https://github.com/truffle-box/bare-boxing",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("invalid origin/master", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox truffle-box/bare-boxer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid official truffle box", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox barer", config, () => {
            const output = logger.contents();
            assert(output.includes("doesn't exist."));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid git@ ssh", () => {
        it("throws an error", done => {
          CommandRunner.run(
            "unbox git@github.com:truffle-box/bare-boxer",
            config,
            () => {
              const output = logger.contents();
              assert(output.includes("doesn't exist."));
              done();
            }
          );
        }).timeout(20000);
      });

      describe("absolutePaths", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox bare:/path/to/subDir", config, () => {
            const output = logger.contents();
            assert(output.includes("not allowed!"));
            done();
          });
        }).timeout(20000);
      });

      describe("invalid box format", () => {
        it("throws an error", done => {
          CommandRunner.run("unbox /bare/", config, () => {
            const output = logger.contents();
            assert(output.includes("invalid format"));
            done();
          });
        }).timeout(20000);
      });
    });
  });
});
<|endoftext|>


<commit_before>/** unauthenticated.js
* @file: /src/app/routes/ajax/unauthenticated.js
* @description: Handles express routing for the unathenticated ajax routes
* @parameters: Object(app), Object(resources)
* @returns: Express routes
*/

var ObjectID = require('mongodb').ObjectID
var striptags = require('striptags')
var extend = require('util')._extend;

module.exports = function (app, resources) {
  /** /ajax/map
  * @type: GET
  * @description: Ajax route for loading page info to a map.
  * @parameters: {
      Object(filter): {
        id: String("568207facddd6a6a0808c770"),
        type: String("5")
      }
  * }
  */
  app.get('/ajax/map', function (req, res) {
    var filter = {
      accepted: true, //Only published pages
      $or: [
        { type: '3' },
        { type: '5' },
        { type: '6' }
      ]
    }

    if(req.query.filter !== undefined) { //A filter is used
      var filters = {
        id: function(id) {
          return {
            _id: new ObjectID(id)
          }
        },
        type: function(type) {
          return {
            type: String(type)
          }
        },
        ids: function(ids) {
          var objIds = ids.map(function(id) {
            return new ObjectID(id)
          })

          return {
            _id: {
              $in: objIds
            }
          }
        },
        city: function(city) {
          return {
            "post.city": String(city).toLowerCase()
          }
        }
      }

      for(var key in req.query.filter) {
        if(key in filters) {
          filter = filters[key](req.query.filter[key])
        }
      }
    }

    var pagesdb = resources.collections.pages

    pagesdb.find(filter).toArray(function(err, pages) {
      for (var i = 0; i < pages.length; i++) {
        pages[i].post.content = striptags(pages[i].post.content, ['br'])
      }

      res.json(pages)
    })
  })

  /** /ajax/search
  *
  */
  app.get('/ajax/search', function (req, res) {
    var searchString = req.query.s
    var searchArray = searchString.toLowerCase().split(' ')

    //The default query object
    var query = {}

    //General query object
    var filteredQuery = {
      $match: {
        accepted: true //Only published pages
      }
    }

    //The default fields we search
    var searchFields = ['url','title','post.content','post.food','post.product_type','post.city']

    //Check if query matches a type
    var queryType = false

    var queryOperations = {
      'kafe': function() {
        query['type'] = '6'
        return true
      },
      'cafe': function() {
        query['type'] = '6'
        return true
      },
      'butik': function() {
        query['type'] = '5'
        return true
      },
      'produkt': function() {
        query['type'] = '4'
        return true
      },
      'restaurang': function() {
        query['type'] = '3'
        return true
      },
      'recept': function() {
        query['type'] = '2'
        return true
      },
      'fakta': function() {
        query['type'] = '1'
        return true
      },
      'vegan': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'vegan'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'vegan'
          })
          return false
        }
      },
      'laktoovo': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'lacto_ovo'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'lacto_ovo'
          })
          return false
        }
      },
      'animal': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'animal'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'animal'
          })
          return false
        }
      }
    }

    var queryTypes = function(string) {
      string = string.toLowerCase().replace(/[^a-z]/gi,'') //Remove non alphabet characters
      string = string.replace(/éè/) //Remove accent, mainly for café/kafé

      var keywords = ['butik','restaurang','produkt','recept','fakta','vegan','laktoovo','animal']
      var regexMatches = new RegExp('^' + keywords.join('|'))

      var match = string.match(regexMatches)
      if(match !== null && match.length > 0) {
        var key = match[0]

        if(key in queryOperations) {
          //Perform the operations on the search query
          if(queryOperations[key]()) {
            //Update the search string to remove the key from the search, otherwise might result in unwanted results
            var tmpArray = searchString.toLowerCase().split(' ')

            //Filter out the current key from the search query
            searchString = tmpArray.filter(function(text) {
              var isKey = text.match(key)
              if(isKey === null) {
                return text
              }
            }).join(' ').trim()
          }
        }
      }
    }

    for (var i in searchArray) {
      queryTypes(searchArray[i])
    }

    //Go over all the keys
    for(var key in query) {
      if( ! (key in filteredQuery.$match) ) {
        filteredQuery.$match[key] = query[key]
      }
    }

    //Array to hold regex objects of search strings
    var regexArray = []

    //As the searchString has been manipulated it might not even be anything at all anymore
    if(searchString.length > 0) {
      regexArray = searchString.split(' ').map(function(text) {
        return new RegExp(text, 'gi')
      })

      var orFields = []
      for (var i = searchFields.length - 1; i >= 0; i--) {
        var obj = {}

        if(typeof searchFields[i] === 'object') {
          if('property' in searchFields[i] && 'value' in searchFields[i]) {
            obj[searchFields[i].property] = {
              $in: [searchFields[i].value]
            }
          }
        } else {
          obj[searchFields[i]] = {
            $in: regexArray
          }
        }

        orFields.push(obj)
      }

      //Add $or matches with the regex strings
      filteredQuery.$match.$or = orFields
    }

    //Check if query matches a city
    var citiesdb = resources.collections.cities
    citiesdb.find({
      name: {
        $in: searchArray
      }
    }).toArray(function(err, cities) {
      if(err) throw err

      if(cities.length > 0) {
        filteredQuery.$match['post.city'] = {
          '$regex': cities[0].name, //Search only this city
          '$options': '-i'
        }

      }

      /*
      //Check if query matches a category
      var categoriesdb = resources.collections.categories
      categoriesdb.find({
        $or: [{
          name: {
            $in: searchArray
          }
        }, {
          subcategory: {
            $in: searchArray
          }
        }]
      }).toArray(function(err, categories) {
        //console.log(categories)
        //If we found a match here, we might want to restrict the query to that type of category
      })
      */

      //Find pages
      var pagesdb = resources.collections.pages
      pagesdb.aggregate([filteredQuery], function (err, pages) {
        if(err) throw err

        var weightedResult = [] //To hold the page results with their newly calculated weights

        for (var i = 0; i < pages.length; i++) {
          //Look up weights for each field and reorder array of results accordingly

          //The order is important, not just the weights.
          //If a match is made later that value can not match against another key in searchWeights, choose carefully
          var searchWeights = {
            'post.veg_type': 30, //This is very high, since it can only match 'vegan', 'lacto_ovo' and 'animal'
            'title': 25,
            'post.product_type': 18,
            'post.content': 15,
            'post.city': 15,
            'post.food': 10,
            'post.veg_offer': 1
          }

          //Calculate the weight of each result
          var totalWeight = 0
          var matchedValues = []
          for(var key in searchWeights) {
            var weight = searchWeights[key]
            var value = ''

            //TODO This should really be replaced with a loop that supports deeper structures, will do for now though considering our weights are only 2 levels max
            if(key.indexOf('.') >= 0) {
              subKey = key.substr( key.indexOf('.') +1 )
              parentKey = key.substr(0, key.indexOf('.') )
              if(parentKey in pages[i]) {
                if(subKey in pages[i][parentKey]) {
                    value = pages[i][parentKey][subKey]
                }
              }
            } else {
              if(key in pages[i]) {
                value = pages[i][key]
              }
            }

            if(value) { //If value was found, check which fields it matched in the db query
              var matches = 0 //No matches = no points

              //Count the matched regex cases against the search query string
              for(var index in regexArray) {
                var regex = regexArray[index]
                var match = value.match(regex)
                if(match !== null && match.length > 0) {
                  var matchedValue = match[0].toLowerCase()
                  if(matchedValues.indexOf(matchedValue) === -1) {
                    var points = 1

                    //If this was an "exact" case insensitive match, half a bonus point is given
                    var exactRegex = new RegExp('^'+matchedValue+'$', 'i')
                    var exactMatch = value.match(exactRegex)

                    if(exactMatch !== null) {
                      points += .5
                    }

                    matches += points
                    matchedValues.push(matchedValue)
                  }
                }
              }

              totalWeight += Math.abs(matches * weight) //Add the new weight to the totalWeight
            }
          }

          //Give bonus points if several matches were made
          if(matchedValues.length > 1) {
            totalWeight += (totalWeight * Math.floor(matchedValues.length * .5) )
          }

          if('post' in pages[i]) {
            if('content' in pages[i].post) {
              //All pages should have content, if not, then something is wrong with document in db, anyway make sure this is not cause of failure
              //Strip html tags of content
              pages[i].post.content = striptags(pages[i].post.content, ['br','p','a','span','i','b'])

              //Add the page with its new weight
              weightedResult.push({
                page: pages[i],
                weight: totalWeight,
                keywords: matchedValues
              })
            }
          }
        }

        //Sort the weighted results based on the weight value
        weightedResult.sort(function(a,b) {
          if (a.weight < b.weight)
            return 1
          else if (a.weight > b.weight)
            return -1
          else
            return 0
        })

        //Get the final result array of just the pages
        var finalResult = weightedResult.map(function(obj) {
          //console.log(obj.page.title, obj.weight) //This is really useful info for debugging search result weights
          return obj.page
        })

        res.json(finalResult)
      })
    })
  })

  /** /ajax/imageInfo
  *
  */
  app.get('/ajax/imageInfo', function (req, res) {
    if(req.query.id != undefined) {
      var imagesdb = resources.collections.images
      imagesdb.find({ _id : new ObjectID(req.query.id) }).toArray(function (err, doc) {
        res.json(doc)
      })
    }
  })
}<commit_msg>Modify search for new cafe type<commit_after>/** unauthenticated.js
* @file: /src/app/routes/ajax/unauthenticated.js
* @description: Handles express routing for the unathenticated ajax routes
* @parameters: Object(app), Object(resources)
* @returns: Express routes
*/

var ObjectID = require('mongodb').ObjectID
var striptags = require('striptags')
var extend = require('util')._extend;

module.exports = function (app, resources) {
  /** /ajax/map
  * @type: GET
  * @description: Ajax route for loading page info to a map.
  * @parameters: {
      Object(filter): {
        id: String("568207facddd6a6a0808c770"),
        type: String("5")
      }
  * }
  */
  app.get('/ajax/map', function (req, res) {
    var filter = {
      accepted: true, //Only published pages
      $or: [
        { type: '3' },
        { type: '5' },
        { type: '6' }
      ]
    }

    if(req.query.filter !== undefined) { //A filter is used
      var filters = {
        id: function(id) {
          return {
            _id: new ObjectID(id)
          }
        },
        type: function(type) {
          return {
            type: String(type)
          }
        },
        ids: function(ids) {
          var objIds = ids.map(function(id) {
            return new ObjectID(id)
          })

          return {
            _id: {
              $in: objIds
            }
          }
        },
        city: function(city) {
          return {
            "post.city": String(city).toLowerCase()
          }
        }
      }

      for(var key in req.query.filter) {
        if(key in filters) {
          filter = filters[key](req.query.filter[key])
        }
      }
    }

    var pagesdb = resources.collections.pages

    pagesdb.find(filter).toArray(function(err, pages) {
      for (var i = 0; i < pages.length; i++) {
        pages[i].post.content = striptags(pages[i].post.content, ['br'])
      }

      res.json(pages)
    })
  })

  /** /ajax/search
  *
  */
  app.get('/ajax/search', function (req, res) {
    var searchString = req.query.s
    var searchArray = searchString.toLowerCase().split(' ')

    //The default query object
    var query = {}

    //General query object
    var filteredQuery = {
      $match: {
        accepted: true //Only published pages
      }
    }

    //The default fields we search
    var searchFields = ['url','title','post.content','post.food','post.product_type','post.city']

    //Check if query matches a type
    var queryType = false

    var queryOperations = {
      'kafe': function() {
        query['type'] = '6'
        return true
      },
      'cafe': function() {
        query['type'] = '6'
        return true
      },
      'butik': function() {
        query['type'] = '5'
        return true
      },
      'produkt': function() {
        query['type'] = '4'
        return true
      },
      'restaurang': function() {
        query['type'] = '3'
        return true
      },
      'recept': function() {
        query['type'] = '2'
        return true
      },
      'fakta': function() {
        query['type'] = '1'
        return true
      },
      'vegan': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'vegan'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'vegan'
          })
          return false
        }
      },
      'laktoovo': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'lacto_ovo'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'lacto_ovo'
          })
          return false
        }
      },
      'animal': function() {
        if('type' in query && query.type === '3') {
          query['veg_type'] = 'animal'
          return true
        } else {
          searchFields.push({
            property: 'post.veg_type',
            value: 'animal'
          })
          return false
        }
      }
    }

    var queryTypes = function(string) {
      string = string.toLowerCase().replace(/é|è/gi, 'e') //Remove accent, mainly for café/kafé
      string = string.replace(/[^a-z]/gi, '') //Remove non alphabet characters

      var keywords = ['cafe','kafe','butik','restaurang','produkt','recept','fakta','vegan','laktoovo','animal']
      var regexMatches = new RegExp('^' + keywords.join('|'))

      var match = string.match(regexMatches)
      if(match !== null && match.length > 0) {
        var key = match[0]

        if(key in queryOperations) {
          //Perform the operations on the search query
          if(queryOperations[key]()) {
            //Update the search string to remove the key from the search, otherwise might result in unwanted results
            searchString = searchString.toLowerCase().replace(/é|è/gi, 'e') //Remove accent, mainly for café/kafé
            var tmpArray = searchString.toLowerCase().split(' ')

            //Filter out the current key from the search query
            searchString = tmpArray.filter(function(text) {
              var isKey = text.match(key)
              if(isKey === null) {
                return text
              }
            }).join(' ').trim()
          }
        }
      }
    }

    for (var i in searchArray) {
      queryTypes(searchArray[i])
    }

    //Go over all the keys
    for(var key in query) {
      if( ! (key in filteredQuery.$match) ) {
        filteredQuery.$match[key] = query[key]
      }
    }

    //Array to hold regex objects of search strings
    var regexArray = []

    //As the searchString has been manipulated it might not even be anything at all anymore
    if(searchString.length > 0) {
      regexArray = searchString.split(' ').map(function(text) {
        return new RegExp(text, 'gi')
      })

      var orFields = []
      for (var i = searchFields.length - 1; i >= 0; i--) {
        var obj = {}

        if(typeof searchFields[i] === 'object') {
          if('property' in searchFields[i] && 'value' in searchFields[i]) {
            obj[searchFields[i].property] = {
              $in: [searchFields[i].value]
            }
          }
        } else {
          obj[searchFields[i]] = {
            $in: regexArray
          }
        }

        orFields.push(obj)
      }

      //Add $or matches with the regex strings
      filteredQuery.$match.$or = orFields
    }

    console.log(searchString)

    //Check if query matches a city
    var citiesdb = resources.collections.cities
    citiesdb.find({
      name: {
        $in: searchArray
      }
    }).toArray(function(err, cities) {
      if(err) throw err

      if(cities.length > 0) {
        filteredQuery.$match['post.city'] = {
          '$regex': cities[0].name, //Search only this city
          '$options': '-i'
        }

      }

      /*
      //Check if query matches a category
      var categoriesdb = resources.collections.categories
      categoriesdb.find({
        $or: [{
          name: {
            $in: searchArray
          }
        }, {
          subcategory: {
            $in: searchArray
          }
        }]
      }).toArray(function(err, categories) {
        //console.log(categories)
        //If we found a match here, we might want to restrict the query to that type of category
      })
      */

      //Find pages
      var pagesdb = resources.collections.pages
      pagesdb.aggregate([filteredQuery], function (err, pages) {
        if(err) throw err

        var weightedResult = [] //To hold the page results with their newly calculated weights

        for (var i = 0; i < pages.length; i++) {
          //Look up weights for each field and reorder array of results accordingly

          //The order is important, not just the weights.
          //If a match is made later that value can not match against another key in searchWeights, choose carefully
          var searchWeights = {
            'post.veg_type': 30, //This is very high, since it can only match 'vegan', 'lacto_ovo' and 'animal'
            'title': 25,
            'post.product_type': 18,
            'post.content': 15,
            'post.city': 15,
            'post.food': 10,
            'post.veg_offer': 1
          }

          //Calculate the weight of each result
          var totalWeight = 0
          var matchedValues = []
          for(var key in searchWeights) {
            var weight = searchWeights[key]
            var value = ''

            //TODO This should really be replaced with a loop that supports deeper structures, will do for now though considering our weights are only 2 levels max
            if(key.indexOf('.') >= 0) {
              subKey = key.substr( key.indexOf('.') +1 )
              parentKey = key.substr(0, key.indexOf('.') )
              if(parentKey in pages[i]) {
                if(subKey in pages[i][parentKey]) {
                    value = pages[i][parentKey][subKey]
                }
              }
            } else {
              if(key in pages[i]) {
                value = pages[i][key]
              }
            }

            if(value) { //If value was found, check which fields it matched in the db query
              var matches = 0 //No matches = no points

              //Count the matched regex cases against the search query string
              for(var index in regexArray) {
                var regex = regexArray[index]
                var match = value.match(regex)
                if(match !== null && match.length > 0) {
                  var matchedValue = match[0].toLowerCase()
                  if(matchedValues.indexOf(matchedValue) === -1) {
                    var points = 1

                    //If this was an "exact" case insensitive match, half a bonus point is given
                    var exactRegex = new RegExp('^'+matchedValue+'$', 'i')
                    var exactMatch = value.match(exactRegex)

                    if(exactMatch !== null) {
                      points += .5
                    }

                    matches += points
                    matchedValues.push(matchedValue)
                  }
                }
              }

              totalWeight += Math.abs(matches * weight) //Add the new weight to the totalWeight
            }
          }

          //Give bonus points if several matches were made
          if(matchedValues.length > 1) {
            totalWeight += (totalWeight * Math.floor(matchedValues.length * .5) )
          }

          if('post' in pages[i]) {
            if('content' in pages[i].post) {
              //All pages should have content, if not, then something is wrong with document in db, anyway make sure this is not cause of failure
              //Strip html tags of content
              pages[i].post.content = striptags(pages[i].post.content, ['br','p','a','span','i','b'])

              //Add the page with its new weight
              weightedResult.push({
                page: pages[i],
                weight: totalWeight,
                keywords: matchedValues
              })
            }
          }
        }

        //Sort the weighted results based on the weight value
        weightedResult.sort(function(a,b) {
          if (a.weight < b.weight)
            return 1
          else if (a.weight > b.weight)
            return -1
          else
            return 0
        })

        //Get the final result array of just the pages
        var finalResult = weightedResult.map(function(obj) {
          //console.log(obj.page.title, obj.weight) //This is really useful info for debugging search result weights
          return obj.page
        })

        res.json(finalResult)
      })
    })
  })

  /** /ajax/imageInfo
  *
  */
  app.get('/ajax/imageInfo', function (req, res) {
    if(req.query.id != undefined) {
      var imagesdb = resources.collections.images
      imagesdb.find({ _id : new ObjectID(req.query.id) }).toArray(function (err, doc) {
        res.json(doc)
      })
    }
  })
}<|endoftext|>


<commit_before>/*
 * openi_data_api
 * openi-ict.eu
 *
 * Copyright (c) 2013 dmccarthy
 * Licensed under the MIT license.
 */

'use strict';

var openiLogger  = require('openi-logger')
var openiUtils   = require('openi-cloudlet-utils')
var zmq          = require('m2nodehandler');
var querystring  = require('querystring')

var allowedTypes = ['boolean', 'int', 'float', 'string', 'date', 'timestamp', 'openitype', 'hexadecimal', 'base64']

var init = function(logger_params){
   this.logger = openiLogger(logger_params);
}

var getType = function (path) {

   var parts   = path.split('/')
   var namePos = 4;

   return parts[namePos]

}

var validateType = function(type){

   if ( !('@reference' in  type) || '' === type['@reference']){
      return {valid:false, message:'There is no _reference property'};
   }
   if ( !('@context' in  type) || !Array.isArray(type['@context']) || 0 === type['@context'].length ){
      return {valid:false, message:'There is no _context property'};
   }

   for ( var i in type['@context']){

      var entry = type['@context'][i];

      if ( !('@property_name' in  entry) || '' === entry['@property_name']){
         return {valid:false, message:'There is no _property_name parameter in entry ' + i};
      }
      if ( !('@property_context' in  entry) ){
         return {valid:false, message:'There is no _property_context parameter in entry ' + i};

      }

      if ( !( '@id' in entry['@property_context']) || '' === entry['@property_context']['@id']){
         return {valid:false, message:'There is no _id parameter in context of the entry ' + i};
      }

      if ( !( '@openi_type' in entry['@property_context']) ){
         return {valid:false, message:'There is no _openi_type parameter in context of the entry ' + i};
      }

      if (-1 === allowedTypes.indexOf(entry['@property_context']['@openi_type'])){
         return {valid:false, message: entry['@property_context']['@openi_type'] + ' is not a valid type.'};
      }

   }

   return {valid:true};
}

var genPostMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var typeId = 't_' + openiUtils.hash(msg.json)

   var typeRestUrl = "http://" + msg.headers.host + "/api/v1/types/" + typeId;

   msg.json['@id']            = typeId;
   msg.json['@location']      = typeRestUrl;
   msg.json['_date_created '] = new Date().toJSON();

   var validCheck = validateType(msg.json);

   if (!validCheck.valid){

      var resp = zmq.Response(zmq.status.BAD_REQUEST_400, zmq.header_json, {'error' : 'Type object isn\'t properly structured : ' + validCheck.message})

      senderToClient.send(msg.uuid, msg.connId, resp);

      return;
   }

   senderToDao.send({
      'dao_actions'      : [
         {
            'action'       : 'POST',
            'database'    : typeId,
            'object_name' : 'meta',
            'object_data' : msg.json,
            'id'          : typeId
         }
      ],
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {'uuid' : msg.uuid, 'connId' : msg.connId }
      ]
   });
}

var genGetMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var query = querystring.parse(msg.headers.QUERY);

   if ( msg.path === '/api/v1/types' ){

      var viewName  = 'types_list';

      if ('true' === query.id_only){
         viewName  = 'types_id_list';
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : viewName,
               'count'        : Number(query.limit),
               'skip'         : Number(query.skip),
               'filter_show'  : query['only_show_properties'],
               'content-type' : query['content-type'],
               'resp_type'    : 'type'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      })
   }
   else if ( msg.path === '/api/v1/types/stats' ){

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_usage',
               'group'        : true,
               'resp_type'    : 'type_stats'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      })
   }
   else{
      var type =  getType(msg.path).replace('/api/v1/types/','')

      var typeRestUrl = "http://" + msg.headers.host + "/api/v1/types/" + type;

      senderToDao.send({
         'dao_actions'      : [
            {
               'action' : 'GET',
               'database': type,
               'id' : type,
               'content-type' : query['content-type'],
               'resp_type'    : 'type'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      });
   }
}

var genPatchMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var actions = []

   for ( var i =0; i < msg.json.length; i++){
      var entry       = msg.json[i]
      var typeId      = 't_' + openiUtils.hash(entry)
      var typeRestUrl = "http://" + msg.headers.host + "/api/v1/types/" + typeId;

      if (!validateType(entry)){

         var resp = zmq.Response(zmq.status.BAD_REQUEST_400, zmq.header_json, {'error' : 'Type object isn\'t properly structured' })

         senderToClient.send(msg.uuid, msg.connId, resp);

         return;
      }

      entry['@id']            = typeId;
      entry['@location']      = typeRestUrl;
      entry['_date_created'] = new Date().toJSON();

      actions.push({ 'action' : 'POST',
         'database'    : typeId,
         'object_name' : 'meta',
         'object_data' : entry,
         'id'          : typeId,
         'resp_type'   : 'type'
      });
   }

   senderToDao.send({
      'dao_actions'  : actions,
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {'uuid' : msg.uuid, 'connId' : msg.connId }
      ]
   });
}

var processMongrel2Message = function (msg, senderToDao, senderToClient, terminal_handler) {

   this.logger.logMongrel2Message(msg);

   for(var key in msg.json) if(msg.json[key] === null) delete msg.json[key];

   switch(msg.headers['METHOD']){
   case 'POST':
      genPostMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   case 'GET':
      genGetMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   case 'PATCH':
      genPatchMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   default:
      break;
   }

}

module.exports.init                   = init
module.exports.getObject              = getType
module.exports.processMongrel2Message = processMongrel2Message
<commit_msg>Set default @location to https<commit_after>/*
 * openi_data_api
 * openi-ict.eu
 *
 * Copyright (c) 2013 dmccarthy
 * Licensed under the MIT license.
 */

'use strict';

var openiLogger  = require('openi-logger')
var openiUtils   = require('openi-cloudlet-utils')
var zmq          = require('m2nodehandler');
var querystring  = require('querystring')

var allowedTypes = ['boolean', 'int', 'float', 'string', 'date', 'timestamp', 'openitype', 'hexadecimal', 'base64']

var init = function(logger_params){
   this.logger = openiLogger(logger_params);
}

var getType = function (path) {

   var parts   = path.split('/')
   var namePos = 4;

   return parts[namePos]

}

var validateType = function(type){

   if ( !('@reference' in  type) || '' === type['@reference']){
      return {valid:false, message:'There is no _reference property'};
   }
   if ( !('@context' in  type) || !Array.isArray(type['@context']) || 0 === type['@context'].length ){
      return {valid:false, message:'There is no _context property'};
   }

   for ( var i in type['@context']){

      var entry = type['@context'][i];

      if ( !('@property_name' in  entry) || '' === entry['@property_name']){
         return {valid:false, message:'There is no _property_name parameter in entry ' + i};
      }
      if ( !('@property_context' in  entry) ){
         return {valid:false, message:'There is no _property_context parameter in entry ' + i};

      }

      if ( !( '@id' in entry['@property_context']) || '' === entry['@property_context']['@id']){
         return {valid:false, message:'There is no _id parameter in context of the entry ' + i};
      }

      if ( !( '@openi_type' in entry['@property_context']) ){
         return {valid:false, message:'There is no _openi_type parameter in context of the entry ' + i};
      }

      if (-1 === allowedTypes.indexOf(entry['@property_context']['@openi_type'])){
         return {valid:false, message: entry['@property_context']['@openi_type'] + ' is not a valid type.'};
      }

   }

   return {valid:true};
}

var genPostMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var typeId = 't_' + openiUtils.hash(msg.json)

   var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + typeId;

   msg.json['@id']            = typeId;
   msg.json['@location']      = typeRestUrl;
   msg.json['_date_created '] = new Date().toJSON();

   var validCheck = validateType(msg.json);

   if (!validCheck.valid){

      var resp = zmq.Response(zmq.status.BAD_REQUEST_400, zmq.header_json, {'error' : 'Type object isn\'t properly structured : ' + validCheck.message})

      senderToClient.send(msg.uuid, msg.connId, resp);

      return;
   }

   senderToDao.send({
      'dao_actions'      : [
         {
            'action'       : 'POST',
            'database'    : typeId,
            'object_name' : 'meta',
            'object_data' : msg.json,
            'id'          : typeId
         }
      ],
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {'uuid' : msg.uuid, 'connId' : msg.connId }
      ]
   });
}

var genGetMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var query = querystring.parse(msg.headers.QUERY);

   if ( msg.path === '/api/v1/types' ){

      var viewName  = 'types_list';

      if ('true' === query.id_only){
         viewName  = 'types_id_list';
      }

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : viewName,
               'count'        : Number(query.limit),
               'skip'         : Number(query.skip),
               'filter_show'  : query['only_show_properties'],
               'content-type' : query['content-type'],
               'resp_type'    : 'type'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      })
   }
   else if ( msg.path === '/api/v1/types/stats' ){

      senderToDao.send({
         'dao_actions'      : [
            {
               'action'       : 'VIEW',
               'design_doc'   : 'type_views',
               'view_name'    : 'types_usage',
               'group'        : true,
               'resp_type'    : 'type_stats'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      })
   }
   else{
      var type =  getType(msg.path).replace('/api/v1/types/','')

      var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + type;

      senderToDao.send({
         'dao_actions'      : [
            {
               'action' : 'GET',
               'database': type,
               'id' : type,
               'content-type' : query['content-type'],
               'resp_type'    : 'type'
            }
         ],
         'mongrel_sink' : terminal_handler,
         'clients'      : [
            {'uuid' : msg.uuid, 'connId' : msg.connId }
         ]
      });
   }
}

var genPatchMessage = function(msg, senderToDao, senderToClient, terminal_handler){

   var actions = []

   for ( var i =0; i < msg.json.length; i++){
      var entry       = msg.json[i]
      var typeId      = 't_' + openiUtils.hash(entry)
      var typeRestUrl = "https://" + msg.headers.host + "/api/v1/types/" + typeId;

      if (!validateType(entry)){

         var resp = zmq.Response(zmq.status.BAD_REQUEST_400, zmq.header_json, {'error' : 'Type object isn\'t properly structured' })

         senderToClient.send(msg.uuid, msg.connId, resp);

         return;
      }

      entry['@id']            = typeId;
      entry['@location']      = typeRestUrl;
      entry['_date_created'] = new Date().toJSON();

      actions.push({ 'action' : 'POST',
         'database'    : typeId,
         'object_name' : 'meta',
         'object_data' : entry,
         'id'          : typeId,
         'resp_type'   : 'type'
      });
   }

   senderToDao.send({
      'dao_actions'  : actions,
      'mongrel_sink' : terminal_handler,
      'clients'      : [
         {'uuid' : msg.uuid, 'connId' : msg.connId }
      ]
   });
}

var processMongrel2Message = function (msg, senderToDao, senderToClient, terminal_handler) {

   this.logger.logMongrel2Message(msg);

   for(var key in msg.json) if(msg.json[key] === null) delete msg.json[key];

   switch(msg.headers['METHOD']){
   case 'POST':
      genPostMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   case 'GET':
      genGetMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   case 'PATCH':
      genPatchMessage(msg, senderToDao, senderToClient, terminal_handler)
      break;
   default:
      break;
   }

}

module.exports.init                   = init
module.exports.getObject              = getType
module.exports.processMongrel2Message = processMongrel2Message
<|endoftext|>


<commit_before>/*
 * Replacement variables:
 *  jQuery
 *  AJAXURL
 *  IDPARAM
 */

// Return a helper with preserved width of cells
var fixHelper = function (e, ui) {
    ui.children().each(function () {
        $(this).width($(this).width());
    });
    return ui;
};

function getURLParameter(url, name) {
    return (RegExp("/" + name + "/" + "(.+?)(/|$)").exec(url) || [, null])[1];
}

jQuery("#sort").click(function () {
    jQuery("#sort").toggle();
    jQuery("#sort-ok").toggle();
    jQuery("#sort-cancel").toggle();

    $("table.browser.table tbody").sortable({
        helper: fixHelper,
        placeholder: "ui-sortable-placeholder"
    }).disableSelection();
});

jQuery("#sort-ok").click(function () {
    var sortables = [];
    jQuery("table.browser.table:not(.fixed) tbody tr").each(function () {
        href = jQuery(this).find("td.table-button").first().find("a").attr("href");
        id = getURLParameter(href, "IDPARAM");
        sortables.push(id);
    });
    jQuery.ajax({
        url: "AJAXURL",
        type: "POST",
        dataType: "html",
        data: {ids: sortables},
        error: function (request, status, error) {
            errorContainer = $("#error");
            if (errorContainer.length == 0) {
                // Insert error container
                $("body").append("

");
            }
            $("#error").html(request.responseText);
            $("#error").dialog({
                modal: true,
                width: 200,
                position: {my: "left top", at: "left top", of: "#main"}
            })
        },
        success: function (data, status, request) {
            jQuery("#AUTO_SEARCH_TEXT_BUTTON").click();
        }
    })
});

jQuery("#sort-cancel").click(function () {
    jQuery("#AUTO_SEARCH_TEXT_BUTTON").click();
});
<commit_msg>Fixed firefox bug for sortables<commit_after>/*
 * Replacement variables:
 *  jQuery
 *  AJAXURL
 *  IDPARAM
 */

// Return a helper with preserved width of cells, and disabled onlick attribute
// for FireFox bug https://bugzilla.mozilla.org/show_bug.cgi?id=787944
var fixHelper = function (e, ui) {
    var clone = jQuery.extend(true, {}, ui);
    clone.children().each(function () {
        $(this).width($(this).width());
        $(this).attr('onclick', null);
    });
    return clone;
};

function getURLParameter(url, name) {
    return (RegExp("/" + name + "/" + "(.+?)(/|$)").exec(url) || [, null])[1];
}

jQuery("#sort").click(function () {
    jQuery("#sort").toggle();
    jQuery("#sort-ok").toggle();
    jQuery("#sort-cancel").toggle();

    $("table.browser.table tbody").sortable({
        helper: fixHelper,
        placeholder: "ui-sortable-placeholder"
    }).disableSelection();
});

jQuery("#sort-ok").click(function () {
    var sortables = [];
    jQuery("table.browser.table:not(.fixed) tbody tr").each(function () {
        href = jQuery(this).find("td.table-button").first().find("a").attr("href");
        id = getURLParameter(href, "IDPARAM");
        sortables.push(id);
    });
    jQuery.ajax({
        url: "AJAXURL",
        type: "POST",
        dataType: "html",
        data: {ids: sortables},
        error: function (request, status, error) {
            errorContainer = $("#error");
            if (errorContainer.length == 0) {
                // Insert error container
                $("body").append("

");
            }
            $("#error").html(request.responseText);
            $("#error").dialog({
                modal: true,
                width: 200,
                position: {my: "left top", at: "left top", of: "#main"}
            })
        },
        success: function (data, status, request) {
            jQuery("#AUTO_SEARCH_TEXT_BUTTON").click();
        }
    })
});

jQuery("#sort-cancel").click(function () {
    jQuery("#AUTO_SEARCH_TEXT_BUTTON").click();
});<|endoftext|>


<commit_before>(function(jQuery) {
  var $ = jQuery;

  if (window.top !== window) {
    // Don't run in iframes
    return;
  }

  $(document).ready(function() {
    var commentTd = $('body.thread #commenttd');
    var htmlComment = commentTd.find('#comment');
    var mdComment = $('<textarea>')
      .attr('rows', 20)
      .attr('cols', 8)
      .css('background-color', '#f0f0f0');
    commentTd.append(mdComment);

    var updateHtmlFromMd = function() {
      var mdText = mdComment.val();
      var htmlText = md4mefi.md2html(mdText);
      htmlComment.val(htmlText);

      htmlComment.trigger('keyup');
    };
    mdComment.on('input', updateHtmlFromMd);

    mdComment.on('focus', function() {
      // Turn on live preview, by running the init_lp function.
      // That function is assigned to the onfocus handler.
      //
      // However, if we run jQuery's .trigger('focus')
      // function, we'll actually switch focus to the
      // htmlComment textarea. Therefore, run
      // the onfocus handler that's set through plain ol'
      // DOM manipulation.

      var htmlCommentDomNode = htmlComment.get(0);
      htmlCommentDomNode.onfocus();
    });

    mdComment.on('blur', function() {
      // Turn off live preview, by running the kill_lp function,
      // which is the onBlur handler.

      var htmlCommentDomNode = htmlComment.get(0);
      htmlCommentDomNode.onblur();
    });

  });

// noConflict(true) will revert both $ and jQuery, making
// it possible to use this plugin in combination w/ other
// versions of jQuery.
//
// See: http://stackoverflow.com/a/7882550/939467
})(jQuery.noConflict(true));<commit_msg>Add a checkbox to show/hide the markdown<commit_after>(function(jQuery) {
  "use strict";

  var $ = jQuery;

  if (window.top !== window) {
    // Don't run in iframes
    return;
  }

  // When the Markdown has changed, generate
  // new HTML.
  var updateHtmlFromMd = function(event) {
    var mdComment = event.data.mdComment;
    var htmlComment = event.data.htmlComment;

    var mdText = mdComment.val();
    var htmlText = md4mefi.md2html(mdText);
    htmlComment.val(htmlText);

    // The keyup event is the listener for
    // refreshing the live preview.
    htmlComment.trigger('keyup');
  };

  // Turn on the task that updates the live preview
  var turnOnLivePreview = function(event) {
    // Turn on live preview, by running the init_lp function.
    // That function is assigned to the onfocus handler.
    //
    // However, if we run jQuery's .trigger('focus')
    // function, we'll actually switch focus to the
    // htmlComment textarea. Therefore, run
    // the onfocus handler that's set through plain ol'
    // DOM manipulation.

    var htmlCommentDomNode = event.data.htmlComment.get(0);
    htmlCommentDomNode.onfocus();
  };

  var turnOffLivePreview = function(event) {
    // Turn off live preview, by running the kill_lp function,
    // which is the onBlur handler.

    var htmlCommentDomNode = event.data.htmlComment.get(0);
    htmlCommentDomNode.onblur();
  };

  var showHideHtml = function(event) {
    var htmlComment = event.data.htmlComment;
    var showHtml = event.data.showHtml;

    var isShow = showHtml.prop('checked');

    var animationOptions = {
      duration: 200,
      //easing: 'easeOut',
    };

    if (isShow) {
      htmlComment.show(animationOptions);
    }
    else {
      htmlComment.hide(animationOptions);
    }
  };

  $(document).ready(function() {
    // Todo: Abort if the body doesn't have a class of .thread
    var commentTd = $('body.thread #commenttd');
    var htmlComment = commentTd.find('#comment');
    var mdComment = $('<textarea>')
      .attr('rows', 8)
      .attr('cols', 60)
      .css('background-color', '#f3f0f0');

    var showHtmlLabel = $('<label><input type=checkbox> Show HTML</label>')
      .prop('checked', false);
    var showHtml = showHtmlLabel.find('input');

    commentTd.prepend(showHtmlLabel);
    commentTd.prepend(mdComment);
    htmlComment.hide();

    // Hide the formatting toolbar (B, I, link)
    var toolbar = $('#toolbar');
    var toolbarParentTr = toolbar.closest('tr');
    toolbarParentTr.hide();

    var eventData = {
      htmlComment: htmlComment,
      mdComment: mdComment,
      showHtml: showHtml,
    };
    mdComment.on('input', eventData, updateHtmlFromMd);
    mdComment.on('focus', eventData, turnOnLivePreview);
    mdComment.on('blur',  eventData, turnOffLivePreview);

    showHtml.on('change', eventData, showHideHtml);
  });

// noConflict(true) will revert both $ and jQuery, making
// it possible to use this plugin in combination w/ other
// versions of jQuery. Maybe this isn't necessary b/c
// Safari protects plugins from conflicts w/ the page's
// Javascript, but it makes me feel safer.
//
// See: http://stackoverflow.com/a/7882550/939467
})(jQuery.noConflict(true));<|endoftext|>


<commit_before>// moon.sample.login.FrontDoorViaPanelSample

enyo.kind({
    //* @public
    name: "moon.sample.login.FrontDoorViaPanelSample",
    kind: "moon.Panel",
    //* @protected
    title: "3rd PARTY APP NAME",
    components: [
        {kind: "FittableColumns", components: [
            {name: "appInfo", kind: "enyo.DataRepeater", components: [
                {
                    kind: "moon.Button",
                    ontap: "selectApp",
                    bindFrom: "text",
                    style: "width: 300px;",
                    classes: "moon-dark-gray moon-margin-top-bottom"
                }
            ]},
            {fit: true, components:[
                {kind: "FittableColumns", classes: "moon-margin-top-bottom", components:[
                    {content: "Email", style: "width: 180px;"},
                    {
                        kind: "moon.InputDecorator",
                        fit: true,
                        components: [
                            {
                                name: "email",
                                kind: "moon.Input",
                                onchange: "emailChanged",
                            }
                        ]
                    }
                ]},
                {kind: "FittableColumns", classes: "moon-margin-top-bottom", components:[
                    {content: "Password", style: "width: 180px; margin-bottom: 20px;"},
                    {
                        kind: "moon.InputDecorator",
                        fit: true,
                        components: [
                            {
                                name: "password",
                                kind: "moon.Input",
                                onchange: "passwordChanged",
                            }
                        ]
                    },
                ]},
                {
                    layoutKind: 'HFlexLayout',
                    fit: true,
                    classes: "moon-margin-top-bottom",
                    components: [
                        {style: "width: 250px;", classes: "moon-margin-left-right", components:[
                            {style: "height: 32px"},
                            {
                                kind: "moon.CheckboxItem",
                                checked: true,
                                content: "Log in setting"
                            }
                        ]},
                        {
                            kind: "moon.Button",
                            content: "Log in",
                            flex: true,
                            classes: "moon-dark-gray moon-margin-left-right"
                        },
                        {
                            kind: "moon.Button",
                            content: "Registration",
                            flex: true,
                            classes: "moon-dark-gray"
                        }
                    ]
                }
            ]}
        ]}
    ],
    bindings: [
        {from: ".controller.apps", to: "$.appInfo.controller"}
    ],

    //* @public

    emailChanged: function(){
        this.log("The email was changed");
    },
    passwordChanged: function(){
        this.log("The password was changed");
    }
});

enyo.ready(function(){

// Sample model

    var sampleModel = new enyo.Model({
        apps: new enyo.Collection([
            {text: "LOG IN WITH FACEBOOK"},
            {text: "LOG IN WITH TWITTER"},
            {text: "JOIN APP"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {kind: "enyo.Spotlight"},
                {
                    kind: "moon.sample.login.FrontDoorViaPanelSample",
                    controller: ".app.controllers.loginFrontDoorViaPanelController",
                    classes: "enyo-fit"
                }
            ],
        },
        controllers: [
            {
                name: "loginFrontDoorViaPanelController",
                kind: "enyo.ModelController",
                model: sampleModel,
                selectApp: function(inSender, inEvent) {
                    inSender.parent.controller.set("text", "We are the Champions")
                }
            }
        ]
    });
});
<commit_msg>GF-5508: apply "password" type in the input<commit_after>// moon.sample.login.FrontDoorViaPanelSample

enyo.kind({
    //* @public
    name: "moon.sample.login.FrontDoorViaPanelSample",
    kind: "moon.Panel",
    //* @protected
    title: "3rd PARTY APP NAME",
    components: [
        {kind: "FittableColumns", components: [
            {name: "appInfo", kind: "enyo.DataRepeater", components: [
                {
                    kind: "moon.Button",
                    ontap: "selectApp",
                    bindFrom: "text",
                    style: "width: 300px;",
                    classes: "moon-dark-gray moon-margin-top-bottom"
                }
            ]},
            {fit: true, components:[
                {kind: "FittableColumns", classes: "moon-margin-top-bottom", components:[
                    {content: "Email", style: "width: 180px;"},
                    {
                        kind: "moon.InputDecorator",
                        fit: true,
                        components: [
                            {
                                name: "email",
                                kind: "moon.Input",
                                onchange: "emailChanged"
                            }
                        ]
                    }
                ]},
                {kind: "FittableColumns", classes: "moon-margin-top-bottom", components:[
                    {content: "Password", style: "width: 180px; margin-bottom: 20px;"},
                    {
                        kind: "moon.InputDecorator",
                        fit: true,
                        components: [
                            {
                                name: "password",
                                kind: "moon.Input",
                                onchange: "passwordChanged",
                                type: "password"
                            }
                        ]
                    }
                ]},
                {
                    layoutKind: 'HFlexLayout',
                    fit: true,
                    classes: "moon-margin-top-bottom",
                    components: [
                        {style: "width: 250px;", classes: "moon-margin-left-right", components:[
                            {style: "height: 32px"},
                            {
                                kind: "moon.CheckboxItem",
                                checked: true,
                                content: "Log in setting"
                            }
                        ]},
                        {
                            kind: "moon.Button",
                            content: "Log in",
                            flex: true,
                            classes: "moon-dark-gray moon-margin-left-right"
                        },
                        {
                            kind: "moon.Button",
                            content: "Registration",
                            flex: true,
                            classes: "moon-dark-gray"
                        }
                    ]
                }
            ]}
        ]}
    ],
    bindings: [
        {from: ".controller.apps", to: "$.appInfo.controller"}
    ],

    //* @public

    emailChanged: function(){
        this.log("The email was changed");
    },
    passwordChanged: function(){
        this.log("The password was changed");
    }
});

enyo.ready(function(){

// Sample model

    var sampleModel = new enyo.Model({
        apps: new enyo.Collection([
            {text: "LOG IN WITH FACEBOOK"},
            {text: "LOG IN WITH TWITTER"},
            {text: "JOIN APP"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {kind: "enyo.Spotlight"},
                {
                    kind: "moon.sample.login.FrontDoorViaPanelSample",
                    controller: ".app.controllers.loginFrontDoorViaPanelController",
                    classes: "enyo-fit"
                }
            ],
        },
        controllers: [
            {
                name: "loginFrontDoorViaPanelController",
                kind: "enyo.ModelController",
                model: sampleModel,
                selectApp: function(inSender, inEvent) {
                    inSender.parent.controller.set("text", "We are the Champions")
                }
            }
        ]
    });
});
<|endoftext|>


<commit_before>import {FlowWS, error} from '../../utils/index';
import {searchReceive, SEARCH_RECEIVE, SEARCH_COMPLETED} from '../../modules/search/index';
import {receiveIndices, INDICES_RECEIVE} from '../../modules/indices/index';
import {receiveFields, FIELDS_RECEIVE} from '../../modules/fields/index';
import {
    receiveInitialState,
    INITIAL_STATE_RECEIVE
} from '../../modules/data/index';
import {searchCompleted} from "../../modules/search/actions";

export const Socket = {
    ws: null,
    searchResults: {},
    searchTimeouts: {},
    searchReceive: (results, query, dispatch) => {
        if (results === null) {
            return;
        }

        let prevResults = [];
        if (Socket.searchResults[query]) {
            prevResults = Socket.searchResults[query];
        }

        Socket.searchResults[query] = prevResults.concat(results);
        clearTimeout(Socket.searchTimeouts[query]);

        Socket.searchTimeouts[query] = setTimeout(() => {
            dispatch(searchReceive({
                results: Socket.searchResults[query],
                query: query,
            }));

            delete Socket.searchResults[query];
        }, 500);
    },
    wsDispatcher: (message, dispatch) => {
        if (message.error) {
            return dispatch(error(message.error.message));
        }

        switch (message.type) {
            case SEARCH_RECEIVE:
                Socket.searchReceive(message.results, message.query, dispatch);
                break;

            case INDICES_RECEIVE:
                dispatch(receiveIndices(message.indices));
                break;

            case FIELDS_RECEIVE:
                dispatch(receiveFields(message.fields));
                break;

            case INITIAL_STATE_RECEIVE:
                dispatch(receiveInitialState({
                    datasources: message.datasources,
                    version: message.version
                }));
                break;

            case SEARCH_COMPLETED:
                dispatch(searchCompleted(message['request-id']));
        }
    },
    startWS: (dispatch) => {
        if (!!Socket.ws) {
            return;
        }

        let url;

        if (process.env.WEBSOCKET_URI) {
            url = process.env.WEBSOCKET_URI;
        } else {
            const {location} = window;
            url = ((location.protocol === "https:") ? "wss://" : "ws://") + location.host + "/ws";
        }

        try {
            Socket.ws = new FlowWS(url, null, Socket.wsDispatcher, dispatch);
        } catch (e) {
            dispatch(error(e));
        }
    }
};
<commit_msg>prevent adding duplicate items (on id), update count instead<commit_after>import {FlowWS, error} from '../../utils/index';
import {searchReceive, SEARCH_RECEIVE, SEARCH_COMPLETED} from '../../modules/search/index';
import {receiveIndices, INDICES_RECEIVE} from '../../modules/indices/index';
import {receiveFields, FIELDS_RECEIVE} from '../../modules/fields/index';
import {
    receiveInitialState,
    INITIAL_STATE_RECEIVE
} from '../../modules/data/index';
import {searchCompleted} from "../../modules/search/actions";

export const Socket = {
    ws: null,
    searchResults: {},
    searchTimeouts: {},
    searchReceive: (newResults, query, dispatch) => {
        if (newResults === null) {
            return;
        }

        let results = Socket.searchResults[query] || [];

        for ( var i = 0; i < newResults.length; i++ ) {
            let result = newResults[i];

            let index = results.findIndex((item) => (item.id == result.id));

            if (index == -1) {
                results.push(result);
                continue;
            }

            // already exists, update count
            results[index].count = result.count;
        };

        Socket.searchResults[query] = results;

        clearTimeout(Socket.searchTimeouts[query]);

        Socket.searchTimeouts[query] = setTimeout(() => {
            dispatch(searchReceive({
                results: Socket.searchResults[query],
                query: query,
            }));

            delete Socket.searchResults[query];
        }, 500);
    },
    wsDispatcher: (message, dispatch) => {
        if (message.error) {
            return dispatch(error(message.error.message));
        }

        switch (message.type) {
            case SEARCH_RECEIVE:
                Socket.searchReceive(message.results, message.query, dispatch);
                break;

            case INDICES_RECEIVE:
                dispatch(receiveIndices(message.indices));
                break;

            case FIELDS_RECEIVE:
                dispatch(receiveFields(message.fields));
                break;

            case INITIAL_STATE_RECEIVE:
                dispatch(receiveInitialState({
                    datasources: message.datasources,
                    version: message.version
                }));
                break;

            case SEARCH_COMPLETED:
                dispatch(searchCompleted(message['request-id']));
        }
    },
    startWS: (dispatch) => {
        if (!!Socket.ws) {
            return;
        }

        let url;

        if (process.env.WEBSOCKET_URI) {
            url = process.env.WEBSOCKET_URI;
        } else {
            const {location} = window;
            url = ((location.protocol === "https:") ? "wss://" : "ws://") + location.host + "/ws";
        }

        try {
            Socket.ws = new FlowWS(url, null, Socket.wsDispatcher, dispatch);
        } catch (e) {
            dispatch(error(e));
        }
    }
};
<|endoftext|>