<commit_before>'use strict';
const path = require('path');
const os = require('os');
const Convert = require('./convert-source-map');
const fs = require('../file-system');
const SourceInclusion = require('./source-inclusion').SourceInclusion;
const DependencyInclusion = require('./dependency-inclusion').DependencyInclusion;
const Configuration = require('../configuration').Configuration;
const Utils = require('./utils');

exports.Bundle = class {
  constructor(bundler, config) {
    this.Minimatch = require('minimatch').Minimatch; //nested dep of vinyl-fs
    this.bundler = bundler;
    this.config = config;
    this.dependencies = [];
    this.prepend = (config.prepend || []).filter(x => bundler.itemIncludedInBuild(x));
    this.append = (config.append || []).filter(x => bundler.itemIncludedInBuild(x));
    this.moduleId = config.name.replace(path.extname(config.name), '');
    this.hash = '';
    this.includes = (config.source || []);
    this.excludes = [];
    if (this.includes instanceof Array) {
      this.includes = this.includes.map(x => new SourceInclusion(this, x));
    } else {
      this.excludes = (this.includes.exclude || []).map(x => this.createMatcher(x));
      this.includes = this.includes.include.map(x => new SourceInclusion(this, x));
    }
    this.buildOptions = new Configuration(config.options, bundler.buildOptions.getAllOptions());
    this.requiresBuild = true;
    this.fileCache = {};
  }

  static create(bundler, config) {
    let bundle = new exports.Bundle(bundler, config);
    let dependencies = config.dependencies || [];
    let dependenciesToBuild = dependencies
        .filter(x => bundler.itemIncludedInBuild(x));

    return Utils.runSequentially(
        dependenciesToBuild,
        dep => bundler.configureDependency(dep))
    .then(descriptions => {
      return Utils.runSequentially(
        descriptions,
        description => bundle.addDependency(description)
      );
    })
    .then(() => bundle);
  }

  createMatcher(pattern) {
    return new this.Minimatch(pattern);
  }

  addDependency(description) {
    this.dependencies.push(description);
    let inclusion = new DependencyInclusion(this, description);
    this.includes.push(inclusion);
    return inclusion.traceResources();
  }

  trySubsume(item) {
    let includes = this.includes;

    for (let i = 0, ii = includes.length; i < ii; ++i) {
      if (includes[i].trySubsume(item)) {
        this.requiresBuild = true;
        return true;
      }
    }

    return false;
  }

  transform() {
    if (this.requiresBuild) {
      let index = -1;
      let items = this.includes;

      function doTransform() {
        index++;

        if (index < items.length) {
          return items[index].transform().then(doTransform);
        }

        return Promise.resolve();
      }

      return doTransform();
    }

    return Promise.resolve();
  }

  getDependencyLocations() {
    return this.includes.filter(inclusion => inclusion.description && inclusion.description.location)
      .map(inclusion => {
        let normalizedLocation = path.posix.normalize(inclusion.description.location).replace(/\\/g, '\/');
        return {
          location: normalizedLocation,
          inclusion: inclusion
        };
      });
  }

  getBundledModuleIds() {
    return unique(this.includes.reduce((a, b) => a.concat(b.getAllModuleIds()), []));
  }

  getBundledFiles() {
    return this.includes.reduce((a, b) => a.concat(b.getAllFiles()), []);
  }

  write(platform) {
    if (!this.requiresBuild) {
      return Promise.resolve();
    }

    let work = Promise.resolve();
    let loaderOptions = this.bundler.loaderOptions;
    let buildOptions = this.buildOptions;
    let files = [];

    if (this.prepend.length) {
      work = work.then(() => addFilesInOrder(this, this.prepend, files));
    }

    if (loaderOptions.configTarget === this.config.name) {
      work = work.then(() => {
        files.push({ contents: '_aureliaConfigureModuleLoader();'});
      });
    }

    work = work.then(() => files = files.concat(this.getBundledFiles()));

    if (this.append.length) {
      work = work.then(() => addFilesInOrder(this, this.append, files));
    }

    return work.then(() => {
      const Concat = require('./concat-with-sourcemaps');
      let concat = new Concat(true, this.config.name, os.EOL);
      const generateHashedPath = require('./utils').generateHashedPath;
      const generateHash = require('./utils').generateHash;
      let needsSourceMap = false;

      for (let i = 0; i < files.length; ++i) {
        let currentFile = files[i];
        let sourceMap = buildOptions.isApplicable('sourcemaps') ? currentFile.sourceMap : undefined;

        function fileIsDependency(file) {
          return file
            && file.path
            && file.path.indexOf('node_modules') >= 0;
        }

        function acquireSourceMapForDependency(file) {
          if (!file || !file.path) {
            return;
          }

          let parsedPath = path.parse(file.path);

          try {
            let base64SourceMap = Convert.fromSource(file.contents.toString());

            if (base64SourceMap) {
              return null;
            }
          } catch (error) {
            // we don't want the build to fail when a sourcemap file can't be parsed
            return null;
          }

          let converter;

          try {
            converter = Convert.fromMapFileSource(file.contents.toString(), parsedPath.dir);
          } catch (e) {
            console.log(e);
            return null;
          }

          sourceMap = converter
            ? converter.sourcemap
            : null;

          if (sourceMap !== null) {
            // path.posix.relative(from, to) does not work here
            sourceMap.sourceRoot = parsedPath.dir.substring(process.cwd().length);
          }

          return sourceMap;
        }

        if (fileIsDependency(currentFile)) {
          sourceMap = acquireSourceMapForDependency(currentFile);
        }

        if (sourceMap) {
          needsSourceMap = true;
        }

        concat.add(currentFile.path, currentFile.contents, sourceMap ? JSON.stringify(sourceMap) : undefined);
      }

      let mapContents;
      let contents = concat.content;
      let bundleFileName = this.config.name;

      if (loaderOptions.configTarget === this.config.name) {
        //Add to the config bundle the loader config. Can't change index.html yet because we haven't generated hashes for all the files
        concat.add(undefined, this.writeLoaderCode(platform));
        contents = concat.content;

        if (buildOptions.isApplicable('rev')) {
          //Generate a unique hash based off of the bundle contents
          //Must generate hash after we write the loader config so that any other bundle changes (hash changes) can cause a new hash for the vendor file
          this.hash = generateHash(concat.content);
          bundleFileName = generateHashedPath(this.config.name, this.hash);
        }

        //Again, in the config setup, we're at the last bundle, and we can modify the index.html correctly now
        let outputDir = platform.baseUrl || platform.output; //If we have a baseUrl, then the files are served from there, else it's the output
        if (platform.index) {
          this.setIndexFileConfigTarget(platform, path.posix.join(outputDir, bundleFileName));
        }
      } else if (buildOptions.isApplicable('rev')) {
        //Generate a unique hash based off of the bundle contents
        //Must generate hash after we write the loader config so that any other bundle changes (hash changes) can cause a new hash for the vendor file
        this.hash = generateHash(concat.content);
        bundleFileName = generateHashedPath(this.config.name, this.hash);
      }

      let mapFileName = bundleFileName + '.map';
      let mapSourceRoot = path.posix.relative(
        path.posix.join(process.cwd(), platform.output),
        process.cwd()
      );

      console.log(`Writing ${bundleFileName}...`);

      if (buildOptions.isApplicable('minify')) {

        const UglifyJS = require('uglify-js'); //added to user project devDependencies
        // fromString is not a supported option in v3
        const isV3 = !!(UglifyJS.minify('', {fromString: true}).error);

        let minificationOptions = {};
        if (!isV3) minificationOptions.fromString = true;

        let minifyOptions = buildOptions.getValue('minify');
        if (typeof minifyOptions === 'object') {
          Object.assign(minificationOptions, minifyOptions);
        }

        if (needsSourceMap) {
          if (isV3) {
            minificationOptions.sourceMap = {
              content: concat.sourceMap,
              filename: bundleFileName,
              url: mapFileName,
              root: mapSourceRoot
            };
          } else {
            minificationOptions.inSourceMap = Convert.fromJSON(concat.sourceMap).toObject();
            minificationOptions.outSourceMap = mapFileName;
            minificationOptions.sourceRoot = mapSourceRoot;
          }
        }

        let minificationResult = UglifyJS.minify(String(contents), minificationOptions);
        if (minificationResult.error) throw minificationResult.error;

        contents = minificationResult.code;
        mapContents = needsSourceMap ? Convert.fromJSON(minificationResult.map).toJSON() : undefined;
      } else if (needsSourceMap) {
        mapContents = Convert.fromJSON(concat.sourceMap)
          .setProperty('sourceRoot', mapSourceRoot)
          .toJSON();

        contents += os.EOL + '//# sourceMappingURL=' + mapFileName;
      }

      return fs.writeFile(path.posix.join(platform.output, bundleFileName), contents).then(() => {
        this.requiresBuild = false;

        if (mapContents) {
          return fs.writeFile(path.posix.join(platform.output, mapFileName), mapContents)
          .catch(e => {
            console.log(`Unable to write the sourcemap to ${path.posix.join(platform.output, mapFileName)}`);
          });
        }
      })
      .catch(e => {
        console.log(`Unable to write the bundle to ${path.posix.join(platform.output, bundleFileName)}`);
        console.log(e);
        throw e;
      });
    })
    .catch(e => {
      console.log('Failed to write the bundle');
      console.log(e);
      throw e;
    });
  }

  getFileFromCacheOrLoad(x) {
    let found = this.fileCache[x];
    if (found) {
      return Promise.resolve(found);
    }

    return fs.readFile(x).then(data => {
      found = { contents: data.toString() };
      this.fileCache[x] = found;
      return found;
    });
  }

  writeLoaderCode(platform) {
    const createLoaderCode = require('./loader').createLoaderCode;
    let config = createLoaderCode(platform, this.bundler);

    return 'function _aureliaConfigureModuleLoader(){' + config + '}';
  }

  setIndexFileConfigTarget(platform, location) {
    //Replace the reference to the vendor bundle in the "index.html" file to use the correct build revision file (or remove the build revision hash);
    const createSrcFileRegex = require('./utils').createSrcFileRegex;
    let indexLocation = platform.index;
    try {
      let indexFile = fs.readFileSync(indexLocation);
      let outputDir = platform.baseUrl || platform.output; //If we have a baseUrl, then the files are served from there, else it's the output
      let configMatcher = createSrcFileRegex(outputDir, this.moduleId);
      if (configMatcher.test(indexFile)) {
        indexFile = indexFile.replace(configMatcher, 'src="$2' + location + '"');//Replace the old reference to the file with whatever the new one is (preserving any unknown path parts before)
        fs.writeFile(indexLocation, indexFile);
      } else {
        console.log('Error: Unable to update ' + this.moduleId + ' path to ' + location + ', could not find existing reference to replace');
      }
    } catch (err) {
      if (err.code === 'ENOENT') {
        console.log('Error: No index file found at "' + indexLocation + '"');
      } else {
        console.log(err);
      }
    }
  }
};

