<commit_before>define('extplug/hooks/api-early', function (require, exports, module) {

  var fnUtils = require('extplug/util/function');

  function intercept(dispatch, eventName /*, ...params */) {
    var params = [].slice.call(arguments, 2);

    API.trigger.apply(
      API,
      // userLeave → beforeUserLeave
      [ 'before' + eventName.charAt(0).toUpperCase() + eventName.slice(1) ].concat(params)
    );

    dispatch.apply(null, [ eventName ].concat(params));
  }

  function nop() { return 'Dummy handler to ensure that plug.dj actually triggers the event'; }

  // find default plug.dj API event names
  var eventKeys = Object.keys(API).filter(function (key) {
    return key.toUpperCase() === key && typeof API[key] === 'string';
  });

  exports.install = function () {
    fnUtils.replaceMethod(API, 'dispatch', intercept);
    eventKeys.forEach(function (key) {
      // add the API constants for these, too
      API['BEFORE_' + key] = 'before' + API[key].charAt(0).toUpperCase() + API[key].slice(1);
      // plug.dj checks if an event is actually attached (through the _events hash)
      // before dispatching. We might run into situations where there is a BEFORE_
      // handler, but not a normal one, and we do need to get the BEFORE_ event to
      // trigger there. So we just pretend like we have handlers for all the things.
      API.on(key, nop);
    });
  };

  exports.uninstall = function () {
    eventKeys.forEach(function (key) {
      delete API['BEFORE_' + key];
      API.off(key, nop);
    });
    fnUtils.unreplaceMethod(API, 'dispatch', intercept);
  };

});<commit_msg>fix BEFORE_ api hooks when no handler is attached to the normal event<commit_after>define('extplug/hooks/api-early', function (require, exports, module) {

  var fnUtils = require('extplug/util/function');

  function intercept(dispatch, eventName /*, ...params */) {
    var params = [].slice.call(arguments, 2);

    API.trigger.apply(
      API,
      // userLeave → beforeUserLeave
      [ 'before' + eventName.charAt(0).toUpperCase() + eventName.slice(1) ].concat(params)
    );

    dispatch.apply(null, [ eventName ].concat(params));
  }

  function nop() { return 'Dummy handler to ensure that plug.dj actually triggers the event'; }

  // find default plug.dj API event names
  var eventKeys = Object.keys(API).filter(function (key) {
    return key.toUpperCase() === key && typeof API[key] === 'string';
  });

  exports.install = function () {
    fnUtils.replaceMethod(API, 'dispatch', intercept);
    eventKeys.forEach(function (key) {
      // add the API constants for these, too
      API['BEFORE_' + key] = 'before' + API[key].charAt(0).toUpperCase() + API[key].slice(1);
      // plug.dj checks if an event is actually attached (through the _events hash)
      // before dispatching. We might run into situations where there is a BEFORE_
      // handler, but not a normal one, and we do need to get the BEFORE_ event to
      // trigger there. So we just pretend like we have handlers for all the things.
      API.on(API[key], nop);
    });
  };

  exports.uninstall = function () {
    eventKeys.forEach(function (key) {
      delete API['BEFORE_' + key];
      API.off(key, nop);
    });
    fnUtils.unreplaceMethod(API, 'dispatch', intercept);
  };

});<|endoftext|>


<commit_before>import assert from 'assert';
import { parse } from 'graphql';
import { visit, visitInParallel } from 'graphql/language/visitor';
import { validate } from 'graphql/validation';
import { buildASTSchema } from 'graphql/utilities/buildASTSchema';

import { DefinedTypesAreUsed } from '../../src/rules/defined_types_are_used';

describe('DefinedTypesAreUsed rule', () => {
  it('catches object types that are defined but not used', () => {
    const ast = parse(`
      type Query {
        a: String
      }

      type A {
        a: String
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 1);

    assert.equal(errors[0].ruleName, 'defined-types-are-used');
    assert.equal(
      errors[0].message,
      'The type `A` is defined in the schema but not used anywhere.'
    );
    assert.deepEqual(errors[0].locations, [{ line: 6, column: 7 }]);
  });

  it('catches interface types that are defined but not used', () => {
    const ast = parse(`
      type Query {
        a: String
      }

      interface A {
        a: String
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 1);

    assert.equal(errors[0].ruleName, 'defined-types-are-used');
    assert.equal(
      errors[0].message,
      'The type `A` is defined in the schema but not used anywhere.'
    );
    assert.deepEqual(errors[0].locations, [{ line: 6, column: 7 }]);
  });

  it('catches scalar types that are defined but not used', () => {
    const ast = parse(`
      type Query {
        a: String
      }

      scalar A
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 1);

    assert.equal(errors[0].ruleName, 'defined-types-are-used');
    assert.equal(
      errors[0].message,
      'The type `A` is defined in the schema but not used anywhere.'
    );
    assert.deepEqual(errors[0].locations, [{ line: 6, column: 7 }]);
  });

  it('catches input types that are defined but not used', () => {
    const ast = parse(`
      type Query {
        a: String
      }

      input A {
        a: String
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 1);

    assert.equal(errors[0].ruleName, 'defined-types-are-used');
    assert.equal(
      errors[0].message,
      'The type `A` is defined in the schema but not used anywhere.'
    );
    assert.deepEqual(errors[0].locations, [{ line: 6, column: 7 }]);
  });

  it('catches union types that are defined but not used', () => {
    const ast = parse(`
      type Query {
        a: String
      }

      union A = Query
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 1);

    assert.equal(errors[0].ruleName, 'defined-types-are-used');
    assert.equal(
      errors[0].message,
      'The type `A` is defined in the schema but not used anywhere.'
    );
    assert.deepEqual(errors[0].locations, [{ line: 6, column: 7 }]);
  });

  it('ignores types that are a member of a union', () => {
    const ast = parse(`
      type Query {
        a: B
      }

      type A {
        a: A
      }

      union B = A | Query
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 0);
  });

  it('ignores types that implement an interface that is used', () => {
    const ast = parse(`
      type Query {
        a: Node
      }

      interface Node {
        id: ID!
      }

      type A implements Node {
        id: ID!
        a: A
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 0);
  });

  it('ignores types that are used in field definitions', () => {
    const ast = parse(`
      type Query {
        a: A
      }

      type A {
        id: ID!
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 0);
  });

  it('ignores scalar and input types that are used in arguments', () => {
    const ast = parse(`
      type Query {
        a(date: Date): String
        b(b: B): String
      }

      scalar Date

      input B {
        b: String
      }
    `);

    const schema = buildASTSchema(ast);
    const errors = validate(schema, ast, [DefinedTypesAreUsed]);

    assert.equal(errors.length, 0);
  });
});
<commit_msg>Use test helpers in DefinedTypesAreUsed tests<commit_after>import { DefinedTypesAreUsed } from '../../src/rules/defined_types_are_used';
import { expectFailsRule, expectPassesRule } from '../assertions';

describe('DefinedTypesAreUsed rule', () => {
  it('catches object types that are defined but not used', () => {
    expectFailsRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: String
      }

      type A {
        a: String
      }
    `,
      [
        {
          message:
            'The type `A` is defined in the schema but not used anywhere.',
          locations: [{ line: 6, column: 7 }],
        },
      ]
    );
  });

  it('catches interface types that are defined but not used', () => {
    expectFailsRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: String
      }

      interface A {
        a: String
      }
    `,
      [
        {
          message:
            'The type `A` is defined in the schema but not used anywhere.',
          locations: [{ line: 6, column: 7 }],
        },
      ]
    );
  });

  it('catches scalar types that are defined but not used', () => {
    expectFailsRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: String
      }

      scalar A
    `,
      [
        {
          message:
            'The type `A` is defined in the schema but not used anywhere.',
          locations: [{ line: 6, column: 7 }],
        },
      ]
    );
  });

  it('catches input types that are defined but not used', () => {
    expectFailsRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: String
      }

      input A {
        a: String
      }
    `,
      [
        {
          message:
            'The type `A` is defined in the schema but not used anywhere.',
          locations: [{ line: 6, column: 7 }],
        },
      ]
    );
  });

  it('catches union types that are defined but not used', () => {
    expectFailsRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: String
      }

      union A = Query
    `,
      [
        {
          message:
            'The type `A` is defined in the schema but not used anywhere.',
          locations: [{ line: 6, column: 7 }],
        },
      ]
    );
  });

  it('ignores types that are a member of a union', () => {
    expectPassesRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: B
      }

      type A {
        a: A
      }

      union B = A | Query
    `
    );
  });

  it('ignores types that implement an interface that is used', () => {
    expectPassesRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: Node
      }

      interface Node {
        id: ID!
      }

      type A implements Node {
        id: ID!
        a: A
      }
    `
    );
  });

  it('ignores types that are used in field definitions', () => {
    expectPassesRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a: A
      }

      type A {
        id: ID!
      }
    `
    );
  });

  it('ignores scalar and input types that are used in arguments', () => {
    expectPassesRule(
      DefinedTypesAreUsed,
      `
      type Query {
        a(date: Date): String
        b(b: B): String
      }

      scalar Date

      input B {
        b: String
      }
    `
    );
  });
});
<|endoftext|>


<commit_before>import { expect } from 'chai';
import Stubs from './Stubs.js';
const app = {};

import Search from '../../server/APIv1/search/searchController.js';

describe('search results', () => {

  beforeEach(() => {
    app.request = new Stubs.request();
    app.response = new Stubs.response();
  });

  describe('Basic search functionality', () => {
    it('Should find results when using keyword with known match', (done) => {
      app.request.params = {};
      app.request.params.q = 'sdfasdf%20cupcake';
      console.log(app.request.params.q);

      const cb = () => {
        // done callback fails if comparison fails. WUT
        // expect(app.response.json().length).to.equal(2);
        expect(app.response.json()[0]).to.have.property('title');
        done();
      };

      Search.searchRecipes(app.request, app.response, cb);
    });
    it('Should return empty array when searching for term that has no matching recipe', (done) => {
      app.request.params = {};
      app.request.params.q = 'DefinitelyNoMatchForThisLongString';

      const cb = () => {
        // done callback fails if comparison fails. WUT
        // expect(app.response.json().length).to.equal(2);
        expect(app.response.json().length).to.equal(0);
        done();
      };

      Search.searchRecipes(app.request, app.response, cb);
    });
  });

});
<commit_msg>Remove console.log from test<commit_after>import { expect } from 'chai';
import Stubs from './Stubs.js';
const app = {};

import Search from '../../server/APIv1/search/searchController.js';

