<commit_before>//import { expect } from "chai";
import test from "tape";
import tie from "../lib";

test("Constraint ties", (assert) => {
	var x = tie(2);
	var y = tie(() => 3);
	var z = tie(() => x.get() * y.get());
	assert.equal(x.get(), 2,
		"A constraint is equal to set value.");
	assert.equal(y.get(), 3,
		"A constraint value can be set with a function.");
	assert.equal(z.get(), 6,
		"Constraint value can be calculated from other constraints.");
	x.set(10);
	assert.equal(x.get(), 10,
		"Constraint can be reset.");
	assert.equal(z.get(), 30,
		"Dependent constraint are updated when depedencies' value change.");

	assert.end();
});

test("Constraint set to constraint", (assert) => {
	var x = tie('x');
	var y = tie('y');
	var z = tie(x);

	assert.equal(z.get(), 'x',
		"Constraint set to a constraint get its value."
	)
	z.set('z');
	assert.equal(z.get(), 'z',
		"It can be reset..."
	);
	assert.equal(x.get(), 'x',
		"...without changing the set constraint value."
	);
	z.set(y);
	assert.equal(z.get(), 'y',
		"It can be reset to a new constraint and will take its value."
	);

	assert.end();
});

test("Evaluations and dependency updates", (assert) => {
	let xUpdates = 0;
	let condUpdates = 0;
	const det = tie(true);
	const xSource = tie('a');
	const x = tie(() => {
		xUpdates++;
		return xSource.get();
	});
	const cond = tie(() => {
		condUpdates++;
		if(det.get()){
			return x.get();
		} else {
			return '';
		}
	});
	assert.equal(xUpdates, 0,
		"A constraint is not evaluated uncessary."
	)
	assert.equal(cond.get(), "a",
		"Proper constraint value.");
	assert.equal(xUpdates, 1,
		"Dependencies are evaluated when a constraint is get."
	);
	assert.equal(condUpdates, 1,
		"A constraint is evaluated when get."
	);
	xSource.set("b");
	assert.equal(cond.get(), "b",
		"Proper constraint value after source reset.");
	assert.equal(xUpdates, 2,
		"Source has been re-evaluated."
	);
	assert.equal(condUpdates, 2,
		"Constraint has been re-evaluated."
	);
	det.set(false);
	assert.equal(cond.get(), "",
		"Source isn't a dependency anymore."
	);
	assert.equal(xUpdates, 2,
		"Source has not been re-evaluated."
	);
	assert.equal(condUpdates, 3,
		"Constraint has been re-evaluated."
	);
	xSource.set('c');
	assert.equal(cond.get(), '',
		"Constraint does not change anymore when source is reset."
	);
	assert.equal(xUpdates, 2,
		"Source has not been re-evaluated while constraint has been requested."
	);
	assert.equal(condUpdates, 3,
		"Constraint has not been re-evaluated after being requested."
	);
	det.set(true);
	assert.equal(cond.get(), 'c',
		"Constraint is now dependent of source again."
	);
	assert.equal(condUpdates, 4,
		"It has been re-evaluated after bein requested."
	);
	assert.equal(xUpdates, 3,
		"Source too."
	);

	assert.end();
});

test("Avoid update when parent are invalidated but did not change", (assert) => {
	let zn = 0;
	let yn = 0;
	const x = tie(0);
	const y = tie(() => {
		yn++;
		return x.get() == 3;
	});
	const z = tie(() => {
		zn++;
		return y.get() ? "ok": "not ok";
	});
	z.get();
	x.set(2);
	z.get();
	assert.equal(y.get(), false,
		"Parent's value has not changed."
	)
	assert.equal(yn, 2,
		"Constraint's parent has been re-evaluated."
	);
	assert.equal(zn, 1,
		"Constraint has not as its parent's value did not actually change."
	);
	x.set(3);
	assert.equal(y.get(), true,
		"Value of constraint's parent has changed."
	);
	assert.equal(yn, 3,
		"Constraint's parent has been re-evaluated."
	);
	const lastZn = zn;
	z.get();
	assert.equal(zn, lastZn + 1,
		"Constraint is re-evaluated."
	)
	assert.end();
});

test("Cycles", (assert) => {
	const x = tie(() => x.get() || 0 + 1);
	assert.equal(x.get(), 1,
		"Self referring constraint does not create infinite loop."
	);
	const y = tie(2);
	y.get();
	y.set(() => y.get() * 2)
	assert.equal(y.get(), 4,
		"Self referring constraint return the cached value when recursively called."
	);
    // This part is still under reflection.
    // One other approach may be to allow self-invalidating evaluation (i.e. y below will always being invalid).
    // However, such constraint will create an infinite loop if a liven makes use of it.
    assert.equal(y.get(), 4,
        "Self referring constraint are still validated and are not updated  at each call."
    );
	assert.end();
});
<commit_msg>Change some tests' text.<commit_after>//import { expect } from "chai";
import test from "tape";
import tie from "../lib";

test("Constraint ties", (assert) => {
	var x = tie(2);
    assert.equal(x.get(), 2,
        "A constraint is equal to set value.");
	var y = tie(() => 3);
    assert.equal(y.get(), 3,
        "A constraint value can be set with a function.");
	var z = tie(() => x.get() * y.get());
	assert.equal(z.get(), 6,
		"Constraint value can be calculated from other constraints.");
	x.set(10);
	assert.equal(x.get(), 10,
		"Constraint can be reset.");
	assert.equal(z.get(), 30,
		"Dependent constraint are updated when depedencies' value change.");

	assert.end();
});

test("Constraint set to constraint", (assert) => {
	var x = tie('x');
	var y = tie('y');
	var z = tie(x);

	assert.equal(z.get(), 'x',
		"Constraint set to a constraint get its value."
	)
	z.set('z');
	assert.equal(z.get(), 'z',
		"It can be reset..."
	);
	assert.equal(x.get(), 'x',
		"...without changing the set constraint value."
	);
	z.set(y);
	assert.equal(z.get(), 'y',
		"It can be reset to a new constraint and will take its value."
	);

	assert.end();
});

test("Evaluations and dependency updates", (assert) => {
	let xUpdates = 0;
	let condUpdates = 0;
	const det = tie(true);
	const xSource = tie('a');
	const x = tie(() => {
		xUpdates++;
		return xSource.get();
	});
	const cond = tie(() => {
		condUpdates++;
		if(det.get()){
			return x.get();
		} else {
			return '';
		}
	});
	assert.equal(xUpdates, 0,
		"A constraint is not evaluated uncessary."
	)
	assert.equal(cond.get(), "a",
		"Constraint value ok.");
	assert.equal(xUpdates, 1,
		"Dependencies are evaluated when a constraint is get."
	);
	assert.equal(condUpdates, 1,
		"A constraint is evaluated when get."
	);
	xSource.set("b");
	assert.equal(cond.get(), "b",
		"Constraint value ok after source reset.");
	assert.equal(xUpdates, 2,
		"Source has been re-evaluated."
	);
	assert.equal(condUpdates, 2,
		"Constraint has been re-evaluated."
	);
	det.set(false);
	assert.equal(cond.get(), "",
		"Constraint value ok after source isn't a dependency anymore."
	);
	assert.equal(xUpdates, 2,
		"Source has not been re-evaluated."
	);
	assert.equal(condUpdates, 3,
		"Constraint has been re-evaluated."
	);
	xSource.set('c');
	assert.equal(cond.get(), '',
		"Constraint does not change anymore when source is reset."
	);
	assert.equal(xUpdates, 2,
		"Source has not been re-evaluated while constraint has been requested."
	);
	assert.equal(condUpdates, 3,
		"Constraint has not been re-evaluated after being requested."
	);
	det.set(true);
	assert.equal(cond.get(), 'c',
		"Constraint is now dependent of source again."
	);
	assert.equal(condUpdates, 4,
		"It has been re-evaluated after bein requested."
	);
	assert.equal(xUpdates, 3,
		"Source too."
	);

	assert.end();
});

test("Avoid update when parent are invalidated but did not change", (assert) => {
	let zn = 0;
	let yn = 0;
	const x = tie(0);
	const y = tie(() => {
		yn++;
		return x.get() == 3;
	});
	const z = tie(() => {
		zn++;
		return y.get() ? "ok": "not ok";
	});
	z.get();
	x.set(2);
	z.get();
	assert.equal(y.get(), false,
		"Parent's value has not changed."
	)
	assert.equal(yn, 2,
		"Constraint's parent has been re-evaluated."
	);
	assert.equal(zn, 1,
		"Constraint has not as its parent's value did not actually change."
	);
	x.set(3);
	assert.equal(y.get(), true,
		"Value of constraint's parent has changed."
	);
	assert.equal(yn, 3,
		"Constraint's parent has been re-evaluated."
	);
	const lastZn = zn;
	z.get();
	assert.equal(zn, lastZn + 1,
		"Constraint is re-evaluated."
	)
	assert.end();
});