function addFilesInOrder(bundle, paths, files) {
  let index = -1;

  function addFile() {
    index++;

    if (index < paths.length) {
      return bundle.getFileFromCacheOrLoad(paths[index])
        .then(file => files.push(file))
        .then(addFile);
    }

    return Promise.resolve();
  }

  return addFile();
}

function unique(collection) {
  let u = {};
  let a = [];

  for (let i = 0, l = collection.length; i < l; ++i) {
    if (u.hasOwnProperty(collection[i])) {
      continue;
    }

    a.push(collection[i]);
    u[collection[i]] = 1;
  }

  return a;
}
<commit_msg>chore(bundle): fixed linter issues<commit_after>'use strict';
const path = require('path');
const os = require('os');
const Convert = require('./convert-source-map');
const fs = require('../file-system');
const SourceInclusion = require('./source-inclusion').SourceInclusion;
const DependencyInclusion = require('./dependency-inclusion').DependencyInclusion;
const Configuration = require('../configuration').Configuration;
const Utils = require('./utils');

exports.Bundle = class {
  constructor(bundler, config) {
    this.Minimatch = require('minimatch').Minimatch; //nested dep of vinyl-fs
    this.bundler = bundler;
    this.config = config;
    this.dependencies = [];
    this.prepend = (config.prepend || []).filter(x => bundler.itemIncludedInBuild(x));
    this.append = (config.append || []).filter(x => bundler.itemIncludedInBuild(x));
    this.moduleId = config.name.replace(path.extname(config.name), '');
    this.hash = '';
    this.includes = (config.source || []);
    this.excludes = [];
    if (this.includes instanceof Array) {
      this.includes = this.includes.map(x => new SourceInclusion(this, x));
    } else {
      this.excludes = (this.includes.exclude || []).map(x => this.createMatcher(x));
      this.includes = this.includes.include.map(x => new SourceInclusion(this, x));
    }
    this.buildOptions = new Configuration(config.options, bundler.buildOptions.getAllOptions());
    this.requiresBuild = true;
    this.fileCache = {};
  }

  static create(bundler, config) {
    let bundle = new exports.Bundle(bundler, config);
    let dependencies = config.dependencies || [];
    let dependenciesToBuild = dependencies
        .filter(x => bundler.itemIncludedInBuild(x));

    return Utils.runSequentially(
        dependenciesToBuild,
        dep => bundler.configureDependency(dep))
    .then(descriptions => {
      return Utils.runSequentially(
        descriptions,
        description => bundle.addDependency(description)
      );
    })
    .then(() => bundle);
  }

  createMatcher(pattern) {
    return new this.Minimatch(pattern);
  }

  addDependency(description) {
    this.dependencies.push(description);
    let inclusion = new DependencyInclusion(this, description);
    this.includes.push(inclusion);
    return inclusion.traceResources();
  }

  trySubsume(item) {
    let includes = this.includes;

    for (let i = 0, ii = includes.length; i < ii; ++i) {
      if (includes[i].trySubsume(item)) {
        this.requiresBuild = true;
        return true;
      }
    }

    return false;
  }

  transform() {
    if (this.requiresBuild) {
      let index = -1;
      let items = this.includes;

      function doTransform() {
        index++;

        if (index < items.length) {
          return items[index].transform().then(doTransform);
        }

        return Promise.resolve();
      }

      return doTransform();
    }

    return Promise.resolve();
  }

  getDependencyLocations() {
    return this.includes.filter(inclusion => inclusion.description && inclusion.description.location)
      .map(inclusion => {
        let normalizedLocation = path.posix.normalize(inclusion.description.location).replace(/\\/g, '\/');
        return {
          location: normalizedLocation,
          inclusion: inclusion
        };
      });
  }

  getBundledModuleIds() {
    return unique(this.includes.reduce((a, b) => a.concat(b.getAllModuleIds()), []));
  }

  getBundledFiles() {
    return this.includes.reduce((a, b) => a.concat(b.getAllFiles()), []);
  }

  write(platform) {
    if (!this.requiresBuild) {
      return Promise.resolve();
    }

    let work = Promise.resolve();
    let loaderOptions = this.bundler.loaderOptions;
    let buildOptions = this.buildOptions;
    let files = [];

    if (this.prepend.length) {
      work = work.then(() => addFilesInOrder(this, this.prepend, files));
    }

    if (loaderOptions.configTarget === this.config.name) {
      work = work.then(() => {
        files.push({ contents: '_aureliaConfigureModuleLoader();'});
      });
    }

    work = work.then(() => files = files.concat(this.getBundledFiles()));

    if (this.append.length) {
      work = work.then(() => addFilesInOrder(this, this.append, files));
    }

    return work.then(() => {
      const Concat = require('./concat-with-sourcemaps');
      let concat = new Concat(true, this.config.name, os.EOL);
      const generateHashedPath = require('./utils').generateHashedPath;
      const generateHash = require('./utils').generateHash;
      let needsSourceMap = false;

      for (let i = 0; i < files.length; ++i) {
        let currentFile = files[i];
        let sourceMap = buildOptions.isApplicable('sourcemaps') ? currentFile.sourceMap : undefined;

        function fileIsDependency(file) {
          return file
            && file.path
            && file.path.indexOf('node_modules') >= 0;
        }

        function acquireSourceMapForDependency(file) {
          if (!file || !file.path) {
            return;
          }

          let parsedPath = path.parse(file.path);

          try {
            let base64SourceMap = Convert.fromSource(file.contents.toString());

            if (base64SourceMap) {
              return null;
            }
          } catch (error) {
            // we don't want the build to fail when a sourcemap file can't be parsed
            return null;
          }

          let converter;

          try {
            converter = Convert.fromMapFileSource(file.contents.toString(), parsedPath.dir);
          } catch (e) {
            console.log(e);
            return null;
          }

          sourceMap = converter
            ? converter.sourcemap
            : null;

          if (sourceMap !== null) {
            // path.posix.relative(from, to) does not work here
            sourceMap.sourceRoot = parsedPath.dir.substring(process.cwd().length);
          }

          return sourceMap;
        }

        if (fileIsDependency(currentFile)) {
          sourceMap = acquireSourceMapForDependency(currentFile);
        }

        if (sourceMap) {
          needsSourceMap = true;
        }

        concat.add(currentFile.path, currentFile.contents, sourceMap ? JSON.stringify(sourceMap) : undefined);
      }

      let mapContents;
      let contents = concat.content;
      let bundleFileName = this.config.name;

      if (loaderOptions.configTarget === this.config.name) {
        //Add to the config bundle the loader config. Can't change index.html yet because we haven't generated hashes for all the files
        concat.add(undefined, this.writeLoaderCode(platform));
        contents = concat.content;

        if (buildOptions.isApplicable('rev')) {
          //Generate a unique hash based off of the bundle contents
          //Must generate hash after we write the loader config so that any other bundle changes (hash changes) can cause a new hash for the vendor file
          this.hash = generateHash(concat.content);
          bundleFileName = generateHashedPath(this.config.name, this.hash);
        }

        //Again, in the config setup, we're at the last bundle, and we can modify the index.html correctly now
        let outputDir = platform.baseUrl || platform.output; //If we have a baseUrl, then the files are served from there, else it's the output
        if (platform.index) {
          this.setIndexFileConfigTarget(platform, path.posix.join(outputDir, bundleFileName));
        }
      } else if (buildOptions.isApplicable('rev')) {
        //Generate a unique hash based off of the bundle contents
        //Must generate hash after we write the loader config so that any other bundle changes (hash changes) can cause a new hash for the vendor file
        this.hash = generateHash(concat.content);
        bundleFileName = generateHashedPath(this.config.name, this.hash);
      }

      let mapFileName = bundleFileName + '.map';
      let mapSourceRoot = path.posix.relative(
        path.posix.join(process.cwd(), platform.output),
        process.cwd()
      );

      console.log(`Writing ${bundleFileName}...`);

      if (buildOptions.isApplicable('minify')) {
        const UglifyJS = require('uglify-js');
        // fromString is not a supported option in v3
        const isV3 = !!(UglifyJS.minify('', {fromString: true}).error);

        let minificationOptions = {};
        if (!isV3) minificationOptions.fromString = true;

        let minifyOptions = buildOptions.getValue('minify');
        if (typeof minifyOptions === 'object') {
          Object.assign(minificationOptions, minifyOptions);
        }

        if (needsSourceMap) {
          if (isV3) {
            minificationOptions.sourceMap = {
              content: concat.sourceMap,
              filename: bundleFileName,
              url: mapFileName,
              root: mapSourceRoot
            };
          } else {
            minificationOptions.inSourceMap = Convert.fromJSON(concat.sourceMap).toObject();
            minificationOptions.outSourceMap = mapFileName;
            minificationOptions.sourceRoot = mapSourceRoot;
          }
        }

        let minificationResult = UglifyJS.minify(String(contents), minificationOptions);
        if (minificationResult.error) throw minificationResult.error;

        contents = minificationResult.code;
        mapContents = needsSourceMap ? Convert.fromJSON(minificationResult.map).toJSON() : undefined;
      } else if (needsSourceMap) {
        mapContents = Convert.fromJSON(concat.sourceMap)
          .setProperty('sourceRoot', mapSourceRoot)
          .toJSON();

        contents += os.EOL + '//# sourceMappingURL=' + mapFileName;
      }

      return fs.writeFile(path.posix.join(platform.output, bundleFileName), contents).then(() => {
        this.requiresBuild = false;

        if (mapContents) {
          return fs.writeFile(path.posix.join(platform.output, mapFileName), mapContents)
          .catch(e => {
            console.log(`Unable to write the sourcemap to ${path.posix.join(platform.output, mapFileName)}`);
          });
        }
      })
      .catch(e => {
        console.log(`Unable to write the bundle to ${path.posix.join(platform.output, bundleFileName)}`);
        console.log(e);
        throw e;
      });
    })
    .catch(e => {
      console.log('Failed to write the bundle');
      console.log(e);
      throw e;
    });
  }

  getFileFromCacheOrLoad(x) {
    let found = this.fileCache[x];
    if (found) {
      return Promise.resolve(found);
    }

    return fs.readFile(x).then(data => {
      found = { contents: data.toString() };
      this.fileCache[x] = found;
      return found;
    });
  }

  writeLoaderCode(platform) {
    const createLoaderCode = require('./loader').createLoaderCode;
    let config = createLoaderCode(platform, this.bundler);

    return 'function _aureliaConfigureModuleLoader(){' + config + '}';
  }

  setIndexFileConfigTarget(platform, location) {
    //Replace the reference to the vendor bundle in the "index.html" file to use the correct build revision file (or remove the build revision hash);
    const createSrcFileRegex = require('./utils').createSrcFileRegex;
    let indexLocation = platform.index;
    try {
      let indexFile = fs.readFileSync(indexLocation);
      let outputDir = platform.baseUrl || platform.output; //If we have a baseUrl, then the files are served from there, else it's the output
      let configMatcher = createSrcFileRegex(outputDir, this.moduleId);
      if (configMatcher.test(indexFile)) {
        indexFile = indexFile.replace(configMatcher, 'src="$2' + location + '"');//Replace the old reference to the file with whatever the new one is (preserving any unknown path parts before)
        fs.writeFile(indexLocation, indexFile);
      } else {
        console.log('Error: Unable to update ' + this.moduleId + ' path to ' + location + ', could not find existing reference to replace');
      }
    } catch (err) {
      if (err.code === 'ENOENT') {
        console.log('Error: No index file found at "' + indexLocation + '"');
      } else {
        console.log(err);
      }
    }
  }
};