describe('search results', () => {

  beforeEach(() => {
    app.request = new Stubs.request();
    app.response = new Stubs.response();
  });

  describe('Basic search functionality', () => {
    it('Should find results when using keyword with known match', (done) => {
      app.request.params = {};
      app.request.params.q = 'sdfasdf%20cupcake';

      const cb = () => {
        // done callback fails if comparison fails. WUT
        // expect(app.response.json().length).to.equal(2);
        expect(app.response.json()[0]).to.have.property('title');
        done();
      };

      Search.searchRecipes(app.request, app.response, cb);
    });
    it('Should return empty array when searching for term that has no matching recipe', (done) => {
      app.request.params = {};
      app.request.params.q = 'DefinitelyNoMatchForThisLongString';

      const cb = () => {
        // done callback fails if comparison fails. WUT
        // expect(app.response.json().length).to.equal(2);
        expect(app.response.json().length).to.equal(0);
        done();
      };

      Search.searchRecipes(app.request, app.response, cb);
    });
  });

});
<|endoftext|>


<commit_before><commit_msg>app: add new qualityControl migration, #1668<commit_after><|endoftext|>


<commit_before>const chai = require('chai');
const chaiHttp = require('chai-http');
const freeport = require('freeport');

const logger = require('../../../src/logger');
const MockServer = require('./MockServer');
const testObjects = require('../helpers/testObjects');
const { setEnv, revertAllEnvs } = require('../helpers/configEnvs');

const { expect } = chai;

chai.use(chaiHttp);

function request({
	server,
	method = 'get',
	endpoint,
	data,
	accessToken,
}) {
	return new Promise((resolve, reject) => (
		chai.request(server)[method](endpoint)
			.set({
				Accept: 'application/json',
				Authorization: accessToken,
				'Content-Type': 'application/x-www-form-urlencoded',
			})
			.send(data)
			.end((err, res) => {
				if (err) {
					reject(err);
					return;
				}
				resolve(res);
			})
	));
}

describe('Nexboard services', () => {
	let mockServer;
	let server;
	let app;
	let testHelpers;

	before((done) => {
		freeport((err, port) => {
			if (err) {
				logger.warning('freeport:', err);
			}

			const mockUrl = `http://localhost:${port}`;
			setEnv('NEXBOARD_URL', mockUrl);

			// eslint-disable-next-line global-require
			app = require('../../../src/app');
			server = app.listen(0);
			testHelpers = testObjects(app);

			({ server: mockServer } = MockServer({
				resolver: done,
				url: mockUrl,
				port,
			}));
		});
	});

	after(async () => {
		revertAllEnvs();
		await mockServer.close();
		await server.close();
	});

	it('should create a new project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = { title: 'my title', description: 'abc' };

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			data,
			accessToken,
		});

		expect(body.title).to.equal(data.title);
		expect(body.description).to.equal(data.description);
		expect(!!body.id).to.equal(true);
	});

	it('should create a new project with default title & description', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			accessToken,
		});

		expect(body.title).to.be.a('string');
		expect(body.description).to.be.a('string');
		expect(body.title.length).to.be.greaterThan(0);
		expect(body.description.length).to.be.greaterThan(0);
	});

	it('should show the details of one project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			accessToken,
		});

		const { body: detailedProject } = await request({
			server: app,
			endpoint: `/nexboard/projects/${body.id}`,
			accessToken,
		});

		expect(detailedProject.title).to.be.a('string');
		expect(detailedProject.description).to.be.a('string');
		expect(detailedProject.title.length).to.be.greaterThan(0);
		expect(detailedProject.description.length).to.be.greaterThan(0);
		expect(detailedProject.boardIds).to.be.an('array');
	});

	it('should list projects', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body: projects } = await request({
			server: app,
			endpoint: '/nexboard/projects',
			accessToken,
		});

		expect(projects).to.be.an('array');
		expect(projects.length).to.be.greaterThan(0);
	});

	it('should create a board with a project id', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = {
			title: '1',
			description: '2',
			projectId: '1234',
		};

		const { body: board } = await request({
			server: app,
			endpoint: '/nexboard/boards',
			method: 'post',
			data,
			accessToken,
		});

		expect(board.title).to.equal(data.title);
		expect(board.description).to.equal(data.description);
		expect(board.projectId).to.equal(data.projectId);
	});

	it('should list multiple boards depending on a project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = {
			projectId: '1234',
		};

		const { body: boards } = await request({
			server: app,
			endpoint: `/nexboard/boards?projectId=${data.projectId}`,
			accessToken,
		});

		expect(boards).to.be.an('array');
		expect(boards.length).to.be.greaterThan(0);
		boards.forEach((board) => {
			expect(board.projectId).to.equal(data.projectId);
		});
	});

	it('should return detailed information about one board', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const id = '1234';
		const { body: board } = await request({
			server: app,
			endpoint: `/nexboard/boards/${id}`,
			accessToken,
		});

		expect(board).to.be.an('object');
		expect(board.id).to.equal(id);
	});
});
<commit_msg>WIP test what is going wrong with travis<commit_after>const chai = require('chai');
const chaiHttp = require('chai-http');
const freeport = require('freeport');

const logger = require('../../../src/logger');
const MockServer = require('./MockServer');
const testObjects = require('../helpers/testObjects');
const { setEnv, revertAllEnvs } = require('../helpers/configEnvs');

const { expect } = chai;

chai.use(chaiHttp);

function request({
	server,
	method = 'get',
	endpoint,
	data,
	accessToken,
}) {
	return new Promise((resolve, reject) => (
		chai.request(server)[method](endpoint)
			.set({
				Accept: 'application/json',
				Authorization: accessToken,
				'Content-Type': 'application/x-www-form-urlencoded',
			})
			.send(data)
			.end((err, res) => {
				if (err) {
					reject(err);
					return;
				}
				resolve(res);
			})
	));
}

describe.skip('Nexboard services', () => {
	let mockServer;
	let server;
	let app;
	let testHelpers;

	before((done) => {
		freeport((err, port) => {
			if (err) {
				logger.warning('freeport:', err);
			}

			const mockUrl = `http://localhost:${port}`;
			setEnv('NEXBOARD_URL', mockUrl);

			// eslint-disable-next-line global-require
			app = require('../../../src/app');
			server = app.listen(0);
			testHelpers = testObjects(app);

			({ server: mockServer } = MockServer({
				resolver: done,
				url: mockUrl,
			}));
		});
	});

	after(async () => {
		revertAllEnvs();
		await mockServer.close();
		await server.close();
	});

	it('should create a new project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = { title: 'my title', description: 'abc' };

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			data,
			accessToken,
		});

		expect(body.title).to.equal(data.title);
		expect(body.description).to.equal(data.description);
		expect(!!body.id).to.equal(true);
	});

	it('should create a new project with default title & description', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			accessToken,
		});

		expect(body.title).to.be.a('string');
		expect(body.description).to.be.a('string');
		expect(body.title.length).to.be.greaterThan(0);
		expect(body.description.length).to.be.greaterThan(0);
	});

	it('should show the details of one project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body } = await request({
			server: app,
			method: 'post',
			endpoint: '/nexboard/projects',
			accessToken,
		});

		const { body: detailedProject } = await request({
			server: app,
			endpoint: `/nexboard/projects/${body.id}`,
			accessToken,
		});

		expect(detailedProject.title).to.be.a('string');
		expect(detailedProject.description).to.be.a('string');
		expect(detailedProject.title.length).to.be.greaterThan(0);
		expect(detailedProject.description.length).to.be.greaterThan(0);
		expect(detailedProject.boardIds).to.be.an('array');
	});

	it('should list projects', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const { body: projects } = await request({
			server: app,
			endpoint: '/nexboard/projects',
			accessToken,
		});

		expect(projects).to.be.an('array');
		expect(projects.length).to.be.greaterThan(0);
	});

	it('should create a board with a project id', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = {
			title: '1',
			description: '2',
			projectId: '1234',
		};

		const { body: board } = await request({
			server: app,
			endpoint: '/nexboard/boards',
			method: 'post',
			data,
			accessToken,
		});

		expect(board.title).to.equal(data.title);
		expect(board.description).to.equal(data.description);
		expect(board.projectId).to.equal(data.projectId);
	});

	it('should list multiple boards depending on a project', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const data = {
			projectId: '1234',
		};

		const { body: boards } = await request({
			server: app,
			endpoint: `/nexboard/boards?projectId=${data.projectId}`,
			accessToken,
		});

		expect(boards).to.be.an('array');
		expect(boards.length).to.be.greaterThan(0);
		boards.forEach((board) => {
			expect(board.projectId).to.equal(data.projectId);
		});
	});

	it('should return detailed information about one board', async () => {
		const {
			requestParams: { authentication: { accessToken } },
		} = await testHelpers.setupUser({ roles: ['teacher'] });

		const id = '1234';
		const { body: board } = await request({
			server: app,
			endpoint: `/nexboard/boards/${id}`,
			accessToken,
		});

		expect(board).to.be.an('object');
		expect(board.id).to.equal(id);
	});
});
<|endoftext|>


<commit_before>import {
  GET_SECTIONS,
} from '../actions/types';

export default function (state = null, action) {
    let newState;
    switch (action.type) {
    case GET_SECTIONS:
        return action.payload;
    default:
        return state;
    }
}
<commit_msg>fixed travis error<commit_after>import {
  GET_SECTIONS,
} from '../actions/types';

export default function (state = null, action) {
    switch (action.type) {
    case GET_SECTIONS:
        return action.payload;
    default:
        return state;
    }
}
<|endoftext|>


<commit_before><commit_msg>Add enddate to appointments query (#16787)<commit_after><|endoftext|>


<commit_before>/**
A version of each
For strings the order of items returned is:
currentChar, position, string, firstChar, lastChar, startPosition, endPostion, length

For arrays the order of items returned is:
currentItem, index, array, firstElement, lastElement, startIndex, endIndex, length

For objects the order of items returned is:
value, key, object, firstValue, lastValue, startKey, endKey, length

*/
function $$each(collection, callback) {
    if (typeof collection === 'string') {
        collection = collection.split("")
        for (let i = 0; i < collection.length; i++) {
            callback(collection[i], i, collection.join(""), collection['0'], collection[collection.length-1], 0, collection.length - 1, collection.length);
        }
    }
    else if (Array.isArray(collection)) {
        for (let i = 0; i < collection.length; i++) {
            callback(collection[i], i, collection, collection['0'], collection[collection.length-1], 0, collection.length - 1, collection.length);
        }
    }
    else if (typeof collection === 'object') {
        for (let key in collection) {
            callback(collection[key], key, collection, collection[Object.keys(collection)[0]], collection[(Object.keys(collection)[Object.keys(collection).length - 1])], Object.keys(collection)[0], Object.keys(collection)[Object.keys(collection).length - 1], Object.keys(collection).length);
        }
    }
}

console.log("")
 console.log("################################")
 console.log("# On Arrays")
 console.log("################################")

var myArr = ['a', [2], 3, 'd']
$$each(myArr, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})