test("Cycles", (assert) => {
	const x = tie(() => x.get() || 0 + 1);
	assert.equal(x.get(), 1,
		"Self referring constraint does not create infinite loop."
	);
	const y = tie(2);
	y.get();
	y.set(() => y.get() * 2)
	assert.equal(y.get(), 4,
		"Self referring constraint return the cached value when recursively called."
	);
    // This part is still under reflection.
    // One other approach may be to allow self-invalidating evaluation (i.e. y below will always being invalid).
    // However, such constraint will create an infinite loop if a liven makes use of it.
    assert.equal(y.get(), 4,
        "Self referring constraint are still validated and are not updated  at each call."
    );
	assert.end();
});
<|endoftext|>


<commit_before>var postcss = require('postcss');
var expect  = require('chai').expect;

var plugin = require('../');

var test = function (input, output, opts, done) {
    postcss([ plugin(opts) ]).process(input).then(function (result) {
        expect(result.css).to.eql(output);
        expect(result.warnings()).to.be.empty;
        done();
    }).catch(function (error) {
        done(error);
    });
};

describe('postcss-german-stylesheets', function () {

    /* Write tests here

    it('does something', function (done) {
        test('a{ }', 'a{ }', { }, done);
    });*/

});
<commit_msg>added testing<commit_after>var postcss = require('postcss');
var expect  = require('chai').expect;

var plugin = require('../');

var test = function (input, output, opts, done) {
    postcss([ plugin(opts) ]).process(input).then(function (result) {
        expect(result.css).to.eql(output);
        expect(result.warnings()).to.be.empty;
        done();
    }).catch(function (error) {
        done(error);
    });
};

describe('postcss-german-stylesheets', function () {

    // Properties
    it('converts farbe to color', function (done) {
        test('a{ farbe: white; }', 'a{ color: white; }', {}, done);
    });

    // Values
    it('converts grau to gray', function (done) {
        test('a{ color: grau; }', 'a{ color: gray; }', {}, done);
    });

});
<|endoftext|>


<commit_before>import test from 'ava';
import {
  createConnection,
  closeConnection,
  createStore,
  watchTable,
  listen,
  upsert,
  get
} from '../src/index';

const getRandomInt = function (min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
};

const {POSTGRES_USER, POSTGRES_DB} = process.env;
const PG_URL = `postgresql://${POSTGRES_USER}@localhost/${POSTGRES_DB}`;

const DEFAULTS = {
  connectionName: 'default',
  url: PG_URL,
  connection: {
    ssl: false,
    max: 10,
    min: 4,
    idleTimeoutMillis: 30000
  }
};

const STATE = {
  openPools: {},
  openClients: []
};

const FIXTURES = [
  {firstName: 'Cool', lastName: 'Foo', car: 'Prius', age: 16},
  {firstName: 'Little', lastName: 'Guy', car: 'Rari', age: 21},
  {firstName: 'BIG', lastName: 'Guy', car: 'Lambo', age: 22},
  {firstName: 'King', lastName: 'Kong', car: 'Prius', age: 30, nested: {foo: 'bar'}}
];

test.beforeEach('create connection', async t => {
  const client = await createConnection(null, {
    state: STATE,
    options: DEFAULTS
  });

  const table = `Test${getRandomInt(10000, 999999)}`;

  let createResults;

  try {
    createResults = await createStore({
      client,
      table,
      index: true,
      options: {
        watch: true,
        btreeIndex: {
          fields: [['age', 'integer']]
        }
      }
    });
  } catch (error) {
    console.log(error);
    t.fail();
  }

  if (createResults.code === 'ERROR') {
    console.log(createResults);
  }

  t.is(createResults.code, 'CREATED');

  t.context.client = client;
  t.context.table = table;
});

test.afterEach('cleanup', async t => {
  const {client, table} = t.context;
  await client.query(`DROP TABLE "${table}"`);
  client.close();
  await closeConnection(null, {state: STATE});
});

test('everything...', async t => {
  const {client, table} = t.context;

  let watcherCount = 0;
  let watcherCalled = false;

  const watcher = () => {
    watcherCount += 1;
    watcherCalled = true;
  };

  watchTable({client, table, watcher});

  listen({client});

  await upsert({
    client,
    table,
    val: FIXTURES[0],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    client,
    table,
    val: FIXTURES[1],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    client,
    table,
    val: FIXTURES[2],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    client,
    table,
    val: FIXTURES[3],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    client,
    table,
    key: {lastName: FIXTURES[0].lastName},
    val: {car: 'Lambo'},
    options: {merge: true},
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  const got1 = await get({
    client,
    table,
    key: {car: 'Lambo'}
  });

  const got2 = await get({
    client,
    table,
    key: {age: 21}
  });

  const got3 = await get({
    client,
    table,
    key: {nested: {foo: 'bar'}}
  });

  t.is(watcherCalled, true);
  t.is(watcherCount, 10);

  t.deepEqual(got1.val, Object.assign({}, FIXTURES[0], {car: 'Lambo'}));
  t.deepEqual(got2.val, FIXTURES[1]);
  t.deepEqual(got3.val, FIXTURES[3]);
});
<commit_msg>passing client now optional for main methods<commit_after>import test from 'ava';
import {
  createConnection,
  closeConnection,
  createStore,
  watchTable,
  listen,
  upsert,
  get
} from '../src/index';

const getRandomInt = function (min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
};

const {POSTGRES_USER, POSTGRES_DB} = process.env;
const PG_URL = `postgresql://${POSTGRES_USER}@localhost/${POSTGRES_DB}`;

const DEFAULTS = {
  connectionName: 'default',
  url: PG_URL,
  connection: {
    ssl: false,
    max: 10,
    min: 4,
    idleTimeoutMillis: 30000
  }
};

const STATE = {
  openPools: {},
  openClients: []
};

const FIXTURES = [
  {firstName: 'Cool', lastName: 'Foo', car: 'Prius', age: 16},
  {firstName: 'Little', lastName: 'Guy', car: 'Rari', age: 21},
  {firstName: 'BIG', lastName: 'Guy', car: 'Lambo', age: 22},
  {firstName: 'King', lastName: 'Kong', car: 'Prius', age: 30, nested: {foo: 'bar'}}
];

test.beforeEach('create connection', async t => {
  const client = await createConnection(null, {
    state: STATE,
    options: DEFAULTS
  });

  const table = `Test${getRandomInt(10000, 999999)}`;

  let createResults;

  try {
    createResults = await createStore({
      client,
      table,
      index: true,
      options: {
        watch: true,
        btreeIndex: {
          fields: [['age', 'integer']]
        }
      }
    });
  } catch (error) {
    console.log(error);
    t.fail();
  }

  if (createResults.code === 'ERROR') {
    console.log(createResults);
  }

  t.is(createResults.code, 'CREATED');

  t.context.client = client;
  t.context.table = table;
});

test.afterEach('cleanup', async t => {
  const {client, table} = t.context;
  await client.query(`DROP TABLE "${table}"`);
  client.close();
  await closeConnection(null, {state: STATE});
});

test('everything...', async t => {
  const {client, table} = t.context;

  let watcherCount = 0;
  let watcherCalled = false;

  const watcher = () => {
    watcherCount += 1;
    watcherCalled = true;
  };

  watchTable({table, watcher});

  listen({client});

  await upsert({
    table,
    val: FIXTURES[0],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    table,
    val: FIXTURES[1],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    table,
    val: FIXTURES[2],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    table,
    val: FIXTURES[3],
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  await upsert({
    table,
    key: {lastName: FIXTURES[0].lastName},
    val: {car: 'Lambo'},
    options: {merge: true},
    generateKeyFn: () => getRandomInt(1000, 1000000)
  });

  const got1 = await get({
    table,
    key: {car: 'Lambo'}
  });

  const got2 = await get({
    table,
    key: {age: 21}
  });

  const got3 = await get({
    table,
    key: {nested: {foo: 'bar'}}
  });

  t.is(watcherCalled, true);
  t.is(watcherCount, 10);

  t.deepEqual(got1.val, Object.assign({}, FIXTURES[0], {car: 'Lambo'}));
  t.deepEqual(got2.val, FIXTURES[1]);
  t.deepEqual(got3.val, FIXTURES[3]);
});
<|endoftext|>


<commit_before>const assert = require('assert')
const expect = require('chai').expect

const conf = require('../config')
const Bot = require('../index')
const test_options = {
  username : conf.test_user,
  oauth    : conf.test_oauth,
  channel  : conf.test_channel
}

describe('Bot', () => {

  describe('init', () => {
    it('should create a new bot instance when given valid arguments', () => {
      const TwitchBot = new Bot(test_options)
    })
    it('should fail when no options given', () => {
      expect(() => new Bot()).to.throw(Error)
    })
    it('should fail when given no username, oauth or channel arguments', () => {
      expect(() => new Bot({}).to.throw(Error))
      expect(() => new Bot({username: 'hal',}).to.throw(Error))
    })
  })

  describe('connect', () => {
    let TwitchBot

    afterEach(done => {
      TwitchBot.client.disconnect()
      done()
    })

    it('should connect to twitch irc', done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect()
      .then(() => {
        assert.equal(true, TwitchBot.client.conn.connected)
        done()
      })
    })
    it('should connect to the correct twitch channel', done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect()
      .then(() => {
        assert.equal('#'+test_options.channel, TwitchBot.client.opt.channels[0])
        done()
      })
    })
  })

  /* TODO: Make this test better */
  describe('raw', () => {
    let TwitchBot

    before(done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect().then(() => done())
    })

    it('should return all irc events', (done) => {
      TwitchBot.raw((err, event) => {
        if(!err && event.rawCommand === 'JOIN') {
          expect(event).to.have.any.keys('prefix', 'nick', 'user', 'host', 'args')
          expect(event.args[0]).to.equal('#'+test_options.channel)
          done()
        }
      })
    })
  })

  describe('msg', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    after(() => {
      TwitchBotSender.client.disconnect()
      TwitchBotListener.client.disconnect()
    })

    it('should send a message to the correct twitch irc channel', done => {
      TwitchBotListener.listen((err, chatter) => {
        if(!err) {
          expect(chatter.msg).to.equal('message test FeelsGoodMan')
          expect(chatter.user).to.equal(test_options.username)
          expect(chatter.channel).to.equal(test_options.channel)
          done()
        }
      })
      TwitchBotSender.msg('message test FeelsGoodMan')
    })
  })

  describe('listen', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    after(() => {
      TwitchBotSender.client.disconnect()
      TwitchBotListener.client.disconnect()
    })

    it('should listen for all messages and return chatter objects', (done) => {
      const messages = []
      TwitchBotSender.msg('chatter test 1')
      TwitchBotSender.msg('chatter test 2')
      TwitchBotListener.listen((err, chatter) => {
        if(!err) {
          messages.push(chatter)
          if(messages.length > 1) {
            expect(messages[0]).to.have.keys('user', 'msg', 'channel', 'twitch_id', 'level', 'sub', 'turbo')
            expect(messages[0].msg).to.equal('chatter test 1')
            expect(messages[1]).to.have.keys('user', 'msg', 'channel', 'twitch_id', 'level', 'sub', 'turbo')
            expect(messages[1].msg).to.equal('chatter test 2')
            done()
          }
        }
      })
    })
  })

  describe('listenFor', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    it('should listen for an exact match and return a chatter object', (done) => {
      TwitchBotSender.msg('exact match test NaM')
      TwitchBotSender.msg('exact match test KKona')
      TwitchBotListener.listenFor('exact match test KKona', (err, chatter) => {
        if(!err) {
          expect(chatter).to.not.be.null
          expect(chatter.user).to.equal(test_options.username)
          expect(chatter.msg).to.equal('exact match test KKona')
          done()
        }
      })
    })
  })

})<commit_msg>Removed config and use env variables instead<commit_after>const assert = require('assert')
const expect = require('chai').expect