function addFilesInOrder(bundle, paths, files) {
  let index = -1;

  function addFile() {
    index++;

    if (index < paths.length) {
      return bundle.getFileFromCacheOrLoad(paths[index])
        .then(file => files.push(file))
        .then(addFile);
    }

    return Promise.resolve();
  }

  return addFile();
}

function unique(collection) {
  let u = {};
  let a = [];

  for (let i = 0, l = collection.length; i < l; ++i) {
    if (u.hasOwnProperty(collection[i])) {
      continue;
    }

    a.push(collection[i]);
    u[collection[i]] = 1;
  }

  return a;
}
<|endoftext|>


<commit_before>import platform from 'common/utils/platform';
import $ from 'browser/menus/expressions';

export default {
  label: 'Window',
  allow: platform.isDarwin,
  role: 'window',
  submenu: [{
    label: 'Reload',
    accelerator: 'Cmd+R',
    needsWindow: true,
    role: 'forcereload'
  }, {
    label: 'Reset',
    accelerator: 'Cmd+Alt+R',
    needsWindow: true,
    click: $.resetWindow()
  }, {
    type: 'separator'
  }, {
    type: 'checkbox',
    label: 'Float on Top',
    accelerator: 'Cmd+Alt+T',
    needsWindow: true,
    click: $.floatOnTop($.key('checked'))
  }, {
    type: 'checkbox',
    label: 'Close with Escape Key',
    click: $.setPref('close-with-esc', $.key('checked')),
    parse: $.setLocal('checked', $.pref('close-with-esc'))
  }, {
    type: 'checkbox',
    label: 'Open Links in Browser',
    click: $.setPref('links-in-browser', $.key('checked')),
    parse: $.setLocal('checked', $.pref('links-in-browser'))
  }, {
    type: 'checkbox',
    label: 'Notifications Badge in Dock',
    click: $.all(
      $.setPref('show-notifications-badge', $.key('checked')),
      $.hideDockBadge($.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-notifications-badge'))
    )
  }, {
    type: 'separator'
  }, {
    id: 'show-tray',
    type: 'checkbox',
    label: 'Show in Menu Bar',
    click: $.all(
      $.showInTray($.key('checked')),
      $.updateSibling('show-dock', 'enabled', $.key('checked')),
      $.updateMenuItem('tray', 'show-tray')($.key('checked'))((checked) => $.all(
        $.setLocal('checked', $.val(checked)),
        $.updateSibling('show-dock', 'enabled', $.val(checked))
      )),
      $.setPref('show-tray', $.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-tray')),
      $.updateSibling('show-dock', 'enabled', $.key('checked'))
    )
  }, {
    id: 'show-dock',
    type: 'checkbox',
    label: 'Show in Dock',
    click: $.all(
      $.showInDock($.key('checked')),
      $.updateSibling('show-tray', 'enabled', $.key('checked')),
      $.updateMenuItem('tray', 'show-dock')($.key('checked'))((checked) => $.all(
        $.setLocal('checked', $.val(checked)),
        $.updateSibling('show-tray', 'enabled', $.val(checked))
      )),
      $.setPref('show-dock', $.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-dock')),
      $.updateSibling('show-tray', 'enabled', $.key('checked')),
      $.showInDock($.key('checked'))
    )
  }, {
    type: 'separator'
  }, {
    role: 'minimize'
  }, {
    role: 'zoom'
  }, {
    role: 'close'
  }]
};
<commit_msg>Revert "Make Reload menu item force reload"<commit_after>import platform from 'common/utils/platform';
import $ from 'browser/menus/expressions';

export default {
  label: 'Window',
  allow: platform.isDarwin,
  role: 'window',
  submenu: [{
    label: 'Reload',
    accelerator: 'Cmd+R',
    needsWindow: true,
    click: $.reloadWindow()
  }, {
    label: 'Reset',
    accelerator: 'Cmd+Alt+R',
    needsWindow: true,
    click: $.resetWindow()
  }, {
    type: 'separator'
  }, {
    type: 'checkbox',
    label: 'Float on Top',
    accelerator: 'Cmd+Alt+T',
    needsWindow: true,
    click: $.floatOnTop($.key('checked'))
  }, {
    type: 'checkbox',
    label: 'Close with Escape Key',
    click: $.setPref('close-with-esc', $.key('checked')),
    parse: $.setLocal('checked', $.pref('close-with-esc'))
  }, {
    type: 'checkbox',
    label: 'Open Links in Browser',
    click: $.setPref('links-in-browser', $.key('checked')),
    parse: $.setLocal('checked', $.pref('links-in-browser'))
  }, {
    type: 'checkbox',
    label: 'Notifications Badge in Dock',
    click: $.all(
      $.setPref('show-notifications-badge', $.key('checked')),
      $.hideDockBadge($.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-notifications-badge'))
    )
  }, {
    type: 'separator'
  }, {
    id: 'show-tray',
    type: 'checkbox',
    label: 'Show in Menu Bar',
    click: $.all(
      $.showInTray($.key('checked')),
      $.updateSibling('show-dock', 'enabled', $.key('checked')),
      $.updateMenuItem('tray', 'show-tray')($.key('checked'))((checked) => $.all(
        $.setLocal('checked', $.val(checked)),
        $.updateSibling('show-dock', 'enabled', $.val(checked))
      )),
      $.setPref('show-tray', $.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-tray')),
      $.updateSibling('show-dock', 'enabled', $.key('checked'))
    )
  }, {
    id: 'show-dock',
    type: 'checkbox',
    label: 'Show in Dock',
    click: $.all(
      $.showInDock($.key('checked')),
      $.updateSibling('show-tray', 'enabled', $.key('checked')),
      $.updateMenuItem('tray', 'show-dock')($.key('checked'))((checked) => $.all(
        $.setLocal('checked', $.val(checked)),
        $.updateSibling('show-tray', 'enabled', $.val(checked))
      )),
      $.setPref('show-dock', $.key('checked'))
    ),
    parse: $.all(
      $.setLocal('checked', $.pref('show-dock')),
      $.updateSibling('show-tray', 'enabled', $.key('checked')),
      $.showInDock($.key('checked'))
    )
  }, {
    type: 'separator'
  }, {
    role: 'minimize'
  }, {
    role: 'zoom'
  }, {
    role: 'close'
  }]
};
<|endoftext|>


<commit_before>"use strict";
var request = require('request-promise');

// Service used to make all API calls. Must be instantiated with a version and consumer creds.
// Functions always return a promise, and the response will be parsed as JSON except for getFile() and getRaw().
module.exports = (function(version, settings) {

  // Private Members
  var apiBase = "https://api.context.io/"
  var oauth
  var options

  // Public class CallService
  return new class {
    constructor() {

      if(!version) {
        throw new Error("Context.IO CallService must be instantiated with a context.io api version.")
      }

      if(!settings || !(settings.secret && settings.key)) {
        throw new Error("Context.IO CallService must be instantiated with oauth attributes 'key' and 'secret'.")
      }

      apiBase = apiBase + version + '/'

      oauth = {
        consumer_key: settings.key,
        consumer_secret: settings.secret
      }
    }

    //Main get funciton. Params are added as querystring params.
    get(url, params) {
      options = {
        url: apiBase + url,
        oauth: oauth,
        qs: params
      }

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //File get, returns headers and the body.
    getFile(url, params) {
      options = {
        url: apiBase + url,
        oauth: oauth,
        qs: params,
        resolveWithFullResponse: true
      }

      return request(options).then(function(res) {
        return {headers: res.headers, body: res.body}
      })
    }

    //Return raw response, no JSON parsing.
    getRaw(url, params) {
      options = {
        url: apiBase + url,
        oauth: oauth,
        qs: params
      }

      return request(options).then(function(body) {
        return body
      })
    }

    //Post. Params are added as querystring params. Body is sent as application/x-www-form-urlencoded
    post(url, body, params) {
      options = {
        method: 'POST',
        url: apiBase + url,
        oauth: oauth,
        form: body,
        qs: params
      }

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //Put. Params are added as querystring params. Body is sent as application/x-www-form-urlencoded
    put(url, body, params) {
      options = {
        method: 'PUT',
        url: apiBase + url,
        oauth: oauth,
        form: body,
        qs: params
      }

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //Delete. Params are added as querystring params.
    delete(url, params) {
      options = {
        method: 'DELETE',
        url: apiBase + url,
        oauth: oauth,
        qs: params
      }

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

  }()

})
<commit_msg>Slight refactor of call-service. User Agent!<commit_after>"use strict";
var request = require('request-promise');

// Service used to make all API calls. Must be instantiated with a version and consumer creds.
// Functions always return a promise, and the response will be parsed as JSON except for getFile() and getRaw().
module.exports = (function(version, settings) {

  // Private Members
  var apiBase = "https://api.context.io/"
  var oauth
  var options

  // Public class CallService
  return new class {
    constructor() {

      if(!version) {
        throw new Error("Context.IO CallService must be instantiated with a context.io api version.")
      }

      if(!settings || !(settings.secret && settings.key)) {
        throw new Error("Context.IO CallService must be instantiated with oauth attributes 'key' and 'secret'.")
      }

      apiBase = apiBase + version + '/'

      oauth = {
        consumer_key: settings.key,
        consumer_secret: settings.secret
      }

      options = {
        oauth: oauth,
        "User-Agent": 'C.IO Node Client'
      }
    }

    //Main get funciton. Params are added as querystring params.
    get(url, params) {
      options.url = apiBase + url
      options.qs = params

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //File get, returns headers and the body.
    getFile(url, params) {
      options.url = apiBase + url
      options.qs = params
      options.resolveWithFullResponse = true

      return request(options).then(function(res) {
        return { headers: res.headers, body: res.body }
      })
    }

    //Return raw response, no JSON parsing.
    getRaw(url, params) {
      options.url = apiBase + url
      options.qs = params

      return request(options).then(function(body) {
        return body
      })
    }

    //Post. Params are added as querystring params. Body is sent as application/x-www-form-urlencoded
    post(url, body, params) {
      options.url = apiBase + url
      options.method = 'POST'
      options.qs = params
      options.form = body

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //Put. Params are added as querystring params. Body is sent as application/x-www-form-urlencoded
    put(url, body, params) {
      options.url = apiBase + url
      options.method = 'PUT'
      options.qs = params
      options.form = body

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

    //Delete. Params are added as querystring params.
    delete(url, params) {
      options.url = apiBase + url
      options.method = 'DELETE'
      options.qs = params

      return request(options).then(function(body) {
        return JSON.parse(body)
      })
    }

  }()

})
<|endoftext|>


<commit_before>/**
 * Copyright 2017 NEC Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

(function() {
  'use strict';

  /**
   * @ngdoc overview
   * @name horizon.dashboard.container-infra.clusters.update.service
   * @description Service for the container-infra cluster update modal
   */
  angular
    .module('horizon.dashboard.container-infra.clusters')
    .factory('horizon.dashboard.container-infra.clusters.update.service', updateService);

  updateService.$inject = [
    'horizon.app.core.openstack-service-api.magnum',
    'horizon.app.core.openstack-service-api.policy',
    'horizon.framework.util.actions.action-result.service',
    'horizon.framework.util.i18n.gettext',
    'horizon.framework.util.q.extensions',
    'horizon.framework.widgets.form.ModalFormService',
    'horizon.framework.widgets.toast.service',
    'horizon.dashboard.container-infra.clusters.resourceType',
    'horizon.dashboard.container-infra.clusters.workflow'
  ];

  function updateService(
    magnum, policy, actionResult, gettext, $qExtensions, modal, toast, resourceType, workflow
  ) {

    var config;
    var message = {
      success: gettext('Cluster %s was successfully updated.')
    };

    var service = {
      perform: perform,
      allowed: allowed
    };

    return service;

    //////////////

    function perform(selected, $scope) {
      config = workflow.init('update', gettext('Update Cluster'), $scope);
      config.model.id = selected.id;

      // load current data
      magnum.getCluster(selected.id).then(onLoad);
      function onLoad(response) {
        config.model.name = response.data.name
          ? response.data.name : "";
        config.model.cluster_template_id = response.data.cluster_template_id
          ? response.data.cluster_template_id : "";
        config.model.master_count = response.data.master_count
          ? response.data.master_count : null;
        config.model.node_count = response.data.node_count
          ? response.data.node_count : null;
        config.model.discovery_url = response.data.discovery_url
          ? response.data.discovery_url : "";
        config.model.create_timeout = response.data.create_timeout
          ? response.data.create_timeout : null;
        config.model.keypair = response.data.keypair
          ? response.data.keypair : "";
        config.model.docker_volume_size = response.data.docker_volume_size
          ? response.data.docker_volume_size : "";
        var labels = "";
        for (var key in response.data.labels) {
          if (response.data.labels.hasOwnProperty(key)) {
            if (labels !== "") {
              labels += ",";
            }
            labels += key + "=" + response.data.labels[key];
          }
        }
        config.model.labels = labels;
      }

      return modal.open(config).then(submit);
    }

    function allowed() {
      return $qExtensions.booleanAsPromise(true);
    }

    function submit(context) {
      var id = context.model.id;
      context.model = cleanNullProperties(context.model);
      return magnum.updateCluster(id, context.model, true)
        .then(success, true);
    }

    function cleanNullProperties(model) {
      // Initially clean fields that don't have any value.
      // Not only "null", blank too.
      for (var key in model) {
        if (model.hasOwnProperty(key) && model[key] === null || model[key] === "" ||
            key === "tabs" || key === "id") {
          delete model[key];
        }
      }
      return model;
    }

    function success(response) {
      response.data.id = response.data.uuid;
      toast.add('success', interpolate(message.success, [response.data.id]));
      return actionResult.getActionResult()
        .updated(resourceType, response.data.id)
        .result;
    }
  }
})();
<commit_msg>Display master_flavor_id and flavor_id when updating cluster<commit_after>/**
 * Copyright 2017 NEC Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

(function() {
  'use strict';

  /**
   * @ngdoc overview
   * @name horizon.dashboard.container-infra.clusters.update.service
   * @description Service for the container-infra cluster update modal
   */
  angular
    .module('horizon.dashboard.container-infra.clusters')
    .factory('horizon.dashboard.container-infra.clusters.update.service', updateService);

  updateService.$inject = [
    'horizon.app.core.openstack-service-api.magnum',
    'horizon.app.core.openstack-service-api.policy',
    'horizon.framework.util.actions.action-result.service',
    'horizon.framework.util.i18n.gettext',
    'horizon.framework.util.q.extensions',
    'horizon.framework.widgets.form.ModalFormService',
    'horizon.framework.widgets.toast.service',
    'horizon.dashboard.container-infra.clusters.resourceType',
    'horizon.dashboard.container-infra.clusters.workflow'
  ];

  function updateService(
    magnum, policy, actionResult, gettext, $qExtensions, modal, toast, resourceType, workflow
  ) {

    var config;
    var message = {
      success: gettext('Cluster %s was successfully updated.')
    };

    var service = {
      perform: perform,
      allowed: allowed
    };

    return service;

    //////////////

    function perform(selected, $scope) {
      config = workflow.init('update', gettext('Update Cluster'), $scope);
      config.model.id = selected.id;

      // load current data
      magnum.getCluster(selected.id).then(onLoad);
      function onLoad(response) {
        config.model.name = response.data.name
          ? response.data.name : "";
        config.model.cluster_template_id = response.data.cluster_template_id
          ? response.data.cluster_template_id : "";
        config.model.master_count = response.data.master_count
          ? response.data.master_count : null;
        config.model.node_count = response.data.node_count
          ? response.data.node_count : null;
        config.model.discovery_url = response.data.discovery_url
          ? response.data.discovery_url : "";
        config.model.create_timeout = response.data.create_timeout
          ? response.data.create_timeout : null;
        config.model.keypair = response.data.keypair
          ? response.data.keypair : "";
        config.model.docker_volume_size = response.data.docker_volume_size
          ? response.data.docker_volume_size : "";
        config.model.master_flavor_id = response.data.master_flavor_id
          ? response.data.master_flavor_id : "";
        config.model.flavor_id = response.data.flavor_id
          ? response.data.flavor_id : "";
        var labels = "";
        for (var key in response.data.labels) {
          if (response.data.labels.hasOwnProperty(key)) {
            if (labels !== "") {
              labels += ",";
            }
            labels += key + "=" + response.data.labels[key];
          }
        }
        config.model.labels = labels;
      }

      return modal.open(config).then(submit);
    }

    function allowed() {
      return $qExtensions.booleanAsPromise(true);
    }

    function submit(context) {
      var id = context.model.id;
      context.model = cleanNullProperties(context.model);
      return magnum.updateCluster(id, context.model, true)
        .then(success, true);
    }

    function cleanNullProperties(model) {
      // Initially clean fields that don't have any value.
      // Not only "null", blank too.
      for (var key in model) {
        if (model.hasOwnProperty(key) && model[key] === null || model[key] === "" ||
            key === "tabs" || key === "id") {
          delete model[key];
        }
      }
      return model;
    }

    function success(response) {
      response.data.id = response.data.uuid;
      toast.add('success', interpolate(message.success, [response.data.id]));
      return actionResult.getActionResult()
        .updated(resourceType, response.data.id)
        .result;
    }
  }
})();
<|endoftext|>


<commit_before>var  parseUrl = require('url').parse;
var http = require('http');
var request = require('request');
var querystring = require('querystring');
/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

exports.validate = function validate(options){

    // have to validate cas service calls

    var cas_host = 'cas.ctmlabs.net';
    var validation_service = '/cas/serviceValidate';
    var login_service = '/cas/login';
    var service = options.service; //'http://safety.ctmlabs.net/geojson';

    return function validate(req,res,next){
        var method = req.method.toLowerCase();
        console.log('method: '+method);
        if (method == 'post'){
            invalidate(req,res,next);
            return;
        }
        var url = parseUrl(req.url,true);
        if(url.query && url.query.ticket){
            // time to validate the service ticket
            var ticket = url.query.ticket;
            var cas_uri =  'https://'+cas_host+validation_service
                +'?'
                +querystring.stringify(
                    {'service':service,
                     'ticket':ticket});
            request({uri:cas_uri}, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    if(/cas:authenticationSuccess/.exec(body)){
                        console.log('auth passed ' + body);
                            // stuff the cookie  into a session
                            // and store the ticket as well

                        // respond with json containing the url to use next?
                        req.session.regenerate(function(err){
                            // valid user
                            if(/<cas:user>(\w+)<\/cas:user>/.exec(body)){
                                req.session.name = RegExp.$1;
                            }
                            req.session.st = ticket;

                            // double pointer
                            req.sessionStore.set(ticket,{'sid':req.sessionId,
                                                         'lastAccess':+new Date});

                            res.writeHead(200, { 'Content-Type': 'application/json' });
                            res.end(JSON.stringify({'url':service}));
                        });

                    }else{
                        console.log('auth failed with:'+body) ;
                        //next(new Error('must log in again?'));
                        res.writeHead(403, { 'Content-Type': 'application/json' });
                        var cas_login_uri =  'https://'+cas_host+login_service
                            +'?'
                            +querystring.stringify(
                                {'service':service});
                        res.end(JSON.stringify({'url':cas_login_uri}));
                    }
                }
            });
            console.log('ticket was in the query');
            // no next if that was the case
        }else{
            // no ticket in the request.  check for still valid CAS session
            var st; // temporary service ticket holder
            if(st = req.session.st){
                // okay.  renew the stored ticket
                req.sessionStore.set(st,{'sid':req.sessionId,
                                         'lastAccess':+new Date});
            }else{
                // not okay.  must log in again
                console.log('ticket not in session store:'+JSON.stringify(req.session) + ' query:' + url.query) ;
                res.writeHead(403, { 'Content-Type': 'application/json' });
                var cas_login_uri =  'https://'+cas_host+login_service
                    +'?'
                    +querystring.stringify(
                        {'service':service});
                res.end(JSON.stringify({'url':cas_login_uri}));
            }
            next();
        }
        return;
        // https://cas.ctmlabs.net/cas/serviceValidate?service=http://safety.ctmlabs.net/geojson&ticket=ST-2-tpJilV9tKI1aDzsbNIRr-cas
    };

};

var invalidate = exports.invalidate = function invalidate(req,res,next){
    // handling a post here

    // parse out the ticket number from the body, then get the
    // sessionid associated with that ticket, and destroy it.
    for( var param in req.body){
        if(/<samlp:SessionIndex>(.*)<\/samlp:SessionIndex>/.exec(req.body[param])){
            var st = RegExp.$1;
            req.sessionStore.get(st,function(err,sess){
                var sid = sess.sid;
                req.sessionStore.destroy(sid);
                console.log('found session store, killing it');
            });
            break;
        }else{
            console.log('regex for service ticket failed on '+req.body[param]);
        }
    }
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end();
    return;

};

<commit_msg>modified runtime.  seems to work.  lots too many debug statements at teh mo 	modified:   lib/cas_validate.js<commit_after>var  parseUrl = require('url').parse;
var http = require('http');
var request = require('request');
var querystring = require('querystring');
/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

exports.validate = function validate(options){

    // have to validate cas service calls

    var cas_host = 'cas.ctmlabs.net';
    var validation_service = '/cas/serviceValidate';
    var login_service = '/cas/login';
    var service = options.service; //'http://safety.ctmlabs.net/geojson';

    return function validate(req,res,next){
        var method = req.method.toLowerCase();
        console.log('method: '+method);
        if (method == 'post'){
            invalidate(req,res,next);
            return;
        }
        var url = parseUrl(req.url,true);
        if(url.query && url.query.ticket){
            // time to validate the service ticket
            var ticket = url.query.ticket;
            var cas_uri =  'https://'+cas_host+validation_service
                +'?'
                +querystring.stringify(
                    {'service':service,
                     'ticket':ticket});
            request({uri:cas_uri}, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    if(/cas:authenticationSuccess/.exec(body)){
                        console.log('auth passed ' + body);
                            // stuff the cookie  into a session
                            // and store the ticket as well

                        // respond with json containing the url to use next?
                        req.session.regenerate(function(err){
                            // valid user
                            if(/<cas:user>(\w+)<\/cas:user>/.exec(body)){
                                req.session.name = RegExp.$1;
                            }
                            req.session.st = ticket;

                            // double pointer
                            req.sessionStore.set(ticket,{'sid':req.sessionID,
                                                         'lastAccess':+new Date});

                            res.writeHead(200, { 'Content-Type': 'application/json' });
                            res.end(JSON.stringify({'url':service}));
                        });

                    }else{
                        console.log('auth failed with:'+body) ;
                        //next(new Error('must log in again?'));
                        res.writeHead(403, { 'Content-Type': 'application/json' });
                        var cas_login_uri =  'https://'+cas_host+login_service
                            +'?'
                            +querystring.stringify(
                                {'service':service});
                        res.end(JSON.stringify({'url':cas_login_uri}));
                    }
                }
            });
            console.log('ticket was in the query');
            // no next if that was the case
        }else{
            // no ticket in the request.  check for still valid CAS session
            var st; // temporary service ticket holder
            if(st = req.session.st){
                // okay.  renew the stored ticket
                console.log(JSON.stringify(req.session));
                req.sessionStore.get(st,function(err,sess){
                    sess.lastAccess = +new Date;
                    sess.sid = req.sessionID;
                    console.log('st sess is '+JSON.stringify(sess));
                });
                console.log('valid cas session');
                next();
            }else{
                // not okay.  must log in again
                console.log('ticket not in session store:'+JSON.stringify(req.session) + ' query:' + url.query) ;
                res.writeHead(403, { 'Content-Type': 'application/json' });
                var cas_login_uri =  'https://'+cas_host+login_service
                    +'?'
                    +querystring.stringify(
                        {'service':service});
                res.end(JSON.stringify({'url':cas_login_uri}));
            }

        }
        return;
        // https://cas.ctmlabs.net/cas/serviceValidate?service=http://safety.ctmlabs.net/geojson&ticket=ST-2-tpJilV9tKI1aDzsbNIRr-cas
    };

};

var invalidate = exports.invalidate = function invalidate(req,res,next){
    // handling a post here

    // parse out the ticket number from the body, then get the
    // sessionid associated with that ticket, and destroy it.
    for( var param in req.body){
        if(/<samlp:SessionIndex>(.*)<\/samlp:SessionIndex>/.exec(req.body[param])){
            var st = RegExp.$1;
            req.sessionStore.get(st,function(err,sess){
                if(sess && sess.sid){
                    console.log('found session store '+JSON.stringify(sess));
                    var sid = sess.sid;
                    req.sessionStore.get(sid,function(err,sess){
                        if(sess){
                            delete sess.st;
                            sess.destroy();
                            console.log('found session store '+sid+', killing it');
                        }
                    })
                }else{
                    console.log(JSON.stringify(sess));
                }
            });

            break;
        }else{
            console.log('regex for service ticket failed on '+req.body[param]);
        }
    }
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end();
    return;

};

<|endoftext|>


<commit_before>var parseUrl = require('url').parse;
var http = require('http');
var request = require('request');
var querystring = require('querystring');
var redis = require("redis");

/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

var redclient = redis.createClient();

redclient.on("error", function (err) {
    console.log("Error " + err);
});

exports.validate = function validate(options){

    // have to validate cas service calls

    var cas_host = 'cas.ctmlabs.net';
    var validation_service = '/cas/serviceValidate';
    var login_service = '/cas/login';
    var options_service = options.service; //'http://safety.ctmlabs.net/geojson';

    return function validate(req,res,next){
        var url = parseUrl(req.url,true);
        var service = options_service ? options_service :
        'http://'+req.headers.host + url.pathname;
        var method = req.method.toLowerCase();
        // console.log('HITTING VALIDATE: method: '+method);
        if (method == 'post'){
            invalidate(req,res,next);
            return;
        }
        if(url.query && url.query.ticket){
            // time to validate the service ticket
            var ticket = url.query.ticket;
            var cas_uri =  'https://'+cas_host+validation_service
            +'?'
            +querystring.stringify(
            {'service':service,
            'ticket':ticket});
            request({uri:cas_uri}, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    if(/cas:authenticationSuccess/.exec(body)){
                        console.log('auth passed ');
                        // stuff the cookie  into a session
                        // and store the ticket as well

                        // valid user
                        if(/<cas:user>(\w+)<\/cas:user>/.exec(body)){
                            req.session.name = RegExp.$1;
                        }
                        req.session.st = ticket;

                        // my old hack modifying session keys no longer works.
                        redclient.set(ticket,req.sessionID);
                        res.writeHead(307,{'location':service});
                        res.end();
                    }
                }else{
                    console.log('auth failed') ;
                    //next(new Error('must log in again?'));
                    res.writeHead(307, { 'location': 'https://'+cas_host+login_service
                                         +'?'
                                         +querystring.stringify(
                                             {'service':service})});
                    res.end();
                }

            });
            // console.log('ticket was in the query');
            // no next if that was the case
        }else{
            // no ticket in the request.  check for still valid CAS session
            var st; // temporary service ticket holder
            if(st = req.session.st){
                return next();
            }else{
                // not okay.  must log in again
                // console.log('ticket not in session store:'+JSON.stringify(req.session) + ' query:' + url.query) ;
                // console.log('url headers:'+JSON.stringify(req.headers))
                if(/text\/html/.exec(req.headers.accept)){
                    res.writeHead(307, { 'location': 'https://'+cas_host+login_service
                                         +'?'
                                         +querystring.stringify(
                                             {'service':service})});
                    res.end();
                }else if(/json/.exec(req.headers.accept)){
                    res.writeHead(403, { 'Content-Type': 'application/json' });
                    var cas_login_uri =  'https://'+cas_host+login_service
                        +'?'
                        +querystring.stringify(
                            {'service':service});
                    res.end(JSON.stringify({'url':cas_login_uri}));
                }else{
                    res.statusCode=404;
                    res.end();
                }
            }

        }
        // https://cas.ctmlabs.net/cas/serviceValidate?service=http://safety.ctmlabs.net/geojson&ticket=ST-2-tpJilV9tKI1aDzsbNIRr-cas
    };

};

var invalidate = exports.invalidate = function invalidate(req,res,next){
    // handling a post here

    // parse out the ticket number from the body, then get the
    // sessionid associated with that ticket, and destroy it.
    for( var param in req.body){
        if(/<samlp:SessionIndex>(.*)<\/samlp:SessionIndex>/.exec(req.body[param])){
            var st = RegExp.$1;
            redclient.get(st,function(err,sid){
                if(!err){
                    req.sessionStore.destroy(sid,function(err){
                        if(err){
                            console.log(err);
                        }
                    });
                    redclient.del(st);
                }
            });
            break;
        }
    }
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end();
    return;

};

<commit_msg>added a username service, returning json<commit_after>var parseUrl = require('url').parse;
var http = require('http');
var request = require('request');
var querystring = require('querystring');
var redis = require("redis");

/**
 * CAS validate:  validate requests via CAS service tickets
 *
 * Options:
 *
 *   - `serivce`  the service url we are checking
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

var redclient = redis.createClient();

redclient.on("error", function (err) {
    console.log("Error " + err);
});

exports.username = function username(req,res,next){
    if(req.session.name){
        res.setHeader('Content-Type','application/json');
        res.end(JSON.stringify({'user':req.session.name}));
    }else{
        next();
    }
    return null;
}

exports.validate = function validate(options){

    // have to validate cas service calls

    var cas_host = 'cas.ctmlabs.net';
    var validation_service = '/cas/serviceValidate';
    var login_service = '/cas/login';
    var options_service = options.service; //'http://safety.ctmlabs.net/geojson';

    return function validate(req,res,next){
        var url = parseUrl(req.url,true);
        var service = options_service ? options_service :
        'http://'+req.headers.host + url.pathname;
        var method = req.method.toLowerCase();
        // console.log('HITTING VALIDATE: method: '+method);
        if (method == 'post'){
            invalidate(req,res,next);
            return;
        }
        if(url.query && url.query.ticket){
            // time to validate the service ticket
            var ticket = url.query.ticket;
            var cas_uri =  'https://'+cas_host+validation_service
            +'?'
            +querystring.stringify(
            {'service':service,
            'ticket':ticket});
            request({uri:cas_uri}, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    if(/cas:authenticationSuccess/.exec(body)){
                        console.log('auth passed ');
                        // stuff the cookie  into a session
                        // and store the ticket as well

                        // valid user
                        if(/<cas:user>(\w+)<\/cas:user>/.exec(body)){
                            req.session.name = RegExp.$1;
                        }
                        req.session.st = ticket;

                        // my old hack modifying session keys no longer works.
                        redclient.set(ticket,req.sessionID);
                        res.writeHead(307,{'location':service});
                        res.end();
                    }
                }else{
                    console.log('auth failed') ;
                    //next(new Error('must log in again?'));
                    res.writeHead(307, { 'location': 'https://'+cas_host+login_service
                                         +'?'
                                         +querystring.stringify(
                                             {'service':service})});
                    res.end();
                }

            });
            // console.log('ticket was in the query');
            // no next if that was the case
        }else{
            // no ticket in the request.  check for still valid CAS session
            var st; // temporary service ticket holder
            if(st = req.session.st){
                return next();
            }else{
                // not okay.  must log in again
                // console.log('ticket not in session store:'+JSON.stringify(req.session) + ' query:' + url.query) ;
                // console.log('url headers:'+JSON.stringify(req.headers))
                if(/text\/html/.exec(req.headers.accept)){
                    res.writeHead(307, { 'location': 'https://'+cas_host+login_service
                                         +'?'
                                         +querystring.stringify(
                                             {'service':service})});
                    res.end();
                }else if(/json/.exec(req.headers.accept)){
                    res.writeHead(403, { 'Content-Type': 'application/json' });
                    var cas_login_uri =  'https://'+cas_host+login_service
                        +'?'
                        +querystring.stringify(
                            {'service':service});
                    res.end(JSON.stringify({'url':cas_login_uri}));
                }else{
                    res.statusCode=404;
                    res.end();
                }
            }

        }
        // https://cas.ctmlabs.net/cas/serviceValidate?service=http://safety.ctmlabs.net/geojson&ticket=ST-2-tpJilV9tKI1aDzsbNIRr-cas
    };

};

var invalidate = exports.invalidate = function invalidate(req,res,next){
    // handling a post here

    // parse out the ticket number from the body, then get the
    // sessionid associated with that ticket, and destroy it.
    for( var param in req.body){
        if(/<samlp:SessionIndex>(.*)<\/samlp:SessionIndex>/.exec(req.body[param])){
            var st = RegExp.$1;
            redclient.get(st,function(err,sid){
                if(!err){
                    req.sessionStore.destroy(sid,function(err){
                        if(err){
                            console.log(err);
                        }
                    });
                    redclient.del(st);
                }
            });
            break;
        }
    }
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end();
    return;

};

<|endoftext|>


<commit_before>/*jshint -W024 */

(function(){
  'use strict';

  var ALL = -1;

  function getEndpoint(selectedProject, params) {
    if (typeof(params.status) === "undefined") {
      params.status = 'unresolved';
    }
    return '/api/0/projects/' + selectedProject.id + '/groups/?' + $.param(params);
  }

  SentryApp.controller('ProjectStreamActionModalCtrl', [
    '$scope', '$modalInstance', 'context',
    function($scope, $modalInstance, context) {
      $scope.numEvents = context.selectedGroupIds.length;
      $scope.actionLabel = context.actionLabel;
      $scope.canActionAll = context.canActionAll;
      $scope.cancel = function(){
        $modalInstance.dismiss('cancel');
      };
      $scope.actionAll = function(){
        $modalInstance.close(ALL);
      };
      $scope.actionSelected = function(){
        $modalInstance.close(context.selectedGroupIds);
      };
    }
  ]);

  SentryApp.controller('ProjectStreamControlsCtrl', [
    '$scope', '$timeout',
    function($scope, $timeout){
      var params = app.utils.getQueryParams();

      $('.filter-nav .search-input').focus(function(){
        $('.search-dropdown').show();
      }).blur(function(){
        $('.search-dropdown').hide();
      });

      if (params.bookmarks) {
        $scope.activeButton = 'bookmarks';
      } else if (params.assigned) {
        $scope.activeButton = 'assigned';
      } else {
        $scope.activeButton = 'all';
      }

      switch ($scope.activeButton) {
        case 'bookmarks':
          $('.btn-bookmarks').addClass('active');
          break;
        case 'assigned':
          $('.btn-assigned').addClass('active');
          break;
        default:
          $('.btn-all-events').addClass('active');
      }
    }
  ]);

  SentryApp.controller('ProjectStreamCtrl', [
    '$http', '$modal', '$scope', '$timeout', 'Collection', 'GroupModel', 'selectedProject',
    function($http, $modal, $scope, $timeout, Collection, GroupModel, selectedProject) {
      var timeoutId,
          pollingCursor,
          params = app.utils.getQueryParams(),
          endpoint = getEndpoint(selectedProject, params);

      var pollForChanges = function() {
        $.ajax({
          url: endpoint,
          method: 'GET',
          success: function(data, textStatus, jqXHR){
            if (!data.length) {
              return;
            }
            var duration = $scope.chartDuration;
            data = $.map(data, GroupModel);
            angular.forEach(data, function(group){
              group.activeChartData = group.stats[duration];
            });

            var links = app.utils.parseLinkHeader(jqXHR.getResponseHeader('Link'));
            endpoint = links.previous;

            $timeout(function(){
              $scope.groupList.extend(data);
            });
          },
          complete: function(){
            timeoutId = window.setTimeout(pollForChanges, 3000);
          }
        });
      };

      $scope.selectAllActive = false;
      $scope.multiSelected = false;
      $scope.anySelected = false;
      $('.stream-actions .chk-select-all').change(function(){
        var checked = $(this).is(':checked');

        $('.group-list .chk-select').prop('checked', checked);

        var numSelected = $('.group-list .chk-select:checked').length;

        $timeout(function(){
          $scope.selectAllActive = checked;
          $scope.anySelected = numSelected !== 0;
          $scope.multiSelected = numSelected > 1;
        });
      });

      var checkboxHandler = function(){
        var allSelected = !$('.group-list .chk-select').is(':not(:checked)'),
            numSelected = $('.group-list .chk-select:checked').length;

        $('.stream-actions .chk-select-all').prop('checked', allSelected);

        $timeout(function(){
          $scope.selectAllActive = allSelected;
          $scope.anySelected = numSelected !== 0;
          $scope.multiSelected = numSelected > 1;
        });
      };

      $scope.$watch('anySelected', function(anySelected){
        if (!anySelected) {
          $('.stream-actions .action').addClass('disabled').prop('disabled', true);
        } else {
          $('.stream-actions .action').removeClass('disabled').prop('disabled', false);
        }
      });

      $scope.$watch('multiSelected', function(multiSelected){
        if (!multiSelected) {
          $('.stream-actions .action-merge').addClass('disabled').prop('disabled', true);
        } else {
          $('.stream-actions .action-merge').removeClass('disabled').prop('disabled', false);
        }
      });

      // TODO(dcramer): this is pretty shitty, but I'm not sure of a good
      // way to bind the events and maintain the global status
      $scope.$watchCollection('groupList', function(){
        $timeout(function(){
          $('.group-list').undelegate('.chk-select', 'change', checkboxHandler);
          $('.group-list').delegate('.chk-select', 'change', checkboxHandler);
        });
      });

      var groupList = $.map(window.groupList, GroupModel);

      $scope.groupList = new Collection(groupList, {
        sortFunc: function(data) {
          app.utils.sortArray(data, function(item){
            return [item.sortWeight];
          });
        },
        canUpdate: function(current, pending) {
          return (current.version < pending.version);
        },
        limit: 50
      });

      $scope.setChartDuration = function(duration) {
        $scope.chartDuration = duration;
        angular.forEach($scope.groupList, function(group){
          group.activeChartData = group.stats[duration];
        });
      };

      var sortBy = params.sort || 'date',
          sortLabel;

      switch (sortBy) {
        case 'new':
          sortLabel = 'First Seen';
          break;
        case 'priority':
          sortLabel = 'Priority';
          break;
        case 'freq':
          sortLabel = 'Frequency';
          break;
        case 'tottime':
          sortLabel = 'Total Time Spent';
          break;
        case 'avgtime':
          sortLabel = 'Average Time Spent';
          break;
        default:
          sortLabel = 'Last Seen';
          sortBy = 'date';
      }
      $scope.sortLabel = sortLabel;

      function confirmAction(options){
        var selectedGroupIds = $.map($('.group-list .chk-select:checked'), function(item){
          return $(item).val();
        });
        if (selectedGroupIds.length === 0) {
          return;
        }

        var modal = $modal.open({
          templateUrl: '/templates/action-modal.html',
          controller: 'ProjectStreamActionModalCtrl',
          resolve: {
            context: function(){
              return {
                selectAllActive: $scope.selectAllActive,
                selectedGroupIds: selectedGroupIds,
                actionLabel: options.actionLabel,
                canActionAll: options.canActionAll && $scope.selectAllActive || false
              };
            }
          }
        }).result.then(options.action);
      }

      function actionGroups(options) {
        var data = options.data || {},
            url = options.url || '/api/0/projects/' + selectedProject.id + '/groups/';
        if (options.ids !== ALL) {
          url += '?id=' + options.ids.join('&id=');
        }
        $http({
          url: url,
          method: options.method || 'PUT',
          data: data
        });
        $timeout(function(){
          var groupList = [];
          if (options.ids === ALL) {
             groupList = $scope.groupList;
          } else {
            $.each(options.ids, function(id){
              var item = groupList[groupList.indexOf({id: id})];
              groupList.push(item);
            });
          }
          $.each(groupList, function(item){
            item.version = new Date().getTime() + 10;
            $.extend(true, item, data);
          });
        });
        $('.stream-actions .chk-select-all').prop('checked', false);
        $('.group-list .chk-select').prop('checked', false);
      }

      $('.stream-actions .action-resolve').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Resolve',
          canActionAll: true,
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {status: 'resolved'}
            });
          }
        });
      });

      $('.stream-actions .action-merge').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Merge',
          canActionAll: true,
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {merge: '1'}
            });
            // TODO(dcramer): show flash message
          }
        });
      });

      $('.stream-actions .action-delete').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Delete',
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              method: 'DELETE',
            });
            // TODO(dcramer): show flash message
          }
        });
      });

      $('.stream-actions .action-bookmark').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Bookmark',
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {isBookmarked: 1}
            });
          }
        });
      });

      $('.stream-actions .datepicker-box').click(function(e){
        e.preventDefault();
      });

      // we explicitly avoid $timeout here to prevent the watcher
      timeoutId = window.setTimeout(pollForChanges, 1000);
      $scope.$on('destroy', function(){
        window.clearTimeout(timeoutId);
      });

      $scope.setChartDuration('24h');
    }
  ]);
}());
<commit_msg>Correct disabled property on merge<commit_after>/*jshint -W024 */

