<commit_before>/* eslint-disable array-element-newline */
'use strict';
const {dialog, BrowserWindow} = require('electron');
const fs = require('fs');
const {dirname} = require('path');
const {ipcMain: ipc} = require('electron-better-ipc');
const base64Img = require('base64-img');
const tmp = require('tmp');
const ffmpeg = require('@ffmpeg-installer/ffmpeg');
const util = require('electron-util');
const execa = require('execa');
const makeDir = require('make-dir');
const moment = require('moment');

const settings = require('./common/settings');
const {track} = require('./common/analytics');
const {openPrefsWindow} = require('./preferences');
const {getExportsWindow, openExportsWindow} = require('./exports');
const {openEditorWindow} = require('./editor');
const {toggleExportMenuItem} = require('./menus');
const Export = require('./export');

const ffmpegPath = util.fixPathForAsarUnpack(ffmpeg.path);
let lastSavedDirectory;

const filterMap = new Map([
  ['mp4', [{name: 'Movies', extensions: ['mp4']}]],
  ['webm', [{name: 'Movies', extensions: ['webm']}]],
  ['gif', [{name: 'Images', extensions: ['gif']}]],
  ['apng', [{name: 'Images', extensions: ['apng']}]]
]);

const getPreview = async inputPath => {
  const previewPath = tmp.tmpNameSync({postfix: '.jpg'});
  await execa(ffmpegPath, [
    '-ss', 0,
    '-i', inputPath,
    '-t', 1,
    '-vframes', 1,
    '-f', 'image2',
    previewPath
  ]);

  return previewPath;
};

const getDragIcon = async inputPath => {
  const iconPath = tmp.tmpNameSync({postfix: '.jpg'});
  await execa(ffmpegPath, [
    '-i', inputPath,
    // Scale the largest dimension to 64px maintaining aspect ratio
    '-vf', 'scale=if(gte(iw\\,ih)\\,min(64\\,iw)\\,-2):if(lt(iw\\,ih)\\,min(64\\,ih)\\,-2)',
    iconPath
  ]);

  return iconPath;
};

const saveSnapshot = async ({inputPath, time}) => {
  const now = moment();

  const {filePath: outputPath} = await dialog.showSaveDialog(BrowserWindow.getFocusedWindow(), {
    defaultPath: `Snapshot ${now.format('YYYY-MM-DD')} at ${now.format('H.mm.ss')}.jpg`
  });

  if (outputPath) {
    await execa(ffmpegPath, [
      '-i', inputPath,
      '-ss', time,
      '-vframes', 1,
      outputPath
    ]);
  }
};

class ExportList {
  constructor() {
    this.exports = [];
    this.queue = [];
  }

  _startNext() {
    if (this.queue.length === 0) {
      return;
    }

    this.currentExport = this.queue.shift();
    if (this.currentExport.canceled) {
      this._startNext();
      return;
    }

    (async () => {
      try {
        await this.currentExport.run();
        delete this.currentExport;
        this._startNext();
      } catch (error) {
        console.log(error);
        this.currentExport.updateExport({
          status: 'failed',
          text: 'Export failed',
          error: error.stack
        });
        delete this.currentExport;
        this._startNext();
      }
    })();
  }

  cancelExport(createdAt) {
    if (this.currentExport && this.currentExport.createdAt === createdAt) {
      track('export/canceled/current');
      this.currentExport.cancel();
    } else {
      const exportToCancel = this.exports.find(exp => exp.createdAt === createdAt);
      if (exportToCancel) {
        track('export/canceled/waiting');
        exportToCancel.cancel();
      }
    }
  }

  async addExport(options) {
    options.exportOptions.loop = settings.get('loopExports');
    const newExport = new Export(options);
    const createdAt = (new Date()).toISOString();

    if (options.plugin.pluginName === '_saveToDisk') {
      const wasExportsWindowOpen = Boolean(getExportsWindow());
      const exportsWindow = await openExportsWindow();
      const kapturesDir = settings.get('kapturesDir');
      await makeDir(kapturesDir);

      const filters = filterMap.get(options.format);

      const {filePath} = await dialog.showSaveDialog(exportsWindow, {
        title: newExport.defaultFileName,
        defaultPath: `${lastSavedDirectory || kapturesDir}/${newExport.defaultFileName}`,
        filters
      });

      if (filePath) {
        newExport.context.targetFilePath = filePath;
        lastSavedDirectory = dirname(filePath);
      } else {
        if (!wasExportsWindowOpen) {
          exportsWindow.close();
        }

        return;
      }
    } else if (options.plugin.pluginName === '_openWith') {
      newExport.context.appUrl = options.openWithApp.url;
    }

    if (!newExport.config.isConfigValid()) {
      const result = dialog.showMessageBoxSync({
        type: 'error',
        buttons: ['Configure', 'Cancel'],
        defaultId: 0,
        message: 'Error in plugin config',
        detail: `Review the config for the "${options.pluginName}" plugin to continue exporting`,
        cancelId: 1
      });

      track(`export/plugin/invalid/${options.pluginName}`);

      if (result === 0) {
        const prefsWindow = await openPrefsWindow();
        ipc.callRenderer(prefsWindow, 'open-plugin-config', options.pluginName);
      }

      return;
    }

    toggleExportMenuItem(true);

    newExport.status = 'waiting';
    newExport.text = 'Waiting…';
    newExport.imagePath = await getPreview(options.inputPath);
    newExport.image = base64Img.base64Sync(newExport.imagePath);
    newExport.createdAt = createdAt;
    newExport.originalFps = options.originalFps;

    callExportsWindow('update-export', {...newExport.data, createdAt});
    openExportsWindow();

    newExport.updateExport = updates => {
      if (newExport.canceled) {
        return;
      }

      for (const key in updates) {
        if (updates[key] !== undefined) {
          newExport[key] = updates[key];
        }
      }

      callExportsWindow('update-export', {...newExport.data, createdAt});
    };

    this.exports.push(newExport);
    this.queue.push(newExport);
    track(`export/queued/${this.queue.length}`);

    if (!this.currentExport) {
      this._startNext();
    }
  }

  getExports() {
    return this.exports.map(exp => exp.data);
  }

  getExport(createdAt) {
    return this.exports.find(exp => exp.createdAt === createdAt);
  }

  openExport(createdAt) {
    track('export/history/opened/recording');
    const exp = this.getExport(createdAt);
    if (exp) {
      openEditorWindow(exp.previewPath, {recordedFps: exp.originalFps, originalFilePath: exp.inputPath});
    }
  }
}

let exportList;

ipc.answerRenderer('get-exports', () => exportList.getExports());

ipc.answerRenderer('export', options => exportList.addExport(options));

ipc.answerRenderer('cancel-export', createdAt => exportList.cancelExport(createdAt));

ipc.answerRenderer('open-export', createdAt => exportList.openExport(createdAt));

ipc.answerRenderer('export-snapshot', saveSnapshot);

ipc.on('drag-export', async (event, createdAt) => {
  const exportItem = exportList.getExport(createdAt);
  const file = exportItem && exportItem.data.filePath;

  if (file && fs.existsSync(file)) {
    event.sender.startDrag({
      file,
      icon: await getDragIcon(exportItem.imagePath)
    });
  }
});

const callExportsWindow = (channel, data) => {
  const exportsWindow = getExportsWindow();

  if (exportsWindow) {
    // TODO(karaggeorge): Investigate why `ipc.callRenderer(exportsWindow, channel, data);` is not working here.
    exportsWindow.webContents.send(channel, data);
  }
};

