<commit_before>const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sheetrock = require('sheetrock');

const app = express();

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    // GET where ssl_check set to 1 from Slack
    if (req.query.ssl_check == 1) {
        return res.sendStatus(200);
    }
    return res.sendStatus(403);
});

app.get('/slack-auth', function(req, res) {
    let data = {form: {
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: req.query.code
    }};

    request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {

        // let bot_access_token = JSON.parse(body).bot.bot_access_token;
        // console.log('bot_access_token', bot_access_token);

        let token = JSON.parse(body).access_token; // Auth token
        console.log('token', token);

        if (!error && response.statusCode == 200) {
            res.redirect(process.env.THANK_YOU_REDIRECT);
        }
    });
});

app.post('/', function(req, res) {
    if (!req.body) {
        return res.sendStatus(400);
    }

    if (req.body.token == process.env.SLACK_AUTH_TOKEN) {

        let text = req.body.text ? req.body.text : 'excuseme';
        let channel = req.body.channel_id ? req.body.channel_id : '#general';

        console.log('channel', channel);

        sheetrock({
            // url: "https://docs.google.com/spreadsheets/d/1QO5dyK6EgIP81SGZMlHMk8xn88u_budzF2Td3OoOZzY/edit#gid=0",
            // url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit?usp=sharing`,
            url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit#gid=0`,
            query: `Select B where A = "${text}"`,
            reset: true,
            callback: function (error, options, response) {
                // console.log('>>', response.rows);
                // console.log('attributes', response.attributes.labels[0]);
                // response.rows.cellsArray[0] // nope

                let donger = response.attributes ? response.attributes.labels[0] : 'ヽ| ͡☉ ︿ ͡☉ |ノ⌒.';

                let data = {form: {
                    // "token": process.env.SLACK_BOT_TOKEN,
                    "token": process.env.SLACK_AUTH_TOKEN,
                    "username": text,
                    "channel": channel,
                    "text": donger,
                    "as_user": true,
                }};

                console.log('data', data);

                request.post('https://slack.com/api/chat.postMessage', data, function (error, response, body) {
                    let json = JSON.parse(body);
                    console.log('ok?', json.ok);

                    if (!json.ok) {
                        console.log('bad');
                        console.log('error', json.error);
                    } else {
                        console.log('good');
                        if (json.warning) {
                            console.log('BUT warning', json.warning);
                        }
                    }

                    // if (!error && response.statusCode == 200) {
                    //     console.log('allgood?');
                    // }

                    // if (error) {
                    //     console.log('error', error);
                    // }
                });
                // res.json(response);

                // var response = {
                //     "response_type": "in_channel",
                //     "text": donger,
                // }
                // res.json(response);
                res.json({"text": "working..."});
            }
        });
    }
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
<commit_msg>bot/api integration<commit_after>const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sheetrock = require('sheetrock');

const app = express();

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    // GET where ssl_check set to 1 from Slack
    if (req.query.ssl_check == 1) {
        return res.sendStatus(200);
    }
    return res.sendStatus(403);
});

app.get('/slack-auth', function(req, res) {
    let data = {form: {
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: req.query.code
    }};

    request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {

        // let bot_access_token = JSON.parse(body).bot.bot_access_token;
        // console.log('bot_access_token', bot_access_token);

        let token = JSON.parse(body).access_token; // Auth token
        console.log('token', token);

        if (!error && response.statusCode == 200) {
            res.redirect(process.env.THANK_YOU_REDIRECT);
        }
    });
});

app.post('/', function(req, res) {
    if (!req.body) {
        return res.sendStatus(400);
    }

    if (req.body.token == process.env.SLACK_AUTH_TOKEN) {

        let text = req.body.text ? req.body.text : 'excuseme';
        let channel = req.body.channel_id ? req.body.channel_id : '#general';

        console.log('channel', channel);

        sheetrock({
            // url: "https://docs.google.com/spreadsheets/d/1QO5dyK6EgIP81SGZMlHMk8xn88u_budzF2Td3OoOZzY/edit#gid=0",
            // url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit?usp=sharing`,
            url: `https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SPREADSHEET_ID}/edit#gid=0`,
            query: `Select B where A = "${text}"`,
            reset: true,
            callback: function (error, options, response) {
                // console.log('>>', response.rows);
                // console.log('attributes', response.attributes.labels[0]);
                // response.rows.cellsArray[0] // nope

                let donger = response.attributes ? response.attributes.labels[0] : 'ヽ| ͡☉ ︿ ͡☉ |ノ⌒.';

                let data = {form: {
                    // "token": process.env.SLACK_BOT_TOKEN,
                    "token": process.env.SLACK_API_TOKEN,
                    "username": text,
                    "channel": channel,
                    "text": donger,
                    "as_user": true,
                }};

                console.log('data', data);

                request.post('https://slack.com/api/chat.postMessage', data, function (error, response, body) {
                    let json = JSON.parse(body);
                    console.log('ok?', json.ok);

                    if (!json.ok) {
                        console.log('bad');
                        console.log('error', json.error);
                    } else {
                        console.log('good');
                        if (json.warning) {
                            console.log('BUT warning', json.warning);
                        }
                    }

                    // if (!error && response.statusCode == 200) {
                    //     console.log('allgood?');
                    // }

                    // if (error) {
                    //     console.log('error', error);
                    // }
                });
                // res.json(response);

                // var response = {
                //     "response_type": "in_channel",
                //     "text": donger,
                // }
                // res.json(response);
                res.json({"text": "working..."});
            }
        });
    }
});

app.listen(app.get('port'), function() {
    console.log('Node app is running on port', app.get('port'));
});
<|endoftext|>


<commit_before>/* eslint-env mocha */
var Logsene = require('../index.js')
var token = process.env.LOGSENE_TOKEN || 'YOUR_TEST_TOKEN'
process.env.LOGSENE_URL = 'http://127.0.0.1:19200/_bulk'
if (!process.env.LOGSENE_URL) {
  process.env.LOGSENE_URL = 'http://apps1.test.sematext.com:8088/_bulk'
}

console.log('Receiver: ' + process.env.LOGSENE_URL)
console.log('Token: ' + process.env.LOGSENE_TOKEN)
var http = require('http')
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'})
  req.on('data', function (data) {
    // console.log(data.toString().substring(0,10))
  })
  req.on('end', function () {
    res.end('{"code":"200"}\n')
  })
// console.log(req.path)
}).listen(19200, '127.0.0.1')

var MAX_MB = Number(process.env.LOAD_TEST_MAX_MB) || 30
describe('Logsene Load Test ', function () {
  it('memory keeps below ' + MAX_MB + ' MB since start', function (done) {
    this.timeout(120000)
    try {
      console.log('\t\tLOAD_TEST_MAX_MB: ' + MAX_MB)
      var logCount = Number(process.env.LOAD_TEST_SIZE) || 50000
      console.log('\t\tLOAD_TEST_SIZE: ' + logCount)

      var memory = process.memoryUsage().heapUsed
      var counter = 0

      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL, './')
      var start = new Date().getTime()
      var doneCalled = false
      console.log('\tRSS: ' + process.memoryUsage().rss / 1024 / 1024 + ' MB')
      console.log('\tHeap used: ' + process.memoryUsage().heapUsed / 1024 / 1024 + ' MB')

      function evtH (event) {
        if (doneCalled) {
          return
        }
        counter = counter + event.count
        var memory2 = 0
        if (counter >= logCount) {
          memory2 = process.memoryUsage().heapUsed
          var heapDiff = ((memory2 - memory) / 1024 / 1024)
          console.log('\tHeap diff: ' + heapDiff + ' MB')
          console.log('\tHeap used: ' + process.memoryUsage().heapUsed / 1024 / 1024 + ' MB')
          console.log('\tRSS: ' + process.memoryUsage().rss / 1024 / 1024 + ' MB')
          console.log('\tTransmission duration for ' + counter + ' logs: ' + (new Date().getTime() - start) / 1000 + ' sec.')
          if (heapDiff < MAX_MB) {
            doneCalled = true
            done()
          } else {
            done(new Error('Too much memory used:' + heapDiff + ' MB'))
          }
        }
      }

      logsene.on('log', evtH)
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.on('error', console.log)
      for (var i = 0; i < logCount; i++) {
        logsene.log('info', 'test message ' + i, {testField: 'Test custom field ' + i, counter: i})
      }
    } catch (err) {
      done(err)
    }
  })
})

describe('Logsene constructor', function () {
  it('should fail without a token', function (done) {
    var emptyTokens = [undefined, null, '']
    emptyTokens.forEach(function (token) {
      try {
        new Logsene(token)
        done(new Error('Should throw exception'))
      } catch (err) {
        // nothing to do here
      }
    })
    done()
  })
})

describe('Logsene log ', function () {
  it('should not throw circular reference error', function (done) {
    var logsene = new Logsene(token, 'test')
    logsene.on('error', console.log)
    function Foo () {
      this.abc = 'Hello'
      this.circular = this
    }
    var foo = new Foo()
    try {
      logsene.log('info', 'circular test', foo)
      if (logsene.bulkReq.getContentsAsString('utf-8').indexOf('[Circular') !== -1) {
        done()
      } else {
        done(new Error('The circular reference was not caught'))
      }
    } catch (err) {
      done(err)
    }
  })
  it('logs have default fields message, @timestamp, host, ip + custom fields', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.once('logged', function (event) {
        if (!event.msg.testField || !event.msg.message || !event.msg['@timestamp'] || !event.msg.severity || !event.msg.host || !event.msg.ip) {
          done(new Error('missing fields in log: ' + JSON.stringify(event.msg)))
        } else {
          if (event.msg.message === 'test') {
            done()
          }
        }
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.log('info', 'test', {testField: 'Test custom field '})
    } catch (err) {
      done(err)
    }
  })
  it('leading _ in field names are removed', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.once('logged', function (event) {
        if (!event.msg.test) {
          done(new Error('field _test was not renamed: ' + JSON.stringify(event.msg)))
        } else {
          if (event.msg.test === 'test') {
            done()
          }
        }
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.log('info', 'test', {_test: 'test'})
    } catch (err) {
      done(err)
    }
  })
  it('transmit', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.on('logged', function (event) {
        if (!event.msg.message || !event.msg['@timestamp'] || !event.msg.severity || !event.msg.host || !event.msg.ip) {
          done(new Error('missing fields in log:' + JSON.stringify(event.msg)))
        }
      })
      logsene.once('log', function (event) {
        done()
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.on('error', console.log)
      for (var i = 0; i <= 100; i++) {
        logsene.log('info', 'test message ' + i, {testField: 'Test custom field ' + i, counter: i})
      }
    } catch (err) {
      done(err)
    }
  })
})