(function(){
  'use strict';

  var ALL = -1;

  function getEndpoint(selectedProject, params) {
    if (typeof(params.status) === "undefined") {
      params.status = 'unresolved';
    }
    return '/api/0/projects/' + selectedProject.id + '/groups/?' + $.param(params);
  }

  SentryApp.controller('ProjectStreamActionModalCtrl', [
    '$scope', '$modalInstance', 'context',
    function($scope, $modalInstance, context) {
      $scope.numEvents = context.selectedGroupIds.length;
      $scope.actionLabel = context.actionLabel;
      $scope.canActionAll = context.canActionAll;
      $scope.cancel = function(){
        $modalInstance.dismiss('cancel');
      };
      $scope.actionAll = function(){
        $modalInstance.close(ALL);
      };
      $scope.actionSelected = function(){
        $modalInstance.close(context.selectedGroupIds);
      };
    }
  ]);

  SentryApp.controller('ProjectStreamControlsCtrl', [
    '$scope', '$timeout',
    function($scope, $timeout){
      var params = app.utils.getQueryParams();

      $('.filter-nav .search-input').focus(function(){
        $('.search-dropdown').show();
      }).blur(function(){
        $('.search-dropdown').hide();
      });

      if (params.bookmarks) {
        $scope.activeButton = 'bookmarks';
      } else if (params.assigned) {
        $scope.activeButton = 'assigned';
      } else {
        $scope.activeButton = 'all';
      }

      switch ($scope.activeButton) {
        case 'bookmarks':
          $('.btn-bookmarks').addClass('active');
          break;
        case 'assigned':
          $('.btn-assigned').addClass('active');
          break;
        default:
          $('.btn-all-events').addClass('active');
      }
    }
  ]);

  SentryApp.controller('ProjectStreamCtrl', [
    '$http', '$modal', '$scope', '$timeout', 'Collection', 'GroupModel', 'selectedProject',
    function($http, $modal, $scope, $timeout, Collection, GroupModel, selectedProject) {
      var timeoutId,
          pollingCursor,
          params = app.utils.getQueryParams(),
          endpoint = getEndpoint(selectedProject, params);

      var pollForChanges = function() {
        $.ajax({
          url: endpoint,
          method: 'GET',
          success: function(data, textStatus, jqXHR){
            if (!data.length) {
              return;
            }
            var duration = $scope.chartDuration;
            data = $.map(data, GroupModel);
            angular.forEach(data, function(group){
              group.activeChartData = group.stats[duration];
            });

            var links = app.utils.parseLinkHeader(jqXHR.getResponseHeader('Link'));
            endpoint = links.previous;

            $timeout(function(){
              $scope.groupList.extend(data);
            });
          },
          complete: function(){
            timeoutId = window.setTimeout(pollForChanges, 3000);
          }
        });
      };

      $scope.selectAllActive = false;
      $scope.multiSelected = false;
      $scope.anySelected = false;
      $('.stream-actions .chk-select-all').change(function(){
        var checked = $(this).is(':checked');

        $('.group-list .chk-select').prop('checked', checked);

        var numSelected = $('.group-list .chk-select:checked').length;

        $timeout(function(){
          $scope.selectAllActive = checked;
          $scope.anySelected = numSelected !== 0;
          $scope.multiSelected = numSelected > 1;
        });
      });

      var checkboxHandler = function(){
        var allSelected = !$('.group-list .chk-select').is(':not(:checked)'),
            numSelected = $('.group-list .chk-select:checked').length;

        $('.stream-actions .chk-select-all').prop('checked', allSelected);

        $timeout(function(){
          $scope.selectAllActive = allSelected;
          $scope.anySelected = numSelected !== 0;
          $scope.multiSelected = numSelected > 1;
        });
      };

      $scope.$watch('anySelected', function(anySelected){
        if (!anySelected) {
          $('.stream-actions .btn.action').addClass('disabled').prop('disabled', true);
        } else {
          $('.stream-actions .btn.action').removeClass('disabled').prop('disabled', false);
        }
      });

      $scope.$watch('multiSelected', function(multiSelected){
        if (!multiSelected) {
          $('.stream-actions .action-merge').addClass('disabled').prop('disabled', true);
        } else {
          $('.stream-actions .action-merge').removeClass('disabled').prop('disabled', false);
        }
      });

      // TODO(dcramer): this is pretty shitty, but I'm not sure of a good
      // way to bind the events and maintain the global status
      $scope.$watchCollection('groupList', function(){
        $timeout(function(){
          $('.group-list').undelegate('.chk-select', 'change', checkboxHandler);
          $('.group-list').delegate('.chk-select', 'change', checkboxHandler);
        });
      });

      var groupList = $.map(window.groupList, GroupModel);

      $scope.groupList = new Collection(groupList, {
        sortFunc: function(data) {
          app.utils.sortArray(data, function(item){
            return [item.sortWeight];
          });
        },
        canUpdate: function(current, pending) {
          return (current.version < pending.version);
        },
        limit: 50
      });

      $scope.setChartDuration = function(duration) {
        $scope.chartDuration = duration;
        angular.forEach($scope.groupList, function(group){
          group.activeChartData = group.stats[duration];
        });
      };

      var sortBy = params.sort || 'date',
          sortLabel;

      switch (sortBy) {
        case 'new':
          sortLabel = 'First Seen';
          break;
        case 'priority':
          sortLabel = 'Priority';
          break;
        case 'freq':
          sortLabel = 'Frequency';
          break;
        case 'tottime':
          sortLabel = 'Total Time Spent';
          break;
        case 'avgtime':
          sortLabel = 'Average Time Spent';
          break;
        default:
          sortLabel = 'Last Seen';
          sortBy = 'date';
      }
      $scope.sortLabel = sortLabel;

      function confirmAction(options){
        var selectedGroupIds = $.map($('.group-list .chk-select:checked'), function(item){
          return $(item).val();
        });
        if (selectedGroupIds.length === 0) {
          return;
        }

        var modal = $modal.open({
          templateUrl: '/templates/action-modal.html',
          controller: 'ProjectStreamActionModalCtrl',
          resolve: {
            context: function(){
              return {
                selectAllActive: $scope.selectAllActive,
                selectedGroupIds: selectedGroupIds,
                actionLabel: options.actionLabel,
                canActionAll: options.canActionAll && $scope.selectAllActive || false
              };
            }
          }
        }).result.then(options.action);
      }

      function actionGroups(options) {
        var data = options.data || {},
            url = options.url || '/api/0/projects/' + selectedProject.id + '/groups/';
        if (options.ids !== ALL) {
          url += '?id=' + options.ids.join('&id=');
        }
        $http({
          url: url,
          method: options.method || 'PUT',
          data: data
        });
        $timeout(function(){
          var groupList = [];
          if (options.ids === ALL) {
             groupList = $scope.groupList;
          } else {
            $.each(options.ids, function(id){
              var item = groupList[groupList.indexOf({id: id})];
              groupList.push(item);
            });
          }
          $.each(groupList, function(item){
            item.version = new Date().getTime() + 10;
            $.extend(true, item, data);
          });
        });
        $('.stream-actions .chk-select-all').prop('checked', false);
        $('.group-list .chk-select').prop('checked', false);
      }

      $('.stream-actions .action-resolve').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Resolve',
          canActionAll: true,
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {status: 'resolved'}
            });
          }
        });
      });

      $('.stream-actions .action-merge').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Merge',
          canActionAll: true,
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {merge: '1'}
            });
            // TODO(dcramer): show flash message
          }
        });
      });

      $('.stream-actions .action-delete').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Delete',
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              method: 'DELETE',
            });
            // TODO(dcramer): show flash message
          }
        });
      });

      $('.stream-actions .action-bookmark').click(function(e){
        e.preventDefault();

        confirmAction({
          actionLabel: 'Bookmark',
          action: function(selectedGroupIds){
            actionGroups({
              ids: selectedGroupIds,
              data: {isBookmarked: 1}
            });
          }
        });
      });

      $('.stream-actions .datepicker-box').click(function(e){
        e.preventDefault();
      });

      // we explicitly avoid $timeout here to prevent the watcher
      timeoutId = window.setTimeout(pollForChanges, 1000);
      $scope.$on('destroy', function(){
        window.clearTimeout(timeoutId);
      });

      $scope.setChartDuration('24h');
    }
  ]);
}());
<|endoftext|>