console.log("")
 console.log("################################")
 console.log("# On strings")
 console.log("################################")

var myStr = "a23d"
$$each(myStr, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})

console.log("")
 console.log("################################")
 console.log("# on Objects")
 console.log("################################")

var myObj = {'aaa': 'one', 'b': [2], 'cee': 3, 'd': "four"}
$$each(myObj, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})
<commit_msg>Fix typo<commit_after>/**
A version of each
For strings the order of items returned is:
currentChar, position, string, firstChar, lastChar, startPosition, endPostion, length

For arrays the order of items returned is:
currentItem, index, array, firstElement, lastElement, startIndex, endIndex, length

For objects the order of items returned is:
value, key, object, firstValue, lastValue, startKey, endKey, length

*/
function $$each(collection, callback) {
    if (typeof collection === 'string') {
        collection = collection.split("")
        for (let i = 0; i < collection.length; i++) {
            callback(collection[i], i, collection.join(""), collection[0], collection[collection.length-1], 0, collection.length - 1, collection.length);
        }
    }
    else if (Array.isArray(collection)) {
        for (let i = 0; i < collection.length; i++) {
            callback(collection[i], i, collection, collection[0], collection[collection.length-1], 0, collection.length - 1, collection.length);
        }
    }
    else if (typeof collection === 'object') {
        for (let key in collection) {
            callback(collection[key], key, collection, collection[Object.keys(collection)[0]], collection[(Object.keys(collection)[Object.keys(collection).length - 1])], Object.keys(collection)[0], Object.keys(collection)[Object.keys(collection).length - 1], Object.keys(collection).length);
        }
    }
}

console.log("")
 console.log("################################")
 console.log("# On Arrays")
 console.log("################################")

var myArr = ['a', [2], 3, 'd']
$$each(myArr, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})

console.log("")
 console.log("################################")
 console.log("# On strings")
 console.log("################################")

var myStr = "a23d"
$$each(myStr, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})

console.log("")
 console.log("################################")
 console.log("# on Objects")
 console.log("################################")

var myObj = {'aaa': 'one', 'b': [2], 'cee': 3, 'd': "four"}
$$each(myObj, function(item, index, array, first, last, start, end, length) {
    console.log('item', 'index', 'array', 'first', 'last', 'start', 'end', 'length')
    console.log(item, index, array, first, last, start, end, length)
})
<|endoftext|>


<commit_before>module.exports = function(launchServer) {
  const db = require('./db.js');
  const Users = require('./models/userModel.js');
  const Languages = require('./models/languageModel.js');
  const Levels = require('./models/levelModel.js');
  const LanguagesLevels = require('./models/languageLevelModel.js');
  const UsersLanguagesLevels = require('./models/userLanguageLevelModel.js');
  const Messages = require('./models/messageModel.js');
  const Rooms = require('./models/roomModel.js');
  const UserRooms = require('./models/userRoomModel.js');
  const Relationships = require('./models/relationshipModel.js');

  const testDB = require('../tests/db.js');

  const languagesData = require('./seed/languages.js');
  const levelsData = require('./seed/levels.js');
  const test = require('../utils/getRoomInfo.js')

  Languages.belongsToMany(Levels, { through: 'languages_levels', foreignKey: 'language_id' });
  Levels.belongsToMany(Languages, { through: 'languages_levels', foreignKey: 'level_id' });

  Users.belongsToMany(LanguagesLevels, { through: 'users_languages_levels', foreignKey: 'user_id' });
  LanguagesLevels.belongsToMany(Users, { through: 'users_languages_levels', foreignKey: 'language_level_id' });

  Users.belongsToMany(Rooms, { through: 'users_rooms', foreignKey: 'user_id' });
  Rooms.belongsToMany(Users, { through: 'users_rooms', foreignKey: 'room_id' });

  Messages.belongsTo(Rooms, { foreignKey: 'room_id' });
  Messages.belongsTo(Users, { foreignKey: 'user_id' });

  // ZACH: ideally call user1Id initiator and user2Id affected or soemthing
  Users.belongsToMany(Users, { as: 'User1', through: 'relationships', foreignKey: 'user1Id' });
  Users.belongsToMany(Users, { as: 'User2', through: 'relationships', foreignKey: 'user2Id' });

  // TODO: remove force true
  db.sync({ force: true })
    .then(languagesData.seed)
    .then(levelsData.seed)
    // make sure first test function does not need ANY inputs
    .then(testDB.addUsers)
    // don't need these since they're already seeded:
    // .then(testDB.addLevels)
    // .then(testDB.addLanguages)
    .then(testDB.addLanguagesLevels)
    .then(testDB.addUsersLanguagesLevels)
    .then(testDB.addRooms)
    .then(testDB.addUsersRooms)
    .then(testDB.addMessages)
    .then(testDB.addRelationships)
    // end of tests
    // .then(r => console.log(r))
    .then(() => test.convertUserIdsToNames(['111213', '678910', '12345']))
    .then(() => launchServer());
};
<commit_msg>Remove vestegial function<commit_after>module.exports = function(launchServer) {
  const db = require('./db.js');
  const Users = require('./models/userModel.js');
  const Languages = require('./models/languageModel.js');
  const Levels = require('./models/levelModel.js');
  const LanguagesLevels = require('./models/languageLevelModel.js');
  const UsersLanguagesLevels = require('./models/userLanguageLevelModel.js');
  const Messages = require('./models/messageModel.js');
  const Rooms = require('./models/roomModel.js');
  const UserRooms = require('./models/userRoomModel.js');
  const Relationships = require('./models/relationshipModel.js');

  const testDB = require('../tests/db.js');

  const languagesData = require('./seed/languages.js');
  const levelsData = require('./seed/levels.js');

  Languages.belongsToMany(Levels, { through: 'languages_levels', foreignKey: 'language_id' });
  Levels.belongsToMany(Languages, { through: 'languages_levels', foreignKey: 'level_id' });

  Users.belongsToMany(LanguagesLevels, { through: 'users_languages_levels', foreignKey: 'user_id' });
  LanguagesLevels.belongsToMany(Users, { through: 'users_languages_levels', foreignKey: 'language_level_id' });

  Users.belongsToMany(Rooms, { through: 'users_rooms', foreignKey: 'user_id' });
  Rooms.belongsToMany(Users, { through: 'users_rooms', foreignKey: 'room_id' });

  Messages.belongsTo(Rooms, { foreignKey: 'room_id' });
  Messages.belongsTo(Users, { foreignKey: 'user_id' });

  // ZACH: ideally call user1Id initiator and user2Id affected or soemthing
  Users.belongsToMany(Users, { as: 'User1', through: 'relationships', foreignKey: 'user1Id' });
  Users.belongsToMany(Users, { as: 'User2', through: 'relationships', foreignKey: 'user2Id' });

  // TODO: remove force true
  db.sync({ force: true })
    .then(languagesData.seed)
    .then(levelsData.seed)
    // make sure first test function does not need ANY inputs
    .then(testDB.addUsers)
    // don't need these since they're already seeded:
    // .then(testDB.addLevels)
    // .then(testDB.addLanguages)
    .then(testDB.addLanguagesLevels)
    .then(testDB.addUsersLanguagesLevels)
    .then(testDB.addRooms)
    .then(testDB.addUsersRooms)
    .then(testDB.addMessages)
    .then(testDB.addRelationships)
    // end of tests
    // .then(r => console.log(r))
    .then(() => launchServer());
};
<|endoftext|>


<commit_before>/**
 * author: WaizauTam
 * des: 事件通知机制工具
 */

let events = [];
// todo 上线时这个最好关闭
let isDebug = true;

/**
 * 增加一个事件监听
 *
 * @param {String} eventName
 * @param {function} func
 * @param {any} observer
 */
function register(eventName, func, observer) {
    if (eventName && func) {
        if (!observer)
            if (isDebug) console.warn(eventName, ', no observer can\'t remove event');
        events.push({
            eventName: eventName,
            func: func,
            observer: observer
        });
    } else {
        if (isDebug) console.error('event name || function can\'t not be null');
    }
}

/**
 * 发送一个事件
 *
 * @param {String} eventName
 * @param {any} data
 */
function post(eventName, data) {
    if (eventName) {
        for (let i = 0; i < events.length; ++i) {
            let e = events[i];
            if (e.eventName === eventName) {
                e.func(data);
                if (isDebug) console.log('event: ',eventName," get a event_post");
            }
        }
    } else {
        if (isDebug) console.error('event name  can\'t not be null');
    }
}

/**
 * 删掉一个事件监听
 * 两个参数其中一个不能为空，
 * @param {String} eventName 若只有事件名字为空，则删除所有observer下的事件
 * @param {any} observer 若只有observer为空，则删除所有名为eventName的事件
 * @returns
 */
function unRegister(eventName, observer) {
    if (eventName && observer) {
        // 精准的删除某个页面下的某个注册事件监听
        for (let i = 0; i < events.length; ++i) {
            let e = events[i];
            if (e.eventName === eventName && e.observer === observer) {
                events.splice(i, 1);
                if (isDebug) console.log('unRegister event:', eventName);
                return 1;
            }
        }
        if (isDebug) console.log('can\'t find event:', eventName);
        return 0;
    } else if (eventName && !observer) {
        //删除所有名为eventName的事件
        let indexes = events.map((e, i) => e.eventName === eventName ? i : -1).filter(i => i >= 0).reverse();
        console.log(indexes);
        if (indexes.length > 0) {
            for (let i = 0; i < indexes.length; i++) {
                events.splice(indexes[i], 1);
                if (isDebug) console.log('unRegister event by eventName: ', eventName);
            }
            return indexes.length;
        } else {
            if (isDebug) console.log('can\'t find event: ', eventName);
        }
        return 0;
    } else if (!eventName && observer) {
        // 删除所有observer下的事件
        let indexes = events.map((e, i) => e.observer === observer ? i : -1).filter(i => i >= 0).reverse();
        console.log(indexes);
        if (indexes.length > 0) {
            for (let i = 0; i < indexes.length; i++) {
                events.splice(indexes[i], 1);
                if (isDebug) console.log('unRegister event by  observer');
            }
            return indexes.length;
        } else {
            if (isDebug) console.log('can\'t find event by observer');
        }
        return 0;
    } else {
        if (isDebug) console.error('event name || function can\'t not be null');
    }
    return 0;
}