module.exports = () => {
  exportList = new ExportList();
};
<commit_msg>Check if exports are running before quitting Kap (#719)<commit_after>/* eslint-disable array-element-newline */
'use strict';
const {dialog, BrowserWindow, app} = require('electron');
const fs = require('fs');
const {dirname} = require('path');
const {ipcMain: ipc} = require('electron-better-ipc');
const base64Img = require('base64-img');
const tmp = require('tmp');
const ffmpeg = require('@ffmpeg-installer/ffmpeg');
const util = require('electron-util');
const execa = require('execa');
const makeDir = require('make-dir');
const moment = require('moment');

const settings = require('./common/settings');
const {track} = require('./common/analytics');
const {openPrefsWindow} = require('./preferences');
const {getExportsWindow, openExportsWindow} = require('./exports');
const {openEditorWindow} = require('./editor');
const {toggleExportMenuItem} = require('./menus');
const Export = require('./export');

const ffmpegPath = util.fixPathForAsarUnpack(ffmpeg.path);
let lastSavedDirectory;

const filterMap = new Map([
  ['mp4', [{name: 'Movies', extensions: ['mp4']}]],
  ['webm', [{name: 'Movies', extensions: ['webm']}]],
  ['gif', [{name: 'Images', extensions: ['gif']}]],
  ['apng', [{name: 'Images', extensions: ['apng']}]]
]);

const getPreview = async inputPath => {
  const previewPath = tmp.tmpNameSync({postfix: '.jpg'});
  await execa(ffmpegPath, [
    '-ss', 0,
    '-i', inputPath,
    '-t', 1,
    '-vframes', 1,
    '-f', 'image2',
    previewPath
  ]);

  return previewPath;
};

const getDragIcon = async inputPath => {
  const iconPath = tmp.tmpNameSync({postfix: '.jpg'});
  await execa(ffmpegPath, [
    '-i', inputPath,
    // Scale the largest dimension to 64px maintaining aspect ratio
    '-vf', 'scale=if(gte(iw\\,ih)\\,min(64\\,iw)\\,-2):if(lt(iw\\,ih)\\,min(64\\,ih)\\,-2)',
    iconPath
  ]);

  return iconPath;
};

const saveSnapshot = async ({inputPath, time}) => {
  const now = moment();

  const {filePath: outputPath} = await dialog.showSaveDialog(BrowserWindow.getFocusedWindow(), {
    defaultPath: `Snapshot ${now.format('YYYY-MM-DD')} at ${now.format('H.mm.ss')}.jpg`
  });

  if (outputPath) {
    await execa(ffmpegPath, [
      '-i', inputPath,
      '-ss', time,
      '-vframes', 1,
      outputPath
    ]);
  }
};

class ExportList {
  constructor() {
    this.exports = [];
    this.queue = [];
  }

  _startNext() {
    if (this.queue.length === 0) {
      return;
    }

    this.currentExport = this.queue.shift();
    if (this.currentExport.canceled) {
      delete this.currentExport;
      this._startNext();
      return;
    }

    (async () => {
      try {
        await this.currentExport.run();
        delete this.currentExport;
        this._startNext();
      } catch (error) {
        console.log(error);
        this.currentExport.updateExport({
          status: 'failed',
          text: 'Export failed',
          error: error.stack
        });
        delete this.currentExport;
        this._startNext();
      }
    })();
  }

  cancelExport(createdAt) {
    if (this.currentExport && this.currentExport.createdAt === createdAt) {
      track('export/canceled/current');
      this.currentExport.cancel();
    } else {
      const exportToCancel = this.exports.find(exp => exp.createdAt === createdAt);
      if (exportToCancel) {
        track('export/canceled/waiting');
        exportToCancel.cancel();
      }
    }
  }

  async addExport(options) {
    options.exportOptions.loop = settings.get('loopExports');
    const newExport = new Export(options);
    const createdAt = (new Date()).toISOString();

    if (options.plugin.pluginName === '_saveToDisk') {
      const wasExportsWindowOpen = Boolean(getExportsWindow());
      const exportsWindow = await openExportsWindow();
      const kapturesDir = settings.get('kapturesDir');
      await makeDir(kapturesDir);

      const filters = filterMap.get(options.format);

      const {filePath} = await dialog.showSaveDialog(exportsWindow, {
        title: newExport.defaultFileName,
        defaultPath: `${lastSavedDirectory || kapturesDir}/${newExport.defaultFileName}`,
        filters
      });

      if (filePath) {
        newExport.context.targetFilePath = filePath;
        lastSavedDirectory = dirname(filePath);
      } else {
        if (!wasExportsWindowOpen) {
          exportsWindow.close();
        }

        return;
      }
    } else if (options.plugin.pluginName === '_openWith') {
      newExport.context.appUrl = options.openWithApp.url;
    }

    if (!newExport.config.isConfigValid()) {
      const result = dialog.showMessageBoxSync({
        type: 'error',
        buttons: ['Configure', 'Cancel'],
        defaultId: 0,
        message: 'Error in plugin config',
        detail: `Review the config for the "${options.pluginName}" plugin to continue exporting`,
        cancelId: 1
      });

      track(`export/plugin/invalid/${options.pluginName}`);

      if (result === 0) {
        const prefsWindow = await openPrefsWindow();
        ipc.callRenderer(prefsWindow, 'open-plugin-config', options.pluginName);
      }

      return;
    }

    toggleExportMenuItem(true);

    newExport.status = 'waiting';
    newExport.text = 'Waiting…';
    newExport.imagePath = await getPreview(options.inputPath);
    newExport.image = base64Img.base64Sync(newExport.imagePath);
    newExport.createdAt = createdAt;
    newExport.originalFps = options.originalFps;

    callExportsWindow('update-export', {...newExport.data, createdAt});
    openExportsWindow();

    newExport.updateExport = updates => {
      if (newExport.canceled) {
        return;
      }

      for (const key in updates) {
        if (updates[key] !== undefined) {
          newExport[key] = updates[key];
        }
      }

      callExportsWindow('update-export', {...newExport.data, createdAt});
    };

    this.exports.push(newExport);
    this.queue.push(newExport);
    track(`export/queued/${this.queue.length}`);

    if (!this.currentExport) {
      this._startNext();
    }
  }

  getExports() {
    return this.exports.map(exp => exp.data);
  }

  getExport(createdAt) {
    return this.exports.find(exp => exp.createdAt === createdAt);
  }

  openExport(createdAt) {
    track('export/history/opened/recording');
    const exp = this.getExport(createdAt);
    if (exp) {
      openEditorWindow(exp.previewPath, {recordedFps: exp.originalFps, originalFilePath: exp.inputPath});
    }
  }
}

let exportList;

ipc.answerRenderer('get-exports', () => exportList.getExports());

ipc.answerRenderer('export', options => exportList.addExport(options));

ipc.answerRenderer('cancel-export', createdAt => exportList.cancelExport(createdAt));

ipc.answerRenderer('open-export', createdAt => exportList.openExport(createdAt));

ipc.answerRenderer('export-snapshot', saveSnapshot);

ipc.on('drag-export', async (event, createdAt) => {
  const exportItem = exportList.getExport(createdAt);
  const file = exportItem && exportItem.data.filePath;

  if (file && fs.existsSync(file)) {
    event.sender.startDrag({
      file,
      icon: await getDragIcon(exportItem.imagePath)
    });
  }
});

const callExportsWindow = (channel, data) => {
  const exportsWindow = getExportsWindow();

  if (exportsWindow) {
    // TODO(karaggeorge): Investigate why `ipc.callRenderer(exportsWindow, channel, data);` is not working here.
    exportsWindow.webContents.send(channel, data);
  }
};

module.exports = () => {
  exportList = new ExportList();

  app.on('before-quit', event => {
    if (exportList.currentExport) {
      openExportsWindow();
      const exportsWindow = getExportsWindow();

      const buttonIndex = dialog.showMessageBoxSync(exportsWindow, {
        type: 'question',
        buttons: [
          'Continue',
          'Quit'
        ],
        defaultId: 0,
        cancelId: 1,
        message: 'Do you want to continue exporting?',
        detail: 'Kap is currently exporting files. If you quit, the export task will be canceled.'
      });

      if (buttonIndex === 0) {
        event.preventDefault();
      }
    }
  });
};
<|endoftext|>


<commit_before>var expect = require('expect.js'),
    common = require('./common'),
    extractYoutubeId = require("../public/js/extract-youtube-id"),
    _ = require("underscore");

describe("PREVIOUS VIDEOS", function() {
    var browser = null;
    if (process.env.SKIP_SELENIUM_TESTS) {
        return;
    }
    this.timeout(80000); // Extra long timeout for selenium :(

    before(function(done) {
        common.getSeleniumBrowser(function (theBrowser) {
            browser = theBrowser;
            common.standardSetup(done);
        });
    });
    after(function(done) {
        browser.quit().then(function() {
            common.standardShutdown(done);
        });
    });

    var PREVIOUS = [
        {youtubeId: "wd9OY0E8A98"},
        {youtubeId: "gjPr7sfS5bs"},
        {youtubeId: "4DUz4tzhv-w"},
        {youtubeId: "2laB2BmSNn0"}
    ];

    function prepEvent(event) {
        var event = common.server.db.events.findWhere({shortName: "writers-at-work"});
        event.set("open", true);
        event.set("previousVideoEmbeds", PREVIOUS);
        return event;
    }

    it("Removes individual videos", function(done) {
        var event = prepEvent();
        browser.get(common.URL);
        browser.mockAuthenticate("superuser1");
        browser.get(common.URL + event.getEventUrl());
        browser.waitForEventReady(event, "superuser1");
        browser.waitForSelector(".inline-video-controls .dropdown-toggle");
        browser.byCss(".inline-video-controls .dropdown-toggle").click();
        browser.byCss(".remove-one-previous-video[data-youtube-id='wd9OY0E8A98']").click();
        browser.wait(function() {
            return event.get("previousVideoEmbeds").length === PREVIOUS.length - 1;
        });
        browser.then(function() {
            var newPrevious = _.clone(PREVIOUS);
            newPrevious.shift();
            expect(event.get("previousVideoEmbeds")).to.eql(newPrevious);
        });
        browser.waitForSelector(".inline-video-controls .dropdown-toggle");
        browser.byCss(".inline-video-controls .dropdown-toggle").click();
        browser.byCsss(".previous-videos li", function(lis) {
            expect(lis.length).to.be(PREVIOUS.length - 1);
        });
        browser.then(function() {
            done();
        });
    });

    it("Clears the list of videos", function(done) {
        var event = prepEvent();
        browser.get(common.URL);
        browser.mockAuthenticate("superuser1");
        browser.get(common.URL + event.getEventUrl());
        browser.waitForEventReady(event, "superuser1");
        browser.waitForSelector("#video-embed .dropdown-toggle");
        browser.byCss("#video-embed .dropdown-toggle").click();
        browser.waitForSelector(".clear-previous-videos");
        browser.byCsss(".restore-previous-video:not(.header)").then(function(els) {
            expect(els.length).to.be(event.get("previousVideoEmbeds").length);
        });
        browser.byCss(".clear-previous-videos").click();
        browser.switchTo().alert().accept();
        browser.wait(function() {
            return event.get("previousVideoEmbeds").length === 0;
        }).then(function() {
            done();
        });
    });

});
<commit_msg>test fix for previous videos<commit_after>var expect = require('expect.js'),
    common = require('./common'),
    extractYoutubeId = require("../public/js/extract-youtube-id"),
    _ = require("underscore");

describe("PREVIOUS VIDEOS", function() {
    var browser = null;
    if (process.env.SKIP_SELENIUM_TESTS) {
        return;
    }
    this.timeout(80000); // Extra long timeout for selenium :(

    before(function(done) {
        common.getSeleniumBrowser(function (theBrowser) {
            browser = theBrowser;
            common.standardSetup(done);
        });
    });
    after(function(done) {
        browser.quit().then(function() {
            common.standardShutdown(done);
        });
    });

    var PREVIOUS = [
        {youtubeId: "wd9OY0E8A98"},
        {youtubeId: "gjPr7sfS5bs"},
        {youtubeId: "4DUz4tzhv-w"},
        {youtubeId: "2laB2BmSNn0"}
    ];

    function prepEvent(event) {
        var event = common.server.db.events.findWhere({shortName: "writers-at-work"});
        event.set("open", true);
        event.set("previousVideoEmbeds", PREVIOUS);
        return event;
    }

    it("Removes individual videos", function(done) {
        var event = prepEvent();
        browser.get(common.URL);
        browser.mockAuthenticate("superuser1");
        browser.get(common.URL + event.getEventUrl());
        browser.waitForEventReady(event, "superuser1");
        browser.waitForSelector("#video-embed .dropdown-toggle");
        browser.byCss("#video-embed .dropdown-toggle").click();
        browser.byCss(".remove-one-previous-video[data-youtube-id='wd9OY0E8A98']").click();
        browser.wait(function() {
            return event.get("previousVideoEmbeds").length === PREVIOUS.length - 1;
        });
        browser.then(function() {
            var newPrevious = _.clone(PREVIOUS);
            newPrevious.shift();
            expect(event.get("previousVideoEmbeds")).to.eql(newPrevious);
        });
        browser.waitForSelector("#video-embed .dropdown-toggle");
        browser.byCss("#video-embed .dropdown-toggle").click();
        browser.byCsss(".previous-videos li", function(lis) {
            expect(lis.length).to.be(PREVIOUS.length - 1);
        });
        browser.then(function() {
            done();
        });
    });

    it("Clears the list of videos", function(done) {
        var event = prepEvent();
        browser.get(common.URL);
        browser.mockAuthenticate("superuser1");
        browser.get(common.URL + event.getEventUrl());
        browser.waitForEventReady(event, "superuser1");
        browser.waitForSelector("#video-embed .dropdown-toggle");
        browser.byCss("#video-embed .dropdown-toggle").click();
        browser.waitForSelector(".clear-previous-videos");
        browser.byCsss(".restore-previous-video:not(.header)").then(function(els) {
            expect(els.length).to.be(event.get("previousVideoEmbeds").length);
        });
        browser.byCss(".clear-previous-videos").click();
        browser.switchTo().alert().accept();
        browser.wait(function() {
            return event.get("previousVideoEmbeds").length === 0;
        }).then(function() {
            done();
        });
    });

});
<|endoftext|>


<commit_before>"use strict"; // run code in ES5 strict mode

var nodeclass = require("nodeclass"),
    compile = nodeclass.compile,
    path = require("path");

var alamidPath = path.resolve(__dirname, "../../");

nodeclass.stdout = function(msg) {
  //No output in test mode
};

compile(alamidPath + "/lib", alamidPath + "/compiled");
<commit_msg>- removed deprecated file<commit_after><|endoftext|>


<commit_before>"use strict";

var f = require('util').format;

exports['Should iterate cursor'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor1", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}, {a:2}, {a:3}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(3, results.result.n);

          // Execute find
          var cursor = _server.cursor(ns, {
              find: ns
            , query: {}
            , batchSize: 2
          });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);
            test.equal(1, cursor.bufferedCount());

            // Kill the cursor
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(2, d.a);
              test.equal(0, cursor.bufferedCount());
              // Destroy the server connection
              _server.destroy();
              // Finish the test
              test.done();
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
}