<commit_before>var http = require( 'http' );
var querystring = require( 'querystring' );

http.createServer(function( req, res ) {
  // parse everything after the '?' into key/value pairs
  console.log( req.url );
  var qs = querystring.parse( req.url.split( '?' )[ 1 ] );
  // property names are the same in the querystring
  var userName = qs.firstName + ' ' + qs.lastName;
  var html = '<!doctype html>' +
      '<title>Hello ' + userName + '</title>' +
      '
Hello, ' + userName + '!
';

  res.end( html );
}).listen( 8000 );<commit_msg>add routing<commit_after>/*var http = require( 'http' );
var querystring = require( 'querystring' );

http.createServer(function( req, res ) {
  // parse everything after the '?' into key/value pairs
  var qs = querystring.parse( req.url.split( '?' )[ 1 ] );
  // property names are the same in the querystring
  var userName = qs.firstName + ' ' + qs.lastName;
  var html = '<!doctype html>' +
      '<title>Hello ' + userName + '</title>' +
      '
Hello, ' + userName + '!
';

  res.end( html );
}).listen( 8000 );*/

var http = require( 'http' );
var url = require( 'url' );

http.createServer(function( req, res ) {
  // split out parts of the path
  var path = url.parse( req.url ).pathname.split( '/' );
  // handle GET requests to /sayHello/
  if ( req.method == 'GET' && path[1] == 'sayHello' ) {
    var userName = path[ 2 ] + ' ' + path[ 3 ];
    var html = '<!doctype html>' +
        '<title>Hello ' + userName + '</title>' +
        '
Hello, ' + userName + '!
';

    res.end( html );
  }
}).listen( 8000 );<|endoftext|>