module.exports = {
    register: register,
    post: post,
    unRegister: unRegister
}<commit_msg>change the params order for register \ unregister<commit_after>/**
 * author: WaizauTam
 * des: 事件通知机制工具
 */

let events = [];
// todo 上线时这个最好关闭
let isDebug = true;

/**
 * 增加一个事件监听
 *
 * @param {String} eventName
 * @param {function} func
 * @param {any} observer
 */
function register(observer, eventName, func) {
    if (eventName && func) {
        if (!observer)
            if (isDebug) console.warn(eventName, ', no observer can\'t remove event');
        events.push({
            eventName: eventName,
            func: func,
            observer: observer
        });
    } else {
        if (isDebug) console.error('event name || function can\'t not be null');
    }
}

/**
 * 发送一个事件
 *
 * @param {String} eventName
 * @param {any} data
 */
function post(eventName, data) {
    if (eventName) {
        for (let i = 0; i < events.length; ++i) {
            let e = events[i];
            if (e.eventName === eventName) {
                e.func(data);
                if (isDebug) console.log('event: ', eventName, " get a event_post");
            }
        }
    } else {
        if (isDebug) console.error('event name  can\'t not be null');
    }
}

/**
 * 删掉一个事件监听
 * 两个参数其中一个不能为空，
 * @param {String} eventName 若只有事件名字为空，则删除所有observer下的事件
 * @param {any} observer 若只有observer为空，则删除所有名为eventName的事件
 * @returns
 */
function unRegister(observer, eventName) {
    if (eventName && observer) {
        // 精准的删除某个页面下的某个注册事件监听
        for (let i = 0; i < events.length; ++i) {
            let e = events[i];
            if (e.eventName === eventName && e.observer === observer) {
                events.splice(i, 1);
                if (isDebug) console.log('unRegister event:', eventName);
                return 1;
            }
        }
        if (isDebug) console.log('can\'t find event:', eventName);
        return 0;
    } else if (eventName && !observer) {
        //删除所有名为eventName的事件
        let indexes = events.map((e, i) => e.eventName === eventName ? i : -1).filter(i => i >= 0).reverse();
        console.log(indexes);
        if (indexes.length > 0) {
            for (let i = 0; i < indexes.length; i++) {
                events.splice(indexes[i], 1);
                if (isDebug) console.log('unRegister event by eventName: ', eventName);
            }
            return indexes.length;
        } else {
            if (isDebug) console.log('can\'t find event: ', eventName);
        }
        return 0;
    } else if (!eventName && observer) {
        // 删除所有observer下的事件
        let indexes = events.map((e, i) => e.observer === observer ? i : -1).filter(i => i >= 0).reverse();
        console.log(indexes);
        if (indexes.length > 0) {
            for (let i = 0; i < indexes.length; i++) {
                events.splice(indexes[i], 1);
                if (isDebug) console.log('unRegister event by  observer');
            }
            return indexes.length;
        } else {
            if (isDebug) console.log('can\'t find event by observer');
        }
        return 0;
    } else {
        if (isDebug) console.error('event name || function can\'t not be null');
    }
    return 0;
}

module.exports = {
    register: register,
    post: post,
    unRegister: unRegister
}<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var babel = require('gulp-babel');
var del = require('del');
var lint = require('gulp-eslint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');

var srcJS = './src/foo.js';

// Tasks
// ---------------------------------------------------------
gulp.task('clean', function () {
  del(['./foo.js']);
});

gulp.task('lint', function () {
  return gulp.src(srcJS)
    .pipe(plumber())
    .pipe(lint())
    .pipe(lint.format())
    .pipe(lint.failOnError());
});

gulp.task('build', ['clean', 'lint'], function () {
  return gulp.src(srcJS)
    .pipe(plumber())
    .pipe(babel())
    .pipe(rename('index.js'))
    .pipe(gulp.dest('./'));
});

gulp.task('watch', function () {
  gulp.watch(srcJS, ['lint']);
});

// default task
// -----------------------------------------------
gulp.task('default', ['clean', 'lint', 'watch']);
<commit_msg>Set gulpfile config vars<commit_after>'use strict';

var gulp = require('gulp');
var babel = require('gulp-babel');
var del = require('del');
var lint = require('gulp-eslint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');

var config = {
  src: './src/server.js'
};

// Tasks
// ---------------------------------------------------------
gulp.task('clean', function () {
  del(['./dist']);
});

gulp.task('lint', function () {
  return gulp.src(config.src)
    .pipe(plumber())
    .pipe(lint())
    .pipe(lint.format())
    .pipe(lint.failOnError());
});

gulp.task('build', ['clean', 'lint'], function () {
  return gulp.src(config.src)
    .pipe(plumber())
    .pipe(babel())
    .pipe(rename('index.js'))
    .pipe(gulp.dest('./'));
});

gulp.task('watch', function () {
  gulp.watch(config.src, ['lint']);
});

// default task
// -----------------------------------------------
gulp.task('default', ['clean', 'lint', 'watch']);
<|endoftext|>


<commit_before>var Discord = require('discord.js');
var nlp = require('compromise');
var _l = require('lodash')
var Twitter = require('twitter')
var jsmegahal = require('jsmegahal');
var megahal = new jsmegahal(2);
var client = new Twitter({
  consumer_key: process.env.consumer_key,
  consumer_secret: process.env.consumer_secret,
  access_token_key: process.env.access_token_key,
  access_token_secret: process.env.access_token_secret
});
var fs = require('fs');

fs.readFile('./seed.txt','utf8', (err,data) => {
  megahal.addMass(data)
})
var bot = new Discord.Client({autoReconnect: true});

var tomato = ['jejune','pretentious', 'meh', "wouldn't see it in theatres", "first-rate", "insightful", "clever", "charming", "comical", "charismatic", "enjoyable", "uproarious", "original", "tender", "hilarious", "absorbing", "sensitive", "riveting", "intriguing"]

//var reactions = ['sounds interesting','that one sucks', "i'd watch it", "maybe not", "for real?", "lol no", "come on man"]

var reactions = ["🤷","👍", "👎"]

var emojis = null;

bot.on('ready', function() {
  console.log('logged in')

});

function askForScript() {
  bot.channels.find( c => c.id == '345940851412828161').send('gimme a script').catch()
}

(function loop() {
  var rand = Math.round(Math.random() * (1920000) + 240000) ;
  console.log(`doing it again in ${rand/(60000)} minutes`)
  setTimeout(function() {
    askForScript();
    loop();
  }, rand);
}());