const Bot = require('../index')
const test_options = {
  username : process.env.username,
  oauth    : process.env.oauth,
  channel  : process.env.channel
}

describe('Bot', () => {

  describe('init', () => {
    it('should create a new bot instance when given valid arguments', () => {
      const TwitchBot = new Bot(test_options)
    })
    it('should fail when no options given', () => {
      expect(() => new Bot()).to.throw(Error)
    })
    it('should fail when given no username, oauth or channel arguments', () => {
      expect(() => new Bot({}).to.throw(Error))
      expect(() => new Bot({username: 'hal',}).to.throw(Error))
    })
  })

  describe('connect', () => {
    let TwitchBot

    afterEach(done => {
      TwitchBot.client.disconnect()
      done()
    })

    it('should connect to twitch irc', done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect()
      .then(() => {
        assert.equal(true, TwitchBot.client.conn.connected)
        done()
      })
    })
    it('should connect to the correct twitch channel', done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect()
      .then(() => {
        assert.equal('#'+test_options.channel, TwitchBot.client.opt.channels[0])
        done()
      })
    })
  })

  /* TODO: Make this test better */
  describe('raw', () => {
    let TwitchBot

    before(done => {
      TwitchBot = new Bot(test_options)
      TwitchBot.connect().then(() => done())
    })

    it('should return all irc events', (done) => {
      TwitchBot.raw((err, event) => {
        if(!err && event.rawCommand === 'JOIN') {
          expect(event).to.have.any.keys('prefix', 'nick', 'user', 'host', 'args')
          expect(event.args[0]).to.equal('#'+test_options.channel)
          done()
        }
      })
    })
  })

  describe('msg', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    after(() => {
      TwitchBotSender.client.disconnect()
      TwitchBotListener.client.disconnect()
    })

    it('should send a message to the correct twitch irc channel', done => {
      TwitchBotListener.listen((err, chatter) => {
        if(!err) {
          expect(chatter.msg).to.equal('message test FeelsGoodMan')
          expect(chatter.user).to.equal(test_options.username)
          expect(chatter.channel).to.equal(test_options.channel)
          done()
        }
      })
      TwitchBotSender.msg('message test FeelsGoodMan')
    })
  })

  describe('listen', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    after(() => {
      TwitchBotSender.client.disconnect()
      TwitchBotListener.client.disconnect()
    })

    it('should listen for all messages and return chatter objects', (done) => {
      const messages = []
      TwitchBotSender.msg('chatter test 1')
      TwitchBotSender.msg('chatter test 2')
      TwitchBotListener.listen((err, chatter) => {
        if(!err) {
          messages.push(chatter)
          if(messages.length > 1) {
            expect(messages[0]).to.have.keys('user', 'msg', 'channel', 'twitch_id', 'level', 'sub', 'turbo')
            expect(messages[0].msg).to.equal('chatter test 1')
            expect(messages[1]).to.have.keys('user', 'msg', 'channel', 'twitch_id', 'level', 'sub', 'turbo')
            expect(messages[1].msg).to.equal('chatter test 2')
            done()
          }
        }
      })
    })
  })

  describe('listenFor', () => {
    let TwitchBotSender, TwitchBotListener

    before(done => {
      TwitchBotSender = new Bot(test_options)
      TwitchBotListener = new Bot(test_options)
      Promise.all([
        TwitchBotSender.connect(),
        TwitchBotListener.connect()
      ])
      .then(() => done())
    })

    it('should listen for an exact match and return a chatter object', (done) => {
      TwitchBotSender.msg('exact match test NaM')
      TwitchBotSender.msg('exact match test KKona')
      TwitchBotListener.listenFor('exact match test KKona', (err, chatter) => {
        if(!err) {
          expect(chatter).to.not.be.null
          expect(chatter.user).to.equal(test_options.username)
          expect(chatter.msg).to.equal('exact match test KKona')
          done()
        }
      })
    })
  })

})<|endoftext|>


<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 *
 */