<commit_before>/**
 * We.js widget class
 */

var fs = require('fs');
var view = require('../view');
var hbs = require('hbs');
var env = require('../env');

/**
 * Constructor
 */
function Widget(type, widgetFolder) {
  this.attributes = {};

  this.type = type;
  this.template = type + '/view';

  this.formTemplatePath = widgetFolder + '/form.hbs';
  this.viewTemplatePath = widgetFolder + '/view.hbs';

  this.clientscript = widgetFolder +'/client-script.js';

  this.formTemplate = null;
  this.viewTemplate = null;
}

Widget.prototype.viewMiddleware = function viewMiddleware(widget, req, res, next) {
  next();
}

/**
 * Form middleware, use to preload form data
 */
Widget.prototype.formMiddleware = function formMiddleware(req, res, next) {
  next();
};

/**
 * After save middleware
 *
 * override this function in your widget to chage your widget values
 */
Widget.prototype.afterSave = function afterSave(req, res, next) { next(); }

Widget.prototype.getTemplate = function getTemplate(ctx, themeName) {
  if ( view.themes[themeName].widgets[ctx.widget.type]) {
    // first check if this template exits in theme
    var templatePath = view.themes[themeName].widgets[ctx.widget.type];
    return hbs.compile(fs.readFileSync(templatePath, 'utf8'));
  } else {
    return hbs.compile(fs.readFileSync(this.viewTemplatePath, 'utf8'));
  }
}