function startStream(s){
  client.stream('statuses/filter', s,  function(stream) {
    stream.on('data', function(tweet) {
      if(tweet.level == 'medium' || tweet.retweeted || Math.random() < 0.001){
        var embed = new Discord.RichEmbed()
            .setColor("#"+tweet.user.profile_background_color)
            .setTimestamp(new Date(tweet.created_at))
            .setThumbnail(tweet.user.profile_image_url)
            .setAuthor(tweet.user.name)
            .setTitle(tweet.text)
            .addField("retweets", tweet.retweet_count, true)
            .setFooter(tweet.user.screen_name)
           .setURL(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
        if(tweet.user.location)embed.addField("location", tweet.user.location, true)
        bot.channels.find( c => c.id == '345940851412828161').send({embed}).catch(e => console.log(e));
      }
    })
    stream.on('error', e => console.log(e))
  })
}

function queryTwitter(s){
  client.get('search/tweets', {q: s},  function(error, tweets, response) {
    if(error)console.log(e)
    else{
      var tweet = _l(tweets).maxBy( t => t.retweet_count)
          var embed = new Discord.RichEmbed()
              .setColor("#"+tweet.user.profile_background_color)
              .setTimestamp(new Date(tweet.created_at))
              .setThumbnail(tweet.user.profile_image_url)
              .setAuthor(tweet.user.name)
              .setTitle(tweet.text)
              .addField("retweets", tweet.retweet_count, true)
              .setFooter(tweet.user.screen_name)
             .setURL(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
          if(tweet.user.location)embed.addField("location", tweet.user.location, true)
          bot.channels.find( c => c.id == '345940851412828161').send({embed}).catch(e => console.log(e));
        }
      })
}

bot.on('message', function(message) {
  if(message.content.match(/.{5,}\..+/))megahal.addMass(message.content)
  else megahal.add(message.content)
  var delay = Math.random()* 50000
  if(message.author.id != bot.user.id && message.channel.id == '345940851412828161' && message.author.username == 'gbp'){
    var convDelay = Math.random() * 120000+60000
    setTimeout(() => {
      console.log('sending in '+convDelay/60000+' minutes')
      message.channel.send(megahal.getReplyFromSentence(message.content))
    }, convDelay)
    if(message.content.length > 800){message.channel.startTyping()
    var topics = _l(nlp(message.content).nouns().out('array')).countBy().toPairs().sortBy(e => -e[1]).value();
    var pro = topics[0][0]
    var sup = topics[1] ? topics[1][0] : 'everyone else'
    if(message.content.length > 800)setTimeout(() => {
      // message.reply(reactions[Math.floor(Math.random() * reactions.length)]).catch((e) => console.log(e))
      message.react(reactions[Math.floor(Math.random() * reactions.length)]).catch((e) => console.log(e))
      var critiques = [`I'm not sure about ${pro}`, `${pro} was definitely unfair to ${sup}`, `Should ${pro} end up happy? What about ${sup}?`, `Should ${pro} end up happy? ${sup} was a shit`, `I don't understand ${pro}`, `${pro} didn't deserve that`, `This story makes no sense to me`, `Is this nonsense?`, `I guess the takeaway is that, in life people like ${pro} take advantage of people like ${sup}`, `What does what happened to ${pro} say about anything?`, `What could ${pro} represent in relation to ${sup}`]
        message.channel.send(critiques[Math.floor(Math.random() * critiques.length)]+'. '+tomato[Math.floor(Math.random() * tomato.length)]).catch((e) => console.log(e))
        message.channel.stopTyping();
      },10000)
    }
  }
  // if(resp && userID != bot.id){console.log('going to respond to resp in %s seconds',delay/1000), setTimeout(() => {
  // }, delay)}
})
bot.login(process.env.SECRET).then(() => {
  startStream({follow: '117394273,34418878,2420931980,2592325530,44918425', language: 'en', filter_level: 'low'});
  startStream({track: 'artificialintelligence, mvci, cryptocurrency, ethereum, openai, skynet, TWTonline', language: 'en', filter_level: 'low'});
  setTimeout(queryTwitter('overwatch'), 10000)
  setInterval(queryTwitter('overwatch'),1000*3600)
  askForScript();
  emojis = bot.guilds.first().emojis})
<commit_msg>SAVEPOINT<commit_after>var Discord = require('discord.js');
var nlp = require('compromise');
var _l = require('lodash')
var Twitter = require('twitter')
var jsmegahal = require('jsmegahal');
var megahal = new jsmegahal(2);
var _util = require('util')
var client = new Twitter({
  consumer_key: process.env.consumer_key,
  consumer_secret: process.env.consumer_secret,
  access_token_key: process.env.access_token_key,
  access_token_secret: process.env.access_token_secret
});
var fs = require('fs');

fs.readFile('./seed.txt','utf8', (err,data) => {
  megahal.addMass(data)
})
var bot = new Discord.Client({autoReconnect: true});

var tomato = ['jejune','pretentious', 'meh', "wouldn't see it in theatres", "first-rate", "insightful", "clever", "charming", "comical", "charismatic", "enjoyable", "uproarious", "original", "tender", "hilarious", "absorbing", "sensitive", "riveting", "intriguing"]

//var reactions = ['sounds interesting','that one sucks', "i'd watch it", "maybe not", "for real?", "lol no", "come on man"]

var reactions = ["🤷","👍", "👎"]

var emojis = null;

bot.on('ready', function() {
  console.log('logged in')

});

function askForScript() {
  bot.channels.find( c => c.id == '345940851412828161').send('gimme a script').catch()
}

(function loop() {
  var rand = Math.round(Math.random() * (1920000) + 240000) ;
  console.log(`doing it again in ${rand/(60000)} minutes`)
  setTimeout(function() {
    askForScript();
    loop();
  }, rand);
}());

function startStream(s){
  client.stream('statuses/filter', s,  function(stream) {
    stream.on('data', function(tweet) {
      if(tweet.level == 'medium' || tweet.retweeted || Math.random() < 0.001){
        var embed = new Discord.RichEmbed()
            .setColor("#"+tweet.user.profile_background_color)
            .setTimestamp(new Date(tweet.created_at))
            .setThumbnail(tweet.user.profile_image_url)
            .setAuthor(tweet.user.name)
            .setTitle(tweet.text)
            .addField("retweets", tweet.retweet_count, true)
            .setFooter(tweet.user.screen_name)
           .setURL(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
        if(tweet.user.location)embed.addField("location", tweet.user.location, true)
        bot.channels.find( c => c.id == '345940851412828161').send({embed}).catch(e => console.log(e));
      }
    })
    stream.on('error', e => console.log(e))
  })
}

function queryTwitter(s){
  client.get('search/tweets', {q: s},  function(error, tweets, response) {
    console.log(_util.inspect(tweets))
    if(error)console.log(e)
    else{
      var tweet = _l(tweets).maxBy( t => t.retweet_count)
          var embed = new Discord.RichEmbed()
              .setColor("#"+tweet.user.profile_background_color)
              .setTimestamp(new Date(tweet.created_at))
              .setThumbnail(tweet.user.profile_image_url)
              .setAuthor(tweet.user.name)
              .setTitle(tweet.text)
              .addField("retweets", tweet.retweet_count, true)
              .setFooter(tweet.user.screen_name)
             .setURL(`https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`)
          if(tweet.user.location)embed.addField("location", tweet.user.location, true)
          bot.channels.find( c => c.id == '345940851412828161').send({embed}).catch(e => console.log(e));
        }
      })
}

bot.on('message', function(message) {
  if(message.content.match(/.{5,}\..+/))megahal.addMass(message.content)
  else megahal.add(message.content)
  var delay = Math.random()* 50000
  if(message.author.id != bot.user.id && message.channel.id == '345940851412828161' && message.author.username == 'gbp'){
    var convDelay = Math.random() * 120000+60000
    setTimeout(() => {
      console.log('sending in '+convDelay/60000+' minutes')
      message.channel.send(megahal.getReplyFromSentence(message.content))
    }, convDelay)
    if(message.content.length > 800){message.channel.startTyping()
    var topics = _l(nlp(message.content).nouns().out('array')).countBy().toPairs().sortBy(e => -e[1]).value();
    var pro = topics[0][0]
    var sup = topics[1] ? topics[1][0] : 'everyone else'
    if(message.content.length > 800)setTimeout(() => {
      // message.reply(reactions[Math.floor(Math.random() * reactions.length)]).catch((e) => console.log(e))
      message.react(reactions[Math.floor(Math.random() * reactions.length)]).catch((e) => console.log(e))
      var critiques = [`I'm not sure about ${pro}`, `${pro} was definitely unfair to ${sup}`, `Should ${pro} end up happy? What about ${sup}?`, `Should ${pro} end up happy? ${sup} was a shit`, `I don't understand ${pro}`, `${pro} didn't deserve that`, `This story makes no sense to me`, `Is this nonsense?`, `I guess the takeaway is that, in life people like ${pro} take advantage of people like ${sup}`, `What does what happened to ${pro} say about anything?`, `What could ${pro} represent in relation to ${sup}`]
        message.channel.send(critiques[Math.floor(Math.random() * critiques.length)]+'. '+tomato[Math.floor(Math.random() * tomato.length)]).catch((e) => console.log(e))
        message.channel.stopTyping();
      },10000)
    }
  }
  // if(resp && userID != bot.id){console.log('going to respond to resp in %s seconds',delay/1000), setTimeout(() => {
  // }, delay)}
})
bot.login(process.env.SECRET).then(() => {
  startStream({follow: '117394273,34418878,2420931980,2592325530,44918425', language: 'en', filter_level: 'low'});
  startStream({track: 'artificialintelligence, mvci, cryptocurrency, ethereum, openai, skynet, TWTonline', language: 'en', filter_level: 'low'});
  setTimeout(queryTwitter('overwatch'), 10000)
  setInterval(queryTwitter('overwatch'),1000*3600)
  askForScript();
  emojis = bot.guilds.first().emojis})
<|endoftext|>


<commit_before>'use strict';
/* global github: false, Async: false, Buffer: false, Subscriptions: false */

/*
GitHub API Resources:

https://developer.github.com/v3/repos/hooks/
https://github.com/mikedeboer/node-github
http://mikedeboer.github.io/node-github/

- Hooks

http://mikedeboer.github.io/node-github/#repos.prototype.getHook
http://mikedeboer.github.io/node-github/#repos.prototype.getHooks
http://mikedeboer.github.io/node-github/#repos.prototype.createHook
https://developer.github.com/v3/repos/hooks/#create-a-hook
*/

var hookUrl = Meteor.settings.hookUrl;

// Read the package.js file
// This is a simplified version of the original one from @raix
// https://raw.githubusercontent.com/raix/Meteor-mrtbulkrelease/master/mrtbulkrelease.js
var readPackagejs = function(packagejsSource) {

  var empty = function() {};
  var ret = {
    warnings: []
  };

  // Create our own fake Package api
  var PackageApi = function() {

    var describe = function(obj) {
      // Check name
      if (obj.name) {
        if (obj.name !== obj.name.toLowerCase()) {
          // Malformed name...
          ret.warnings.push(
            'Correct malformed name "' +
            obj.name +
            '" into "' +
            obj.name.toLowerCase() +
            '"'
          );
        }
        ret.name = obj.name;
      }
      else {
        ret.warnings.push('No name provided');
      }

      // Check version
      if (!obj.version) {
        ret.warnings.push('Missing version');
      }
      ret.version = obj.version;

      // Check summary
      if (!obj.summary) {
        ret.warnings.push('Missing summary');
      } else {
        if (obj.summary.length > 100) {
          ret.warnings.push(
            'Summary too long: currently ' +
            obj.summary.length +
            ' chars > 100 allowed chars'
          );
        }
      }
      ret.summary = obj.summary;

      // Check git url...
      if (!obj.git) {
        ret.warnings.push('Missing git url');
      } else {
        if (!/.git$/.test(obj.git)) {
          ret.warnings.push('Missing *.git in git url');
        }
      }
    };

    var addF = 0;
    var add_files = function() {
      if (!addF++) {
        ret.warnings.push('Use "addFiles" instead of "add_files"');
      }
    };

    var onUse = function(f) {
      f({
        use: empty,
        imply: empty,
        add_files: add_files,
        addFiles: empty,
        versionsFrom: empty,
        export: empty
      });
    };

    var onU = 0;
    var on_use = function(f) {
      if (!onU++) {
        ret.warnings.push('Use "onUse" instead of "on_use"');
      }
      onUse(f);
    };

    var onT = 0;
    var on_test = function(f) {
      if (!onT++) {
        ret.warnings.push('Use "onTest" instead of "on_test"');
      }
    };

    var regP = 0;
    var _register_plugin = function() {
      if (!regP++) {
        ret.warnings.push(
          'Use "registerBuildPlugin" instead of' +
          ' "_transitional_registerBuildPlugin"'
        );
      }
    };

    return {
      describe: describe,
      on_test: on_test,
      onTest: empty,
      on_use: on_use,
      onUse: onUse,
      registerBuildPlugin: empty,
      _transitional_registerBuildPlugin: _register_plugin
    };
  };

  // Create an empty Npm api
  var NpmApi = {
    depends: empty,
    require: empty
  };

  var CordovaApi = {
    depends: empty,
    require: empty
  };

  var reader = new Function(
    'return function (Package, Npm, Cordova) {\n' +
      // body will be the package.js file
      packagejsSource +
    '\n};'
  )();
  // Run the thing
  reader(PackageApi(), NpmApi, CordovaApi);

  // Possibly removes empty warning list
  if (ret.warnings.length === 0) {
    delete ret.warnings;
  }

  // Return the result
  return ret;
};

Meteor.methods({
  getRepoDetails: function(repoInfo) {
    // Since this is not a blocking method, tells the next method calls can
    // start in a new fiber without waiting this one to complete
    this.unblock();

    var
      user = Meteor.users.findOne(this.userId),
      ghs = user && user.services && user.services.github,
      token = ghs && ghs.accessToken;

    // Full name must be in the form 'user/repoName' or 'org/repoName'
    // Splits user and repo name
    var
      repoFullName = repoInfo.fullName.split('/'),
      repoId = repoInfo.id,
      gitUrl = repoInfo.gitUrl
    ;

    if (token) {
      github.authenticate({
        type: "oauth",
        token: token
      });
    }

    var get = Async.runSync(function(done) {
      github.repos.getContent({
        user: repoFullName[0],
        repo: repoFullName[1],
        path: 'package.js',
      }, function(err, data) {
        done(null, data);
      });
    });
    if (get.result) {
      var content = new Buffer(get.result.content, 'base64').toString('utf8');
      var pkg = {};
      try {
        pkg = readPackagejs(content);
      }
      catch(err) {
        pkg.name = 'Probably a Meteor Package';
        pkg.version = '';
        pkg.summary = '';
        pkg.warnings = ['We were unable to parse your package.js file!'];
      }
      finally {

        // Gets the list of hooks for the requested repository
        var getHooks = Async.runSync(function(done) {
          github.repos.getHooks({
            user: repoFullName[0],
            repo: repoFullName[1],
          }, function(err, data) {
            done(null, data);
          });
        });
        if (getHooks.result) {
          // Checks whether there's already (at least) one hook pointing to
          // 'https://autopublish.meteor.com/publish'
          var hooks = _
          .chain(getHooks.result)
          .filter(function(hook){
            if (hook.name === 'web' && hook.config) {
              return hook.config.url === hookUrl;
            }
          })
          .value();

          if (hooks.length > 0){
            pkg.hookId = hooks[0].id;
            pkg.enabled = true;

            // Updates the Subscription document
            Subscriptions.update({
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
            }, {$set: {
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
              hookId: hooks[0].id,
              hookEvents: hooks[0].events,
              pkgName: pkg.name,
              pkgVersion: pkg.version,
              pkgSummary: pkg.summary,
              gitUrl: gitUrl,
            }}, {
              upsert: true
            });
          }
          else {
            // Possibly removes old subscriptions
            Subscriptions.remove({
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
            });
          }
        }

        return pkg;
      }
    } else {
      throw new Meteor.Error("Not a meteor package!");
    }
  },
  toggleRepo: function(repoInfo){
    // Since this is not a blocking method, tells the next method calls can
    // start in a new fiber without waiting this one to complete
    this.unblock();

    var
      user = Meteor.users.findOne(this.userId),
      ghs = user && user.services && user.services.github,
      token = ghs && ghs.accessToken
    ;

    // Full name must be in the form 'user/repoName' or 'org/repoName'
    // Splits user and repo name
    var
      repoFullName = repoInfo.fullName.split('/'),
      repoId = repoInfo.id,
      gitUrl = repoInfo.gitUrl,
      pkgName = repoInfo.pkgName,
      pkgVersion = repoInfo.pkgVersion,
      pkgSummary = repoInfo.pkgSummary
    ;

    if (token) {
      github.authenticate({
        type: "oauth",
        token: token
      });
    }

    // Array of possible errors to appear during toggle operations
    var errs = [];
    // Result object to return
    var ret = {};

    // Gets the list of hooks for the requested repository
    var get = Async.runSync(function(done) {
      github.repos.getHooks({
        user: repoFullName[0],
        repo: repoFullName[1],
      }, function(err, data) {
        done(null, data);
      });
    });
    if (get.result) {
      // Checks whether there's already (at least) one hook pointing to
      // 'https://autopublish.meteor.com/publish'
      var hooks = _
        .chain(get.result)
        .filter(function(hook){
          if (hook.name === 'web' && hook.config) {
            return hook.config.url === hookUrl;
          }
        })
        .value();

      if (hooks.length > 0){
        // In case there is at least one...
        // ...deletes 'all' existing hooks
        _.each(hooks, function(hook){
          var d = Async.runSync(function(done) {
            github.repos.deleteHook({
              user: repoFullName[0],
              repo: repoFullName[1],
              id: hook.id,
            }, function(err, data) {
              done(null, data);
            });
          });
          if (!d.result){
            errs.push(d.err);
          }
        });

        // Possibly removes old subscriptions
        Subscriptions.remove({
          user: repoFullName[0],
          repo: repoFullName[1],
          repoId: repoId,
        });

        ret.enabled = false;
      }
      else {
        // Otherwise creates a new hook
        var d = Async.runSync(function(done) {
          github.repos.createHook({
            user: repoFullName[0],
            repo: repoFullName[1],
            name: 'web',
            config: {
              url: hookUrl,
              content_type: "json",
            },
            // XXX: TODO: It seems that with both "create" and "release"
            //            we get two triggers...
            //            Options needed to select which one to listen to!
            //events: ["create", "release"],
            events: ["create"],
            active: true,
          }, function(err, data) {
            done(null, data);
          });
        });
        if (!d.result){
          errs.push(d.err);
        }
        else{
          ret.hookId = d.result.id;
          ret.enabled = true;

          // Adds the Subscription document
          Subscriptions.update({
            user: repoFullName[0],
            repo: repoFullName[1],
            repoId: repoId,
          }, {$set: {
            user: repoFullName[0],
            repo: repoFullName[1],
            repoId: repoId,
            hookId: d.result.id,
            hookEvents: d.result.events,
            pkgName: pkgName,
            pkgVersion: pkgVersion,
            pkgSummary: pkgSummary,
            gitUrl: gitUrl,
          }}, {
            upsert: true
          });
        }
      }
    }

    // Possibly adds errors to the resutl object
    if (errs.length > 0) {
      ret.errs = errs;
    }
    return ret;
  }
});
<commit_msg>switched to release webhook<commit_after>'use strict';
/* global github: false, Async: false, Buffer: false, Subscriptions: false */

/*
GitHub API Resources:

https://developer.github.com/v3/repos/hooks/
https://github.com/mikedeboer/node-github
http://mikedeboer.github.io/node-github/

- Hooks

http://mikedeboer.github.io/node-github/#repos.prototype.getHook
http://mikedeboer.github.io/node-github/#repos.prototype.getHooks
http://mikedeboer.github.io/node-github/#repos.prototype.createHook
https://developer.github.com/v3/repos/hooks/#create-a-hook
*/

var hookUrl = Meteor.settings.hookUrl;

// Read the package.js file
// This is a simplified version of the original one from @raix
// https://raw.githubusercontent.com/raix/Meteor-mrtbulkrelease/master/mrtbulkrelease.js
var readPackagejs = function(packagejsSource) {

  var empty = function() {};
  var ret = {
    warnings: []
  };

  // Create our own fake Package api
  var PackageApi = function() {

    var describe = function(obj) {
      // Check name
      if (obj.name) {
        if (obj.name !== obj.name.toLowerCase()) {
          // Malformed name...
          ret.warnings.push(
            'Correct malformed name "' +
            obj.name +
            '" into "' +
            obj.name.toLowerCase() +
            '"'
          );
        }
        ret.name = obj.name;
      }
      else {
        ret.warnings.push('No name provided');
      }

      // Check version
      if (!obj.version) {
        ret.warnings.push('Missing version');
      }
      ret.version = obj.version;

      // Check summary
      if (!obj.summary) {
        ret.warnings.push('Missing summary');
      } else {
        if (obj.summary.length > 100) {
          ret.warnings.push(
            'Summary too long: currently ' +
            obj.summary.length +
            ' chars > 100 allowed chars'
          );
        }
      }
      ret.summary = obj.summary;

      // Check git url...
      if (!obj.git) {
        ret.warnings.push('Missing git url');
      } else {
        if (!/.git$/.test(obj.git)) {
          ret.warnings.push('Missing *.git in git url');
        }
      }
    };

    var addF = 0;
    var add_files = function() {
      if (!addF++) {
        ret.warnings.push('Use "addFiles" instead of "add_files"');
      }
    };

    var onUse = function(f) {
      f({
        use: empty,
        imply: empty,
        add_files: add_files,
        addFiles: empty,
        versionsFrom: empty,
        export: empty
      });
    };

    var onU = 0;
    var on_use = function(f) {
      if (!onU++) {
        ret.warnings.push('Use "onUse" instead of "on_use"');
      }
      onUse(f);
    };

    var onT = 0;
    var on_test = function(f) {
      if (!onT++) {
        ret.warnings.push('Use "onTest" instead of "on_test"');
      }
    };

    var regP = 0;
    var _register_plugin = function() {
      if (!regP++) {
        ret.warnings.push(
          'Use "registerBuildPlugin" instead of' +
          ' "_transitional_registerBuildPlugin"'
        );
      }
    };

    return {
      describe: describe,
      on_test: on_test,
      onTest: empty,
      on_use: on_use,
      onUse: onUse,
      registerBuildPlugin: empty,
      _transitional_registerBuildPlugin: _register_plugin
    };
  };

  // Create an empty Npm api
  var NpmApi = {
    depends: empty,
    require: empty
  };

  var CordovaApi = {
    depends: empty,
    require: empty
  };

  var reader = new Function(
    'return function (Package, Npm, Cordova) {\n' +
      // body will be the package.js file
      packagejsSource +
    '\n};'
  )();
  // Run the thing
  reader(PackageApi(), NpmApi, CordovaApi);

  // Possibly removes empty warning list
  if (ret.warnings.length === 0) {
    delete ret.warnings;
  }

  // Return the result
  return ret;
};

Meteor.methods({
  getRepoDetails: function(repoInfo) {
    // Since this is not a blocking method, tells the next method calls can
    // start in a new fiber without waiting this one to complete
    this.unblock();

    var
      user = Meteor.users.findOne(this.userId),
      ghs = user && user.services && user.services.github,
      token = ghs && ghs.accessToken;

    // Full name must be in the form 'user/repoName' or 'org/repoName'
    // Splits user and repo name
    var
      repoFullName = repoInfo.fullName.split('/'),
      repoId = repoInfo.id,
      gitUrl = repoInfo.gitUrl
    ;

    if (token) {
      github.authenticate({
        type: "oauth",
        token: token
      });
    }

    var get = Async.runSync(function(done) {
      github.repos.getContent({
        user: repoFullName[0],
        repo: repoFullName[1],
        path: 'package.js',
      }, function(err, data) {
        done(null, data);
      });
    });
    if (get.result) {
      var content = new Buffer(get.result.content, 'base64').toString('utf8');
      var pkg = {};
      try {
        pkg = readPackagejs(content);
      }
      catch(err) {
        pkg.name = 'Probably a Meteor Package';
        pkg.version = '';
        pkg.summary = '';
        pkg.warnings = ['We were unable to parse your package.js file!'];
      }
      finally {

        // Gets the list of hooks for the requested repository
        var getHooks = Async.runSync(function(done) {
          github.repos.getHooks({
            user: repoFullName[0],
            repo: repoFullName[1],
          }, function(err, data) {
            done(null, data);
          });
        });
        if (getHooks.result) {
          // Checks whether there's already (at least) one hook pointing to
          // 'https://autopublish.meteor.com/publish'
          var hooks = _
          .chain(getHooks.result)
          .filter(function(hook){
            if (hook.name === 'web' && hook.config) {
              return hook.config.url === hookUrl;
            }
          })
          .value();

          if (hooks.length > 0){
            pkg.hookId = hooks[0].id;
            pkg.enabled = true;

            // Updates the Subscription document
            Subscriptions.update({
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
            }, {$set: {
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
              hookId: hooks[0].id,
              hookEvents: hooks[0].events,
              pkgName: pkg.name,
              pkgVersion: pkg.version,
              pkgSummary: pkg.summary,
              gitUrl: gitUrl,
            }}, {
              upsert: true
            });
          }
          else {
            // Possibly removes old subscriptions
            Subscriptions.remove({
              user: repoFullName[0],
              repo: repoFullName[1],
              repoId: repoId,
            });
          }
        }

        return pkg;
      }
    } else {
      throw new Meteor.Error("Not a meteor package!");
    }
  },
  toggleRepo: function(repoInfo){
    // Since this is not a blocking method, tells the next method calls can
    // start in a new fiber without waiting this one to complete
    this.unblock();

    var
      user = Meteor.users.findOne(this.userId),
      ghs = user && user.services && user.services.github,
      token = ghs && ghs.accessToken
    ;

    // Full name must be in the form 'user/repoName' or 'org/repoName'
    // Splits user and repo name
    var
      repoFullName = repoInfo.fullName.split('/'),
      repoId = repoInfo.id,
      gitUrl = repoInfo.gitUrl,
      pkgName = repoInfo.pkgName,
      pkgVersion = repoInfo.pkgVersion,
      pkgSummary = repoInfo.pkgSummary
    ;

    if (token) {
      github.authenticate({
        type: "oauth",
        token: token
      });
    }

    // Array of possible errors to appear during toggle operations
    var errs = [];
    // Result object to return
    var ret = {};

    // Gets the list of hooks for the requested repository
    var get = Async.runSync(function(done) {
      github.repos.getHooks({
        user: repoFullName[0],
        repo: repoFullName[1],
      }, function(err, data) {
        done(null, data);
      });
    });
    if (get.result) {
      // Checks whether there's already (at least) one hook pointing to
      // 'https://autopublish.meteor.com/publish'
      var hooks = _
        .chain(get.result)
        .filter(function(hook){
          if (hook.name === 'web' && hook.config) {
            return hook.config.url === hookUrl;
          }
        })
        .value();

      if (hooks.length > 0){
        // In case there is at least one...
        // ...deletes 'all' existing hooks
        _.each(hooks, function(hook){
          var d = Async.runSync(function(done) {
            github.repos.deleteHook({
              user: repoFullName[0],
              repo: repoFullName[1],
              id: hook.id,
            }, function(err, data) {
              done(null, data);
            });
          });
          if (!d.result){
            errs.push(d.err);
          }
        });

        // Possibly removes old subscriptions
        Subscriptions.remove({
          user: repoFullName[0],
          repo: repoFullName[1],
          repoId: repoId,
        });

        ret.enabled = false;
      }
      else {
        // Otherwise creates a new hook
        var d = Async.runSync(function(done) {
          github.repos.createHook({
            user: repoFullName[0],
            repo: repoFullName[1],
            name: 'web',
            config: {
              url: hookUrl,
              content_type: "json",
            },
            // XXX: TODO: It seems that with both "create" and "release"
            //            we get two triggers...
            //            Options needed to select which one to listen to!
            //events: ["create", "release"],
            events: ["release"],
            active: true,
          }, function(err, data) {
            done(null, data);
          });
        });
        if (!d.result){
          errs.push(d.err);
        }
        else{
          ret.hookId = d.result.id;
          ret.enabled = true;

          // Adds the Subscription document
          Subscriptions.update({
            user: repoFullName[0],
            repo: repoFullName[1],
            repoId: repoId,
          }, {$set: {
            user: repoFullName[0],
            repo: repoFullName[1],
            repoId: repoId,
            hookId: d.result.id,
            hookEvents: d.result.events,
            pkgName: pkgName,
            pkgVersion: pkgVersion,
            pkgSummary: pkgSummary,
            gitUrl: gitUrl,
          }}, {
            upsert: true
          });
        }
      }
    }

    // Possibly adds errors to the resutl object
    if (errs.length > 0) {
      ret.errs = errs;
    }
    return ret;
  }
});
<|endoftext|>


<commit_before>

// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');

exports.init = function (settings) {
    /**
     * Global variables
     */
    // List of currently connected clients (users)
    var clients = [];

	// List of shared activities
	var sharedActivities = [];

    /**
     * Message types
     */
	var msgInit = 0;
	var msgListUsers = 1;
	var msgCreateSharedActivity = 2;
	var msgListSharedActivities = 3;
	var msgJoinSharedActivity = 4;
	var msgLeaveSharedActivity = 5;
	var msgOnConnectionClosed = 6;
	var msgOnSharedActivityUserChanged = 7;
	var msgSendMessage = 8;

    /**
     * HTTP server
     */
    var server = http.createServer(function (request, response) {
    });
    server.listen(settings.presence.port, function () {
        console.log("Presence Server is listening on port " + settings.presence.port+"...");
    });

    /**
     * WebSocket server
     */
    var wsServer = new webSocketServer({
        httpServer: server
    });

    // Callback function called every time someone connect to the WebSocket server
    wsServer.on('request', function (request) {
        // Accept connection from your website
        var connection = request.accept(null, request.origin);

        // Add client to array, wait for userId
        var userIndex = addClient(connection);
        var userId = false;

        // An user sent some message
        connection.on('message', function (message) {
			// Accept only text
            if (message.type === 'utf8') {
				// First message sent is user settings
                if (userId === false) {
					// Get user settings
                    var rjson = JSON.parse(message.utf8Data);
                    clients[userIndex].settings = rjson;

					// Get user name
					userId = rjson.networkId;
                    console.log('User ' + userId + ' join the network');

                } else {
					// Get message content
                    var rjson = JSON.parse(message.utf8Data);

					// Process message depending of this type
                    switch (rjson.type) {
						// MESSAGE: listUsers
						case msgListUsers:
						{
							// Compute connected user list
							var connectedUsers = [];
							for (var i = 0; i < clients.length; i++) {
								if (clients[i] != null)	{
									connectedUsers.push(clients[i].settings);
								}
							}

							// Send the list
							connection.sendUTF(JSON.stringify({
								type: msgListUsers,
								data: connectedUsers
							}));
							break;
						}

						// MESSAGE: createSharedActivity
						case msgCreateSharedActivity:
						{
							// Create shared activities
							var activityId = rjson.activityId;
							var groupId = createSharedActivity(activityId, userId);
							console.log('Shared group ' + groupId + " (" + activityId + ") created");

							// Add user into group
							addUserIntoGroup(groupId, userId);

							// Send the group id
							connection.sendUTF(JSON.stringify({
								type: msgCreateSharedActivity,
								data: groupId
							}));
							break;
						}

						// MESSAGE: listSharedActivities
						case msgListSharedActivities:
						{
							// Compute shared activities list
							var listShared = [];
							for (var i = 0; i < sharedActivities.length; i++) {
								if (sharedActivities[i] != null) {
									listShared.push(sharedActivities[i]);
								}
							}

							// Send the list
							connection.sendUTF(JSON.stringify({
								type: msgListSharedActivities,
								data: listShared
							}));
							break;
						}

						// MESSAGE: joinSharedActivity
						case msgJoinSharedActivity:
						{
							// Update group
							var groupId = rjson.group;
							var groupProperties = addUserIntoGroup(groupId, userId);

							// Send the group properties
							connection.sendUTF(JSON.stringify({
								type: msgJoinSharedActivity,
								data: groupProperties
							}));
							break;
						}

						// MESSAGE: leaveSharedActivity
						case msgLeaveSharedActivity:
						{
							// Update group
							var groupId = rjson.group;
							removeUserFromGroup(groupId, userId);
							break;
						}

						// MESSAGE: sendMessage
						case msgSendMessage:
						{
							// Get arguments
							var groupId = rjson.group;
							var data = rjson.data;

							// Send the group properties
							var message = { type: msgSendMessage, data: data };
							broadcastToGroup(groupId, message);
							break;
						}

                    default:
                        console.log("Unrecognized received json type");
						break;
                    }

                }
            }

        });

        // user disconnected
        connection.on('close', function (connection)
        {
            if (userId !== false)
            {
                console.log("User " + userId + " disconnected");
				removeClient(userIndex);
            }
        });

    });

    /**
     * Utility functions
     */

    // Create a uuid
    function createUUID() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
        s[8] = s[13] = s[18] = s[23] = "-";

        var uuid = s.join("");
        return uuid;
    };

	// Find client by id
	function findClient(userId) {
		for (var i = 0 ; i < clients.length ; i++) {
			if (clients[i] != null && clients[i].settings.networkId == userId)
				return i;
		}
		return -1;
	}

	// Add a new client in the client array
	function addClient(connection) {
		// Create client
		var client = { connection: connection };

		// Find a free space in array
		for (var i = 0 ; i < clients.length ; i++) {
			// Found, use it to store user
			if (clients[i] == null) {
				clients[i] = client;
				return i;
			}
		}

		// Not found, increase array to store user
		return clients.push(client) - 1;
	}

	// Remove a client from the client array
	function removeClient(index) {
		// Iterate on each shared activities
		var userId = clients[index].settings.networkId;
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			if (sharedActivities[i] == null)
				continue;

			// Remove user from group
			removeUserFromGroup(sharedActivities[i].id, userId);
		}

		// Clean array
		clients[index] = null;
	}

	// Create a new shared activity
	function createSharedActivity(activityId, user) {
		// Create a new group
		var group = { id: createUUID(), activityId: activityId, users: [] };

		// Find a free space in array
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			// Found, use it to store group
			if (sharedActivities[i] == null) {
				sharedActivities[i] = group;
				return group.id;
			}
		}

		// Fill activity color with user color
		var userIndex = findClient(user);
		if (userIndex != -1 && clients[userIndex]) {
			group.colorvalue = clients[userIndex].settings.colorvalue;
		}
		// Not found, increase array to store group
		sharedActivities.push(group);
		return group.id;
	}

	// Find a group by Id
	function findGroup(groupId) {
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			// Found, use it to store group
			if (sharedActivities[i] == null)
				continue;
			if (sharedActivities[i].id == groupId)
				return i;
		}
		return -1;
	}

	// Add user into a group id
	function addUserIntoGroup(groupId, userId) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return null;

		// Add the user in group if not already there
		var usersInGroup = sharedActivities[groupIndex].users;
		var foundUser = false;
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Check if client is in the group
			if (usersInGroup[j] == userId) {
				foundUser = true;
				break;
			}
		}
		if (!foundUser) {
			sharedActivities[groupIndex].users.push(userId);
			console.log('User ' + userId + ' join group ' + groupId);
			var userIndex = findClient(userId);
			var message = { type: msgOnSharedActivityUserChanged, data: { user: clients[userIndex].settings, move: +1 } };
			broadcastToGroup(groupId, message);
		}

		// Return group properties
		return sharedActivities[groupIndex];
	}

	// Remove an user from a group id
	function removeUserFromGroup(groupId, userId) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return null;

		// Remove the userId
		var usersInGroup = sharedActivities[groupIndex].users;
		var newUsersInGroup = [];
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Check if client is in the group
			var currentUser = usersInGroup[j];
			if (currentUser != userId)
				newUsersInGroup.push(currentUser);
			else {
				console.log('User ' + userId + ' leave group ' + groupId);
				var userIndex = findClient(userId);
				var message = { type: msgOnSharedActivityUserChanged, data: { user: clients[userIndex].settings, move: -1 } };
				broadcastToGroup(groupId, message);
			}
		}

		// If the group is now empty, remove it
		sharedActivities[groupIndex].users = newUsersInGroup;
		if (newUsersInGroup.length == 0) {
			console.log('Shared group ' + groupId + " removed");
			sharedActivities[groupIndex] = null;
		}
	}

	// Broadcast a message to all group member
    function broadcastToGroup(groupId, json) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return;

		// For each user in the group
		var usersInGroup = sharedActivities[groupIndex].users;
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Get client
			var clientIndex = findClient(usersInGroup[j]);
			if (clientIndex == -1)
				return;

			// Send message
			var connection = clients[clientIndex].connection;
			connection.sendUTF(JSON.stringify(json));
		}
    }
}<commit_msg>Fix issue on shared activity color on server<commit_after>

// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');

exports.init = function (settings) {
    /**
     * Global variables
     */
    // List of currently connected clients (users)
    var clients = [];

	// List of shared activities
	var sharedActivities = [];

    /**
     * Message types
     */
	var msgInit = 0;
	var msgListUsers = 1;
	var msgCreateSharedActivity = 2;
	var msgListSharedActivities = 3;
	var msgJoinSharedActivity = 4;
	var msgLeaveSharedActivity = 5;
	var msgOnConnectionClosed = 6;
	var msgOnSharedActivityUserChanged = 7;
	var msgSendMessage = 8;

    /**
     * HTTP server
     */
    var server = http.createServer(function (request, response) {
    });
    server.listen(settings.presence.port, function () {
        console.log("Presence Server is listening on port " + settings.presence.port+"...");
    });

    /**
     * WebSocket server
     */
    var wsServer = new webSocketServer({
        httpServer: server
    });

    // Callback function called every time someone connect to the WebSocket server
    wsServer.on('request', function (request) {
        // Accept connection from your website
        var connection = request.accept(null, request.origin);

        // Add client to array, wait for userId
        var userIndex = addClient(connection);
        var userId = false;

        // An user sent some message
        connection.on('message', function (message) {
			// Accept only text
            if (message.type === 'utf8') {
				// First message sent is user settings
                if (userId === false) {
					// Get user settings
                    var rjson = JSON.parse(message.utf8Data);
                    clients[userIndex].settings = rjson;

					// Get user name
					userId = rjson.networkId;
                    console.log('User ' + userId + ' join the network');
                } else {
					// Get message content
                    var rjson = JSON.parse(message.utf8Data);

					// Process message depending of this type
                    switch (rjson.type) {
						// MESSAGE: listUsers
						case msgListUsers:
						{
							// Compute connected user list
							var connectedUsers = [];
							for (var i = 0; i < clients.length; i++) {
								if (clients[i] != null)	{
									connectedUsers.push(clients[i].settings);
								}
							}

							// Send the list
							connection.sendUTF(JSON.stringify({
								type: msgListUsers,
								data: connectedUsers
							}));
							break;
						}

						// MESSAGE: createSharedActivity
						case msgCreateSharedActivity:
						{
							// Create shared activities
							var activityId = rjson.activityId;
							var groupId = createSharedActivity(activityId, userId);
							console.log('Shared group ' + groupId + " (" + activityId + ") created");

							// Add user into group
							addUserIntoGroup(groupId, userId);

							// Send the group id
							connection.sendUTF(JSON.stringify({
								type: msgCreateSharedActivity,
								data: groupId
							}));
							break;
						}

						// MESSAGE: listSharedActivities
						case msgListSharedActivities:
						{
							// Compute shared activities list
							var listShared = [];
							for (var i = 0; i < sharedActivities.length; i++) {
								if (sharedActivities[i] != null) {
									listShared.push(sharedActivities[i]);
								}
							}

							// Send the list
							connection.sendUTF(JSON.stringify({
								type: msgListSharedActivities,
								data: listShared
							}));
							break;
						}

						// MESSAGE: joinSharedActivity
						case msgJoinSharedActivity:
						{
							// Update group
							var groupId = rjson.group;
							var groupProperties = addUserIntoGroup(groupId, userId);

							// Send the group properties
							connection.sendUTF(JSON.stringify({
								type: msgJoinSharedActivity,
								data: groupProperties
							}));
							break;
						}

						// MESSAGE: leaveSharedActivity
						case msgLeaveSharedActivity:
						{
							// Update group
							var groupId = rjson.group;
							removeUserFromGroup(groupId, userId);
							break;
						}

						// MESSAGE: sendMessage
						case msgSendMessage:
						{
							// Get arguments
							var groupId = rjson.group;
							var data = rjson.data;

							// Send the group properties
							var message = { type: msgSendMessage, data: data };
							broadcastToGroup(groupId, message);
							break;
						}

                    default:
                        console.log("Unrecognized received json type");
						break;
                    }

                }
            }

        });

        // user disconnected
        connection.on('close', function (connection)
        {
            if (userId !== false)
            {
                console.log("User " + userId + " disconnected");
				removeClient(userIndex);
            }
        });

    });

    /**
     * Utility functions
     */

    // Create a uuid
    function createUUID() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
        s[8] = s[13] = s[18] = s[23] = "-";

        var uuid = s.join("");
        return uuid;
    };

	// Find client by id
	function findClient(userId) {
		for (var i = 0 ; i < clients.length ; i++) {
			if (clients[i] != null && clients[i].settings.networkId == userId)
				return i;
		}
		return -1;
	}

	// Add a new client in the client array
	function addClient(connection) {
		// Create client
		var client = { connection: connection };

		// Find a free space in array
		for (var i = 0 ; i < clients.length ; i++) {
			// Found, use it to store user
			if (clients[i] == null) {
				clients[i] = client;
				return i;
			}
		}

		// Not found, increase array to store user
		return clients.push(client) - 1;
	}

	// Remove a client from the client array
	function removeClient(index) {
		// Iterate on each shared activities
		var userId = clients[index].settings.networkId;
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			if (sharedActivities[i] == null)
				continue;

			// Remove user from group
			removeUserFromGroup(sharedActivities[i].id, userId);
		}

		// Clean array
		clients[index] = null;
	}

	// Create a new shared activity
	function createSharedActivity(activityId, user) {
		// Create a new group
		var group = { id: createUUID(), activityId: activityId, users: [] };

		// Find a free space in array
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			// Found, use it to store group
			if (sharedActivities[i] == null) {
				sharedActivities[i] = group;
				break;
			}
		}
		if (i >= sharedActivities.length) {
			// Not found, increase array size
			sharedActivities.push(group);
		}

		// Fill activity color with user color
		var userIndex = findClient(user);
		if (userIndex != -1 && clients[userIndex]) {
			group.colorvalue = clients[userIndex].settings.colorvalue;
		}

		return group.id;
	}

	// Find a group by Id
	function findGroup(groupId) {
		for (var i = 0 ; i < sharedActivities.length ; i++) {
			// Found, use it to store group
			if (sharedActivities[i] == null)
				continue;
			if (sharedActivities[i].id == groupId)
				return i;
		}
		return -1;
	}

	// Add user into a group id
	function addUserIntoGroup(groupId, userId) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return null;

		// Add the user in group if not already there
		var usersInGroup = sharedActivities[groupIndex].users;
		var foundUser = false;
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Check if client is in the group
			if (usersInGroup[j] == userId) {
				foundUser = true;
				break;
			}
		}
		if (!foundUser) {
			sharedActivities[groupIndex].users.push(userId);
			console.log('User ' + userId + ' join group ' + groupId);
			var userIndex = findClient(userId);
			var message = { type: msgOnSharedActivityUserChanged, data: { user: clients[userIndex].settings, move: +1 } };
			broadcastToGroup(groupId, message);
		}

		// Return group properties
		return sharedActivities[groupIndex];
	}

	// Remove an user from a group id
	function removeUserFromGroup(groupId, userId) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return null;

		// Remove the userId
		var usersInGroup = sharedActivities[groupIndex].users;
		var newUsersInGroup = [];
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Check if client is in the group
			var currentUser = usersInGroup[j];
			if (currentUser != userId)
				newUsersInGroup.push(currentUser);
			else {
				console.log('User ' + userId + ' leave group ' + groupId);
				var userIndex = findClient(userId);
				var message = { type: msgOnSharedActivityUserChanged, data: { user: clients[userIndex].settings, move: -1 } };
				broadcastToGroup(groupId, message);
			}
		}

		// If the group is now empty, remove it
		sharedActivities[groupIndex].users = newUsersInGroup;
		if (newUsersInGroup.length == 0) {
			console.log('Shared group ' + groupId + " removed");
			sharedActivities[groupIndex] = null;
		}
	}

	// Broadcast a message to all group member
    function broadcastToGroup(groupId, json) {
		// Find the group
		var groupIndex = findGroup(groupId);
		if (groupIndex == -1)
			return;

		// For each user in the group
		var usersInGroup = sharedActivities[groupIndex].users;
		for (var j = 0 ; j < usersInGroup.length ; j++) {
			// Get client
			var clientIndex = findClient(usersInGroup[j]);
			if (clientIndex == -1)
				return;

			// Send message
			var connection = clients[clientIndex].connection;
			connection.sendUTF(JSON.stringify(json));
		}
    }
}<|endoftext|>