(function () {

    /**
     * GUI Object

     * A very basic object to manage GUI elements

     * The object simply register on the "pointerdown"

     * or "touchstart" event and call the onClick function"
     * @class
     * @extends me.Sprite
     * @memberOf me
     * @constructor
     * @param {Number} x the x coordinate of the GUI Object
     * @param {Number} y the y coordinate of the GUI Object
     * @param {Object} settings See {@link me.Entity}
     * @example
     *
     * // create a basic GUI Object
     * var myButton = me.GUI_Object.extend(
     * {
     *    init:function (x, y)
     *    {
     *       var settings = {}
     *       settings.image = "button";
     *       settings.framewidth = 100;
     *       settings.frameheight = 50;
     *       // super constructor
     *       this._super(me.GUI_Object, "init", [x, y, settings]);
     *       // define the object z order
     *       this.z = 4;
     *    },
     *
     *    // output something in the console
     *    // when the object is clicked
     *    onClick:function (event)
     *    {
     *       console.log("clicked!");
     *       // don't propagate the event
     *       return false;
     *    }
     * });
     *
     * // add the object at pos (10,10)
     * me.game.world.addChild(new myButton(10,10));
     *
     */
    me.GUI_Object = me.Sprite.extend({
    /** @scope me.GUI_Object.prototype */

        /**
         * @ignore
         */
        init : function (x, y, settings) {
            /**
             * object can be clicked or not
             * @public
             * @type boolean
             * @default true
             * @name me.GUI_Object#isClickable
             */
            this.isClickable = true;

            /**
             * Tap and hold threshold timeout in ms
             * @type {number}
             * @default 250
             * @name me.GUI_Object#holdThreshold
             */
            this.holdThreshold = 250;

            /**
             * object can be tap and hold
             * @public
             * @type boolean
             * @default false
             * @name me.GUI_Object#isHoldable
             */
            this.isHoldable = false;

            /**
             * true if the pointer is over the object
             * @public
             * @type boolean
             * @default false
             * @name me.GUI_Object#hover
             */
            this.hover = false;

            // object has been updated (clicked,etc..)
            this.holdTimeout = null;
            this.updated = false;
            this.released = true;

            // call the parent constructor
            this._super(me.Sprite, "init", [ x, y, settings ]);

            // GUI items use screen coordinates
            this.floating = true;

            // register on mouse event
            me.input.registerPointerEvent("pointerdown", this, this.clicked.bind(this));
            me.input.registerPointerEvent("pointerup", this, this.release.bind(this));
            me.input.registerPointerEvent("pointercancel", this, this.release.bind(this));
            me.input.registerPointerEvent("pointerenter", this, this.enter.bind(this));
            me.input.registerPointerEvent("pointerleave", this, this.leave.bind(this));
        },

        /**
         * return true if the object has been clicked
         * @ignore
         */
        update : function () {
            if (this.updated) {
                // clear the flag
                if (!this.released) {
                    this.updated = false;
                }
                return true;
            }
            return false;
        },

        /**
         * function callback for the pointerdown event
         * @ignore
         */
        clicked : function (event) {
            // Check if left mouse button is pressed OR if device has touch
            if ((event.which === 1 || me.device.touch) && this.isClickable) {
                this.updated = true;
                if (this.isHoldable) {
                    if (this.holdTimeout !== null) {
                        me.timer.clearTimeout(this.holdTimeout);
                    }
                    this.holdTimeout = me.timer.setTimeout(this.hold.bind(this), this.holdThreshold, false);
                    this.released = false;
                }
                return this.onClick(event);
            }
        },

        /**
         * function called when the object is pressed

         * to be extended

         * return false if we need to stop propagating the event
         * @name onClick
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onClick : function (/* event */) {
            return false;
        },

        /**
         * function callback for the pointerEnter event
         * @ignore
         */
        enter : function (event) {
            this.hover = true;
            return this.onOver(event);
        },

        /**
         * function called when the pointer is over the object
         * @name onOver
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onOver : function (/* event */) {},

        /**
         * function callback for the pointerLeave event
         * @ignore
         */
        leave : function (event) {
            this.hover = false;
            return this.onOut(event);
        },

        /**
         * function called when the pointer is leaving the object area
         * @name onOut
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onOut : function (/* event */) {},

        /**
         * function callback for the pointerup event
         * @ignore
         */
        release : function (event) {
            this.released = true;
            this.hover = false; // also clear the hover flag
            me.timer.clearTimeout(this.holdTimeout);
            return this.onRelease(event);
        },

        /**
         * function called when the object is pressed and released

         * to be extended

         * return false if we need to stop propagating the event
         * @name onRelease
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onRelease : function () {
            return false;
        },

        /**
         * function callback for the tap and hold timer event
         * @ignore
         */
        hold : function () {
            me.timer.clearTimeout(this.holdTimeout);
            if (!this.released) {
                this.onHold();
            }
        },

        /**
         * function called when the object is pressed and held

         * to be extended

         * @name onHold
         * @memberOf me.GUI_Object
         * @public
         * @function
         */
        onHold : function () {},

        /**
         * OnDestroy notification function

         * Called by engine before deleting the object

         * be sure to call the parent function if overwritten
         * @name onDestroyEvent
         * @memberOf me.GUI_Object
         * @public
         * @function
         */
        onDestroyEvent : function () {
            me.input.releasePointerEvent("pointerdown", this);
            me.input.releasePointerEvent("pointerup", this);
            me.input.releasePointerEvent("pointercancel", this);
            me.input.releasePointerEvent("pointerenter", this);
            me.input.releasePointerEvent("pointerleave", this);
            me.timer.clearTimeout(this.holdTimeout);
        }
    });
})();
<commit_msg>[#686] also clear the `click` state on the `onPointerLeave` event<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 *
 */
(function () {

    /**
     * GUI Object

     * A very basic object to manage GUI elements

     * The object simply register on the "pointerdown"

     * or "touchstart" event and call the onClick function"
     * @class
     * @extends me.Sprite
     * @memberOf me
     * @constructor
     * @param {Number} x the x coordinate of the GUI Object
     * @param {Number} y the y coordinate of the GUI Object
     * @param {Object} settings See {@link me.Entity}
     * @example
     *
     * // create a basic GUI Object
     * var myButton = me.GUI_Object.extend(
     * {
     *    init:function (x, y)
     *    {
     *       var settings = {}
     *       settings.image = "button";
     *       settings.framewidth = 100;
     *       settings.frameheight = 50;
     *       // super constructor
     *       this._super(me.GUI_Object, "init", [x, y, settings]);
     *       // define the object z order
     *       this.z = 4;
     *    },
     *
     *    // output something in the console
     *    // when the object is clicked
     *    onClick:function (event)
     *    {
     *       console.log("clicked!");
     *       // don't propagate the event
     *       return false;
     *    }
     * });
     *
     * // add the object at pos (10,10)
     * me.game.world.addChild(new myButton(10,10));
     *
     */
    me.GUI_Object = me.Sprite.extend({
    /** @scope me.GUI_Object.prototype */

        /**
         * @ignore
         */
        init : function (x, y, settings) {
            /**
             * object can be clicked or not
             * @public
             * @type boolean
             * @default true
             * @name me.GUI_Object#isClickable
             */
            this.isClickable = true;

            /**
             * Tap and hold threshold timeout in ms
             * @type {number}
             * @default 250
             * @name me.GUI_Object#holdThreshold
             */
            this.holdThreshold = 250;

            /**
             * object can be tap and hold
             * @public
             * @type boolean
             * @default false
             * @name me.GUI_Object#isHoldable
             */
            this.isHoldable = false;

            /**
             * true if the pointer is over the object
             * @public
             * @type boolean
             * @default false
             * @name me.GUI_Object#hover
             */
            this.hover = false;

            // object has been updated (clicked,etc..)
            this.holdTimeout = null;
            this.updated = false;
            this.released = true;

            // call the parent constructor
            this._super(me.Sprite, "init", [ x, y, settings ]);

            // GUI items use screen coordinates
            this.floating = true;

            // register on mouse event
            me.input.registerPointerEvent("pointerdown", this, this.clicked.bind(this));
            me.input.registerPointerEvent("pointerup", this, this.release.bind(this));
            me.input.registerPointerEvent("pointercancel", this, this.release.bind(this));
            me.input.registerPointerEvent("pointerenter", this, this.enter.bind(this));
            me.input.registerPointerEvent("pointerleave", this, this.leave.bind(this));
        },

        /**
         * return true if the object has been clicked
         * @ignore
         */
        update : function () {
            if (this.updated) {
                // clear the flag
                if (!this.released) {
                    this.updated = false;
                }
                return true;
            }
            return false;
        },

        /**
         * function callback for the pointerdown event
         * @ignore
         */
        clicked : function (event) {
            // Check if left mouse button is pressed OR if device has touch
            if ((event.which === 1 || me.device.touch) && this.isClickable) {
                this.updated = true;
                if (this.isHoldable) {
                    if (this.holdTimeout !== null) {
                        me.timer.clearTimeout(this.holdTimeout);
                    }
                    this.holdTimeout = me.timer.setTimeout(this.hold.bind(this), this.holdThreshold, false);
                    this.released = false;
                }
                return this.onClick(event);
            }
        },

        /**
         * function called when the object is pressed

         * to be extended

         * return false if we need to stop propagating the event
         * @name onClick
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onClick : function (/* event */) {
            return false;
        },

        /**
         * function callback for the pointerEnter event
         * @ignore
         */
        enter : function (event) {
            this.hover = true;
            return this.onOver(event);
        },

        /**
         * function called when the pointer is over the object
         * @name onOver
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onOver : function (/* event */) {},

        /**
         * function callback for the pointerLeave event
         * @ignore
         */
        leave : function (event) {
            this.hover = false;
            this.release.call(this, event);
            return this.onOut(event);
        },

        /**
         * function called when the pointer is leaving the object area
         * @name onOut
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onOut : function (/* event */) {},

        /**
         * function callback for the pointerup event
         * @ignore
         */
        release : function (event) {
            if (this.released === false) {
                this.released = true;
                me.timer.clearTimeout(this.holdTimeout);
                return this.onRelease(event);
            }
        },

        /**
         * function called when the object is pressed and released

         * to be extended

         * return false if we need to stop propagating the event
         * @name onRelease
         * @memberOf me.GUI_Object
         * @public
         * @function
         * @param {Event} event the event object
         */
        onRelease : function () {
            return false;
        },

        /**
         * function callback for the tap and hold timer event
         * @ignore
         */
        hold : function () {
            me.timer.clearTimeout(this.holdTimeout);
            if (!this.released) {
                this.onHold();
            }
        },

        /**
         * function called when the object is pressed and held

         * to be extended

         * @name onHold
         * @memberOf me.GUI_Object
         * @public
         * @function
         */
        onHold : function () {},

        /**
         * OnDestroy notification function

         * Called by engine before deleting the object

         * be sure to call the parent function if overwritten
         * @name onDestroyEvent
         * @memberOf me.GUI_Object
         * @public
         * @function
         */
        onDestroyEvent : function () {
            me.input.releasePointerEvent("pointerdown", this);
            me.input.releasePointerEvent("pointerup", this);
            me.input.releasePointerEvent("pointercancel", this);
            me.input.releasePointerEvent("pointerenter", this);
            me.input.releasePointerEvent("pointerleave", this);
            me.timer.clearTimeout(this.holdTimeout);
        }
    });
})();
<|endoftext|>