describe('Logsene DiskBuffer ', function () {
  it('re-transmit', function (done) {
    this.timeout(50000)
    process.env.DEBUG_LOGSENE_DISK_BUFFER = true
    var DiskBuffer = require('../DiskBuffer.js')
    var db = DiskBuffer.createDiskBuffer({
      tmpDir: './tmp',
      interval: 2000
    })
    db.syncFileListFromDir()
    db.on('retransmit-req', function (event) {
      db.rmFile(event.fileName)
      db.retransmitNext()
    })
    db.once('removed', function () {
      done()
    })
    setTimeout(function () {
      db.store({message: 'hello'}, function () {
        db.retransmitNext()
      })
    }, 1000)
  })
})

describe('Logsene persistance ', function () {
  it('re-transmit', function (done) {
    this.timeout(70000)
    try {
      process.env.LOGSENE_DISK_BUFFER_INTERVAL = 2000
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL, './mocha-test')
      var url = logsene.url
      logsene.diskBuffer(true, './mocha-test')
      logsene.setUrl('http://notreachable.test')
      logsene.db.once('removed', function (event) {
        done()
      })
      logsene.on('error', function (err) {
        if (err) {
          logsene.setUrl(url)
        }
      })
      setTimeout(function () {
        for (var i = 0; i <= 1001; i++) {
          logsene.log('info', 'test retransmit message ' + i, {_id: 'hey', testField: 'Test custom field ' + i, counter: i, _type: 'test_type', 'dot.sep.field': 34})
        }
      }, 1000)
    } catch (err) {
      done(err)
    }
  })
})
<commit_msg>test rename of fields with dots<commit_after>/* eslint-env mocha */
var Logsene = require('../index.js')
var token = process.env.LOGSENE_TOKEN || 'YOUR_TEST_TOKEN'
process.env.LOGSENE_URL = 'http://127.0.0.1:19200/_bulk'
if (!process.env.LOGSENE_URL) {
  process.env.LOGSENE_URL = 'http://apps1.test.sematext.com:8088/_bulk'
}

console.log('Receiver: ' + process.env.LOGSENE_URL)
console.log('Token: ' + process.env.LOGSENE_TOKEN)
var http = require('http')
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'})
  req.on('data', function (data) {
    // console.log(data.toString().substring(0,10))
  })
  req.on('end', function () {
    res.end('{"code":"200"}\n')
  })
// console.log(req.path)
}).listen(19200, '127.0.0.1')

var MAX_MB = Number(process.env.LOAD_TEST_MAX_MB) || 30
describe('Logsene Load Test ', function () {
  it('memory keeps below ' + MAX_MB + ' MB since start', function (done) {
    this.timeout(120000)
    try {
      console.log('\t\tLOAD_TEST_MAX_MB: ' + MAX_MB)
      var logCount = Number(process.env.LOAD_TEST_SIZE) || 50000
      console.log('\t\tLOAD_TEST_SIZE: ' + logCount)

      var memory = process.memoryUsage().heapUsed
      var counter = 0

      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL, './')
      var start = new Date().getTime()
      var doneCalled = false
      console.log('\tRSS: ' + process.memoryUsage().rss / 1024 / 1024 + ' MB')
      console.log('\tHeap used: ' + process.memoryUsage().heapUsed / 1024 / 1024 + ' MB')

      function evtH (event) {
        if (doneCalled) {
          return
        }
        counter = counter + event.count
        var memory2 = 0
        if (counter >= logCount) {
          memory2 = process.memoryUsage().heapUsed
          var heapDiff = ((memory2 - memory) / 1024 / 1024)
          console.log('\tHeap diff: ' + heapDiff + ' MB')
          console.log('\tHeap used: ' + process.memoryUsage().heapUsed / 1024 / 1024 + ' MB')
          console.log('\tRSS: ' + process.memoryUsage().rss / 1024 / 1024 + ' MB')
          console.log('\tTransmission duration for ' + counter + ' logs: ' + (new Date().getTime() - start) / 1000 + ' sec.')
          if (heapDiff < MAX_MB) {
            doneCalled = true
            done()
          } else {
            done(new Error('Too much memory used:' + heapDiff + ' MB'))
          }
        }
      }

      logsene.on('log', evtH)
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.on('error', console.log)
      for (var i = 0; i < logCount; i++) {
        logsene.log('info', 'test message ' + i, {testField: 'Test custom field ' + i, counter: i})
      }
    } catch (err) {
      done(err)
    }
  })
})

describe('Logsene constructor', function () {
  it('should fail without a token', function (done) {
    var emptyTokens = [undefined, null, '']
    emptyTokens.forEach(function (token) {
      try {
        new Logsene(token)
        done(new Error('Should throw exception'))
      } catch (err) {
        // nothing to do here
      }
    })
    done()
  })
})

describe('Logsene log ', function () {
  it('should not throw circular reference error', function (done) {
    var logsene = new Logsene(token, 'test')
    logsene.on('error', console.log)
    function Foo () {
      this.abc = 'Hello'
      this.circular = this
    }
    var foo = new Foo()
    try {
      logsene.log('info', 'circular test', foo)
      if (logsene.bulkReq.getContentsAsString('utf-8').indexOf('[Circular') !== -1) {
        done()
      } else {
        done(new Error('The circular reference was not caught'))
      }
    } catch (err) {
      done(err)
    }
  })
  it('logs have default fields message, @timestamp, host, ip + custom fields', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.once('logged', function (event) {
        if (!event.msg.testField || !event.msg.message || !event.msg['@timestamp'] || !event.msg.severity || !event.msg.host || !event.msg.ip) {
          done(new Error('missing fields in log: ' + JSON.stringify(event.msg)))
        } else {
          if (event.msg.message === 'test') {
            done()
          }
        }
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.log('info', 'test', {testField: 'Test custom field '})
    } catch (err) {
      done(err)
    }
  })
  it('leading _ in field names are removed, dots are replaced with _', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.once('logged', function (event) {
        if (!event.msg.test_test) {
          done(new Error('field _test was not renamed: ' + JSON.stringify(event.msg)))
        } else {
          if (event.msg.test_test === 'test') {
            done()
          }
        }
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.log('info', 'test', {'_test.test': 'test'})
    } catch (err) {
      done(err)
    }
  })
  it('transmit', function (done) {
    this.timeout(20000)
    try {
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL)
      // check for all required fields!
      logsene.on('logged', function (event) {
        if (!event.msg.message || !event.msg['@timestamp'] || !event.msg.severity || !event.msg.host || !event.msg.ip) {
          done(new Error('missing fields in log:' + JSON.stringify(event.msg)))
        }
      })
      logsene.once('log', function (event) {
        done()
      })
      logsene.once('error', function (event) {
        done(event)
      })
      logsene.on('error', console.log)
      for (var i = 0; i <= 100; i++) {
        logsene.log('info', 'test message ' + i, {testField: 'Test custom field ' + i, counter: i})
      }
    } catch (err) {
      done(err)
    }
  })
})

describe('Logsene DiskBuffer ', function () {
  it('re-transmit', function (done) {
    this.timeout(50000)
    process.env.DEBUG_LOGSENE_DISK_BUFFER = true
    var DiskBuffer = require('../DiskBuffer.js')
    var db = DiskBuffer.createDiskBuffer({
      tmpDir: './tmp',
      interval: 2000
    })
    db.syncFileListFromDir()
    db.on('retransmit-req', function (event) {
      db.rmFile(event.fileName)
      db.retransmitNext()
    })
    db.once('removed', function () {
      done()
    })
    setTimeout(function () {
      db.store({message: 'hello'}, function () {
        db.retransmitNext()
      })
    }, 1000)
  })
})

describe('Logsene persistance ', function () {
  it('re-transmit', function (done) {
    this.timeout(70000)
    try {
      process.env.LOGSENE_DISK_BUFFER_INTERVAL = 2000
      var logsene = new Logsene(token, 'test', process.env.LOGSENE_URL, './mocha-test')
      var url = logsene.url
      logsene.diskBuffer(true, './mocha-test')
      logsene.setUrl('http://notreachable.test')
      logsene.db.once('removed', function (event) {
        done()
      })
      logsene.on('error', function (err) {
        if (err) {
          logsene.setUrl(url)
        }
      })
      setTimeout(function () {
        for (var i = 0; i <= 1001; i++) {
          logsene.log('info', 'test retransmit message ' + i, {_id: 'hey', testField: 'Test custom field ' + i, counter: i, _type: 'test_type', 'dot.sep.field': 34})
        }
      }, 1000)
    } catch (err) {
      done(err)
    }
  })
})
<|endoftext|>


<commit_before>module.exports = function(grunt) {

// Project configuration.
grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    typescript: {
        base: {
            src: ['src/**/*.ts'],
            dest: 'build/',
            options: {
                module: 'commonjs',
                target: 'es5',
                basePath: 'src/',
                sourceMap: false,
                declaration: false
            }
        }
    },
    mochaTest: {
        test: {
            options: {
                reporter: 'spec',
                clearRequireCache: true // Optionally clear the require cache before running tests (defaults to false)
            },
            src: ['build/test/**/*.js']
        }
    },
    clean: {
        build: {
            src: [ 'build' ],
            force: true
        }
    },
    watch: {
        typescript: {
            files: 'src/**/*.ts',
            tasks: ['build'],
            options: {
                spawn: false
            }
        }
    },
    nodemon: {
        dev: {
            script: 'server.js',
            options: {
                cwd: 'build/app/server/',
                ignore: ['node_modules/**', 'src/**'],
                delay: 100
            }
        }
    },
    concurrent: {
        dev: [
            'watch:typescript',
            'nodemon'
        ],
        options: {
            logConcurrentOutput: true
        }
    }
});