exports['Should iterate cursor but readBuffered'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor2", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}, {a:2}, {a:3}, {a:4}, {a:5}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(5, results.result.n);

          // Execute find
          var cursor = _server.cursor(ns, {
              find: ns
            , query: {}
            , batchSize: 5
          });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);
            test.equal(4, cursor.bufferedCount());

            // Read the buffered Count
            var items = cursor.readBufferedDocuments(cursor.bufferedCount());

            // Get the next item
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(null, d);

              // Destroy the server connection
              _server.destroy();
              // Finish the test
              test.done();
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
}

exports['Should callback exhausted cursor with error'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor3", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(1, results.result.n);

          // Execute find
          var cursor =
            _server.cursor(ns, { find: ns, query: {}, batchSize: 5 });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);

            // Get the next item
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(null, d);

              cursor.next(function(err, d) {
                test.ok(err);
                test.equal(null, d);
                // Destroy the server connection
                _server.destroy();
                // Finish the test
                test.done();
              });
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
};
<commit_msg>repro; Automattic/mongoose#3493<commit_after>"use strict";

var f = require('util').format;

exports['Should iterate cursor'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor1", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}, {a:2}, {a:3}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(3, results.result.n);

          // Execute find
          var cursor = _server.cursor(ns, {
              find: ns
            , query: {}
            , batchSize: 2
          });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);
            test.equal(1, cursor.bufferedCount());

            // Kill the cursor
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(2, d.a);
              test.equal(0, cursor.bufferedCount());
              // Destroy the server connection
              _server.destroy();
              // Finish the test
              test.done();
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
}

exports['Should iterate cursor but readBuffered'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor2", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}, {a:2}, {a:3}, {a:4}, {a:5}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(5, results.result.n);

          // Execute find
          var cursor = _server.cursor(ns, {
              find: ns
            , query: {}
            , batchSize: 5
          });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);
            test.equal(4, cursor.bufferedCount());

            // Read the buffered Count
            var items = cursor.readBufferedDocuments(cursor.bufferedCount());

            // Get the next item
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(null, d);

              // Destroy the server connection
              _server.destroy();
              // Finish the test
              test.done();
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
}