<commit_before>/*
 * @author     Martin Høgh <mh@mapcentia.com>
 * @copyright  2013-2018 MapCentia ApS
 * @license    http://www.gnu.org/licenses/#AGPL  GNU AFFERO GENERAL PUBLIC LICENSE 3
 */

var express = require('express');
var router = express.Router();
var config = require('../../config/config.js').gc2;
var request = require('request');
var fs = require('fs');

router.all('/api/sql/:db', function (req, response) {
    req.setTimeout(0); // no timeout
    var db = req.params.db,
        q = req.body.q || req.query.q,
        srs = req.body.srs || req.query.srs,
        lifetime = req.body.lifetime || req.query.lifetime || "0",
        client_encoding = req.body.client_encoding || req.query.client_encoding,
        base64 = req.body.base64 || req.query.base64,
        format = req.body.format || req.query.format,
        custom_data = req.body.custom_data || req.query.custom_data,
        store = req.body.store || req.query.store,
        userName,
        fileName,
        writeStream,
        rem,
        headers,
        uri,
        key = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });

    var postData = "q=" + (base64 === "true" ? encodeURIComponent(q) : encodeURIComponent(q)) + "&base64=" + (base64 === "true" ? "true" : "false") + "&srs=" + srs + "&lifetime=" + lifetime + "&client_encoding=" + (client_encoding || "UTF8") + "&format=" + (format ? format : "geojson") + "&key=" + req.session.gc2ApiKey + "&custom_data=" + (custom_data || ""),
        options;

    // Check if user is a sub user
    if (req.session.gc2UserName && req.session.subUser) {
        userName = req.session.subUser + "@" + db;
    } else {
        userName = db;
    }

    if (req.body.key && !req.session.gc2ApiKey) {
        postData = postData + "&key=" + req.body.key;
    }

    uri = custom_data !== null && custom_data !== undefined && custom_data !== "null" ? config.host + "/api/v2/sqlwrapper/" + userName : config.host + "/api/v2/sql/" + userName;

    console.log(uri);

    options = {
        method: 'POST',
        uri: uri,
        form: postData
    };

    if (format === "excel") {
        fileName = key + ".xlsx";
        headers = {
            'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Content-Disposition': 'attachment; filename=data.xlsx',
            'Expires': '0',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'X-Powered-By': 'MapCentia Vidi'
        }
    } else {
        fileName = key + ".json";
        headers = {
            'Content-Type': 'application/json',
            'Expires': '0',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'X-Powered-By': 'MapCentia Vidi'
        }
    }

    // if (!store) {
    //     //response.writeHead(200, headers);
    // }

    rem = request(options);

    if (store) {
        writeStream = fs.createWriteStream(__dirname + "/../../public/tmp/stored_results/" + fileName);
    }

    rem.on('response', function(res) {
        console.log(res.statusCode);
        if (!store) {
            response.writeHead(res.statusCode, headers);
        }
    });

    rem.on('data', function (chunk) {
        if (store) {
            writeStream.write(chunk, 'binary');
        } else {
            response.write(chunk);
        }
    });
    rem.on('end', function () {
        if (store) {
            console.log("Result saved");
            response.send({"success": true, "file": fileName});
        } else {
            response.end();
        }
    });

});
module.exports = router;
<commit_msg>set undefined key to text string<commit_after>/*
 * @author     Martin Høgh <mh@mapcentia.com>
 * @copyright  2013-2018 MapCentia ApS
 * @license    http://www.gnu.org/licenses/#AGPL  GNU AFFERO GENERAL PUBLIC LICENSE 3
 */

var express = require('express');
var router = express.Router();
var config = require('../../config/config.js').gc2;
var request = require('request');
var fs = require('fs');

router.all('/api/sql/:db', function (req, response) {
    req.setTimeout(0); // no timeout
    var db = req.params.db,
        q = req.body.q || req.query.q,
        srs = req.body.srs || req.query.srs,
        lifetime = req.body.lifetime || req.query.lifetime || "0",
        client_encoding = req.body.client_encoding || req.query.client_encoding,
        base64 = req.body.base64 || req.query.base64,
        format = req.body.format || req.query.format,
        custom_data = req.body.custom_data || req.query.custom_data,
        store = req.body.store || req.query.store,
        userName,
        fileName,
        writeStream,
        rem,
        headers,
        uri,
        key = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });

    var postData = "q=" + (base64 === "true" ? encodeURIComponent(q) : encodeURIComponent(q)) + "&base64=" + (base64 === "true" ? "true" : "false") + "&srs=" + srs + "&lifetime=" + lifetime + "&client_encoding=" + (client_encoding || "UTF8") + "&format=" + (format ? format : "geojson") + "&key=" + (typeof req.session.gc2ApiKey !=="undefined" ? req.session.gc2ApiKey : "xxxxx") + "&custom_data=" + (custom_data || ""),
        options;

    // Check if user is a sub user
    if (req.session.gc2UserName && req.session.subUser) {
        userName = req.session.subUser + "@" + db;
    } else {
        userName = db;
    }

    if (req.body.key && !req.session.gc2ApiKey) {
        postData = postData + "&key=" + req.body.key;
    }

    uri = custom_data !== null && custom_data !== undefined && custom_data !== "null" ? config.host + "/api/v2/sqlwrapper/" + userName : config.host + "/api/v2/sql/" + userName;

    console.log(uri);

    options = {
        method: 'POST',
        uri: uri,
        form: postData
    };

    if (format === "excel") {
        fileName = key + ".xlsx";
        headers = {
            'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Content-Disposition': 'attachment; filename=data.xlsx',
            'Expires': '0',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'X-Powered-By': 'MapCentia Vidi'
        }
    } else {
        fileName = key + ".json";
        headers = {
            'Content-Type': 'application/json',
            'Expires': '0',
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'X-Powered-By': 'MapCentia Vidi'
        }
    }

    // if (!store) {
    //     //response.writeHead(200, headers);
    // }

    rem = request(options);

    if (store) {
        writeStream = fs.createWriteStream(__dirname + "/../../public/tmp/stored_results/" + fileName);
    }

    rem.on('response', function(res) {
        console.log(res.statusCode);
        if (!store) {
            response.writeHead(res.statusCode, headers);
        }
    });

    rem.on('data', function (chunk) {
        if (store) {
            writeStream.write(chunk, 'binary');
        } else {
            response.write(chunk);
        }
    });
    rem.on('end', function () {
        if (store) {
            console.log("Result saved");
            response.send({"success": true, "file": fileName});
        } else {
            response.end();
        }
    });

});
module.exports = router;
<|endoftext|>