Widget.prototype.render = function render(widgetRecord, themeName) {
  if ( !(env == 'prod' && this.viewTemplate) ) {
    // set cache if
    this.viewTemplate = this.getTemplate(widgetRecord, themeName);
  }

  return view.renderTemplate('widget', themeName, {
    attrTitle: 'model-widget-'+widgetRecord.widget.id+'="title"',
    record: widgetRecord.widget,
    widgetContent: this.viewTemplate(widgetRecord)
  });
}

Widget.prototype.renderForm = function renderForm(widgetRecord) {
  if (env == 'prod') {
    // firts try to get from cache
    if (this.formTemplate) return this.formTemplate(widgetRecord);
  }

  this.formTemplate = hbs.compile(fs.readFileSync(this.formTemplatePath, 'utf8'));

  return this.formTemplate(widgetRecord);
}

module.exports = Widget;<commit_msg>add locals in widget render template<commit_after>/**
 * We.js widget class
 */

var fs = require('fs');
var view = require('../view');
var hbs = require('hbs');
var env = require('../env');

/**
 * Constructor
 */
function Widget(type, widgetFolder) {
  this.attributes = {};

  this.type = type;
  this.template = type + '/view';

  this.formTemplatePath = widgetFolder + '/form.hbs';
  this.viewTemplatePath = widgetFolder + '/view.hbs';

  this.clientscript = widgetFolder +'/client-script.js';

  this.formTemplate = null;
  this.viewTemplate = null;
}