exports['Should callback exhausted cursor with error'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor3", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        // Execute the write
        _server.insert(ns, [{a:1}], {
          writeConcern: {w:1}, ordered:true
        }, function(err, results) {
          test.equal(null, err);
          test.equal(1, results.result.n);

          // Execute find
          var cursor =
            _server.cursor(ns, { find: ns, query: {}, batchSize: 5 });

          // Execute next
          cursor.next(function(err, d) {
            test.equal(null, err);
            test.equal(1, d.a);

            // Get the next item
            cursor.next(function(err, d) {
              test.equal(null, err);
              test.equal(null, d);

              cursor.next(function(err, d) {
                test.ok(err);
                test.equal(null, d);
                // Destroy the server connection
                _server.destroy();
                // Finish the test
                test.done();
              });
            });
          });
        });
      })

      // Start connection
      server.connect();
    });
  }
};

exports['Handles overflow sort error when exhausting cursor'] = {
  metadata: {
    requires: {
      topology: "single"
    }
  },

  test: function(configuration, test) {
    configuration.newTopology(function(err, server) {
      var ns = f("%s.cursor4", configuration.db);
      // Add event listeners
      server.on('connect', function(_server) {
        var totalCount = 1024;
        var numOutstanding = totalCount;
        for (var i = 0; i < totalCount; ++i) {
          var doc = { f: require('crypto').pseudoRandomBytes(32 * totalCount) };
          _server.insert(ns, doc, { w: 1 }, function(error) {
            test.equal(error, null);
            if (!--totalCount) {
              doQuery();
            }
          });
        }

        var numInCursor = 0;
        var exhaust = function(cursor, callback) {
          cursor.next(function(error, res) {
            if (error) {
              return callback(error);
            }
            if (!res) {
              return callback(null);
            }
            exhaust(cursor, callback);
          });
        };

        var doQuery = function() {
          var sort = { f: 1, _id: 1 }
          var cursor = _server.cursor(ns,
            { find: ns, query: {}, batchSize: totalCount, sort: sort });
          exhaust(cursor, function(error) {
            test.ok(error);
            var message = error.toString();
            test.ok(message.indexOf('Overflow sort stage') !== -1);
            _server.destroy();
            test.done();
          });
        };
      });

      // Start connection
      server.connect();
    });
  }
};
<|endoftext|>


<commit_before>/*
 * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size,
 * and setting a number for max files created.
 * maxSize * maxFiles = total storage used by winston.
 *
 * (C) 2011 Daniel Aristizabal
 * MIT LICENSE
 *
 */

var assert = require('assert'),
    exec = require('child_process').exec,
    fs = require('fs'),
    path = require('path'),
    vows = require('vows'),
    winston = require('../../lib/winston'),
    helpers = require('../helpers');

var maxfilesTransport = new winston.transports.File({
  timestamp: false,
  json: false,
  filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'),
  maxsize: 4096,
  maxFiles: 3
});

vows.describe('winston/transports/file/maxfiles').addBatch({
  "An instance of the File Transport": {
    "when passed a valid filename": {
      "checks option": {
        topic: maxfilesTransport,
        "should be a valid transporter": function (transportTest) {
          helpers.assertFile(transportTest);
        },
        "should set the maxFiles option correctly": function (transportTest) {
          assert.isNumber(transportTest.maxFiles);
        }
      },
      "delete old test files": {
        topic: function () {
          exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback);
        },
        "when passed more files than the maxFiles": {
          topic: function () {
            var that = this,
                data = function (ch) {
                  return new Array(1018).join(String.fromCharCode(65 + ch));
                };

            //
            // Setup a list of files which we will later stat.
            //
            that.files = [];

            function logKbytes (kbytes) {
              //
              // With no timestamp and at the info level,
              // winston adds exactly 7 characters:
              // [info](4)[ :](2)[\n](1)
              //
              for (var i = 0; i < kbytes; i++) {
                maxfilesTransport.log('info', data(that.files.length), null, function () { });
              }
            }

            maxfilesTransport.on('open', function (file) {
              var match = file.match(/(\d+)\.log$/),
                  count = match ? match[1] : 0;

              that.files.push(file);

              if (that.files.length === 5) {
                return that.callback();
              }

              logKbytes(4);
            });

            logKbytes(4);
          },
          "should delete old files correctly": function () {
            this.files.forEach(function (file) {
              try {
                var stats = fs.statSync(file);
                assert.equal(stats.size, 4096);
              }
              catch (ex) {
                assert.isNull(ex);
              }
            });
          },
          "should move logs to new names": function () {
            assert.isFalse(true);
          }
        }
      }
    }
  }
}).export(module);<commit_msg>[test] finish test for issue #68<commit_after>/*
 * file-maxfiles-test.js: Tests for instances of the File transport setting the max file size,
 * and setting a number for max files created.
 * maxSize * maxFiles = total storage used by winston.
 *
 * (C) 2011 Daniel Aristizabal
 * MIT LICENSE
 *
 */

var assert = require('assert'),
    exec = require('child_process').exec,
    fs = require('fs'),
    path = require('path'),
    vows = require('vows'),
    winston = require('../../lib/winston'),
    helpers = require('../helpers');

var maxfilesTransport = new winston.transports.File({
  timestamp: false,
  json: false,
  filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles.log'),
  maxsize: 4096,
  maxFiles: 3
});

vows.describe('winston/transports/file/maxfiles').addBatch({
  "An instance of the File Transport": {
    "when passed a valid filename": {
      topic: maxfilesTransport,
      "should be a valid transporter": function (transportTest) {
        helpers.assertFile(transportTest);
      },
      "should set the maxFiles option correctly": function (transportTest) {
        assert.isNumber(transportTest.maxFiles);
      }
    },
    "when delete old test files": {
      topic: function () {
        exec('rm -rf ' + path.join(__dirname, '..', 'fixtures', 'logs', 'testmaxfiles*'), this.callback);
      },
      "and when passed more files than the maxFiles": {
        topic: function () {
          var that = this,
              data = function (ch) {
                return new Array(1018).join(String.fromCharCode(65 + ch));
              };

          function logKbytes (kbytes, txt) {
            //
            // With no timestamp and at the info level,
            // winston adds exactly 7 characters:
            // [info](4)[ :](2)[\n](1)
            //
            for (var i = 0; i < kbytes; i++) {
              maxfilesTransport.log('info', data(txt), null, function () { });
            }
          }

          var j = 0;

          maxfilesTransport.on('logged', function () {
            j++;
            if (j === 5)
              return that.callback();
            else
              logKbytes(4, j);
          });

          logKbytes(4, j);
        },
        "should be only max files": function () {
          ['A', 'B', 'C', 'D', 'E'].forEach(function (name, inx) {
            var file = path.join(__dirname, '..', 'fixtures', 'logs', ((inx === 0) ? 'testmaxfiles.log' : 'testmaxfiles' + inx + '.log'));
            // There should be no files with that name
            if (inx === 3 || inx === 4) {
              assert.throws(function () {
                fs.statSync(file);
              }, Error);
            } else {
              // The other files should be exist
              assert.doesNotThrow(function () {
                fs.statSync(file);
              }, Error);
            }
          });
        },
        "should have the correct content": function () {
          ['C', 'D', 'E'].forEach(function (name, inx) {
            var content = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'logs',
              ((inx === 0) ? 'testmaxfiles.log' : 'testmaxfiles' + inx + '.log')), 'utf-8');
            // The content minus the 7 characters added by winston
            assert.length(content.match(new RegExp(name, 'g')), 4068);
          });
        }
      }
    }
  }
}).export(module);<|endoftext|>


<commit_before>const routeHelper = require('../../helpers/routes/route-helper')
const supertest = require('supertest')
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const config = require('../../../config')
require('sinon-bluebird')

const ARCHIVE_DATA_URL = '/archive-data'

var app
var route
var userRoleService
var authorisationService
var hasRoleStub = sinon.stub()

var initaliseApp = function () {
    userRoleService = sinon.stub()
    authorisationService = {
      assertUserAuthenticated: sinon.stub(),
      hasRole: hasRoleStub
    }
    route = proxyquire('../../../app/routes/archive', {
        '../services/user-role-service': userRoleService,
        '../authorisation': authorisationService
      })
      app = routeHelper.buildApp(route)
    }