grunt.loadNpmTasks('grunt-typescript');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-concurrent');

// Default task(s).
grunt.registerTask('default', ['build']);
grunt.registerTask('run', ['build', 'concurrent']);

grunt.registerTask('build', ['compile', 'mochaTest']);
grunt.registerTask('compile', [/* 'clean', DOES NOT WORK ON WINDOWS */ 'typescript']);

};
<commit_msg>Added a development task<commit_after>module.exports = function(grunt) {

// Project configuration.
grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    typescript: {
        base: {
            src: ['src/**/*.ts'],
            dest: 'build/',
            options: {
                module: 'commonjs',
                target: 'es5',
                basePath: 'src/',
                sourceMap: false,
                declaration: false
            }
        }
    },
    mochaTest: {
        test: {
            options: {
                reporter: 'spec',
                clearRequireCache: true // Optionally clear the require cache before running tests (defaults to false)
            },
            src: ['build/test/**/*.js']
        }
    },
    clean: {
        build: {
            src: [ 'build' ],
            force: true
        }
    },
    watch: {
        typescript: {
            files: 'src/**/*.ts',
            tasks: ['build'],
            options: {
                spawn: false
            }
        }
    },
    nodemon: {
        dev: {
            script: 'server.js',
            options: {
                cwd: 'build/app/server/',
                ignore: ['node_modules/**', 'src/**'],
                delay: 100
            }
        }
    },
    concurrent: {
        dev: [
            'watch:typescript',
            'nodemon'
        ],
        options: {
            logConcurrentOutput: true
        }
    }
});

grunt.loadNpmTasks('grunt-typescript');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-concurrent');

// Default task(s).
grunt.registerTask('default', ['build']);
grunt.registerTask('run', ['build', 'concurrent']);
grunt.registerTask('dev', ['build', 'watch']);

grunt.registerTask('build', ['compile', 'mochaTest']);
grunt.registerTask('compile', [/* 'clean', DOES NOT WORK ON WINDOWS */ 'typescript']);

};
<|endoftext|>


<commit_before>// Load in our dependencies
// DEV: We use `require`/`assert` instead of `peerDependencies` to make floating dependencies easier
var electronPrebuilt;
try {
  electronPrebuilt = require('electron');
} catch (electronNotFoundErr) {
  try {
    electronPrebuilt = require('electron-prebuilt');
    // https://github.com/electron-userland/electron-prebuilt/tree/v1.3.3#installation
    console.warn('WARN: `electron-prebuilt` has been deprecated as of `electron-prebuilt@1.3.1`. ' +
      'Please move to `electron` instead');
  } catch (electronPrebuiltNotFoundErr) {
    console.error('Expected `electron` to be installed but it was not. Please install it.');
    throw electronNotFoundErr;
  }
}

// DEV: This is a trimmed down version of https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/index.js
//   which is MIT licensed https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/LICENSE
var $inject = [
  'baseLauncherDecorator',
  'captureTimeoutLauncherDecorator',
  'retryLauncherDecorator',
  'processLauncherDecorator',
  'processKillTimeout',
  'args', 'config.basePath', 'config.urlRoot'];
function ElectronBrowser(
    baseLauncherDecorator,
    captureTimeoutLauncherDecorator,
    retryLauncherDecorator,
    processLauncherDecorator,
    processKillTimeout,
    args, karmaBasePath, karmaUrlRoot) {
  // Apply browser decorations to ourself
  // console.log('aaaa', baseBrowserDecorator + '');
  // baseBrowserDecorator(this);
  // https://github.com/karma-runner/karma/blob/v4.1.0/lib/launcher.js#L14-L27
  baseLauncherDecorator(this);
  captureTimeoutLauncherDecorator(this);
  retryLauncherDecorator(this);
  console.log('aaa', processLauncherDecorator(this, processKillTimeout));

  // Extract arguments
  var flags = args.flags || [];
  var userDataDir = args.userDataDir || this._tempDir;

  // Set up app to use a custom user data directory to prevent crossover in tests
  this._getOptions = function (url) {
    var retArr = [__dirname + '/electron-launcher.js'].concat(flags, [
      '--user-data-dir', userDataDir,
      '--url', url
    ]);
    if (args.require) { retArr = retArr.concat(['--require', args.require]); }
    return retArr;
  };
}
ElectronBrowser.prototype = {
  name: 'Electron',
  DEFAULT_CMD: {
    linux: electronPrebuilt,
    darwin: electronPrebuilt,
    win32: electronPrebuilt
  },
  ENV_CMD: 'ELECTRON_BIN'
};

// Define depenencies so our function can receive them
ElectronBrowser.$inject = $inject;

// Export our launcher
module.exports = {
  'launcher:Electron': ['type', ElectronBrowser]
};
<commit_msg>Moved back to near-original setup with sane access to _process<commit_after>// Load in our dependencies
// DEV: We use `require`/`assert` instead of `peerDependencies` to make floating dependencies easier
var electronPrebuilt;
try {
  electronPrebuilt = require('electron');
} catch (electronNotFoundErr) {
  try {
    electronPrebuilt = require('electron-prebuilt');
    // https://github.com/electron-userland/electron-prebuilt/tree/v1.3.3#installation
    console.warn('WARN: `electron-prebuilt` has been deprecated as of `electron-prebuilt@1.3.1`. ' +
      'Please move to `electron` instead');
  } catch (electronPrebuiltNotFoundErr) {
    console.error('Expected `electron` to be installed but it was not. Please install it.');
    throw electronNotFoundErr;
  }
}

// DEV: This is a trimmed down version of https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/index.js
//   which is MIT licensed https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/LICENSE
var $inject = ['baseBrowserDecorator', 'args', 'config.basePath', 'config.urlRoot'];
function ElectronBrowser(baseBrowserDecorator, args, karmaBasePath, karmaUrlRoot) {
  // Apply browser decorations to ourself
  baseBrowserDecorator(this);

  // Extract arguments
  var flags = args.flags || [];
  var userDataDir = args.userDataDir || this._tempDir;

  // Set up app to use a custom user data directory to prevent crossover in tests
  this._getOptions = function (url) {
    var retArr = [__dirname + '/electron-launcher.js'].concat(flags, [
      '--user-data-dir', userDataDir,
      '--url', url
    ]);
    if (args.require) { retArr = retArr.concat(['--require', args.require]); }
    return retArr;
  };

  var originalExecCommand = this._execCommand;
  this._execCommand = function (/*cmd, args*/) {
    var retArr = originalExecCommand.apply(this, arguments);
    this._process.stdin.write('foooo');
    return retArr;
  };
}
ElectronBrowser.prototype = {
  name: 'Electron',
  DEFAULT_CMD: {
    linux: electronPrebuilt,
    darwin: electronPrebuilt,
    win32: electronPrebuilt
  },
  ENV_CMD: 'ELECTRON_BIN'
};

// Define depenencies so our function can receive them
ElectronBrowser.$inject = $inject;

// Export our launcher
module.exports = {
  'launcher:Electron': ['type', ElectronBrowser]
};
<|endoftext|>


<commit_before>const assert = require("assert");
const fs = require("fs").promises;
const uuid = require("uuid");

const {
  pipe,
  tap,
  tryCatch,
  assign,
  get,
  eq,
  switchCase,
  map,
} = require("rubico");
const { isEmpty, values, callProp, identity } = require("rubico/x");

const path = require("path");

const contextSet400 =
  ({ context, message }) =>
  () => {
    context.status = 400;
    context.body = {
      error: {
        code: 400,
        name: "BadRequest",
        message,
      },
    };
  };

const contextSet404 = ({ context }) => {
  context.status = 404;
  context.body = {
    error: {
      code: 404,
      name: "NotFound",
    },
  };
};

const contextSetOk =
  ({ context }) =>
  (body) => {
    context.status = 200;
    context.body = body;
  };

const getJobStatus = switchCase([
  eq(get("StatusCode"), 0),
  () => "done",
  () => "error",
]);

const getHttpStatus = switchCase([
  eq(get("StatusCode"), 0),
  () => 200,
  () => 422,
]);