Widget.prototype.viewMiddleware = function viewMiddleware(widget, req, res, next) {
  next();
}

/**
 * Form middleware, use to preload form data
 */
Widget.prototype.formMiddleware = function formMiddleware(req, res, next) {
  next();
};

/**
 * After save middleware
 *
 * override this function in your widget to chage your widget values
 */
Widget.prototype.afterSave = function afterSave(req, res, next) { next(); }

Widget.prototype.getTemplate = function getTemplate(ctx, themeName) {
  if ( view.themes[themeName].widgets[ctx.widget.type]) {
    // first check if this template exits in theme
    var templatePath = view.themes[themeName].widgets[ctx.widget.type];
    return hbs.compile(fs.readFileSync(templatePath, 'utf8'));
  } else {
    return hbs.compile(fs.readFileSync(this.viewTemplatePath, 'utf8'));
  }
}

Widget.prototype.render = function render(widgetRecord, themeName) {
  if ( !(env == 'prod' && this.viewTemplate) ) {
    // set cache if
    this.viewTemplate = this.getTemplate(widgetRecord, themeName);
  }

  return view.renderTemplate('widget', themeName, {
    attrTitle: 'model-widget-'+widgetRecord.widget.id+'="title"',
    record: widgetRecord.widget,
    locals: widgetRecord.locals,
    widgetContent: this.viewTemplate(widgetRecord)
  });
}

Widget.prototype.renderForm = function renderForm(widgetRecord) {
  if (env == 'prod') {
    // firts try to get from cache
    if (this.formTemplate) return this.formTemplate(widgetRecord);
  }

  this.formTemplate = hbs.compile(fs.readFileSync(this.formTemplatePath, 'utf8'));

  return this.formTemplate(widgetRecord);
}

module.exports = Widget;<|endoftext|>