before(function () {
    initaliseApp()
})

describe('archive route', function () {
    it('should respond with 200 when archieve data is called', function () {
      return supertest(app).get(ARCHIVE_DATA_URL).expect(200)
    })
  })<commit_msg>test added for when the wrong url is entered<commit_after>const routeHelper = require('../../helpers/routes/route-helper')
const supertest = require('supertest')
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const config = require('../../../config')
require('sinon-bluebird')

const ARCHIVE_DATA_URL = '/archive-data'

var app
var route
var userRoleService
var authorisationService
var hasRoleStub = sinon.stub()

var initaliseApp = function () {
    userRoleService = sinon.stub()
    authorisationService = {
      assertUserAuthenticated: sinon.stub(),
      hasRole: hasRoleStub
    }
    route = proxyquire('../../../app/routes/archive', {
        '../services/user-role-service': userRoleService,
        '../authorisation': authorisationService
      })
      app = routeHelper.buildApp(route)
    }

before(function () {
    initaliseApp()
})

describe('archive route', function () {
    it('should respond with 200 when archieve data is called', function () {
      return supertest(app).get(ARCHIVE_DATA_URL).expect(200)
    })

    it('should respond with 500 when an incorrect url is called', function () {
        return supertest(app).get(INVALID_URL).expect(500)
      })
  })
  <|endoftext|>