exports.DiagramApi = (app) => {
  const log = require("logfilename")(__filename);

  const { models } = app.data.sequelize;
  const { config, dockerClient } = app;
  assert(dockerClient, "dockerClient");
  const { localOutputPath, localInputPath } = config.infra;
  assert(localOutputPath);
  assert(localInputPath);

  const runDockerJob = ({ dockerClient, params }) =>
    pipe([
      tap(() => {
        assert(params.name);
        assert(dockerClient, "dockerClient");
      }),
      () => dockerClient.container.create(params),
      () => dockerClient.container.start({ name: params.name }),
      () => dockerClient.container.wait({ name: params.name }),
      tap((xxx) => {
        assert(true);
      }),
    ])();

  const gcpConfigFileContent = ({
    credendialFileName,
  }) => `const path = require("path");
  module.exports = ({ stage }) => ({
    credentialFile: path.resolve(__dirname, "${credendialFileName}"),
  });`;

  const writeGcpFiles = ({
    configFileName,
    credendialFileName,
    credendialContent,
  }) =>
    pipe([
      tap(() => {
        log.debug(
          `writeGcpFiles configFileName: ${configFileName}, credendialFileName: ${credendialFileName}`
        );
      }),
      () =>
        fs.writeFile(
          `input/${credendialFileName}`,
          JSON.stringify(credendialContent)
        ),
      () =>
        fs.writeFile(
          configFileName,
          gcpConfigFileContent({ credendialFileName })
        ),
    ])();

  const runGcList = ({
    jobId,
    providerAuth,
    provider,
    containerName = "grucloud-cli",
    containerImage = "grucloud-cli",
    localOutputPath = "output",
    localInputPath = "input",
    dockerClient,
    outputDir = "output",
    inputDir = "input",
  }) =>
    pipe([
      tap(() => {
        assert(provider);
      }),
      () => ({
        outputGcList: `gc-list-${jobId}.json`,
        outputDot: `${jobId}.dot`,
        outputSvg: `${jobId}.svg`,
      }),
      assign({
        name: () => `${containerName}-${jobId}`,
        Cmd: ({ outputGcList, outputDot }) => [
          "list",
          "--provider",
          provider,
          "--infra",
          `iac_${provider}.js`,
          "--all",
          "--graph",
          "--json",
          `output/${outputGcList}`,
          "--dot-file",
          `output/${outputDot}`,
        ],
        outputGcListLocalPath: ({ outputGcList }) =>
          path.resolve(outputDir, outputGcList),
        outputDotLocalPath: ({ outputDot }) =>
          path.resolve(outputDir, outputDot),
        outputSvgLocalPath: ({ outputSvg }) =>
          path.resolve(outputDir, outputSvg),
        HostConfig: () => ({
          Binds: [
            `${path.resolve(localOutputPath)}:/app/${outputDir}`,
            `${path.resolve(localInputPath)}:/app/${inputDir}`,
          ],
        }),
        Env: () =>
          pipe([
            () => providerAuth,
            map.entries(([key, value]) => [key, `${key}=${value}`]),
            values,
          ])(),
      }),
      switchCase([
        eq(provider, "google"),
        pipe([
          assign({
            Cmd: ({ Cmd }) => [...Cmd, "--config", `input/config-${jobId}.js`],
          }),
          tap(() =>
            writeGcpFiles({
              configFileName: `input/config-${jobId}.js`,
              credendialFileName: `gcp-credendial-${jobId}.json`,
              credendialContent: providerAuth.credentials,
            })
          ),
        ]),
        identity,
      ]),
      tap((input) => {
        log.debug(`runGcList: ${JSON.stringify(input, null, 4)}`);
      }),
      ({
        name,
        Cmd,
        HostConfig,
        Env,
        outputGcListLocalPath,
        outputSvgLocalPath,
        outputDotLocalPath,
      }) =>
        pipe([
          () => ({
            name,
            body: {
              Image: containerImage,
              Cmd,
              Env,
              HostConfig,
            },
          }),
          tap((xxx) => {
            assert(true);
          }),
          (params) => runDockerJob({ dockerClient, params }),
          assign({
            list: pipe([
              () => fs.readFile(outputGcListLocalPath, "utf-8"),
              JSON.parse,
            ]),
            dot: () => fs.readFile(outputDotLocalPath, "utf-8"),
            svg: () => fs.readFile(outputSvgLocalPath, "utf-8"),
          }),
          tap((content) => {
            console.log(outputGcListLocalPath);
            console.log(JSON.stringify(content, null, 4));
          }),
        ])(),
    ])();

  const api = {
    pathname: "/cloudDiagram",
    middlewares: [
      app.server.auth.isAuthenticated /*,app.server.auth.isAuthorized*/,
    ],
    ops: {
      getAll: {
        pathname: "/",
        method: "get",
        handler: (context) =>
          tryCatch(
            pipe([
              () =>
                models.Job.findAll({
                  where: { user_id: context.state.user.id },
                }),
              map(callProp("get")),
              contextSetOk({ context }),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },
      getOne: {
        pathname: "/:id",
        method: "get",
        handler: (context) =>
          tryCatch(
            pipe([
              tap(() => {
                assert(context.params.id);
                assert(context.state.user.id);
              }),
              switchCase([
                () => uuid.validate(context.params.id),
                // valid id
                pipe([
                  () =>
                    models.Job.findOne({
                      where: {
                        id: context.params.id,
                      },
                    }),
                  switchCase([
                    isEmpty,
                    tap(() => contextSet404({ context })),
                    pipe([callProp("get"), contextSetOk({ context })]),
                  ]),
                ]),
                // invalid uuid
                contextSet400({ context, message: "invalid uuid" }),
              ]),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },
      create: {
        pathname: "/",
        method: "post",
        handler: tryCatch(
          (context) =>
            pipe([
              tap(() => {
                assert(context);
                assert(context.request);
                assert(context.request.body);
                assert(context.request.body.infra_id);
                assert(context.state.user.id);
              }),
              () =>
                models.Infra.findOne({
                  where: {
                    id: context.request.body.infra_id,
                  },
                }),
              tap((xxx) => {
                assert(true);
              }),
              (infra) =>
                pipe([
                  () => ({
                    ...context.request.body,
                    user_id: context.state.user.id,
                    kind: "list",
                    status: "created",
                  }),
                  (params) => models.Job.create(params),
                  ({ id }) =>
                    pipe([
                      tap(() => {
                        assert(id);
                      }),
                      () =>
                        runGcList({
                          jobId: id,
                          providerAuth: infra.providerAuth,
                          provider: infra.providerType,
                          localOutputPath,
                          localInputPath,
                          dockerClient,
                          containerImage: config.infra.containerImage,
                        }),
                      tap((result) =>
                        models.Job.update(
                          { result, status: getJobStatus(result) },
                          { where: { id } }
                        )
                      ),
                      tap((result) => {
                        context.body = result;
                        context.status = getHttpStatus(result);
                      }),
                    ])(),
                ])(),
            ])(),
          pipe([
            tap((error) => {
              log.error(`post error: ${JSON.stringify(error, null, 4)}`);
              throw error;
            }),
          ])
        ),
      },
      delete: {
        pathname: "/:id",
        method: "delete",
        handler: (context) =>
          tryCatch(
            pipe([
              tap(() => {
                assert(context.params.id);
                assert(context.state.user.id);
              }),
              switchCase([
                () => uuid.validate(context.params.id),
                // valid id
                pipe([
                  () =>
                    models.Job.destroy({
                      where: {
                        id: context.params.id,
                        user_id: context.state.user.id,
                      },
                    }),
                  tap(contextSetOk({ context })),
                ]),
                // invalid uuid
                contextSet400({ context, message: "invalid uuid" }),
              ]),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },

      //update: {
      //   pathname: "/:id",
      //   method: "patch",
      //   handler: async (context) => {
      //     const { id } = context.params;
      //     const user_id = context.state.user.id;
      //     await models.CloudDiagram.update(context.request.body, {
      //       where: {
      //         id,
      //         user_id,
      //       },
      //     });
      //     const cloudDiagram = await models.CloudDiagram.findOne({
      //       where: {
      //         id,
      //         user_id,
      //       },
      //     });
      //     context.body = cloudDiagram.get();
      //     context.status = 200;
      //   },
      // },
    },
  };

  app.server.createRouter(api);
  return { api };
};
<commit_msg>empty title<commit_after>const assert = require("assert");
const fs = require("fs").promises;
const uuid = require("uuid");

const {
  pipe,
  tap,
  tryCatch,
  assign,
  get,
  eq,
  switchCase,
  map,
} = require("rubico");
const { isEmpty, values, callProp, identity } = require("rubico/x");

const path = require("path");

const contextSet400 =
  ({ context, message }) =>
  () => {
    context.status = 400;
    context.body = {
      error: {
        code: 400,
        name: "BadRequest",
        message,
      },
    };
  };

const contextSet404 = ({ context }) => {
  context.status = 404;
  context.body = {
    error: {
      code: 404,
      name: "NotFound",
    },
  };
};

const contextSetOk =
  ({ context }) =>
  (body) => {
    context.status = 200;
    context.body = body;
  };

const getJobStatus = switchCase([
  eq(get("StatusCode"), 0),
  () => "done",
  () => "error",
]);

const getHttpStatus = switchCase([
  eq(get("StatusCode"), 0),
  () => 200,
  () => 422,
]);

exports.DiagramApi = (app) => {
  const log = require("logfilename")(__filename);

  const { models } = app.data.sequelize;
  const { config, dockerClient } = app;
  assert(dockerClient, "dockerClient");
  const { localOutputPath, localInputPath } = config.infra;
  assert(localOutputPath);
  assert(localInputPath);

  const runDockerJob = ({ dockerClient, params }) =>
    pipe([
      tap(() => {
        assert(params.name);
        assert(dockerClient, "dockerClient");
      }),
      () => dockerClient.container.create(params),
      () => dockerClient.container.start({ name: params.name }),
      () => dockerClient.container.wait({ name: params.name }),
      tap((xxx) => {
        assert(true);
      }),
    ])();

  const gcpConfigFileContent = ({
    credendialFileName,
  }) => `const path = require("path");
  module.exports = ({ stage }) => ({
    credentialFile: path.resolve(__dirname, "${credendialFileName}"),
  });`;

  const writeGcpFiles = ({
    configFileName,
    credendialFileName,
    credendialContent,
  }) =>
    pipe([
      tap(() => {
        log.debug(
          `writeGcpFiles configFileName: ${configFileName}, credendialFileName: ${credendialFileName}`
        );
      }),
      () =>
        fs.writeFile(
          `input/${credendialFileName}`,
          JSON.stringify(credendialContent)
        ),
      () =>
        fs.writeFile(
          configFileName,
          gcpConfigFileContent({ credendialFileName })
        ),
    ])();

  const runGcList = ({
    jobId,
    providerAuth,
    provider,
    containerName = "grucloud-cli",
    containerImage = "grucloud-cli",
    localOutputPath = "output",
    localInputPath = "input",
    dockerClient,
    outputDir = "output",
    inputDir = "input",
  }) =>
    pipe([
      tap(() => {
        assert(provider);
      }),
      () => ({
        outputGcList: `gc-list-${jobId}.json`,
        outputDot: `${jobId}.dot`,
        outputSvg: `${jobId}.svg`,
      }),
      assign({
        name: () => `${containerName}-${jobId}`,
        Cmd: ({ outputGcList, outputDot }) => [
          "list",
          "--provider",
          provider,
          "--infra",
          `iac_${provider}.js`,
          "--all",
          "--graph",
          "--json",
          `output/${outputGcList}`,
          "--dot-file",
          `output/${outputDot}`,
          "--title",
          "",
        ],
        outputGcListLocalPath: ({ outputGcList }) =>
          path.resolve(outputDir, outputGcList),
        outputDotLocalPath: ({ outputDot }) =>
          path.resolve(outputDir, outputDot),
        outputSvgLocalPath: ({ outputSvg }) =>
          path.resolve(outputDir, outputSvg),
        HostConfig: () => ({
          Binds: [
            `${path.resolve(localOutputPath)}:/app/${outputDir}`,
            `${path.resolve(localInputPath)}:/app/${inputDir}`,
          ],
        }),
        Env: () =>
          pipe([
            () => providerAuth,
            map.entries(([key, value]) => [key, `${key}=${value}`]),
            values,
          ])(),
      }),
      switchCase([
        eq(provider, "google"),
        pipe([
          assign({
            Cmd: ({ Cmd }) => [...Cmd, "--config", `input/config-${jobId}.js`],
          }),
          tap(() =>
            writeGcpFiles({
              configFileName: `input/config-${jobId}.js`,
              credendialFileName: `gcp-credendial-${jobId}.json`,
              credendialContent: providerAuth.credentials,
            })
          ),
        ]),
        identity,
      ]),
      tap((input) => {
        log.debug(`runGcList: ${JSON.stringify(input, null, 4)}`);
      }),
      ({
        name,
        Cmd,
        HostConfig,
        Env,
        outputGcListLocalPath,
        outputSvgLocalPath,
        outputDotLocalPath,
      }) =>
        pipe([
          () => ({
            name,
            body: {
              Image: containerImage,
              Cmd,
              Env,
              HostConfig,
            },
          }),
          tap((xxx) => {
            assert(true);
          }),
          (params) => runDockerJob({ dockerClient, params }),
          assign({
            list: pipe([
              () => fs.readFile(outputGcListLocalPath, "utf-8"),
              JSON.parse,
            ]),
            dot: () => fs.readFile(outputDotLocalPath, "utf-8"),
            svg: () => fs.readFile(outputSvgLocalPath, "utf-8"),
          }),
          tap((content) => {
            console.log(outputGcListLocalPath);
            console.log(JSON.stringify(content, null, 4));
          }),
        ])(),
    ])();

  const api = {
    pathname: "/cloudDiagram",
    middlewares: [
      app.server.auth.isAuthenticated /*,app.server.auth.isAuthorized*/,
    ],
    ops: {
      getAll: {
        pathname: "/",
        method: "get",
        handler: (context) =>
          tryCatch(
            pipe([
              () =>
                models.Job.findAll({
                  where: { user_id: context.state.user.id },
                }),
              map(callProp("get")),
              contextSetOk({ context }),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },
      getOne: {
        pathname: "/:id",
        method: "get",
        handler: (context) =>
          tryCatch(
            pipe([
              tap(() => {
                assert(context.params.id);
                assert(context.state.user.id);
              }),
              switchCase([
                () => uuid.validate(context.params.id),
                // valid id
                pipe([
                  () =>
                    models.Job.findOne({
                      where: {
                        id: context.params.id,
                      },
                    }),
                  switchCase([
                    isEmpty,
                    tap(() => contextSet404({ context })),
                    pipe([callProp("get"), contextSetOk({ context })]),
                  ]),
                ]),
                // invalid uuid
                contextSet400({ context, message: "invalid uuid" }),
              ]),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },
      create: {
        pathname: "/",
        method: "post",
        handler: tryCatch(
          (context) =>
            pipe([
              tap(() => {
                assert(context);
                assert(context.request);
                assert(context.request.body);
                assert(context.request.body.infra_id);
                assert(context.state.user.id);
              }),
              () =>
                models.Infra.findOne({
                  where: {
                    id: context.request.body.infra_id,
                  },
                }),
              tap((xxx) => {
                assert(true);
              }),
              (infra) =>
                pipe([
                  () => ({
                    ...context.request.body,
                    user_id: context.state.user.id,
                    kind: "list",
                    status: "created",
                  }),
                  (params) => models.Job.create(params),
                  ({ id }) =>
                    pipe([
                      tap(() => {
                        assert(id);
                      }),
                      () =>
                        runGcList({
                          jobId: id,
                          providerAuth: infra.providerAuth,
                          provider: infra.providerType,
                          localOutputPath,
                          localInputPath,
                          dockerClient,
                          containerImage: config.infra.containerImage,
                        }),
                      tap((result) =>
                        models.Job.update(
                          { result, status: getJobStatus(result) },
                          { where: { id } }
                        )
                      ),
                      tap((result) => {
                        context.body = result;
                        context.status = getHttpStatus(result);
                      }),
                    ])(),
                ])(),
            ])(),
          pipe([
            tap((error) => {
              log.error(`post error: ${JSON.stringify(error, null, 4)}`);
              throw error;
            }),
          ])
        ),
      },
      delete: {
        pathname: "/:id",
        method: "delete",
        handler: (context) =>
          tryCatch(
            pipe([
              tap(() => {
                assert(context.params.id);
                assert(context.state.user.id);
              }),
              switchCase([
                () => uuid.validate(context.params.id),
                // valid id
                pipe([
                  () =>
                    models.Job.destroy({
                      where: {
                        id: context.params.id,
                        user_id: context.state.user.id,
                      },
                    }),
                  tap(contextSetOk({ context })),
                ]),
                // invalid uuid
                contextSet400({ context, message: "invalid uuid" }),
              ]),
            ]),
            pipe([
              (error) => {
                throw error;
              },
            ])
          )(),
      },

      //update: {
      //   pathname: "/:id",
      //   method: "patch",
      //   handler: async (context) => {
      //     const { id } = context.params;
      //     const user_id = context.state.user.id;
      //     await models.CloudDiagram.update(context.request.body, {
      //       where: {
      //         id,
      //         user_id,
      //       },
      //     });
      //     const cloudDiagram = await models.CloudDiagram.findOne({
      //       where: {
      //         id,
      //         user_id,
      //       },
      //     });
      //     context.body = cloudDiagram.get();
      //     context.status = 200;
      //   },
      // },
    },
  };

  app.server.createRouter(api);
  return { api };
};
<|endoftext|>


<commit_before>var complement = require("./complement");
var flushGetRequest = require("./flushGetRequest");
var incrementVersion = require("../support/incrementVersion");
var currentCacheVersion = require("../support/currentCacheVersion");

var REQUEST_ID = 0;
var GetRequestType = require("./RequestTypes").GetRequest;
var setJSONGraphs = require("./../set/setJSONGraphs");
var setPathValues = require("./../set/setPathValues");
var $error = require("./../types/error");
var emptyArray = [];
var InvalidSourceError = require("./../errors/InvalidSourceError");

/**
 * Creates a new GetRequest.  This GetRequest takes a scheduler and
 * the request queue.  Once the scheduler fires, all batched requests
 * will be sent to the server.  Upon request completion, the data is
 * merged back into the cache and all callbacks are notified.
 *
 * @param {Scheduler} scheduler -
 * @param {RequestQueueV2} requestQueue -
 */
var GetRequestV2 = function(scheduler, requestQueue) {
    this.sent = false;
    this.scheduled = false;
    this.requestQueue = requestQueue;
    this.id = ++REQUEST_ID;
    this.type = GetRequestType;

    this._scheduler = scheduler;
    this._pathMap = {};
    this._optimizedPaths = [];
    this._requestedPaths = [];
    this._callbacks = [];
    this._count = 0;
    this._disposable = null;
    this._collapsed = null;
    this._disposed = false;
};

GetRequestV2.prototype = {
    /**
     * batches the paths that are passed in.  Once the request is complete,
     * all callbacks will be called and the request will be removed from
     * parent queue.
     * @param {Array} requestedPaths -
     * @param {Array} optimizedPaths -
     * @param {Function} callback -
     */
    batch: function(requestedPaths, optimizedPaths, callback) {
        var self = this;
        var oPaths = self._optimizedPaths;
        var rPaths = self._requestedPaths;
        var callbacks = self._callbacks;
        var idx = oPaths.length;

        // If its not sent, simply add it to the requested paths
        // and callbacks.
        oPaths[idx] = optimizedPaths;
        rPaths[idx] = requestedPaths;
        callbacks[idx] = callback;
        ++self._count;

        // If it has not been scheduled, then schedule the action
        if (!self.scheduled) {
            self.scheduled = true;

            var flushedDisposable;
            var scheduleDisposable = self._scheduler.schedule(function() {
                flushedDisposable =
                    flushGetRequest(self, oPaths, function(err, data) {
                        var i, fn, len;
                        var model = self.requestQueue.model;
                        self.requestQueue.removeRequest(self);
                        self._disposed = true;

                        if (model._treatDataSourceErrorsAsJSONGraphErrors ? err instanceof InvalidSourceError : !!err) {
                            for (i = 0, len = callbacks.length; i < len; ++i) {
                                fn = callbacks[i];
                                if (fn) {
                                    fn(err);
                                }
                            }
                            return;
                        }

                        // If there is at least one callback remaining, then
                        // callback the callbacks.
                        if (self._count) {
                            // currentVersion will get added to each inserted
                            // node as node.$_version inside of self._merge.
                            //
                            // atom values just downloaded with $expires: 0
                            // (now-expired) will get assigned $_version equal
                            // to currentVersion, and checkCacheAndReport will
                            // later consider those nodes to not have expired
                            // for the duration of current event loop tick
                            //
                            // we unset currentCacheVersion after all callbacks
                            // have been called, to ensure that only these
                            // particular callbacks and any synchronous model.get
                            // callbacks inside of these, get the now-expired
                            // values
                            var currentVersion = incrementVersion.getCurrentVersion();
                            currentCacheVersion.setVersion(currentVersion);
                            var mergeContext = {hasInvalidatedResult : false};

                            var pathsErr = model._useServerPaths && data && data.paths === undefined ?
                                new Error("Server responses must include a 'paths' field when Model._useServerPaths === true") : undefined;

                            if (!pathsErr) {
                                self._merge(rPaths, err, data, mergeContext);
                            }

                            // Call the callbacks.  The first one inserts all
                            // the data so that the rest do not have consider
                            // if their data is present or not.
                            for (i = 0, len = callbacks.length; i < len; ++i) {
                                fn = callbacks[i];
                                if (fn) {
                                    fn(pathsErr || err, data, mergeContext.hasInvalidatedResult);
                                }
                            }
                            currentCacheVersion.setVersion(null);
                        }
                    });
                    self._disposable = flushedDisposable;
                });

            // If the scheduler is sync then `flushedDisposable` will be
            // defined, and we want to use it, because that's what aborts an
            // in-flight XHR request, for example.
            // But if the scheduler is async, then `flushedDisposable` won't be
            // defined yet, and so we must use the scheduler's disposable until
            // `flushedDisposable` is defined. Since we want to still use
            // `flushedDisposable` once it is defined (to be able to abort in-
            // flight XHR requests), hence the reassignment of `_disposable`
            // above.
            self._disposable = flushedDisposable || scheduleDisposable;
        }

        // Disposes this batched request.  This does not mean that the
        // entire request has been disposed, but just the local one, if all
        // requests are disposed, then the outer disposable will be removed.
        return createDisposable(self, idx);
    },

    /**
     * Attempts to add paths to the outgoing request.  If there are added
     * paths then the request callback will be added to the callback list.
     * Handles adding partial paths as well
     *
     * @returns {Array} - whether new requested paths were inserted in this
     *                    request, the remaining paths that could not be added,
     *                    and disposable for the inserted requested paths.
     */
    add: function(requested, optimized, depthDifferences, callback) {
        // uses the length tree complement calculator.
        var self = this;
        var complementTuple = complement(requested, optimized, depthDifferences, self._pathMap);
        var optimizedComplement;
        var requestedComplement;

        if (complementTuple) {
            requestedComplement = complementTuple[2];
            optimizedComplement = complementTuple[1];
        } else {
            requestedComplement = requested;
            optimizedComplement = optimized;
        }

        var inserted = false;
        var disposable = false;

        // If we found an intersection, then just add new callback
        // as one of the dependents of that request
        if (complementTuple && complementTuple[0].length) {
            inserted = true;
            var idx = self._callbacks.length;
            self._callbacks[idx] = callback;
            self._requestedPaths[idx] = complementTuple[0];
            self._optimizedPaths[idx] = [];
            ++self._count;

            disposable = createDisposable(self, idx);
        }

        return [inserted, requestedComplement, optimizedComplement, disposable];
    },

    /**
     * merges the response into the model"s cache.
     */
    _merge: function(requested, err, data, mergeContext) {
        var self = this;
        var model = self.requestQueue.model;
        var modelRoot = model._root;
        var errorSelector = modelRoot.errorSelector;
        var comparator = modelRoot.comparator;
        var boundPath = model._path;

        model._path = emptyArray;

        // flatten all the requested paths, adds them to the
        var nextPaths = model._useServerPaths ? data.paths : flattenRequestedPaths(requested);

        // Insert errors in every requested position.
        if (err && model._treatDataSourceErrorsAsJSONGraphErrors) {
            var error = err;

            // Converts errors to objects, a more friendly storage
            // of errors.
            if (error instanceof Error) {
                error = {
                    message: error.message
                };
            }

            // Not all errors are value $types.
            if (!error.$type) {
                error = {
                    $type: $error,
                    value: error
                };
            }

            var pathValues = nextPaths.map(function(x) {
                return {
                    path: x,
                    value: error
                };
            });
            setPathValues(model, pathValues, null, errorSelector, comparator, mergeContext);
        }

        // Insert the jsonGraph from the dataSource.
        else {
            setJSONGraphs(model, [{
                paths: nextPaths,
                jsonGraph: data.jsonGraph
            }], null, errorSelector, comparator, mergeContext);
        }

        // return the model"s boundPath
        model._path = boundPath;
    }
};

// Creates a more efficient closure of the things that are
// needed.  So the request and the idx.  Also prevents code
// duplication.
function createDisposable(request, idx) {
    var disposed = false;
    return function() {
        if (disposed || request._disposed) {
            return;
        }

        disposed = true;
        request._callbacks[idx] = null;
        request._optimizedPaths[idx] = [];
        request._requestedPaths[idx] = [];

        // If there are no more requests, then dispose all of the request.
        var count = --request._count;
        if (count === 0) {
            request._disposable.dispose();
            request.requestQueue.removeRequest(request);
        }
    };
}

function flattenRequestedPaths(requested) {
    var out = [];
    var outLen = -1;
    for (var i = 0, len = requested.length; i < len; ++i) {
        var paths = requested[i];
        for (var j = 0, innerLen = paths.length; j < innerLen; ++j) {
            out[++outLen] = paths[j];
        }
    }
    return out;
}

module.exports = GetRequestV2;
<commit_msg>chore: formatting<commit_after>var complement = require("./complement");
var flushGetRequest = require("./flushGetRequest");
var incrementVersion = require("../support/incrementVersion");
var currentCacheVersion = require("../support/currentCacheVersion");

var REQUEST_ID = 0;
var GetRequestType = require("./RequestTypes").GetRequest;
var setJSONGraphs = require("./../set/setJSONGraphs");
var setPathValues = require("./../set/setPathValues");
var $error = require("./../types/error");
var emptyArray = [];
var InvalidSourceError = require("./../errors/InvalidSourceError");

/**
 * Creates a new GetRequest.  This GetRequest takes a scheduler and
 * the request queue.  Once the scheduler fires, all batched requests
 * will be sent to the server.  Upon request completion, the data is
 * merged back into the cache and all callbacks are notified.
 *
 * @param {Scheduler} scheduler -
 * @param {RequestQueueV2} requestQueue -
 */
var GetRequestV2 = function(scheduler, requestQueue) {
    this.sent = false;
    this.scheduled = false;
    this.requestQueue = requestQueue;
    this.id = ++REQUEST_ID;
    this.type = GetRequestType;

    this._scheduler = scheduler;
    this._pathMap = {};
    this._optimizedPaths = [];
    this._requestedPaths = [];
    this._callbacks = [];
    this._count = 0;
    this._disposable = null;
    this._collapsed = null;
    this._disposed = false;
};

GetRequestV2.prototype = {
    /**
     * batches the paths that are passed in.  Once the request is complete,
     * all callbacks will be called and the request will be removed from
     * parent queue.
     * @param {Array} requestedPaths -
     * @param {Array} optimizedPaths -
     * @param {Function} callback -
     */
    batch: function(requestedPaths, optimizedPaths, callback) {
        var self = this;
        var oPaths = self._optimizedPaths;
        var rPaths = self._requestedPaths;
        var callbacks = self._callbacks;
        var idx = oPaths.length;

        // If its not sent, simply add it to the requested paths
        // and callbacks.
        oPaths[idx] = optimizedPaths;
        rPaths[idx] = requestedPaths;
        callbacks[idx] = callback;
        ++self._count;

        // If it has not been scheduled, then schedule the action
        if (!self.scheduled) {
            self.scheduled = true;

            var flushedDisposable;
            var scheduleDisposable = self._scheduler.schedule(function() {
                flushedDisposable = flushGetRequest(self, oPaths, function(err, data) {
                    var i, fn, len;
                    var model = self.requestQueue.model;
                    self.requestQueue.removeRequest(self);
                    self._disposed = true;

                    if (model._treatDataSourceErrorsAsJSONGraphErrors ? err instanceof InvalidSourceError : !!err) {
                        for (i = 0, len = callbacks.length; i < len; ++i) {
                            fn = callbacks[i];
                            if (fn) {
                                fn(err);
                            }
                        }
                        return;
                    }

                    // If there is at least one callback remaining, then
                    // callback the callbacks.
                    if (self._count) {
                        // currentVersion will get added to each inserted
                        // node as node.$_version inside of self._merge.
                        //
                        // atom values just downloaded with $expires: 0
                        // (now-expired) will get assigned $_version equal
                        // to currentVersion, and checkCacheAndReport will
                        // later consider those nodes to not have expired
                        // for the duration of current event loop tick
                        //
                        // we unset currentCacheVersion after all callbacks
                        // have been called, to ensure that only these
                        // particular callbacks and any synchronous model.get
                        // callbacks inside of these, get the now-expired
                        // values
                        var currentVersion = incrementVersion.getCurrentVersion();
                        currentCacheVersion.setVersion(currentVersion);
                        var mergeContext = {hasInvalidatedResult : false};

                        var pathsErr = model._useServerPaths && data && data.paths === undefined ?
                            new Error("Server responses must include a 'paths' field when Model._useServerPaths === true") : undefined;

                        if (!pathsErr) {
                            self._merge(rPaths, err, data, mergeContext);
                        }

                        // Call the callbacks.  The first one inserts all
                        // the data so that the rest do not have consider
                        // if their data is present or not.
                        for (i = 0, len = callbacks.length; i < len; ++i) {
                            fn = callbacks[i];
                            if (fn) {
                                fn(pathsErr || err, data, mergeContext.hasInvalidatedResult);
                            }
                        }
                        currentCacheVersion.setVersion(null);
                    }
                });
                self._disposable = flushedDisposable;
            });

            // If the scheduler is sync then `flushedDisposable` will be
            // defined, and we want to use it, because that's what aborts an
            // in-flight XHR request, for example.
            // But if the scheduler is async, then `flushedDisposable` won't be
            // defined yet, and so we must use the scheduler's disposable until
            // `flushedDisposable` is defined. Since we want to still use
            // `flushedDisposable` once it is defined (to be able to abort in-
            // flight XHR requests), hence the reassignment of `_disposable`
            // above.
            self._disposable = flushedDisposable || scheduleDisposable;
        }

        // Disposes this batched request.  This does not mean that the
        // entire request has been disposed, but just the local one, if all
        // requests are disposed, then the outer disposable will be removed.
        return createDisposable(self, idx);
    },

    /**
     * Attempts to add paths to the outgoing request.  If there are added
     * paths then the request callback will be added to the callback list.
     * Handles adding partial paths as well
     *
     * @returns {Array} - whether new requested paths were inserted in this
     *                    request, the remaining paths that could not be added,
     *                    and disposable for the inserted requested paths.
     */
    add: function(requested, optimized, depthDifferences, callback) {
        // uses the length tree complement calculator.
        var self = this;
        var complementTuple = complement(requested, optimized, depthDifferences, self._pathMap);
        var optimizedComplement;
        var requestedComplement;

        if (complementTuple) {
            requestedComplement = complementTuple[2];
            optimizedComplement = complementTuple[1];
        } else {
            requestedComplement = requested;
            optimizedComplement = optimized;
        }

        var inserted = false;
        var disposable = false;

        // If we found an intersection, then just add new callback
        // as one of the dependents of that request
        if (complementTuple && complementTuple[0].length) {
            inserted = true;
            var idx = self._callbacks.length;
            self._callbacks[idx] = callback;
            self._requestedPaths[idx] = complementTuple[0];
            self._optimizedPaths[idx] = [];
            ++self._count;

            disposable = createDisposable(self, idx);
        }

        return [inserted, requestedComplement, optimizedComplement, disposable];
    },

    /**
     * merges the response into the model"s cache.
     */
    _merge: function(requested, err, data, mergeContext) {
        var self = this;
        var model = self.requestQueue.model;
        var modelRoot = model._root;
        var errorSelector = modelRoot.errorSelector;
        var comparator = modelRoot.comparator;
        var boundPath = model._path;

        model._path = emptyArray;

        // flatten all the requested paths, adds them to the
        var nextPaths = model._useServerPaths ? data.paths : flattenRequestedPaths(requested);

        // Insert errors in every requested position.
        if (err && model._treatDataSourceErrorsAsJSONGraphErrors) {
            var error = err;

            // Converts errors to objects, a more friendly storage
            // of errors.
            if (error instanceof Error) {
                error = {
                    message: error.message
                };
            }

            // Not all errors are value $types.
            if (!error.$type) {
                error = {
                    $type: $error,
                    value: error
                };
            }

            var pathValues = nextPaths.map(function(x) {
                return {
                    path: x,
                    value: error
                };
            });
            setPathValues(model, pathValues, null, errorSelector, comparator, mergeContext);
        }

        // Insert the jsonGraph from the dataSource.
        else {
            setJSONGraphs(model, [{
                paths: nextPaths,
                jsonGraph: data.jsonGraph
            }], null, errorSelector, comparator, mergeContext);
        }

        // return the model"s boundPath
        model._path = boundPath;
    }
};

// Creates a more efficient closure of the things that are
// needed.  So the request and the idx.  Also prevents code
// duplication.
function createDisposable(request, idx) {
    var disposed = false;
    return function() {
        if (disposed || request._disposed) {
            return;
        }

        disposed = true;
        request._callbacks[idx] = null;
        request._optimizedPaths[idx] = [];
        request._requestedPaths[idx] = [];

        // If there are no more requests, then dispose all of the request.
        var count = --request._count;
        if (count === 0) {
            request._disposable.dispose();
            request.requestQueue.removeRequest(request);
        }
    };
}

function flattenRequestedPaths(requested) {
    var out = [];
    var outLen = -1;
    for (var i = 0, len = requested.length; i < len; ++i) {
        var paths = requested[i];
        for (var j = 0, innerLen = paths.length; j < innerLen; ++j) {
            out[++outLen] = paths[j];
        }
    }
    return out;
}

module.exports = GetRequestV2;
<|endoftext|>


<commit_before><commit_msg>Updated using.js.<commit_after><|endoftext|>


<commit_before>(function() {
  angular.module('ng-echarts', [])

  .directive('echart', ['$timeout', '$window', function($timeout, $window) {

    function draw(chart, echart, option, theme, init) {
      init && (echart = echarts.init(chart, theme));
      echart.setOption(option);
      return echart;
    };

    function calSize(ele, chart) {
      width  = ele.style.width  || chart.offsetWidth || '500px';
      height = ele.style.height || ele.offsetHeight  || '300px';

      return { width: width, height: height };
    };

    function link(scope, element, attrs) {
      var echart, theme, option;
      var autoResize = attrs.autoResize;
      var chart = element.find('div')[0];
      var initialized = false;

      $timeout(function() {
        var size = calSize(element[0], chart);
        chart.style.width = size.width;
        chart.style.height = size.height;
        option && (echart = draw(chart, echart, option, theme, true));
        initialized = true;
      });

      scope.$watch(attrs.theme, function(value) {
        theme = value;
        initialized && option && (echart = draw(chart, echart, option, theme, true));
      });

      scope.$watch(attrs.option, function(value) {
        option = value;
        initialized && option && (echart = draw(chart, echart, option, theme, true));
      }, true);

      scope.$watch(attrs.data, function(value) {
        value && echart.addData(value);
      });

      if (autoResize) {
        $window.addEventListener('resize', function() {
          echart.resize();
        });
      }

    };

    return {
      template: '

',
      restrict: 'E',
      link: link
    };
  }]);
})();
<commit_msg>remove unnecessary width and add echart service<commit_after>(function() {
  angular.module('ng-echarts', [])

  .directive('echart', ['$timeout', '$window', function($timeout, $window) {

    function draw(chart, echart, option, theme, init) {
      init && (echart = echarts.init(chart, theme));
      echart.setOption(option);
      return echart;
    };

    function calSize(ele, chart) {
      width  = ele.style.width;
      height = ele.style.height || ele.offsetHeight || '300px';

      if ((height + '').indexOf('px') < 0) { height = height + 'px'; }
      // this is not necessary
      //if ((width + '').indexOf('px') < 0) { width = width + 'px'; }

      return { width: width, height: height };
    };

    function link(scope, element, attrs) {
      var echart, theme, option;
      var autoResize = attrs.autoResize;
      var chart = element.find('div')[0];
      var initialized = false;

      $timeout(function() {
        var size = calSize(element[0], chart);
        chart.style.width = size.width;
        chart.style.height = size.height;
        option && (echart = draw(chart, echart, option, theme, true));
        initialized = true;
      });

      scope.$watch(attrs.theme, function(value) {
        theme = value;
        initialized && option && (echart = draw(chart, echart, option, theme, true));
      });

      scope.$watch(attrs.option, function(value) {
        option = value;
        initialized && option && (echart = draw(chart, echart, option, theme, true));
      }, true);

      scope.$watch(attrs.data, function(value) {
        value && echart.addData(value);
      });

      if (autoResize) {
        $window.addEventListener('resize', function() {
          echart.resize();
        });
      }

    };

    return {
      template: '

',
      restrict: 'E',
      link: link
    };
  }])

  .factory('echart', ['$window', '$log', function($window, $log) {
    function range(n) {
      var i = -1;
      var a = [];

      while (++i < n) {
        a[i] = i;
      }

      return a;
    }
    function generateXdata(n) {
      return range(n);
    }

    function generateYdata(n) {
      return range(n).map(function() {
        return $window.Math.round($window.Math.random() * 100);
      });
    }

    function generateSeriess(n, line) {
      line = line || 1;
      return range(line).map(function(i) {
        return generateSeries(i, 'line', n);
      });
    }

    function generateSeries(title, type, n) {
      return {
        name: title,
        type: type,
        //showAllSymbol: true,
        //symbolSize: function (value) {
        //  return Math.round(value[2] / 10) + 2;
        //},
        data: generateYdata(n)
      };
    }

    function getSampleChart() {
      var n = 20;
      return {
        option: {
          title: {
            text: 'sample',
            textStyle: { color: '#505050' }
          },
          backgroundColor: { color: 'rgba(0,0,0,0)'},
          theme: 'macarons',
          tooltip: {
            trigger: 'item',
            formatter: function (params) {
              return params.seriesName + '
' + params.name.toLocaleString() + ': ' + params.value[1];
            }
          },
          legend: { data: []},
          xAxis: [{
            type: 'category',
            axisLine: { lineStyle: { color: '#b3bfc3', width: 1 } },
            axisTick: { lineStyle: { color: '#b3bfc3', width: 1 } },
            axisLabel: { textStyle: { color: '#5c5c5c' } },
            data: generateXdata(n)
          }],
          yAxis: [{
            type: 'value',
            axisLine: { lineStyle: { color: '#b3bfc3', width: 1 } },
            axisTick: { lineStyle: { color: '#b3bfc3', width: 1 } },
            axisLabel: { textStyle: { color: '#5c5c5c' } }
          }],
          series: generateSeriess(n, 1)
        },
        theme: 'macarons',
        data: null,
        autoResize: true
      };
    }

    return {
      getSampleChart: getSampleChart
    };
  }]);
})();
<|endoftext|>


<commit_before>  $(function(){

      //カメラの情報を取得
      var cameraData = [];
      var video, canvas, ctx;
      var has_media_stream_track = true;
      var effect_index = 0;
      var filters = ["", "grayscale", "sepia", "blur"];
      try{
        console.log(MediaStreamTrack);
        console.log(!!MediaStreamTrack.getSources);
        console.log(!!MediaDevices.enumerateDevices);

        if(!!MediaStreamTrack.getSources){
          MediaStreamTrack.getSources(function(data){

            //カメラ情報を取得して、出力する
            var strCamera = "";
            var len = data.length;
            for( var i = 0 ; i < len ; i ++ ){
              strCamera += "
種類："+ data[i].kind+"
ID："+ data[i].id+"
";
              if( data[i].kind == "video" ){
                cameraData.push(data[i]);
              }
            }
            if( cameraData.length == 0 ){
              alert("カメラが見つかりません");
              return;
            }
            //カメラを取得・切り替える
            setCamera();
            console.log(cameraData);
            console.log(strCamera);
          });
        }else if(!!MediaDevices.enumerateDevices){
          navigator.mediaDevices.enumerateDevices()
          .then(function(devices) {
            devices.forEach(function(device) {
              console.log(device.kind + ": " + device.label +
                          " id = " + device.deviceId);
              if(device.kind === "video"){
                cameraData.push(device);
              }
            });
          })
          .catch(function(err) {
            console.log(err.name + ": " + error.message);
          });
        }else{
          has_media_stream_track = false;
          //カメラを取得・切り替える
          setCamera();
        }
      }catch(e){
        console.log(e);
        has_media_stream_track = false;
        //カメラを取得・切り替える
        setCamera();
      }

      //カメラを取得・切り替える
      var cnt = 0;
      var localStream = null;
      function setCamera(){

        //カメラを順番に切り替える
        cnt++;
        if( cnt == cameraData.length ){
          cnt = 0;
        }

        //カメラ取得
        video = document.getElementById('myVideo');

        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia;
        window.URL = window.URL || window.webkitURL;

        //カメラ再生中の場合は切り替えのため、一旦停止する
        if( localStream ){
          localStream.getTracks().forEach(function (track) { track.stop()});
        }

        if(has_media_stream_track){
          var constraints = {
            video: {
              optional: [{sourceId: cameraData[cnt].id }] //カメラIDを直接指定する
            },
            audio: false
          };
        }else{
          var constraints = {video: true, audio: false};
        }
        //カメラをIDを使用して取得する
        navigator.getUserMedia(
          constraints,
          function(stream) {

            //切り替え時にカメラを停止するため、情報を保存しておく
            localStream = stream;
            if(has_media_stream_track){
              $("#result_use").html( cameraData[cnt].id );
            }
            //カメラをvideoに結びつける
            video.src = window.URL.createObjectURL(stream);

          },
          function(err) {
            //エラー処理
          }
        );

      }

      function takeCamera(){
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        ctx = canvas.getContext("2d");
        ctx.fillStyle = "rgb(0,255,0)";
        ctx.strokeStyle = "rgb(0,255,0)";
        ctx.drawImage(video, 0, 0);
        //var url = canvas.toDataURL('image/webp');
        var url = canvas.toDataURL();
        var d = new Date();
        var u_time = Math.floor((d.getTime())/1000);
        var filename = "lucky_photo" + u_time + ".png";
        download(url, filename);
      }

      function download(objectURL, filename) {
        var a = document.createElement('a');
        var e = document.createEvent('MouseEvent');
        //console.log(objectURL);

        //a要素のdownload属性にファイル名を設定
        a.download = filename;
        a.href = objectURL;

        //clickイベントを着火
        e.initEvent("click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);

        $(video).hide();
        $(canvas).show();
        setInterval(function(){
          $(video).show();
          $(canvas).hide();
        }, 2000);
      }

      function applyEffect(){
        $(video).removeClass(filters[effect_index]);
        $(canvas).removeClass(filters[effect_index]);
        effect_index ++;
        if(effect_index == filters.length){
          effect_index = 0;
        }
        $(video).addClass(filters[effect_index]);
        $(canvas).addClass(filters[effect_index]);
        console.log(filters[effect_index]);
      }

      //カメラ切り替えボタンクリックイベント
      $("#changeButton").bind("click",function(){
        setCamera();
      });

      $("#takeButton").bind("click", function(){
        takeCamera();
      });

      $("#effectButton").bind("click",function(){
        applyEffect();
      });

      canvas = $("#canvas")
      $(video).css("max-width", screen.width);
      $(canvas).css("max-width", screen.width);
      $(video).css("max-height", screen.height*0.7);
      $(canvas).css("max-height", screen.height*0.7);

      canvas.hide();
      canvas = canvas.get(0);

    });<commit_msg>fix navigator.mediaDevices<commit_after>  $(function(){

      //カメラの情報を取得
      var cameraData = [];
      var video, canvas, ctx;
      var has_media_stream_track = true;
      var effect_index = 0;
      var filters = ["", "grayscale", "sepia", "blur"];
      try{
        console.log(MediaStreamTrack);
        console.log(!!MediaStreamTrack.getSources);
        console.log(!!navigator.mediaDevices.enumerateDevices);

        if(!!MediaStreamTrack.getSources){
          MediaStreamTrack.getSources(function(data){

            //カメラ情報を取得して、出力する
            var strCamera = "";
            var len = data.length;
            for( var i = 0 ; i < len ; i ++ ){
              strCamera += "
種類："+ data[i].kind+"
ID："+ data[i].id+"
";
              if( data[i].kind == "video" ){
                cameraData.push(data[i]);
              }
            }
            if( cameraData.length == 0 ){
              alert("カメラが見つかりません");
              return;
            }
            //カメラを取得・切り替える
            setCamera();
            console.log(cameraData);
            console.log(strCamera);
          });
        }else if(!!navigator.mediaDevices.enumerateDevices){
          navigator.mediaDevices.enumerateDevices()
          .then(function(devices) {
            devices.forEach(function(device) {
              console.log(device.kind + ": " + device.label +
                          " id = " + device.deviceId);
              if(device.kind === "video"){
                cameraData.push(device);
              }
            });
          })
          .catch(function(err) {
            console.log(err.name + ": " + error.message);
          });
        }else{
          has_media_stream_track = false;
          //カメラを取得・切り替える
          setCamera();
        }
      }catch(e){
        console.log(e);
        has_media_stream_track = false;
        //カメラを取得・切り替える
        setCamera();
      }

      //カメラを取得・切り替える
      var cnt = 0;
      var localStream = null;
      function setCamera(){

        //カメラを順番に切り替える
        cnt++;
        if( cnt == cameraData.length ){
          cnt = 0;
        }

        //カメラ取得
        video = document.getElementById('myVideo');

        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia;
        window.URL = window.URL || window.webkitURL;

        //カメラ再生中の場合は切り替えのため、一旦停止する
        if( localStream ){
          localStream.getTracks().forEach(function (track) { track.stop()});
        }

        if(has_media_stream_track){
          var constraints = {
            video: {
              optional: [{sourceId: cameraData[cnt].id }] //カメラIDを直接指定する
            },
            audio: false
          };
        }else{
          var constraints = {video: true, audio: false};
        }
        //カメラをIDを使用して取得する
        navigator.getUserMedia(
          constraints,
          function(stream) {

            //切り替え時にカメラを停止するため、情報を保存しておく
            localStream = stream;
            if(has_media_stream_track){
              $("#result_use").html( cameraData[cnt].id );
            }
            //カメラをvideoに結びつける
            video.src = window.URL.createObjectURL(stream);

          },
          function(err) {
            //エラー処理
          }
        );

      }

      function takeCamera(){
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        ctx = canvas.getContext("2d");
        ctx.fillStyle = "rgb(0,255,0)";
        ctx.strokeStyle = "rgb(0,255,0)";
        ctx.drawImage(video, 0, 0);
        //var url = canvas.toDataURL('image/webp');
        var url = canvas.toDataURL();
        var d = new Date();
        var u_time = Math.floor((d.getTime())/1000);
        var filename = "lucky_photo" + u_time + ".png";
        download(url, filename);
      }

      function download(objectURL, filename) {
        var a = document.createElement('a');
        var e = document.createEvent('MouseEvent');
        //console.log(objectURL);

        //a要素のdownload属性にファイル名を設定
        a.download = filename;
        a.href = objectURL;

        //clickイベントを着火
        e.initEvent("click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);

        $(video).hide();
        $(canvas).show();
        setInterval(function(){
          $(video).show();
          $(canvas).hide();
        }, 2000);
      }

      function applyEffect(){
        $(video).removeClass(filters[effect_index]);
        $(canvas).removeClass(filters[effect_index]);
        effect_index ++;
        if(effect_index == filters.length){
          effect_index = 0;
        }
        $(video).addClass(filters[effect_index]);
        $(canvas).addClass(filters[effect_index]);
        console.log(filters[effect_index]);
      }

      //カメラ切り替えボタンクリックイベント
      $("#changeButton").bind("click",function(){
        setCamera();
      });

      $("#takeButton").bind("click", function(){
        takeCamera();
      });

      $("#effectButton").bind("click",function(){
        applyEffect();
      });

      canvas = $("#canvas")
      $(video).css("max-width", screen.width);
      $(canvas).css("max-width", screen.width);
      $(video).css("max-height", screen.height*0.7);
      $(canvas).css("max-height", screen.height*0.7);

      canvas.hide();
      canvas = canvas.get(0);

    });<|endoftext|>


<commit_before>'use strict';

const chai = require('chai');
const lzo = require('../index');

const expect = chai.expect;

let compressed;

describe('Compression', () => {
	it('Should throw if nothing is passed', () =>
		expect(() => lzo.compress()).to.throw(TypeError)  );

	it('Should properly compress and not throw', () =>
		expect(() => (compressed = lzo.compress('Please don\'t throw!')) ).to.not.throw() );
});

describe('Decompression', () => {
	it('Should throw if nothing is passed', () =>
		expect(() => lzo.decompress()).to.throw(TypeError)  );

	it('Should properly decompress and not throw', () =>
		expect(() => lzo.decompress(compressed)).to.not.throw() );
});

describe('Version Stuff', () => {
	it('Should have a version string', () =>
		expect(lzo).to.have.ownProperty('version') );

	it('Should have a version date', () =>
		expect(lzo).to.have.ownProperty('versionDate') );
});<commit_msg>Changed version tests<commit_after>'use strict';

const chai = require('chai');
const lzo = require('../index');

const expect = chai.expect;

let compressed;

describe('Compression', () => {
	it('Should throw if nothing is passed', () =>
		expect(() => lzo.compress()).to.throw(TypeError)  );

	it('Should properly compress and not throw', () =>
		expect(() => (compressed = lzo.compress('Please don\'t throw!')) ).to.not.throw() );
});

describe('Decompression', () => {
	it('Should throw if nothing is passed', () =>
		expect(() => lzo.decompress()).to.throw(TypeError)  );

	it('Should properly decompress and not throw', () =>
		expect(() => lzo.decompress(compressed)).to.not.throw() );
});

describe('Version Stuff', () => {
	it('Should have property \'version\'', () =>
		expect(lzo).to.have.ownProperty('version') );

	it('Should have property \'versionDate\'', () =>
		expect(lzo).to.have.ownProperty('versionDate') );
});<|endoftext|>