<commit_before>/**
 * This is the Logger API for the nodgine module
 *
 * @module nodgine
 * @submodule $LOGGER
 **/

/**
 * The exporting object, which gets revealed
 *
 * @type {object}
 **/
var EXPORTOBJECT = {},

    /**
     * A reference to the fs-module
     *
     * @private
     * @type {fs}
     **/
    fs = require('fs'),
    logFile = 'Log.txt',
    toFile = false,
    toConsole = true;

/**
 * This function generates a readable timestamp for the log
 *
 * @private
 * @returns {string} readable timestamp
 */
function getDateString() {
    'use strict';
    var d = new Date();
    return d.getDate() + '.' +
        (d.getMonth()+1) + '.' +
        d.getFullYear() + ' ' +
        d.getHours() + ':' +
        ((d.getMinutes().toString().length>1) ? d.getMinutes() : '0' + d.getMinutes()) + ':' +
        ((d.getSeconds().toString().length>1) ? d.getSeconds() : '0' + d.getSeconds());
}

/**
 * This is the general function which is connected to all incoming errors to work with them
 *
 * @private
 * @param {string} aState State of given error
 * @param {boolean} aCritical Is critical or not
 * @param {string} aMessage The message for the log
 */
function enterLog(aState, aCritical, aMessage) {
    'use strict';
    if (typeof aMessage!== 'string') {
        throw 'Logger needs a string as param, got ' + (typeof aMessage);
    }
    if (toFile) {
        fs.appendFileSync(logFile, '[' + aState + '](' + getDateString() + ') '+ aMessage + '\n', {encoding: 'utf-8'});
    }
    if (toConsole) {
        console.log('[' + aState + '](' + getDateString() + ') '+ aMessage);
    }
    if (aCritical) {
        throw new Error('[' + aState + '](' + getDateString() + ') '+ aMessage);
    }
}

/**
 * With this function you can set the log file
 *
 * @chainable
 * @param {string} aFilename
 * @return {object} The instance itself
 */
function setLogFile(aFilename) {
    'use strict';
    logFile = aFilename;
    return EXPORTOBJECT;
}

/**
 * with this function you can set writing to file on or off
 *
 * @chainable
 * @param {boolean} aOption
 * @return {object} The instance itself
 */
function writeToFile(aOption) {
    'use strict';
    toFile = !!(aOption);
    return EXPORTOBJECT;
}

/**
 * with this function you can set writing to console on or off
 *
 * @chainable
 * @param {boolean} aOption
 * @return {object} The instance itself
 */
function writeToConsole(aOption) {
    'use strict';
    toConsole = !!(aOption);
    return EXPORTOBJECT;
}