<commit_before>elation.require(['janusweb.janusbase'], function() {
  elation.component.add('engine.things.janusobject', function() {
    this.sidemap = {
      'back': THREE.FrontSide,
      'front': THREE.BackSide,
      'none': THREE.DoubleSide
    };
    this.postinit = function() {
      elation.engine.things.janusobject.extendclass.postinit.call(this);
      this.defineProperties({
        janusid: { type: 'string', refreshGeometry: true },
        image_id: { type: 'string', set: this.updateMaterial },
        video_id: { type: 'string', set: this.updateMaterial },
        loop: { type: 'boolean' },
        collision_id: { type: 'string' },
        websurface_id: { type: 'string', set: this.updateMaterial },
        lighting: { type: 'boolean', default: true, set: this.updateMaterial },
        cull_face: { type: 'string', default: 'back', set: this.updateMaterial },
        blend_src: { type: 'string', default: 'src_alpha', set: this.updateMaterial },
        blend_dest: { type: 'string', default: 'one_minus_src_alpha', set: this.updateMaterial },
      });
      //elation.events.add(this, 'thing_init3d', elation.bind(this, this.assignTextures));
    }
    this.createObject3D = function() {
      if (this.properties.exists === false) return;

      var object = null, geometry = null, material = null;
      if (this.janusid) {
        object = elation.engine.assets.find('model', this.janusid);
        if (object.userData.loaded) {
          this.assignTextures();
        } else {
          elation.events.add(object, 'asset_load', elation.bind(this, this.assignTextures));
        }
      } else {
        object = new THREE.Object3D();
      }

      return object;
    }
    this.createChildren = function() {
      //this.properties.collidable = false;
      //this.updateColliderFromGeometry(new THREE.BoxGeometry(1,1,1));
    }
    this.createForces = function() {
      elation.engine.things.janusobject.extendclass.createForces.call(this);

      if (this.collision_id) {
        this.collidable = true;
        if (this.collision_id == 'sphere') {
          this.setCollider('sphere', {radius: Math.max(this.scale.x, this.scale.y, this.scale.z)});
        } else if (this.collision_id == 'cube') {
          var halfsize = this.properties.scale.clone().multiplyScalar(.5);
          this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
        } else if (this.collision_id == 'plane') {
          var halfsize = this.properties.scale.clone().multiplyScalar(.5);
          this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
        } else if (this.collision_id == 'cylinder') {
          this.setCollider('cylinder', {height: this.scale.y, radius: Math.max(this.scale.x, this.scale.z) / 2, offset: new THREE.Vector3(0, 0.5 * this.scale.y, 0)});
        } else {
          var collider = elation.engine.assets.find('model', this.collision_id);
          this.collidermesh = collider;
          if (collider.userData.loaded) {
            //this.extractColliders(collider, true);
            collider.userData.thing = this;
            this.colliders.add(collider);
          } else {
            elation.events.add(collider, 'asset_load', elation.bind(this, function(ev) {
              collider.userData.thing = this;
              //this.extractColliders(collider, true);

              //collider.bindPosition(this.position);
              //collider.bindQuaternion(this.orientation);
              //collider.bindScale(this.properties.scale);

              collider.traverse(elation.bind(this, function(n) {
                if (n.geometry) {
                  n.geometry.computeVertexNormals();
                  n.geometry.computeFaceNormals();
                }
                if (n.material) n.material = new THREE.MeshLambertMaterial({color: 0x999900, opacity: .2, transparent: true, emissive: 0x444400, alphaTest: .01, depthTest: false, depthWrite: false});
                n.userData.thing = this;
              }));
              this.colliders.add(collider);

            }) );
          }
        }
      }
    }
    this.createObjectDOM = function() {
      return;
      if (this.properties.websurface_id) {
        var websurface = this.properties.room.websurfaces[this.properties.websurface_id];
        console.log('do a websurface: ' + this.properties.websurface_id, websurface);
        if (websurface) {
          var width = websurface.width || 1024,
              height = websurface.height || 768;

          var iframe = elation.html.create('iframe');
          iframe.src = 'http://www.github.com/';//websurface.src;
          var div = elation.html.create('div');
          div.className = 'janusweb_websurface ';
          div.appendChild(iframe);

          div.style.width = width + 'px';
          div.style.height = height + 'px';
          iframe.style.width = width + 'px';
          iframe.style.height = height + 'px';

          var obj = new THREE.CSS3DObject(div);
          obj.scale.set(1/width, 1/height, 1);
          this.objects['3d'].add(obj);
        }
      }
    }
    this.updateMaterial = function() {
      this.assignTextures();
    }
    this.assignTextures = function() {
      //console.log('assign textures', this.name, this.objects['3d']);
      if (!this.objects['3d']) return;
      var modelasset = false,
          texture = false,
          color = false,
          blend_src = false,
          blend_dest = false,
          side = this.sidemap[this.properties.cull_face];

      if (this.janusid) {
        modelasset = elation.engine.assets.find('model', this.janusid, true);
      }
      if (this.properties.image_id) {
        texture = elation.engine.assets.find('image', this.image_id);
        if (!texture) {
          var asset = { assettype:'image', name:this.image_id, src: this.image_id, baseurl: this.baseurl };
          elation.engine.assets.loadJSON([asset], this.baseurl);
          texture = elation.engine.assets.find('image', this.image_id);
        }
        elation.events.add(texture, 'asset_load', elation.bind(this, this.assignTextures));
        elation.events.add(texture, 'update', elation.bind(this, this.refresh));
      }
      if (this.properties.video_id) {
        var videoasset = elation.engine.assets.find('video', this.properties.video_id, true);
        if (videoasset) {
          texture = videoasset.getInstance();
          if (videoasset.sbs3d) {
            texture.repeat.x = 0.5;
          }
          if (videoasset.loop || this.properties.loop) {
            texture.image.loop = true;
          }
          if (videoasset.auto_play) {
            texture.image.play();
          }
          texture.minFilter = THREE.LinearFilter;
          texture.magFilter = THREE.LinearFilter;
          elation.events.add(texture, 'videoframe', elation.bind(this, this.refresh));
          elation.events.add(this, 'click', elation.bind(this, this.pauseVideo));
          this.videotexture = texture;
        }
      }
      if (this.properties.color !== this.defaultcolor) {
        color = this.properties.color;
      }
/*
      if (this.properties.col) {
        var col = this.properties.col;
        if (!col && modelasset && modelasset.col) {
          col = modelasset.col;
        }
        //color.setRGB(col.x, col.y, col.z);
      }
*/
      var srcfactors = {
        'src_alpha': THREE.SrcAlphaFactor,
        'zero': THREE.ZeroFactor,
        'one': THREE.OneFactor,
        'src_color': THREE.SrcColorFactor,
        'one_minus_src_color': THREE.OneMinusSrcColorFactor,
        'one_minus_src_alpha': THREE.OneMinusSrcAlphaFactor,
        'dst_color': THREE.DstColorFactor,
        'one_minus_dst_color': THREE.OneMinusDstColorFactor,
        'one_minus_dst_alpha': THREE.OneMinusDstAlphaFactor,
      }
      if (srcfactors[this.properties.blend_src]) {
        blend_src = srcfactors[this.properties.blend_src];
      }
      if (srcfactors[this.properties.blend_dest]) {
        blend_dest = srcfactors[this.properties.blend_dest];
      }
      var scene = this.engine.systems.world.scene['world-3d'];
      if (!this.hasalpha) this.hasalpha = {};
      var hasalpha = this.hasalpha;
      var remove = [];
      var cloneMaterial = false;
      this.objects['3d'].traverse(elation.bind(this, function(n) {
        if (n.material) {
          var materials = [];
          if (n.material instanceof THREE.MeshFaceMaterial) {
            //materials = [n.material.materials[1]];
            for (var i = 0; i < n.material.materials.length; i++) {
              if (cloneMaterial) {
                var m = this.copyMaterial(n.material.materials[i]);
                materials.push(m);
              } else {
                materials.push(n.material.materials[i]);
              }
            }
            n.material.materials = materials;
          } else {
/*
            var m = this.copyMaterial(n.material);
            materials.push(m);
            n.material = m;
*/
            materials.push(n.material);
          }

          for (var i = 0; i < materials.length; i++) {
            var m = materials[i];
            //m.envMap = scene.background;
            if (texture && texture.image) {
              m.map = texture;
            }
            if (m.map && m.map.image) {
/*
              if (m.map.image instanceof HTMLCanvasElement) {
                // FIXME - don't think this works
                //hasalpha[m.map.image.src] = this.canvasHasAlpha(m.map.image);
                if (hasalpha[m.map.image.src]) {
                  m.transparent = true;
                  m.alphaTest = 0.01;
                  m.needsUpdate = true;
                }
              } else if (m.map.image.src && m.map.image.src.match(/\.(png|tga)$/)) {
                // If the image is a PNG, check to see if it's got an alpha channel
                // If it does, set the proper material parameters
                elation.events.add(m.map.image, 'load', elation.bind(this, function(ev) {
                  if (typeof hasalpha[ev.target.src] == 'undefined') {
                    var canvas = document.createElement('canvas');
                    canvas.width = m.map.image.width;
                    canvas.height = m.map.image.height;
                    var ctx = canvas.getContext('2d');
                    ctx.drawImage(m.map.image, 0, 0);

                    //hasalpha[ev.target.src] = this.canvasHasAlpha(canvas);
                    m.map.image = canvas;
                  }
                  if (hasalpha[ev.target.src]) {
                    m.transparent = true;
                    m.alphaTest = 0.01;
                    m.needsUpdate = true;
                  }
                }));
              }
*/
            }
            //m.roughness = 0.75;
            if (color) {
              m.color = color;
            }
            if (side) {
              m.side = side;
            }
            if (blend_src) m.blendSrc = blend_src;
            if (blend_dest) m.blendDst = blend_dest;
            m.needsUpdate = true;
          }
        } else if (n instanceof THREE.Light) {
          remove.push(n);
        }
      }));
      for (var i = 0; i < remove.length; i++) {
        remove[i].parent.remove(remove[i]);
      }
      this.refresh();
    }
    this.copyMaterial = function(oldmat) {
      //var m = (this.properties.lighting != false || oldmat.lightMap ? new THREE.MeshPhongMaterial() : new THREE.MeshBasicMaterial());
      var m = new THREE.MeshPhongMaterial();
      m.anisotropy = 16;
      m.name = oldmat.name;
      m.map = oldmat.map;
      m.normalMap = oldmat.normalMap;
      m.lightMap = oldmat.lightMap;
      m.color.copy(oldmat.color);
      m.transparent = oldmat.transparent;
      m.alphaTest = oldmat.alphaTest;

      return m;
    }
    this.pauseVideo = function() {
      if (this.videotexture) {
        var video = this.videotexture.image;
        if (video.currentTime > 0 && !video.paused && !video.ended) {
          video.pause();
        } else {
          video.play();
        }
      }
    }
    this.start = function() {
      if (this.properties.image_id) {
        var texture = elation.engine.assets.find('image', this.properties.image_id);
        console.log('start the image!', texture);
      }
      if (this.properties.video_id) {
        var texture = elation.engine.assets.find('video', this.properties.video_id);
        if (!texture.image.playing) {
          texture.image.play();
          console.log('start the video!', texture);
        }
      }
    }
    this.stop = function() {
      if (this.properties.image_id) {
        var texture = elation.engine.assets.find('image', this.properties.image_id);
        console.log('stop the image!', texture);
      }
      if (this.properties.video_id) {
        var texture = elation.engine.assets.find('video', this.properties.video_id);
        texture.image.pause();
        console.log('stop the video!', texture);
      }
    }
    this.getProxyObject = function() {
      var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this);
      proxy._proxydefs = {
        id:  [ 'property', 'janusid'],
        collision_id:  [ 'property', 'collision_id'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<commit_msg>Added collider and websurface support<commit_after>elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
  elation.component.add('engine.things.janusobject', function() {
    this.sidemap = {
      'back': THREE.FrontSide,
      'front': THREE.BackSide,
      'none': THREE.DoubleSide
    };
    this.postinit = function() {
      elation.engine.things.janusobject.extendclass.postinit.call(this);
      this.defineProperties({
        janusid: { type: 'string', refreshGeometry: true },
        image_id: { type: 'string', set: this.updateMaterial },
        video_id: { type: 'string', set: this.updateMaterial },
        url: { type: 'string' },
        loop: { type: 'boolean' },
        collision_id: { type: 'string' },
        websurface_id: { type: 'string', set: this.updateMaterial },
        lighting: { type: 'boolean', default: true, set: this.updateMaterial },
        cull_face: { type: 'string', default: 'back', set: this.updateMaterial },
        blend_src: { type: 'string', default: 'src_alpha', set: this.updateMaterial },
        blend_dest: { type: 'string', default: 'one_minus_src_alpha', set: this.updateMaterial },
        collider_id: { type: 'string', set: this.updatePhysics },
        collider_pos: { type: 'vector3', set: this.updatePhysics },
        collider_scale: { type: 'vector3', set: this.updatePhysics },
        collision_static: { type: 'boolean', default: true, set: this.updatePhysics },
      });
      //elation.events.add(this, 'thing_init3d', elation.bind(this, this.assignTextures));

      if (this.websurface_id) {
        var websurface = this.room.websurfaces[this.websurface_id];
        console.log('do a websurface: ' + this.websurface_id, websurface, this.room.baseurl);
        if (websurface) {
          var url = websurface.src;
          if (url && !url.match(/^(https?:)?\/\//)) {
            url = this.room.baseurl + url;
          }
          this.url = url;
        }
        this.pickable = false;
        this.collidable = false;
      }
    }
    this.createObject3D = function() {
      if (this.properties.exists === false) return;

      var object = null, geometry = null, material = null;
      if (this.janusid) {
        var asset = this.getAsset('model', this.janusid);
        if (asset) {
          if (asset.loaded) {
            setTimeout(elation.bind(this, this.assignTextures), 0);
          } else {
            elation.events.add(asset, 'asset_load_complete', elation.bind(this, this.assignTextures));
          }
          object = asset.getInstance();
        }
      } else {
        object = new THREE.Object3D();
      }

      return object;
    }
    this.createChildren = function() {
      //this.properties.collidable = false;
      //this.updateColliderFromGeometry(new THREE.BoxGeometry(1,1,1));
    }
    this.createForces = function() {
      elation.engine.things.janusobject.extendclass.createForces.call(this);
      if (!this.collidable) return;

      var collider_id = this.collider_id || this.collision_id;
      var collider_scale = this.properties.collider_scale || this.properties.scale;
      if (collider_id) {
        if ((!this.collision_static || this.collision_static == 'false') && this.room.gravity) { // FIXME - should never receive 'false' as a string here
          this.objects.dynamics.mass = this.mass = 1;
          this.objects.dynamics.addForce('static', new THREE.Vector3(0, this.room.gravity, 0));
        }

        this.collidable = true;
        if (collider_id == 'sphere') {
          this.setCollider('sphere', {radius: Math.max(collider_scale.x, collider_scale.y, collider_scale.z) / 2});
        } else if (collider_id == 'cube') {
          var halfsize = collider_scale.clone().multiplyScalar(.5);
          this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
        } else if (collider_id == 'plane') {
          var halfsize = collider_scale.clone().multiplyScalar(.5);
          halfsize.z = .1;
          this.setCollider('box', {min: halfsize.clone().negate(), max: halfsize});
        } else if (collider_id == 'cylinder') {
          this.setCollider('cylinder', {height: collider_scale.y, radius: Math.max(collider_scale.x, collider_scale.z) / 2, offset: new THREE.Vector3(0, 0.5 * collider_scale.y, 0)});
        } else {
          var colliderasset = this.getAsset('model', collider_id);
          if (colliderasset) {
            var collider = colliderasset.getInstance();
            this.collidermesh = collider;
            if (collider.userData.loaded) {
              this.extractColliders(collider, true);
              collider.userData.thing = this;
              this.colliders.add(collider);
            } else {
              elation.events.add(collider, 'asset_load', elation.bind(this, function(ev) {
                collider.userData.thing = this;
                this.extractColliders(collider, true);

                //collider.bindPosition(this.position);
                //collider.bindQuaternion(this.orientation);
                //collider.bindScale(this.properties.scale);

                collider.traverse(elation.bind(this, function(n) {
                  if (n.geometry) {
                    n.geometry.computeVertexNormals();
                    n.geometry.computeFaceNormals();
                  }
                  if (n.material) n.material = new THREE.MeshLambertMaterial({color: 0x999900, opacity: .2, transparent: true, emissive: 0x444400, alphaTest: .01, depthTest: false, depthWrite: false});
                  n.userData.thing = this;
                }));
                this.colliders.add(collider);

              }) );
            }
          }
        }
      }
    }
    this.createObjectDOM = function() {
/*
      if (this.websurface_id) {
        var websurface = this.room.websurfaces[this.properties.websurface_id];
        if (websurface) {
          var width = websurface.width || 1024,
              height = websurface.height || 768;

          var iframe = elation.html.create('iframe');
          iframe.src = this.url;
          var div = elation.html.create('div');
          div.className = 'janusweb_websurface ';
          div.appendChild(iframe);
          div.style.width = width + 'px';
          div.style.height = height + 'px';
          iframe.style.width = width + 'px';
          iframe.style.height = height + 'px';

          var obj = new THREE.CSS3DObject(div);
          obj.scale.set(1/width, 1/height, 1);
          this.objects['3d'].add(obj);
        }
      }
*/
    }
    this.updateMaterial = function() {
      this.assignTextures();
    }
    this.replaceWebsurfaceMaterial = function() {
      var blankmaterial = new THREE.MeshBasicMaterial({
        color: 0x000000,
        opacity: 0,
        transparent: true,
        blending: THREE.NoBlending,
        side: THREE.DoubleSide
      });
      this.objects['3d'].traverse(function(n) {
        if (n.material) n.material = blankmaterial;
      });
    }
    this.assignTextures = function() {
      //console.log('assign textures', this.name, this.objects['3d']);
      if (!this.objects['3d']) return;
      var modelasset = false,
          texture = false,
          color = false,
          blend_src = false,
          blend_dest = false,
          side = this.sidemap[this.properties.cull_face];

      if (this.janusid) {
        modelasset = this.getAsset('model', this.janusid);
      }
      if (this.properties.image_id) {
        textureasset = this.getAsset('image', this.image_id);
        if (textureasset) {
          texture = textureasset.getInstance();
          //elation.events.add(texture, 'asset_load', elation.bind(this, this.assignTextures));
          elation.events.add(texture, 'update', elation.bind(this, this.refresh));
        }
      }
      if (this.properties.video_id) {
        var videoasset = this.getAsset('video', this.properties.video_id);
        if (videoasset) {
          texture = videoasset.getInstance();
          if (videoasset.sbs3d) {
            texture.repeat.x = 0.5;
          }
          if (videoasset.loop || this.properties.loop) {
            texture.image.loop = true;
          }
          if (videoasset.auto_play) {
            texture.image.play();
          }
          texture.minFilter = THREE.LinearFilter;
          texture.magFilter = THREE.LinearFilter;
          elation.events.add(texture, 'videoframe', elation.bind(this, this.refresh));
          elation.events.add(this, 'click', elation.bind(this, this.pauseVideo));
          this.videotexture = texture;
        }
      }
      if (this.properties.websurface_id) {
        this.replaceWebsurfaceMaterial();
        return;
      }
      if (this.properties.color !== this.defaultcolor) {
        color = this.properties.color;
      }
/*
      if (this.properties.col) {
        var col = this.properties.col;
        if (!col && modelasset && modelasset.col) {
          col = modelasset.col;
        }
        //color.setRGB(col.x, col.y, col.z);
      }
*/
      var srcfactors = {
        'src_alpha': THREE.SrcAlphaFactor,
        'zero': THREE.ZeroFactor,
        'one': THREE.OneFactor,
        'src_color': THREE.SrcColorFactor,
        'one_minus_src_color': THREE.OneMinusSrcColorFactor,
        'one_minus_src_alpha': THREE.OneMinusSrcAlphaFactor,
        'dst_color': THREE.DstColorFactor,
        'one_minus_dst_color': THREE.OneMinusDstColorFactor,
        'one_minus_dst_alpha': THREE.OneMinusDstAlphaFactor,
      }
      if (srcfactors[this.properties.blend_src]) {
        blend_src = srcfactors[this.properties.blend_src];
      }
      if (srcfactors[this.properties.blend_dest]) {
        blend_dest = srcfactors[this.properties.blend_dest];
      }
      var scene = this.engine.systems.world.scene['world-3d'];
      if (!this.hasalpha) this.hasalpha = {};
      var hasalpha = this.hasalpha;
      var remove = [];
      var cloneMaterial = true;//(texture !== false);
      this.objects['3d'].traverse(elation.bind(this, function(n) {
        if (n.material) {
          var materials = [];
          if (n.material instanceof THREE.MeshFaceMaterial) {
            //materials = [n.material.materials[1]];
            for (var i = 0; i < n.material.materials.length; i++) {
              if (cloneMaterial) {
                var m = this.copyMaterial(n.material.materials[i]);
                materials.push(m);
              } else {
                materials.push(n.material.materials[i]);
              }
            }
            if (cloneMaterial) {
              n.material = new THREE.MeshFaceMaterial(materials);
            } else {
              n.material.materials = materials;
            }
          } else {
            if (cloneMaterial) {
              var m = this.copyMaterial(n.material);
              materials.push(m);
              n.material = m;
            } else {
              materials.push(n.material);
            }
          }

          for (var i = 0; i < materials.length; i++) {
            var m = materials[i];
            //m.envMap = scene.background;
            if (texture && texture.image) {
              m.map = texture;
            } else if (m.map) {
              var imagesrc = m.map.sourceFile;
              var asset = this.getAsset('image', imagesrc);
              if (asset && asset.hasalpha) {
                m.transparent = true;
                m.alphaTest = 0.01;
              }
            }
            //m.roughness = 0.75;
            if (color) {
              m.color = color;
            }
            m.side = side;
            if (blend_src) m.blendSrc = blend_src;
            if (blend_dest) m.blendDst = blend_dest;
            m.blending = THREE.CustomBlending;
            m.needsUpdate = true;
          }
        } else if (n instanceof THREE.Light) {
          remove.push(n);
        }
      }));
      for (var i = 0; i < remove.length; i++) {
        remove[i].parent.remove(remove[i]);
      }
      this.refresh();
    }
    this.copyMaterial = function(oldmat) {
      if (oldmat instanceof THREE.MultiMaterial) {
        var materials = [];
        for (var i = 0; i < oldmat.materials.length; i++) {
          materials.push(this.copyMaterial(oldmat.materials[i]));
        }
        var m = new THREE.MultiMaterial(materials);
      } else {
        var m = (this.properties.lighting != false ? new THREE.MeshPhongMaterial() : new THREE.MeshBasicMaterial());
        //var m = new THREE.MeshBasicMaterial();
        m.anisotropy = 16;
        m.name = oldmat.name;
        m.map = oldmat.map;
        m.normalMap = oldmat.normalMap;
        m.lightMap = oldmat.lightMap;
        m.color.copy(oldmat.color);
        m.transparent = oldmat.transparent;
        m.alphaTest = oldmat.alphaTest;
      }

      return m;
    }
    this.pauseVideo = function() {
      if (this.videotexture) {
        var video = this.videotexture.image;
        if (video.currentTime > 0 && !video.paused && !video.ended) {
          video.pause();
        } else {
          video.play();
        }
      }
    }
    this.start = function() {
      if (this.image_id) {
        var textureasset = this.getAsset('image', this.image_id);
        if (textureasset) {
          var texture = textureasset.getInstance();
          //console.log('start the image!', texture);
        }
      }
      if (this.video_id) {
        var texture = elation.engine.assets.find('video', this.video_id);
        if (!texture.image.playing) {
          texture.image.play();
          //console.log('start the video!', texture);
        }
      }
      if (this.websurface_id) {
        if (!this.websurface) {
          this.websurface = this.spawn('januswebsurface', null, {janus: this.janus, room: this.room, websurface_id: this.websurface_id});
          elation.events.add(this, 'mouseover', elation.bind(this.websurface, this.websurface.hover));
          elation.events.add(this, 'mouseout', elation.bind(this.websurface, this.websurface.unhover));
        }
        this.websurface.start();
      }
    }
    this.stop = function() {
      if (this.image_id) {
        var texture = elation.engine.assets.find('image', this.image_id);
        console.log('stop the image!', texture);
      }
      if (this.video_id) {
        var texture = elation.engine.assets.find('video', this.video_id);
        texture.image.pause();
        console.log('stop the video!', texture);
      }
      if (this.websurface_id && this.websurface) {
        this.websurface.stop();
      }
    }
    this.getProxyObject = function() {
      var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this);
      proxy._proxydefs = {
        id:  [ 'property', 'janusid'],
        url:  [ 'property', 'url'],
        collider_id:  [ 'property', 'collider_id'],
        collider_scale:  [ 'property', 'collider_scale'],
        collision_id:  [ 'property', 'collision_id'],
        collision_static:  [ 'property', 'collision_static'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var session = require('express-session');
var port = process.env.PORT || 3000;
var path = require('path');
var helmet = require('helmet');
const passport = require('passport');
require('../server/config/passport')(passport);

server.listen(port);

var url = require('url');
const uuidv4 = require('uuid/v4');

app.use(express.static(path.join(__dirname, "/../build")));

app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: false }));
app.use(require('body-parser').json());
app.use(helmet());
app.use(function(req, res) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
});

app.use(session({ secret: "secret", resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());

app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname + "/../build/index.html"));
});

app.post('/login', passport.authenticate('local-login', {
  successRedirect: '/profile',
  failureRedirect: '/'
}));

app.post('/signup', passport.authenticate('local-signup', {
  successRedirect: '/profile',
  failureRedirect: '/'
}));

function isLoggedIn(req, res, next) {
	if (req.isAuthenticated())
		return next();

	res.redirect('/');
};

var models = require("../server/models");
models.sequelize.sync().then(function() {
   console.log('Database synced without errors')
}).catch(function(err) {
   console.log(err, "Database encountered an error when syncing")
});

let connections = [];

io.on('connection', function (socket) {
  io.set('transports', ['websocket', 'polling']);

  socket.on('connectToRoom', function (data) {
    var roomId = "";
    if (data != null && data.roomId != null) {
      roomId = data.roomId;
    }
    if (roomId === "") {
      roomId = uuidv4();
    }

    socket.join(roomId);

    var socketFound = false;
    var connectionsRoomIndex;
    for (var i = 0; i < connections.length; i++) {
      if (connections[i].roomId === roomId) {
        connectionsRoomIndex = i;
        socketFound = true;
        connections[i].currentConnections.push({socketId: socket.id, userName: data.userName});
        socket.emit('codeUpdate', { roomId: connections[i].roomId, code: connections[i].currentCode });
      }
    }
    if (!socketFound) {
      connectionsRoomIndex = 0;
      connections.push({
        roomId: roomId,
        currentConnections: [{socketId: socket.id, userName: data.userName}],
        currentCode: ""
      });
    }
    io.sockets.in(roomId).emit('newConnection', { roomId: roomId, socketId: socket.id, userName: data.userName, connections: connections[connectionsRoomIndex] });
  });

  socket.on('disconnecting', function() {
    for (var room in socket.rooms) {
      for (var i = 0; i < connections.length; i++) {
        if (connections[i].roomId == room) {
          for (var j = 0; j < connections[i].currentConnections.length; j++) {
            if (connections[i].currentConnections[j].socketId == socket.id) {
              socket.to(room).emit('userDisconnected', { socketId: socket.id, userName: connections[i].currentConnections[j].userName });
              connections[i].currentConnections.splice(j, 1);
              break;
            }
          }
        }
      }
    }
  })

  socket.on('codeChange', function (data) {
    for (var i = 0; i < connections.length; i++) {
      if (connections[i].roomId === data.roomId) {
        connections[i].currentCode = data.code;
      }
    }
    //Using socket.to will not resend to the sending socket
    socket.to(data.roomId).emit('codeUpdate', data);
  });
});
<commit_msg>fix: cleaned up server code and removed experimental code<commit_after>var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var session = require('express-session');
var port = process.env.PORT || 3000;
var path = require('path');
var helmet = require('helmet');
const passport = require('passport');
require('../server/config/passport')(passport);

server.listen(port);

var url = require('url');
const uuidv4 = require('uuid/v4');

app.use(express.static(path.join(__dirname, "/../build")));

app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: false }));
app.use(require('body-parser').json());
app.use(helmet());

app.use(passport.initialize());
app.use(passport.session());

app.post('/login', passport.authenticate('local-login', {
  successRedirect: '/profile',
  failureRedirect: '/'
}));

app.post('/signup', passport.authenticate('local-signup', {
  successRedirect: '/profile',
  failureRedirect: '/'
}));

app.get('*', function (req, res) {
  res.sendFile(path.join(__dirname + "/../build/index.html"));
});

function isLoggedIn(req, res, next) {
	if (req.isAuthenticated())
		return next();

	res.redirect('/');
};

var models = require("../server/models");
models.sequelize.sync().then(function() {
   console.log('Database synced without errors')
}).catch(function(err) {
   console.log(err, "Database encountered an error when syncing")
});

let connections = [];

io.on('connection', function (socket) {
  io.set('transports', ['websocket', 'polling']);

  socket.on('connectToRoom', function (data) {
    var roomId = "";
    if (data != null && data.roomId != null) {
      roomId = data.roomId;
    }
    if (roomId === "") {
      roomId = uuidv4();
    }

    socket.join(roomId);

    var socketFound = false;
    var connectionsRoomIndex;
    for (var i = 0; i < connections.length; i++) {
      if (connections[i].roomId === roomId) {
        connectionsRoomIndex = i;
        socketFound = true;
        connections[i].currentConnections.push({socketId: socket.id, userName: data.userName});
        socket.emit('codeUpdate', { roomId: connections[i].roomId, code: connections[i].currentCode });
      }
    }
    if (!socketFound) {
      connectionsRoomIndex = 0;
      connections.push({
        roomId: roomId,
        currentConnections: [{socketId: socket.id, userName: data.userName}],
        currentCode: ""
      });
    }
    io.sockets.in(roomId).emit('newConnection', { roomId: roomId, socketId: socket.id, userName: data.userName, connections: connections[connectionsRoomIndex] });
  });

  socket.on('disconnecting', function() {
    for (var room in socket.rooms) {
      for (var i = 0; i < connections.length; i++) {
        if (connections[i].roomId == room) {
          for (var j = 0; j < connections[i].currentConnections.length; j++) {
            if (connections[i].currentConnections[j].socketId == socket.id) {
              socket.to(room).emit('userDisconnected', { socketId: socket.id, userName: connections[i].currentConnections[j].userName });
              connections[i].currentConnections.splice(j, 1);
              break;
            }
          }
        }
      }
    }
  })

  socket.on('codeChange', function (data) {
    for (var i = 0; i < connections.length; i++) {
      if (connections[i].roomId === data.roomId) {
        connections[i].currentCode = data.code;
      }
    }
    //Using socket.to will not resend to the sending socket
    socket.to(data.roomId).emit('codeUpdate', data);
  });
});
<|endoftext|>