Object.defineProperty(EXPORTOBJECT, 'error', {
    value: enterLog.bind(null, 'ERROR', true),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'warning', {
    value: enterLog.bind(null, 'WARNING', false),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'log', {
    value: enterLog.bind(null, 'LOG', false),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'setLogFile', {
    value: setLogFile,
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'writeToFile', {
    value: writeToFile,
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'writeToConsole', {
    value: writeToConsole,
    writable: false
});

module.exports = EXPORTOBJECT;<commit_msg>Added some last comments<commit_after>/**
 * This is the Logger API for the nodgine module
 *
 * @module nodgine
 * @submodule $LOGGER
 **/

/**
 * The exporting object, which gets revealed
 *
 * @type {object}
 **/
var EXPORTOBJECT = {},

    /**
     * A reference to the fs-module
     *
     * @private
     * @type {fs}
     **/
    fs = require('fs'),

    /**
     * The name of logfile, where to save all logs
     *
     * @private
     * @type {string}
     * @default 'Log.txt'
     **/
    logFile = 'Log.txt',

    /**
     * Flag, whether logs should be written to the logfile
     *
     * @private
     * @type {boolean}
     * @default false
     **/
    toFile = false,

    /**
     * Flag, whether logs should be written to console
     *
     * @private
     * @type {boolean}
     * @default boolean
     **/
    toConsole = true;

/**
 * This function generates a readable timestamp of current time for the log
 *
 * @private
 * @returns {string} readable timestamp of current time
 */
function getDateString() {
    'use strict';
    var d = new Date();
    return d.getDate() + '.' +
        (d.getMonth()+1) + '.' +
        d.getFullYear() + ' ' +
        d.getHours() + ':' +
        ((d.getMinutes().toString().length>1) ? d.getMinutes() : '0' + d.getMinutes()) + ':' +
        ((d.getSeconds().toString().length>1) ? d.getSeconds() : '0' + d.getSeconds());
}

/**
 * This is the general function which is connected to all incoming errors to work with them
 *
 * @private
 * @param {string} aState State of given error
 * @param {boolean} aCritical Is critical or not. If it's critical, an error will be thrown
 * @param {string} aMessage The message for the log
 */
function enterLog(aState, aCritical, aMessage) {
    'use strict';
    if (typeof aMessage!== 'string') {
        throw 'Logger needs a string as param, got ' + (typeof aMessage);
    }
    if (toFile) {
        fs.appendFileSync(logFile, '[' + aState + '](' + getDateString() + ') '+ aMessage + '\n', {encoding: 'utf-8'});
    }
    if (toConsole) {
        console.log('[' + aState + '](' + getDateString() + ') '+ aMessage);
    }
    if (aCritical) {
        throw new Error('[' + aState + '](' + getDateString() + ') '+ aMessage);
    }
}

/**
 * With this function you can set the log file
 *
 * @chainable
 * @param {string} aFilename
 * @return {object} The instance itself
 */
function setLogFile(aFilename) {
    'use strict';
    logFile = aFilename;
    return EXPORTOBJECT;
}

/**
 * with this function you can set writing to file on or off
 *
 * @chainable
 * @param {boolean} aOption
 * @return {object} The instance itself
 */
function writeToFile(aOption) {
    'use strict';
    toFile = !!(aOption);
    return EXPORTOBJECT;
}

/**
 * with this function you can set writing to console on or off
 *
 * @chainable
 * @param {boolean} aOption
 * @return {object} The instance itself
 */
function writeToConsole(aOption) {
    'use strict';
    toConsole = !!(aOption);
    return EXPORTOBJECT;
}

Object.defineProperty(EXPORTOBJECT, 'error', {
    value: enterLog.bind(null, 'ERROR', true),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'warning', {
    value: enterLog.bind(null, 'WARNING', false),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'log', {
    value: enterLog.bind(null, 'LOG', false),
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'setLogFile', {
    value: setLogFile,
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'writeToFile', {
    value: writeToFile,
    writable: false
});
Object.defineProperty(EXPORTOBJECT, 'writeToConsole', {
    value: writeToConsole,
    writable: false
});

module.exports = EXPORTOBJECT;<|endoftext|>


<commit_before>define('app/models/machine', [
    'ember'
    ],
    /**
     * Machine model
     *
     * Also check state mapping in config.py
     * @returns Class
     */
    function() {
        return Ember.Object.extend({
            id: null,
            imageId: null,
            name: null,
            backend: null,
            selected: false,
            hasKey: false,
            hasMonitoring: null,
            pendingMonitoring: false,
            pendingShell: false,
            pendingAddTag: false,
            pendingDeleteTag: false,
            pendingStats: false,
            state: 'stopped',
            stats:{'cpu': [], 'load': [], 'disk': []},
            graphdata: {},

            image: function() {
                return this.backend.images.getImage(this.imageId);
            }.property('image'),

            user: function() {
                return this.getUser();
            }.property('user'),

            reboot: function() {
                log('Rebooting machine', this.name);

                var that = this;
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=reboot',
                    success: function(data) {
                        that.set('state', 'rebooting');
                        info('Succesfully sent reboot to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending reboot to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending reboot to machine',
                                that.name);
                    }
                });
            },

            destroy: function() {
                log('Destroying machine', this.name);

                var that = this
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=destroy',
                    success: function(data) {
                        that.set('state', 'pending');
                        info('Successfully sent destroy to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending destroy to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending destroy to machine',
                                that.name);
                    }
                });
            },

            start: function() {
                log('Starting machine', this.name);

                var that = this;
                $.ajax({
                    url: 'backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=start',
                    success: function(data) {
                        that.set('state', 'pending');
                        info('Successfully sent start to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending start to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending start to machine',
                                that.name);
                    }
                });
            },

            shutdown: function() {
                log('Stopping machine', this.name);

                var that = this;
                $.ajax({
                    url: 'backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=stop',
                    success: function(data) {
                        that.set('state', 'stopped');
                        info('Successfully sent stop to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending stop to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending stop to machine',
                                that.name);
                    }
                });
            },

            getHost: function() {
                if (this.extra.dns_name) {
                    // it is an ec2 machine so it has dns_name
                    return this.extra.dns_name;
                } else {
                    // if not ec2 it should have a public ip
                    try {
                        var ips_v4 = [];
                        this.public_ips.forEach(function(ip) {
                            if (ip.search(':') == -1) {
                                // this is not an IPv6, so it is supported
                                ips_v4.push(ip);
                            }
                        });
                        return ips_v4[0];
                    } catch (error) {
                        Mist.notificationController.notify('No host available for machine ' + this.name);
                        error('No host available for machine ' + this.name);
                        return false;
                    }
                }
            },

            getUser: function() {
                // In case of ec2, mist.io could have set this. Server can handle empty string.
                try {
                    if (this.extra.tags.ssh_user != undefined) {
                        return this.extra.tags.ssh_user;
                    } else {
                        return 'root';
                    }
                } catch (error) {
                    return 'root';
                }
            },

            shell: function(shell_command, callback, timeout) {
                log('Sending', shell_command, 'to machine', this.name);

                var url = '/backends/' + this.backend.id + '/machines/' + this.id + '/shell';
                var ssh_user = this.getUser();
                var host = this.getHost();
                var that = this;
                var params =  {'host': host,
                               'ssh_user': ssh_user,
                               'command': shell_command}
                if (timeout != undefined) {
                    params['timeout'] = timeout;
                }

                function EncodeQueryData(data)
                {
                   var ret = [];
                   for (var d in data)
                      ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
                   return ret.join("&");
                }
                url = url + '?' + EncodeQueryData(params);
                this.set('pendingShell', true);

                $('#hidden-shell-iframe').attr('src', url);
                callback('');
            },

            hasAlert : function() {
                //TODO when we have alerts
                return false;
            }.property('hasAlert'),

            startUptimeTimer: function() {
                var that = this;

                setInterval(function() {
                    if (that.get('state') == 'running' && that.get('uptimeFromServer') &&
                        that.get('uptimeChecked')) {

                        that.set('uptime', that.get('uptimeFromServer') + (Date.now()
                                           - that.get('uptimeChecked')));
                    } else {
                        return;
                    }
                }, 1000);
            },

            checkUptime: function() {
                var that = this;

                function uptimeTimeout() {
                    if (!that.backend) {
                        return false;
                    }

                    if (that.state == 'running') {
                        var host = that.getHost();
                        if (host) {
                            var ssh_user = that.getUser();

                            $.ajax({
                                url: '/backends/' + that.backend.id + '/machines/' + that.id + '/shell',
                                type: 'POST',
                                headers: { "cache-control": "no-cache" },
                                data: {'host': host,
                                   'ssh_user': ssh_user,
                                   'command': 'cat /proc/uptime'},
                                success: function(data, textStatus, jqXHR) {
                                       // got it fine, also means it has a key
                                    if (jqXHR.status === 200) {
                                        that.set('hasKey', true);
                                        var resp = data.split(' ');
                                        if (resp.length == 2) {
                                            var uptime = parseFloat(resp[0]) * 1000;
                                            that.set('uptimeChecked', Date.now());
                                            that.set('uptimeFromServer', uptime);
                                        }
                                        info('Successfully got uptime', data, 'from machine', that.name);
                                    } else {
                                        // in every other case there is a problem
                                        that.set('hasKey', false);
                                        info('Got response other than 200 while getting uptime from machine', that.name);
                                        setTimeout(uptimeTimeout, 10000);
                                    }
                                },
                                error: function(jqXHR, textstate, errorThrown) {
                                    that.set('hasKey', false);
                                    //Mist.notificationController.notify('Error getting uptime from machine ' +
                                    //    that.name);
                                    error(textstate, errorThrown, 'when getting uptime from machine',
                                        that.name);
                                    setTimeout(uptimeTimeout, 10000);
                                }
                            });
                        }
                    }
                };
                setTimeout(uptimeTimeout, 2000);
            },

            resetUptime: function() {
                if (this.get('state') == 'running') {
                    this.startUptimeTimer();
                    this.checkUptime();
                } else {
                    this.set('uptime', 0);
                    this.uptimeTimer = false;
                }
            }.observes('state'),

            changeMonitoring: function() {
                warn("Setting monitoring to:  " + !this.hasMonitoring);

                this.set('pendingMonitoring', true);
                //$('.monitoring-button').show();
                var payload = {
                   'action': this.hasMonitoring ? 'disable' : 'enable'
                };

                if (!Mist.authenticated){
                    if (!Mist.email || !Mist.password){
                        warn('no auth credentials!');
                        return false;
                    }
                    var d = new Date();
                    var nowUTC = String(d.getTime() + d.getTimezoneOffset()*60*1000);
                    payload['email'] = Mist.email;
                    payload['timestamp'] = nowUTC;
                    payload['pass'] = CryptoJS.SHA256(Mist.password).toString();
                    payload['hash'] = CryptoJS.SHA256(Mist.email + ':' + nowUTC + ':' + CryptoJS.SHA256(Mist.password).toString()).toString();
                }

                var that = this;
                warn('sending request');
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id + '/monitoring',
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    contentType: 'application/json',
                    data: JSON.stringify(payload),
                    dataType: 'json',
                    timeout : 10000,
                    success: function(data) {
                        var user = that.getUser();
                        if (!that.hasMonitoring){
                            $('.pending-monitoring h1').text('Installing collectd');
                            var prefix = URL_PREFIX || document.location.href.split('#')[0];
                            if (prefix.slice(-1) == '/') {
                                prefix = prefix.substring(0, prefix.length - 1);
                            }
                            var cmd = 'wget --no-check-certificate ' + prefix + '/core/scripts/deploy_collectd.sh -O - > /tmp/deploy_collectd.sh && chmod o+x /tmp/deploy_collectd.sh && /tmp/deploy_collectd.sh ' + data['monitor_server'] + ' ' + data['uuid'] + ' ' + data['passwd'];
                            if (user != 'root'){
                                cmd = "sudo su -c '" + cmd + "'";
                            }
                            collectd_install_target = that;
                            warn(cmd);
                            that.shell(cmd, function(){}, timeout=300);
                        } else {
                            $('.pending-monitoring h1').text('Disabling collectd');
                            var cmd = 'chmod -x /etc/init.d/collectd && killall -9 collectd';
                            if (user != 'root'){
                                cmd = "sudo su -c '" + cmd + "'";
                            }
                            collectd_uninstall_target = that;
                            that.shell(cmd, function(){});
                        }
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        that.set('pendingMonitoring', false);
                        Mist.notificationController.notify('Error when changing monitoring to ' +
                            that.name);
                        error(textstate, errorThrown, 'when changing monitoring to machine',
                            that.name);
                    }
                });

            },

            init: function() {
                this._super();

                this.tags = Ember.ArrayController.create();

                this.startUptimeTimer();
                this.checkUptime();
            }
        });
    }
);
<commit_msg>dont draw new machines while a create is pending<commit_after>define('app/models/machine', [
    'ember'
    ],
    /**
     * Machine model
     *
     * Also check state mapping in config.py
     * @returns Class
     */
    function() {
        return Ember.Object.extend({
            id: null,
            imageId: null,
            name: null,
            backend: null,
            selected: false,
            hasKey: false,
            hasMonitoring: null,
            pendingMonitoring: false,
            pendingShell: false,
            pendingAddTag: false,
            pendingDeleteTag: false,
            pendingStats: false,
            state: 'stopped',
            stats:{'cpu': [], 'load': [], 'disk': []},
            graphdata: {},

            image: function() {
                return this.backend.images.getImage(this.imageId);
            }.property('image'),

            user: function() {
                return this.getUser();
            }.property('user'),

            reboot: function() {
                log('Rebooting machine', this.name);

                var that = this;
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=reboot',
                    success: function(data) {
                        that.set('state', 'rebooting');
                        info('Succesfully sent reboot to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending reboot to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending reboot to machine',
                                that.name);
                    }
                });
            },

            destroy: function() {
                log('Destroying machine', this.name);

                var that = this
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=destroy',
                    success: function(data) {
                        that.set('state', 'pending');
                        info('Successfully sent destroy to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending destroy to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending destroy to machine',
                                that.name);
                    }
                });
            },

            start: function() {
                log('Starting machine', this.name);

                var that = this;
                $.ajax({
                    url: 'backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=start',
                    success: function(data) {
                        that.set('state', 'pending');
                        info('Successfully sent start to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending start to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending start to machine',
                                that.name);
                    }
                });
            },

            shutdown: function() {
                log('Stopping machine', this.name);

                var that = this;
                $.ajax({
                    url: 'backends/' + this.backend.id + '/machines/' + this.id,
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    data: 'action=stop',
                    success: function(data) {
                        that.set('state', 'stopped');
                        info('Successfully sent stop to machine', that.name);
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        Mist.notificationController.notify('Error when sending stop to machine ' +
                                that.name);
                        error(textstate, errorThrown, 'when sending stop to machine',
                                that.name);
                    }
                });
            },

            getHost: function() {
                if (this.extra.dns_name) {
                    // it is an ec2 machine so it has dns_name
                    return this.extra.dns_name;
                } else {
                    // if not ec2 it should have a public ip
                    try {
                        var ips_v4 = [];
                        this.public_ips.forEach(function(ip) {
                            if (ip.search(':') == -1) {
                                // this is not an IPv6, so it is supported
                                ips_v4.push(ip);
                            }
                        });
                        return ips_v4[0];
                    } catch (error) {
                        Mist.notificationController.notify('No host available for machine ' + this.name);
                        error('No host available for machine ' + this.name);
                        return false;
                    }
                }
            },

            getUser: function() {
                // In case of ec2, mist.io could have set this. Server can handle empty string.
                try {
                    if (this.extra.tags.ssh_user != undefined) {
                        return this.extra.tags.ssh_user;
                    } else {
                        return 'root';
                    }
                } catch (error) {
                    return 'root';
                }
            },

            shell: function(shell_command, callback, timeout) {
                log('Sending', shell_command, 'to machine', this.name);

                var url = '/backends/' + this.backend.id + '/machines/' + this.id + '/shell';
                var ssh_user = this.getUser();
                var host = this.getHost();
                var that = this;
                var params =  {'host': host,
                               'ssh_user': ssh_user,
                               'command': shell_command}
                if (timeout != undefined) {
                    params['timeout'] = timeout;
                }

                function EncodeQueryData(data)
                {
                   var ret = [];
                   for (var d in data)
                      ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
                   return ret.join("&");
                }
                url = url + '?' + EncodeQueryData(params);
                this.set('pendingShell', true);

                $('#hidden-shell-iframe').attr('src', url);
                callback('');
            },

            hasAlert : function() {
                //TODO when we have alerts
                return false;
            }.property('hasAlert'),

            startUptimeTimer: function() {
                var that = this;

                setInterval(function() {
                    if (that.get('state') == 'running' && that.get('uptimeFromServer') &&
                        that.get('uptimeChecked')) {

                        that.set('uptime', that.get('uptimeFromServer') + (Date.now()
                                           - that.get('uptimeChecked')));
                    } else {
                        return;
                    }
                }, 1000);
            },

            checkUptime: function() {
                var that = this;

                function uptimeTimeout() {
                    if (!that.backend) {
                        return false;
                    }

                    if (that.backend.create_pending){
                        // Try again later if a machine is being created on this backend
                        setTimeout(uptimeTimeout, 10000);
                        return false;
                    }

                    if (that.state == 'running') {
                        var host = that.getHost();
                        if (host) {
                            var ssh_user = that.getUser();

                            $.ajax({
                                url: '/backends/' + that.backend.id + '/machines/' + that.id + '/shell',
                                type: 'POST',
                                headers: { "cache-control": "no-cache" },
                                data: {'host': host,
                                   'ssh_user': ssh_user,
                                   'command': 'cat /proc/uptime'},
                                success: function(data, textStatus, jqXHR) {
                                       // got it fine, also means it has a key
                                    if (jqXHR.status === 200) {
                                        that.set('hasKey', true);
                                        var resp = data.split(' ');
                                        if (resp.length == 2) {
                                            var uptime = parseFloat(resp[0]) * 1000;
                                            that.set('uptimeChecked', Date.now());
                                            that.set('uptimeFromServer', uptime);
                                        }
                                        info('Successfully got uptime', data, 'from machine', that.name);
                                    } else {
                                        // in every other case there is a problem
                                        that.set('hasKey', false);
                                        info('Got response other than 200 while getting uptime from machine', that.name);
                                        setTimeout(uptimeTimeout, 10000);
                                    }
                                },
                                error: function(jqXHR, textstate, errorThrown) {
                                    that.set('hasKey', false);
                                    //Mist.notificationController.notify('Error getting uptime from machine ' +
                                    //    that.name);
                                    error(textstate, errorThrown, 'when getting uptime from machine',
                                        that.name);
                                    setTimeout(uptimeTimeout, 10000);
                                }
                            });
                        }
                    }
                };
                setTimeout(uptimeTimeout, 2000);
            },

            resetUptime: function() {
                if (this.get('state') == 'running') {
                    this.startUptimeTimer();
                    this.checkUptime();
                } else {
                    this.set('uptime', 0);
                    this.uptimeTimer = false;
                }
            }.observes('state'),

            changeMonitoring: function() {
                warn("Setting monitoring to:  " + !this.hasMonitoring);

                this.set('pendingMonitoring', true);
                //$('.monitoring-button').show();
                var payload = {
                   'action': this.hasMonitoring ? 'disable' : 'enable'
                };

                if (!Mist.authenticated){
                    if (!Mist.email || !Mist.password){
                        warn('no auth credentials!');
                        return false;
                    }
                    var d = new Date();
                    var nowUTC = String(d.getTime() + d.getTimezoneOffset()*60*1000);
                    payload['email'] = Mist.email;
                    payload['timestamp'] = nowUTC;
                    payload['pass'] = CryptoJS.SHA256(Mist.password).toString();
                    payload['hash'] = CryptoJS.SHA256(Mist.email + ':' + nowUTC + ':' + CryptoJS.SHA256(Mist.password).toString()).toString();
                }

                var that = this;
                warn('sending request');
                $.ajax({
                    url: '/backends/' + this.backend.id + '/machines/' + this.id + '/monitoring',
                    type: 'POST',
                    headers: { "cache-control": "no-cache" },
                    contentType: 'application/json',
                    data: JSON.stringify(payload),
                    dataType: 'json',
                    timeout : 10000,
                    success: function(data) {
                        var user = that.getUser();
                        if (!that.hasMonitoring){
                            $('.pending-monitoring h1').text('Installing collectd');
                            var prefix = URL_PREFIX || document.location.href.split('#')[0];
                            if (prefix.slice(-1) == '/') {
                                prefix = prefix.substring(0, prefix.length - 1);
                            }
                            var cmd = 'wget --no-check-certificate ' + prefix + '/core/scripts/deploy_collectd.sh -O - > /tmp/deploy_collectd.sh && chmod o+x /tmp/deploy_collectd.sh && /tmp/deploy_collectd.sh ' + data['monitor_server'] + ' ' + data['uuid'] + ' ' + data['passwd'];
                            if (user != 'root'){
                                cmd = "sudo su -c '" + cmd + "'";
                            }
                            collectd_install_target = that;
                            warn(cmd);
                            that.shell(cmd, function(){}, timeout=300);
                        } else {
                            $('.pending-monitoring h1').text('Disabling collectd');
                            var cmd = 'chmod -x /etc/init.d/collectd && killall -9 collectd';
                            if (user != 'root'){
                                cmd = "sudo su -c '" + cmd + "'";
                            }
                            collectd_uninstall_target = that;
                            that.shell(cmd, function(){});
                        }
                    },
                    error: function(jqXHR, textstate, errorThrown) {
                        that.set('pendingMonitoring', false);
                        Mist.notificationController.notify('Error when changing monitoring to ' +
                            that.name);
                        error(textstate, errorThrown, 'when changing monitoring to machine',
                            that.name);
                    }
                });

            },

            init: function() {
                this._super();

                this.tags = Ember.ArrayController.create();

                this.startUptimeTimer();
                this.checkUptime();
            }
        });
    }
);
<|endoftext|>