<commit_before>'use babel';

import { CompositeDisposable } from 'atom';
import { EventEmitter } from 'events';
import ControlPanelView from './control-panel-view';
import UpdateLibraryView from './update-library-view';
import ToolchainDownloadView from './toolchain-download-view';

const http = require('http');

exports.hasToolchain = hasToolchain;
exports.notiDownloadToolchain = notiDownloadToolchain;
exports.doDownloadToolchain = doDownloadToolchain;

export default {
  config: require('./config'),

  subscriptions: null,
  controlPanel: null,

  activate(state) {
    this.controlPanel = new ControlPanelView(state.nolaSdkViewState);

    // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
    this.subscriptions = new CompositeDisposable();

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'nola-sdk:toggle': () => this.toggle(),
      'nola-sdk:openProject': () => this.openProject(),
      'nola-sdk:showControlPanel': () => this.showControlPanel(),
      'nola-sdk:updateSdk': () => this.libUpdate(),
      'nola-sdk:hideControlPanel': () => this.close(),
      'nola-sdk:copyrightNotice': () => this.openCopyrightNotice()
    }));

    this.libUpdate();
    this.essentialToolsUpdate();

    atom.config.set('nola-sdk.build',
    [
      { curdev: 'undefined' },
      { curport: 'undefined' },
    ]);

    require('atom-package-deps').install('nola-sdk');
  },

  deactivate() {
    this.subscriptions.dispose();
    this.controlPanel.destroy();
  },

  close() {
    this.controlPanel.hide();
  },

  serialize() {
  },

  libUpdate() {
    var url = 'http://download.coxlab.kr/lib-latest-version';

    var key = atom.config.get('nola-sdk.orgKey');
    if (key != '') {
      url += '-' + key;
    }
    url += '.json';

    http.get(url, (res) => {
      const statusCode = res.statusCode;
      const contentType = res.headers['content-type'];

      let err;
      if (statusCode !== 200) {
        err = new Error(`Request failed. (Status code: ${statusCode})`);
      } else if (!/^application\/json/.test(contentType)) {
        err = new Error(`Invalid content-type. Expected JSON but received ${contentType}`);
      }

      if (err) {
        console.error(err);
        res.resume();
        return;
      }

      let rawData = '';
      res.on('data', (chunk) => {
        rawData += chunk;
      });

      res.on('end', () => {
        let parsedData = '';
        try {
          parsedData = JSON.parse(rawData);
          this.updateCheck(parsedData, true);
        } catch(e) {
          console.error(e);
        }
      });
    }).on('error', (e) => {
      console.error(e);
    });
  },

  updateCheck(libInfo, feedback) {
    updateList = this._makeUpdateList(libInfo);
    if (updateList.length > 0) {
      updateInfoStr = "";

      for (i = 0; i < updateList.length; i++) {
        updateInfoStr += (i + 1) + ". " + updateList[i].libName;
        if (updateList[i].libOldVer == "NEW") {
          updateInfoStr += " [ New " + updateList[i].libNewVer;
        } else if (updateList[i].libNewVer == "DELETE") {
          updateInfoStr += " [ Delete " + updateList[i].libOldVer;
        } else {
          updateInfoStr += " [ " + updateList[i].libOldVer + " -> " + updateList[i].libNewVer;
        }

        updateInfoStr += " ]\n";
      }

      sdk = this;
      noti = atom.notifications.addInfo("Update for Nol.A SDK!",
                                        {
                                          dismissable: true,
                                          detail: updateInfoStr,
                                          buttons: [{
                                            text: 'Update',
                                            onDidClick() {
                                              noti.dismiss();
                                              updateView = new UpdateLibraryView(updateList);
                                              updateView.doUpdate();
                                            },
                                          }],
                                        });
    } else {
      if (feedback == true) {
        atom.notifications.addInfo("You already have the latest version of Nol.A SDK!");
      }
    }
  },

  _makeUpdateList(libInfo) {
    libVers = atom.config.get('nola-sdk.libVersions');

    if (libVers == undefined) {
      atom.config.set('nola-sdk.libVersions', []);
      libVers = atom.config.get('nola-sdk.libVersions');
    }

    updateList = [];

    for (x = 0; x < libVers.length; x++) {
      for (y = 0; y < libInfo.length; y++) {
        if (libVers[x].libType == libInfo[y].libType) {
          if (libVers[x].libVersion != libInfo[y].libVersion) {
            // Found new version of existing library.
            updateList.push({
              libName: libInfo[y].libName,
              libType: libInfo[y].libType,
              libOldVer: libVers[x].libVersion,
              libNewVer: libInfo[y].libVersion,
              libToolchain : libInfo[y].libToolchain
            });
          }
          break;
        }

        if (y == libInfo.length - 1) {
          // Found Deleted Library.
          updateList.push({
            libName: libVers[x].libName,
            libType: libVers[x].libType,
            libOldVer: libVers[x].libVersion,
            libNewVer: "DELETE"
          });
        }
      }
    }

    for (x = 0; x < libInfo.length; x++) {
      // Found new libraries
      if (libVers.length == 0) {
        updateList.push({
          libName: libInfo[x].libName,
          libType: libInfo[x].libType,
          libOldVer: "NEW",
          libNewVer: libInfo[x].libVersion,
          libToolchain : libInfo[x].libToolchain
        });
      } else {
        for (y = 0; y < libVers.length; y++) {
          if (libInfo[x].libType == libVers[y].libType) {
            break;
          }

          if (y == libVers.length - 1) {
            updateList.push({
              libName: libInfo[x].libName,
              libType: libInfo[x].libType,
              libOldVer: "NEW",
              libNewVer: libInfo[x].libVersion,
              libToolchain : libInfo[x].libToolchain
            });
          }
        }
      }
    }
    return updateList;
  },

  essentialToolsUpdate() {
    try {
      fs.statSync(app.getPath('home') + path.sep + '.atom' + path.sep + 'nola-sdk' + path.sep + 'tools');
    } catch(e) {
      doDownloadToolchain({
        id: 'tools-0.23.0',
        dir: 'tools',
        path: '.'
      });
    }
  },

  showControlPanel() {
    this.controlPanel.show();
  },

  openProject() {
    var dir = require('remote').dialog.showOpenDialog({
      properties:['openDirectory']
    });

    if (dir != undefined) {
      if (dir[0] == this.controlPanel.currentProjectPath) {
        alert('This project is already opened.');
      } else {
        var hasOldFile;
        try {
          fs.statSync(dir[0] + path.sep + '.atom-build.json');
          hasOldFile = true;
        } catch(e) {
          hasOldFile = false;
        }

        if (hasOldFile) {
          // Convert old file to new format.
          var data = fs.readFileSync(dir[0] + path.sep + '.atom-build.json');
          fs.unlink(dir[0] + path.sep + '.atom-build.json');
          var oldFormat = JSON.parse(data.toString());
          var newFormat = {
            'board': oldFormat.args[0],
          };

          fs.writeFileSync(dir[0] + path.sep + 'Nol.A-project.json', JSON.stringify(newFormat, null, ' '));
          this.controlPanel.setProject(dir[0]);

        } else {
          try {
            fs.statSync(dir[0] + path.sep + 'Nol.A-project.json');
          } catch(e) {
            alert('No project is found in this path.');
            console.error(e);
            return;
          }

          this.controlPanel.setProject(dir[0]);
        }
      }
    }
  },

  provideBuilder() {
    const gccErrorMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):(?<col>\\d+):\\s*(fatal error|error):\\s*(?<message>.+)';
    const ocamlErrorMatch = '(?<file>[\\/0-9a-zA-Z\\._\\-]+)", line (?<line>\\d+), characters (?<col>\\d+)-(?<col_end>\\d+):\\n(?<message>.+)';
    const golangErrorMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):\\s*(?<message>.*error.+)';
    const errorMatch = [
      gccErrorMatch, ocamlErrorMatch, golangErrorMatch
    ];

    const gccWarningMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):(?<col>\\d+):\\s*(warning):\\s*(?<message>.+)';
    const warningMatch = [
      gccWarningMatch
    ];

    var controlPanel = this.controlPanel;

    return class NolABuildProvider extends EventEmitter {
      constructor(cwd) {
        super();
        this.cwd = cwd;
        atom.config.observe('nola-sdk.build', () => this.emit('refresh'));
        atom.config.observe('nola-sdk.hwLibDevMode', () => this.emit('refresh'));
        atom.config.observe('nola-sdk.hwLibSourcePath', () => this.emit('refresh'));
      }

      getNiceName() {
        return 'Nol.A Build';
      }

      isEligible() {
        if (this.cwd != controlPanel.currentProjectPath) {
          return false;
        }

        if (controlPanel.devSelectView.curDev == undefined) {
          return false;
        }

        try {
          fs.statSync(this.cwd + path.sep + 'Nol.A-project.json');
        } catch(e) {
          return false;
        }

        return true;
      }

      settings() {
        var config = {
          exec: '',
          args: [
            controlPanel.devSelectView.curDev.libType,
            controlPanel.portSelectView.curPort,
          ],
          errorMatch: errorMatch,
          warningMatch: warningMatch,
        };

        if (atom.config.get('nola-sdk.hwLibDevMode') == true && atom.config.get('nola-sdk.hwLibSourcePath') != '') {
          config.exec = atom.config.get('nola-sdk.hwLibSourcePath');
          config.args.push(atom.config.get('nola-sdk.hwLibSourcePath'));
        } else {
          config.exec = app.getPath('home') + path.sep + '.atom';
        }

        config.exec += path.sep + 'nola-sdk' + path.sep + 'make' + path.sep + 'build';
        if (os.platform() == 'linux' || os.platform() == 'darwin') {
          config.exec += '.sh';
        } else {
          config.exec += '.cmd';
        }

        return config;
      }
    };
  },

  openCopyrightNotice() {
    shell = require('shell');
    shell.openExternal('http://www.coxlab.kr/docs/copyright-notice/');
  }
};

function hasToolchain(toolchain) {
  toolChainList = atom.config.get('nola-sdk.toolchains');
  if (toolChainList == undefined) {
    toolChainList = [];
    atom.config.set('nola-sdk.toolchains', toolChainList);
  }

  for (var i in toolChainList) {
    if (toolChainList[i].name == toolchain)
      return true;
  }
  return false;
}

function notiDownloadToolchain(info) {
  noti = atom.notifications.addInfo("Additional tool is required!", {
    dismissable: true,
    detail: info.id,
    buttons: [{
      text: 'Download',
      className: 'btn-downloadDo',
      onDidClick() {
        noti.dismiss();
        doDownloadToolchain(info);
      }
    }]
  });
}

function doDownloadToolchain(toolInfo) {
  toolchainDownloadView = new ToolchainDownloadView(toolInfo);
  downloadPanel = atom.workspace.addModalPanel({
    item: toolchainDownloadView.element,
    visible: true
  });
  toolchainDownloadView.setPanel(downloadPanel);
  toolchainDownloadView.doDownload();
}
<commit_msg>Added notifying a warning of invalid organization key.<commit_after>'use babel';

import { CompositeDisposable } from 'atom';
import { EventEmitter } from 'events';
import ControlPanelView from './control-panel-view';
import UpdateLibraryView from './update-library-view';
import ToolchainDownloadView from './toolchain-download-view';

const http = require('http');

exports.hasToolchain = hasToolchain;
exports.notiDownloadToolchain = notiDownloadToolchain;
exports.doDownloadToolchain = doDownloadToolchain;

export default {
  config: require('./config'),

  subscriptions: null,
  controlPanel: null,

  activate(state) {
    this.controlPanel = new ControlPanelView(state.nolaSdkViewState);

    // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
    this.subscriptions = new CompositeDisposable();

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'nola-sdk:toggle': () => this.toggle(),
      'nola-sdk:openProject': () => this.openProject(),
      'nola-sdk:showControlPanel': () => this.showControlPanel(),
      'nola-sdk:updateSdk': () => this.libUpdate(),
      'nola-sdk:hideControlPanel': () => this.close(),
      'nola-sdk:copyrightNotice': () => this.openCopyrightNotice()
    }));

    this.libUpdate();
    this.essentialToolsUpdate();

    atom.config.set('nola-sdk.build',
    [
      { curdev: 'undefined' },
      { curport: 'undefined' },
    ]);

    require('atom-package-deps').install('nola-sdk');
  },

  deactivate() {
    this.subscriptions.dispose();
    this.controlPanel.destroy();
  },

  close() {
    this.controlPanel.hide();
  },

  serialize() {
  },

  libUpdate() {
    var url = 'http://download.coxlab.kr/lib-latest-version';

    var key = atom.config.get('nola-sdk.orgKey');
    if (key != '') {
      url += '-' + key;
    }
    url += '.json';

    http.get(url, (res) => {
      const statusCode = res.statusCode;
      const contentType = res.headers['content-type'];

      let err;
      if (statusCode !== 200) {
        err = new Error(`Request failed. (Status code: ${statusCode})`);
      } else if (!/^application\/json/.test(contentType)) {
        err = new Error(`Invalid content-type. Expected JSON but received ${contentType}`);
      }

      if (err) {
        if (key != '') {
          atom.notifications.addWarning("Invalid organization key!", {
            detail: `You entered '${key}'. Check it again.`,
          });
        } else {
          console.error(err);
        }
        res.resume();
        return;
      }

      let rawData = '';
      res.on('data', (chunk) => {
        rawData += chunk;
      });

      res.on('end', () => {
        let parsedData = '';
        try {
          parsedData = JSON.parse(rawData);
          this.updateCheck(parsedData, true);
        } catch(e) {
          console.error(e);
        }
      });
    }).on('error', (e) => {
      console.error(e);
    });
  },

  updateCheck(libInfo, feedback) {
    updateList = this._makeUpdateList(libInfo);
    if (updateList.length > 0) {
      updateInfoStr = "";

      for (i = 0; i < updateList.length; i++) {
        updateInfoStr += (i + 1) + ". " + updateList[i].libName;
        if (updateList[i].libOldVer == "NEW") {
          updateInfoStr += " [ New " + updateList[i].libNewVer;
        } else if (updateList[i].libNewVer == "DELETE") {
          updateInfoStr += " [ Delete " + updateList[i].libOldVer;
        } else {
          updateInfoStr += " [ " + updateList[i].libOldVer + " -> " + updateList[i].libNewVer;
        }

        updateInfoStr += " ]\n";
      }

      sdk = this;
      noti = atom.notifications.addInfo("Update for Nol.A SDK!",
                                        {
                                          dismissable: true,
                                          detail: updateInfoStr,
                                          buttons: [{
                                            text: 'Update',
                                            onDidClick() {
                                              noti.dismiss();
                                              updateView = new UpdateLibraryView(updateList);
                                              updateView.doUpdate();
                                            },
                                          }],
                                        });
    } else {
      if (feedback == true) {
        atom.notifications.addInfo("You already have the latest version of Nol.A SDK!");
      }
    }
  },

  _makeUpdateList(libInfo) {
    libVers = atom.config.get('nola-sdk.libVersions');

    if (libVers == undefined) {
      atom.config.set('nola-sdk.libVersions', []);
      libVers = atom.config.get('nola-sdk.libVersions');
    }

    updateList = [];

    for (x = 0; x < libVers.length; x++) {
      for (y = 0; y < libInfo.length; y++) {
        if (libVers[x].libType == libInfo[y].libType) {
          if (libVers[x].libVersion != libInfo[y].libVersion) {
            // Found new version of existing library.
            updateList.push({
              libName: libInfo[y].libName,
              libType: libInfo[y].libType,
              libOldVer: libVers[x].libVersion,
              libNewVer: libInfo[y].libVersion,
              libToolchain : libInfo[y].libToolchain
            });
          }
          break;
        }

        if (y == libInfo.length - 1) {
          // Found Deleted Library.
          updateList.push({
            libName: libVers[x].libName,
            libType: libVers[x].libType,
            libOldVer: libVers[x].libVersion,
            libNewVer: "DELETE"
          });
        }
      }
    }

    for (x = 0; x < libInfo.length; x++) {
      // Found new libraries
      if (libVers.length == 0) {
        updateList.push({
          libName: libInfo[x].libName,
          libType: libInfo[x].libType,
          libOldVer: "NEW",
          libNewVer: libInfo[x].libVersion,
          libToolchain : libInfo[x].libToolchain
        });
      } else {
        for (y = 0; y < libVers.length; y++) {
          if (libInfo[x].libType == libVers[y].libType) {
            break;
          }

          if (y == libVers.length - 1) {
            updateList.push({
              libName: libInfo[x].libName,
              libType: libInfo[x].libType,
              libOldVer: "NEW",
              libNewVer: libInfo[x].libVersion,
              libToolchain : libInfo[x].libToolchain
            });
          }
        }
      }
    }
    return updateList;
  },

  essentialToolsUpdate() {
    try {
      fs.statSync(app.getPath('home') + path.sep + '.atom' + path.sep + 'nola-sdk' + path.sep + 'tools');
    } catch(e) {
      doDownloadToolchain({
        id: 'tools-0.23.0',
        dir: 'tools',
        path: '.'
      });
    }
  },

  showControlPanel() {
    this.controlPanel.show();
  },

  openProject() {
    var dir = require('remote').dialog.showOpenDialog({
      properties:['openDirectory']
    });

    if (dir != undefined) {
      if (dir[0] == this.controlPanel.currentProjectPath) {
        alert('This project is already opened.');
      } else {
        var hasOldFile;
        try {
          fs.statSync(dir[0] + path.sep + '.atom-build.json');
          hasOldFile = true;
        } catch(e) {
          hasOldFile = false;
        }

        if (hasOldFile) {
          // Convert old file to new format.
          var data = fs.readFileSync(dir[0] + path.sep + '.atom-build.json');
          fs.unlink(dir[0] + path.sep + '.atom-build.json');
          var oldFormat = JSON.parse(data.toString());
          var newFormat = {
            'board': oldFormat.args[0],
          };

          fs.writeFileSync(dir[0] + path.sep + 'Nol.A-project.json', JSON.stringify(newFormat, null, ' '));
          this.controlPanel.setProject(dir[0]);

        } else {
          try {
            fs.statSync(dir[0] + path.sep + 'Nol.A-project.json');
          } catch(e) {
            alert('No project is found in this path.');
            console.error(e);
            return;
          }

          this.controlPanel.setProject(dir[0]);
        }
      }
    }
  },

  provideBuilder() {
    const gccErrorMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):(?<col>\\d+):\\s*(fatal error|error):\\s*(?<message>.+)';
    const ocamlErrorMatch = '(?<file>[\\/0-9a-zA-Z\\._\\-]+)", line (?<line>\\d+), characters (?<col>\\d+)-(?<col_end>\\d+):\\n(?<message>.+)';
    const golangErrorMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):\\s*(?<message>.*error.+)';
    const errorMatch = [
      gccErrorMatch, ocamlErrorMatch, golangErrorMatch
    ];

    const gccWarningMatch = '(?<file>([A-Za-z]:[\\/])?[^:\\n]+):(?<line>\\d+):(?<col>\\d+):\\s*(warning):\\s*(?<message>.+)';
    const warningMatch = [
      gccWarningMatch
    ];

    var controlPanel = this.controlPanel;

    return class NolABuildProvider extends EventEmitter {
      constructor(cwd) {
        super();
        this.cwd = cwd;
        atom.config.observe('nola-sdk.build', () => this.emit('refresh'));
        atom.config.observe('nola-sdk.hwLibDevMode', () => this.emit('refresh'));
        atom.config.observe('nola-sdk.hwLibSourcePath', () => this.emit('refresh'));
      }

      getNiceName() {
        return 'Nol.A Build';
      }

      isEligible() {
        if (this.cwd != controlPanel.currentProjectPath) {
          return false;
        }

        if (controlPanel.devSelectView.curDev == undefined) {
          return false;
        }

        try {
          fs.statSync(this.cwd + path.sep + 'Nol.A-project.json');
        } catch(e) {
          return false;
        }

        return true;
      }

      settings() {
        var config = {
          exec: '',
          args: [
            controlPanel.devSelectView.curDev.libType,
            controlPanel.portSelectView.curPort,
          ],
          errorMatch: errorMatch,
          warningMatch: warningMatch,
        };

        if (atom.config.get('nola-sdk.hwLibDevMode') == true && atom.config.get('nola-sdk.hwLibSourcePath') != '') {
          config.exec = atom.config.get('nola-sdk.hwLibSourcePath');
          config.args.push(atom.config.get('nola-sdk.hwLibSourcePath'));
        } else {
          config.exec = app.getPath('home') + path.sep + '.atom';
        }

        config.exec += path.sep + 'nola-sdk' + path.sep + 'make' + path.sep + 'build';
        if (os.platform() == 'linux' || os.platform() == 'darwin') {
          config.exec += '.sh';
        } else {
          config.exec += '.cmd';
        }

        return config;
      }
    };
  },

  openCopyrightNotice() {
    shell = require('shell');
    shell.openExternal('http://www.coxlab.kr/docs/copyright-notice/');
  }
};

function hasToolchain(toolchain) {
  toolChainList = atom.config.get('nola-sdk.toolchains');
  if (toolChainList == undefined) {
    toolChainList = [];
    atom.config.set('nola-sdk.toolchains', toolChainList);
  }

  for (var i in toolChainList) {
    if (toolChainList[i].name == toolchain)
      return true;
  }
  return false;
}

function notiDownloadToolchain(info) {
  noti = atom.notifications.addInfo("Additional tool is required!", {
    dismissable: true,
    detail: info.id,
    buttons: [{
      text: 'Download',
      className: 'btn-downloadDo',
      onDidClick() {
        noti.dismiss();
        doDownloadToolchain(info);
      }
    }]
  });
}

function doDownloadToolchain(toolInfo) {
  toolchainDownloadView = new ToolchainDownloadView(toolInfo);
  downloadPanel = atom.workspace.addModalPanel({
    item: toolchainDownloadView.element,
    visible: true
  });
  toolchainDownloadView.setPanel(downloadPanel);
  toolchainDownloadView.doDownload();
}
<|endoftext|>


<commit_before>import Ember from 'ember';
import ModulePrefixMixin from 'ember-theater/mixins/module-prefix';

const {
  get,
  inject,
  isEmpty,
  isPresent,
  observer,
  Service
} = Ember;

export default Service.extend(ModulePrefixMixin, {
  emberTheaterSaveStateManager: inject.service(),

  updateSceneRecord(key, value) {
    this.get('emberTheaterSaveStateManager').updateSceneRecord(key, value);
  },

  setInitialSceneId: observer('scene.id', function() {
    const {
      initialSceneId,
      scene
    } = this.getProperties('initialSceneId', 'scene');
    const sceneId = scene.id;

    if (isEmpty(initialSceneId) && isPresent(sceneId)) {
      this.set('initialSceneId', sceneId);
    }
  }),

  resetScene() {
    const initialSceneId = this.get('initialSceneId');

    this.toScene(initialSceneId);
  },

  liftCurtains: async function() {
    if (isEmpty(this.get('scene'))) {
      const options = { autosave: false };
      const autosave = await this.get('emberTheaterSaveStateManager.autosave');
      let sceneId = autosave.get('activeState.sceneId');

      if (isEmpty(sceneId)) {
        sceneId = this.get('sceneId');
        options.autosave = true;
      }

      this.toScene(sceneId, options);
    }
  },

  toScene: async function(sceneId, options = {}) {
    const oldScene = this.get('scene');
    if (isPresent(oldScene)) { oldScene.abort(); }

    const saveStateManager = this.get('emberTheaterSaveStateManager');
    const sceneRecord = saveStateManager.get('sceneRecord');

    const modulePrefix = this.get('modulePrefix');
    const sceneFactory = require(`${modulePrefix}/ember-theater/scenes/${sceneId}`)['default'];
    const scene = sceneFactory.create({
      container: this.get('container'),
      id: sceneId,
      isLoading: options.loading,
      options,
      sceneRecord
    })

    if (get(options, 'autosave') !== false) {
      const autosave = await saveStateManager.get('autosave');

      saveStateManager.appendActiveState({ sceneId });
      saveStateManager.updateRecord(autosave);
      saveStateManager.clearSceneRecord();
    }

    this.set('scene', scene);
  }
});
<commit_msg>properly set initialSceneId<commit_after>import Ember from 'ember';
import ModulePrefixMixin from 'ember-theater/mixins/module-prefix';

const {
  get,
  inject,
  isEmpty,
  isPresent,
  observer,
  Service
} = Ember;

export default Service.extend(ModulePrefixMixin, {
  emberTheaterSaveStateManager: inject.service(),

  updateSceneRecord(key, value) {
    this.get('emberTheaterSaveStateManager').updateSceneRecord(key, value);
  },

  setInitialSceneId: observer('sceneId', function() {
    const {
      initialSceneId,
      sceneId
    } = this.getProperties('initialSceneId', 'sceneId');

    if (isEmpty(initialSceneId) && isPresent(sceneId)) {
      this.set('initialSceneId', sceneId);
    }
  }),

  resetScene() {
    const initialSceneId = this.get('initialSceneId');

    this.toScene(initialSceneId);
  },

  liftCurtains: async function() {
    if (isEmpty(this.get('scene'))) {
      const options = { autosave: false };
      const autosave = await this.get('emberTheaterSaveStateManager.autosave');
      let sceneId = autosave.get('activeState.sceneId');

      if (isEmpty(sceneId)) {
        sceneId = this.get('sceneId');
        options.autosave = true;
      }

      this.toScene(sceneId, options);
    }
  },

  toScene: async function(sceneId, options = {}) {
    const oldScene = this.get('scene');
    if (isPresent(oldScene)) { oldScene.abort(); }

    const saveStateManager = this.get('emberTheaterSaveStateManager');
    const sceneRecord = saveStateManager.get('sceneRecord');

    const modulePrefix = this.get('modulePrefix');
    const sceneFactory = require(`${modulePrefix}/ember-theater/scenes/${sceneId}`)['default'];
    const scene = sceneFactory.create({
      container: this.get('container'),
      id: sceneId,
      isLoading: options.loading,
      options,
      sceneRecord
    })

    if (get(options, 'autosave') !== false) {
      const autosave = await saveStateManager.get('autosave');

      saveStateManager.appendActiveState({ sceneId });
      saveStateManager.updateRecord(autosave);
      saveStateManager.clearSceneRecord();
    }

    this.set('scene', scene);
  }
});
<|endoftext|>


<commit_before>// --------------------
// Overlook
// Prototype methods
// --------------------

// modules
var _ = require('overlook-utils'),
	pathModule = require('path'),
	http = require('http'),
	Promise = require('bluebird-extra');

// libraries
var OverlookError = require('./errors').OverlookError,
	db = require('./db'),
	express = require('./express'),
	routes = require('./routes'),
	workers = require('./workers'),
	Mailer = require('./email');

// exports
module.exports = {
	// initialize Overlook server
	init: function(options) {
		console.log('Initializing Overlook app');

		// parse options and save to overlook instance
		if (!options) throw new OverlookError('No options provided to Overlook');
		this.options = options;

		// set longStackTraces if in development mode
		if (options.development) Promise.longStackTraces();

		// set up paths
		var paths = _.defaultValue(options, 'paths', {});
		_.defaultValue(paths, 'root', pathModule.join(__dirname, '../../'));

		_.defaults(paths, {
			controllers: pathModule.join(paths.root, './controllers'),
			models: pathModule.join(paths.root, './models'),
			public: pathModule.join(paths.root, './public'),
			src: pathModule.join(paths.root, './src'),
			views: pathModule.join(paths.root, './views'),
			workers: pathModule.join(paths.root, './workers')
		});

		// default options
		if (!options.database) throw new OverlookError('No database details provided to Overlook');

		_.defaultValue(options, 'port', 3000);

		if (!options.domain || !options.domain.cookieSecret) throw new OverlookError('No cookieSecret provided to Overlook');

		_.defaults(options.domain, {
			domain: 'localhost',
			sessionCookieDuration: 1 * 60 * 60 * 1000, // 1 hour
			loginCookieDuration: 14 * 24 * 60 * 60 * 1000, // 14 days
			postLoginCookieDuration: 30 * 60 * 1000, // 30 minutes
			cookieOptions: {}
		});

		_.defaults(options.domain.cookieOptions, {
			path: '/',
			secure: false,
			httpOnly: false
		});

		_.defaultValue(options, 'general', {});
		_.defaults(options.general, {
			pageLength: 20
		});

		// init email
		console.log('Initializing email');

		_.defaultValue(options, 'email', {});
		if (options.email.apiKey) this.mailer = new Mailer(options.email);

		// init sequelize and load models
		var sequelize = db.init(options.database, paths.models);
		this.sequelize = sequelize;
		this.models = sequelize.models;

		// init express
		console.log('Initializing express app');
		this.app = express(this);

		// init workers
		console.log('Initializing workers');

		_.defaultValue(options, 'workers', {});
		workers.init(this);

		// done
		console.log('Overlook app initialized');
	},

	startDB: function() {
		// sync sequelize to create models in db
		console.log('Syncing database');

		return this.sequelize.sync({logging: logger}).bind(this)
		.then(function() {
			console.log('Database synced');

			// initialise public and root users
			console.log('Initialising system, root and public users');

			return db.stock(this.sequelize).bind(this)
			.spread(function(users, roles) {
				// save to app
				this.systemUserId = users.system.id;
				this.publicUserId = users.public.id;
				this.rootRole = roles.root;
				this.userRole = roles.user;

				console.log('Initialised system, root and public users');
			});
		}).then(function() {
			this.dbSynced = true;
			console.log('Database started');
		});
	},

	// start Overlook server
	start: function() {
		console.log('Starting Overlook app');

		return Promise.bind(this).then(function() {
			// sync db if not already done
			if (!this.dbSynced) return this.startDb();
		}).then(function() {
			// initialize routes
			return routes(this.sequelize.models, this, this.options.paths.controllers, this.options.paths.views);
		}).then(function() {
			// clean-up workers after crash/shutdown
			console.log('Cleaning up after workers');

			return workers.startup(this);
		}).then(function() {
			// start server
			console.log('Server starting');

			var port = this.options.port;

			var server = http.createServer(this.app);
			this.server = server;

			return new Promise(function(resolve, reject) { // jshint ignore:line
				server.listen(port, function() {
					console.log('Server listening on port ' + port);
					resolve();
				});
			});
		}).then(function() {
			console.log('Server ready');

			// start workers
			workers.autoStart(this);

			console.log('READY');
		})
		.catch(function(err) {
			console.log('ERROR:', err.name + ':', err.message);
			console.log(err.stack);

			return Promise.reject(err);
		})
		.done();
	}
};

function logger(msg) {
	//xxx use a proper logger!
	console.log(msg);
}
<commit_msg>Set longStackTraces on Sequelize.Promise if in development mode<commit_after>// --------------------
// Overlook
// Prototype methods
// --------------------

// modules
var _ = require('overlook-utils'),
	pathModule = require('path'),
	http = require('http'),
	Promise = require('bluebird-extra'),
	Sequelize = require('sequelize-extra');

// libraries
var OverlookError = require('./errors').OverlookError,
	db = require('./db'),
	express = require('./express'),
	routes = require('./routes'),
	workers = require('./workers'),
	Mailer = require('./email');

// exports
module.exports = {
	// initialize Overlook server
	init: function(options) {
		console.log('Initializing Overlook app');

		// parse options and save to overlook instance
		if (!options) throw new OverlookError('No options provided to Overlook');
		this.options = options;

		// set longStackTraces if in development mode
		if (options.development) {
			Promise.longStackTraces();
			Sequelize.Promise.longStackTraces();
		}

		// set up paths
		var paths = _.defaultValue(options, 'paths', {});
		_.defaultValue(paths, 'root', pathModule.join(__dirname, '../../'));

		_.defaults(paths, {
			controllers: pathModule.join(paths.root, './controllers'),
			models: pathModule.join(paths.root, './models'),
			public: pathModule.join(paths.root, './public'),
			src: pathModule.join(paths.root, './src'),
			views: pathModule.join(paths.root, './views'),
			workers: pathModule.join(paths.root, './workers')
		});

		// default options
		if (!options.database) throw new OverlookError('No database details provided to Overlook');

		_.defaultValue(options, 'port', 3000);

		if (!options.domain || !options.domain.cookieSecret) throw new OverlookError('No cookieSecret provided to Overlook');

		_.defaults(options.domain, {
			domain: 'localhost',
			sessionCookieDuration: 1 * 60 * 60 * 1000, // 1 hour
			loginCookieDuration: 14 * 24 * 60 * 60 * 1000, // 14 days
			postLoginCookieDuration: 30 * 60 * 1000, // 30 minutes
			cookieOptions: {}
		});

		_.defaults(options.domain.cookieOptions, {
			path: '/',
			secure: false,
			httpOnly: false
		});

		_.defaultValue(options, 'general', {});
		_.defaults(options.general, {
			pageLength: 20
		});

		// init email
		console.log('Initializing email');

		_.defaultValue(options, 'email', {});
		if (options.email.apiKey) this.mailer = new Mailer(options.email);

		// init sequelize and load models
		var sequelize = db.init(options.database, paths.models);
		this.sequelize = sequelize;
		this.models = sequelize.models;

		// init express
		console.log('Initializing express app');
		this.app = express(this);

		// init workers
		console.log('Initializing workers');

		_.defaultValue(options, 'workers', {});
		workers.init(this);

		// done
		console.log('Overlook app initialized');
	},

	startDB: function() {
		// sync sequelize to create models in db
		console.log('Syncing database');

		return this.sequelize.sync({logging: logger}).bind(this)
		.then(function() {
			console.log('Database synced');

			// initialise public and root users
			console.log('Initialising system, root and public users');

			return db.stock(this.sequelize).bind(this)
			.spread(function(users, roles) {
				// save to app
				this.systemUserId = users.system.id;
				this.publicUserId = users.public.id;
				this.rootRole = roles.root;
				this.userRole = roles.user;

				console.log('Initialised system, root and public users');
			});
		}).then(function() {
			this.dbSynced = true;
			console.log('Database started');
		});
	},

	// start Overlook server
	start: function() {
		console.log('Starting Overlook app');

		return Promise.bind(this).then(function() {
			// sync db if not already done
			if (!this.dbSynced) return this.startDb();
		}).then(function() {
			// initialize routes
			return routes(this.sequelize.models, this, this.options.paths.controllers, this.options.paths.views);
		}).then(function() {
			// clean-up workers after crash/shutdown
			console.log('Cleaning up after workers');

			return workers.startup(this);
		}).then(function() {
			// start server
			console.log('Server starting');

			var port = this.options.port;

			var server = http.createServer(this.app);
			this.server = server;

			return new Promise(function(resolve, reject) { // jshint ignore:line
				server.listen(port, function() {
					console.log('Server listening on port ' + port);
					resolve();
				});
			});
		}).then(function() {
			console.log('Server ready');

			// start workers
			workers.autoStart(this);

			console.log('READY');
		})
		.catch(function(err) {
			console.log('ERROR:', err.name + ':', err.message);
			console.log(err.stack);

			return Promise.reject(err);
		})
		.done();
	}
};

function logger(msg) {
	//xxx use a proper logger!
	console.log(msg);
}
<|endoftext|>


<commit_before>var requestComp = require('./request');
var path = require('path');
var glob = require('glob');
var fs = require('fs');
var tar = require('tar-stream');
var async = require('async');

module.exports.prepare = function prepare(package, callback) {
  var libpaths = package.libraries || [];
  var sketchfile = package.sketch;
  var board = package.board || 'uno';
  var version = package.version || '10609';
  var service = package.service || null;

  // if user supplies a string path, just convert it into an array without burdening them with an error
  if (typeof libpaths === 'string') {
    libpaths = [libpaths];
  }

  // create array of paths to iterate on
  // end result looks something like:
  // [
  //   ['/path/to/sketch/dir', 'sketch'],
  //   ['/path/to/lib1', 'libs'],
  //   ['/path/to/lib2', 'libs']
  // ]
  // push sketch dir first
  var globPaths = [[path.dirname(sketchfile), 'sketch']];
  // if there are libraries included, push them to list
  libpaths.forEach(function(lib) {
    globPaths.push([lib, 'libs']);
  });

  // prepare a new tarball packing
  var pack = tar.pack();

  // we def needs these top level dirs, let's guarantee that happens
  pack.entry({name: 'libs', type: 'directory'});
  pack.entry({name: 'dist', type: 'directory'});
  pack.entry({name: 'sketch', type: 'directory'});

  async.each(globPaths, findAndPackDependencies, function(error) {
    if (error) return callback(error);

    // finally, pack the sketch file itself
    packSketch(sketchfile, function(error) {
      if (error) return callback(error);

      // we're done with the tarball
      pack.finalize();

      return callback(error, pack);
    });
  });

  function findDependencies(location, callback) {
    var searchPath = location[0];
    var destPath = location[1];

    console.log(location)

    // look for needed files within library dir
    // TODO: look into changing root in options to full path
    glob("**/*+(.h|.cpp|.c)", {ignore: '**/node_modules/**/*+(.h|.cpp|.c)', cwd: searchPath, matchBase: true}, function(error, matches) {
      var error = null;
      if (!matches.length && destPath === 'libs') error = new Error('No library files found in supplied path: ' + searchPath);
      console.log(matches);
      return callback(error, matches);
    });
  }

  function packDependencies(matches, location, callback) {
    if (!matches.length) return callback(null);

    var basepath = location[0];
    var destpath = location[1];

    // save each file into the tarball pack
    matches.forEach(function(filepath, index, arr) {

      var libName = path.basename(basepath);
      fs.readFile(path.join(basepath, filepath), {encoding: 'utf8'}, function(error, filecontent) {
        if (error) return callback(error);

        // pack file into tarball
        pack.entry({name: path.posix.join(destpath, libName, filepath)}, filecontent);

        // return async if we're done
        if (arr.length - 1 === index) return callback(null);

      });
    });
  }

  function findAndPackDependencies(location, callback) {
    // find files that we can pack into the tarball for compilation
    findDependencies(location, function(error, matches) {
      if (error) return callback(error);

      // send matching files to be packed into tarball
      packDependencies(matches, location, function(error) {
        return callback(error);
      });
    });
  }

  function packSketch(sketchfile, callback) {
    // save the main sketch file to a special filename that the compiler can look for
    fs.readFile(sketchfile, {encoding: 'utf8'}, function(error, sketchfile) {
      if (error) return callback(new Error(error.message));

      pack.entry({name: path.posix.join('sketch', 'sketch.ino')}, sketchfile);

      return callback(null);
    });
  }
};
<commit_msg>remove log<commit_after>var requestComp = require('./request');
var path = require('path');
var glob = require('glob');
var fs = require('fs');
var tar = require('tar-stream');
var async = require('async');

module.exports.prepare = function prepare(package, callback) {
  var libpaths = package.libraries || [];
  var sketchfile = package.sketch;
  var board = package.board || 'uno';
  var version = package.version || '10609';
  var service = package.service || null;

  // if user supplies a string path, just convert it into an array without burdening them with an error
  if (typeof libpaths === 'string') {
    libpaths = [libpaths];
  }

  // create array of paths to iterate on
  // end result looks something like:
  // [
  //   ['/path/to/sketch/dir', 'sketch'],
  //   ['/path/to/lib1', 'libs'],
  //   ['/path/to/lib2', 'libs']
  // ]
  // push sketch dir first
  var globPaths = [[path.dirname(sketchfile), 'sketch']];
  // if there are libraries included, push them to list
  libpaths.forEach(function(lib) {
    globPaths.push([lib, 'libs']);
  });

  // prepare a new tarball packing
  var pack = tar.pack();

  // we def needs these top level dirs, let's guarantee that happens
  pack.entry({name: 'libs', type: 'directory'});
  pack.entry({name: 'dist', type: 'directory'});
  pack.entry({name: 'sketch', type: 'directory'});

  async.each(globPaths, findAndPackDependencies, function(error) {
    if (error) return callback(error);

    // finally, pack the sketch file itself
    packSketch(sketchfile, function(error) {
      if (error) return callback(error);

      // we're done with the tarball
      pack.finalize();

      return callback(error, pack);
    });
  });

  function findDependencies(location, callback) {
    var searchPath = location[0];
    var destPath = location[1];

    console.log(location)

    // look for needed files within library dir
    // TODO: look into changing root in options to full path
    glob("**/*+(.h|.cpp|.c)", {ignore: '**/node_modules/**/*+(.h|.cpp|.c)', cwd: searchPath, matchBase: true}, function(error, matches) {
      var error = null;
      if (!matches.length && destPath === 'libs') error = new Error('No library files found in supplied path: ' + searchPath);
      return callback(error, matches);
    });
  }

  function packDependencies(matches, location, callback) {
    if (!matches.length) return callback(null);

    var basepath = location[0];
    var destpath = location[1];

    // save each file into the tarball pack
    matches.forEach(function(filepath, index, arr) {

      var libName = path.basename(basepath);
      fs.readFile(path.join(basepath, filepath), {encoding: 'utf8'}, function(error, filecontent) {
        if (error) return callback(error);

        // pack file into tarball
        pack.entry({name: path.posix.join(destpath, libName, filepath)}, filecontent);

        // return async if we're done
        if (arr.length - 1 === index) return callback(null);

      });
    });
  }

  function findAndPackDependencies(location, callback) {
    // find files that we can pack into the tarball for compilation
    findDependencies(location, function(error, matches) {
      if (error) return callback(error);

      // send matching files to be packed into tarball
      packDependencies(matches, location, function(error) {
        return callback(error);
      });
    });
  }

  function packSketch(sketchfile, callback) {
    // save the main sketch file to a special filename that the compiler can look for
    fs.readFile(sketchfile, {encoding: 'utf8'}, function(error, sketchfile) {
      if (error) return callback(new Error(error.message));

      pack.entry({name: path.posix.join('sketch', 'sketch.ino')}, sketchfile);

      return callback(null);
    });
  }
};
<|endoftext|>


<commit_before>import { PAUSE_STORAGE_KEY } from '..'

const getState = async () => (await browser.storage.local.get(PAUSE_STORAGE_KEY))[PAUSE_STORAGE_KEY] || false
const setState = state => browser.storage.local.set({ [PAUSE_STORAGE_KEY]: state })

/**
 * Main entrypoint for activity-logging pause from the popup. Keeps track of a running pause timeout
 * which will reset the pause flag in local storage.
 *
 * @return {(number?) => void} A function that allows pause state to be toggled, and optional
 *  specifying of a number of minutes for timeout.
 */
export default function initPauser() {
    const unpause = () => setState(false)
    let timeoutId
    setState(false) // Set default unpaused state in local storage flag

    // Either clears or sets the pause timeout depending on its running state as denoted by local storage flag
    return async timeoutMins => {
        const isPaused = await getState()
        setState(!isPaused) // Immediately toggle the local storage flag and continue on

        timeoutId = isPaused
            ? clearTimeout(timeoutId)
            : setTimeout(unpause, timeoutMins * 60000)
    }
}
<commit_msg>Set up browser/system notifs for pause recording events<commit_after>import { PAUSE_STORAGE_KEY } from '..'

const getNotifOptions = (message, requireInteraction = false) => ({
    type: 'basic',
    iconUrl: '/overview/img/worldbrain-logo-narrow.png',
    title: 'WorldBrain Activity Logger',
    message,
    requireInteraction,
})

const getState = async () => (await browser.storage.local.get(PAUSE_STORAGE_KEY))[PAUSE_STORAGE_KEY] || false
const setState = state => browser.storage.local.set({ [PAUSE_STORAGE_KEY]: state })

/**
 * Main entrypoint for activity-logging pause from the popup. Keeps track of a running pause timeout
 * which will reset the pause flag in local storage.
 *
 * @return {(number?) => void} A function that allows pause state to be toggled, and optional
 *  specifying of a number of minutes for timeout.
 */
export default function initPauser() {
    let timeoutId
    setState(false) // Set default unpaused state in local storage flag

    const unpause = () => {
        browser.notifications.create(getNotifOptions('Activity logger now running in background again', true))
        setState(false)
    }

    // Either clears or sets the pause timeout depending on its running state as denoted by local storage flag
    return async timeoutMins => {
        const isPaused = await getState()
        setState(!isPaused) // Immediately toggle the local storage flag and continue on

        if (isPaused) { // Interrupt
            clearTimeout(timeoutId)
            unpause()
        } else { // New pause timeout request
            browser.notifications.create(getNotifOptions(`Activity logger now paused for ${timeoutMins} mins`))
            timeoutId = setTimeout(unpause, timeoutMins * 60000)
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
 *
 * This file defines routes and helpers for Account Policies.
 * These "policies" match the UFDS sdcAccountPolicy objectclass.
 *
 * Alongside the main routes and a helper to translate from
 * UFDS sdcAccountPolicy to CloudAPI policy, the file also provides
 * a method to selectively preload all of some of the account
 * policies using either the uuids or the names.
 */

var assert = require('assert');
var path = require('path');
var fs = require('fs');
var util = require('util'),
    sprintf = util.format;

var restify = require('restify'),
    MissingParameterError = restify.MissingParameterError,
    InvalidArgumentError = restify.InvalidArgumentError;
var bleedingEdge = require('./bleeding-edge'),
    guard = bleedingEdge.bleedingEdgeGuard;
var resources = require('./resources');
var aperture = require('aperture');
var apertureConfig = require('aperture-config').config;

// --- Globals

var USER_FMT = 'uuid=%s, ou=users, o=smartdc';
var SUB_USER_FMT = 'uuid=%s, ' + USER_FMT;
var POLICY_FMT = 'policy-uuid=%s, ' + USER_FMT;

// --- Helpers

// UFDS to CloudAPI policy
function translatePolicy(policy) {
    if (!policy) {
        return {};
    }

    var r = {
        name: policy.name,
        id: policy.uuid,
        rules: policy.rule,
        description: policy.description
    };

    if (typeof (r.rules) === 'string') {
        r.rules = [r.rules];
    }

    return (r);
}

function parseParams(req) {
    var entry = {};

    entry.name = req.params.name;

    if (req.params.rules) {
        try {
            entry.rule = JSON.parse(req.params.rules);
        } catch (e1) {
            entry.rule = req.params.rules;
        }
    }

    if (req.params.description) {
        entry.description = req.params.description;
    }

    return (entry);
}

function validApertureRules(rules) {
    var parser = aperture.createParser({
        types: aperture.types,
        typeTable: apertureConfig.typeTable
    });

    if (!Array.isArray(rules)) {
        rules = [rules];
    }

    var errs = [];
    rules.forEach(function (r) {
        try {
            parser.parse(r);
        } catch (e) {
            errs.push(e.message);
        }
    });

    if (errs.length) {
        return (errs.join(', '));
    } else {
        return true;
    }
}

// --- Functions

/**
 * Preload (and cache into the request object) the given policies.
 *
 * Returns an Array of CloudAPI -UFDS- policies.
 *
 * @param {Object} req (required) the current request object.
 * @param {Array} names an array of names of the policies to retrieve. This
 *  array can contain either the names, the UUIDs or the DNs of the policies.
 * @param {Object} options optional set of search options. Notably, the
 *  @property {string} options.searchby (optional) must be provided when the
 *  given array of names contains DNs or UUIDs. For these cases, the values of
 *  options.searchby must be, respectively, 'dn' or 'uuid'.
 * @param {Function} cb callback if the form f(err, policies)
 * @throws {TypeError} on bad input.
 */
function preloadPolicies(req, names, options, cb) {
    assert.ok(req.sdc);
    assert.ok(req.account);
    assert.ok(names.length);

    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    // Avoid re-loading already loaded policies
    var cached = [];
    if (!req.cache) {
        req.cache = {};
    }
    if (!req.cache.policies) {
        req.cache.policies = {};
    }

    if (typeof (options) === 'function') {
        cb = options;
        options = {};
    }

    if (!options.searchby) {
        options.searchby = 'name';
    }

    if (options.searchby === 'dn') {
        names = names.map(function (m) {
            /* JSSTYLED */
            var RE = /^policy\-uuid=([^,]+)/;
            var res = RE.exec(m);
            if (res !== null) {
                return (res[1]);
            } else {
                return m;
            }
        });
        options.searchby = 'uuid';
    }

    // Lokup cache here, and skip policies already preloaded:
    names = names.filter(function (n) {
        if (req.cache.policies[n]) {
            cached.push(req.cache.policies[n]);
            return false;
        } else {
            return true;
        }
    });

    // At this point, if we've loaded all the policies we could return:
    if (!names.length) {
        return cb(null, cached);
    }

    var filter;

    if (names.length === 1) {
        filter = '(&(objectclass=sdcaccountpolicy)(' + options.searchby + '=' +
                    names[0] + '))';
    } else {
        filter = '(&(objectclass=sdcaccountpolicy)(|(' + options.searchby +
                    '=' + names.join(')(' + options.searchby + '=') + ')))';
    }

    var opts = {
        scope: 'one',
        filter: filter
    };

    var dn = sprintf(USER_FMT, id);
    return ufds.search(dn, opts, function (err, policies) {
        if (err) {
            cb(err);
        } else {
            policies = policies.map(translatePolicy);
            // Store into cache, just in case we may need them later:
            policies.forEach(function (u) {
                req.cache.policies[u.id] = req.cache.policies[u.name] = u;
            });
            // Finally, if we had already preloaded policies, merge here:
            if (cached.length) {
                policies = policies.concat(cached);
            }
            cb(null, policies);
        }
    });
}

function create(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;
    var errors = [];

    if (!req.params.name) {
        errors.push('name is required');
    }

    if (!req.params.rules) {
        errors.push('rules is required');
    }

    if (errors.length) {
        return next(new MissingParameterError(
                'Request is missing required parameters: ' +
                errors.join(', ')));
    }

    var entry = parseParams(req);
    entry.account = id;

    // Validate the provided rules:
    var validRules = validApertureRules(entry.rule);
    if (validRules !== true) {
        return next(new InvalidArgumentError(validRules));
    }

    return ufds.addPolicy(id, entry, function (err, policy) {
        if (err) {
            log.error({err: err}, 'Create policy error');
            if (err.statusCode === 409 &&
                (err.body.code === 'MissingParameter' ||
                err.body.code === 'InvalidArgument')) {
                return next(err);
            } else {
                return next(new InvalidArgumentError('policy is invalid'));
            }
        }

        policy = translatePolicy(policy);

        if (req.headers['role-tag']) {
            // The resource we want to save is the individual one we've
            // just created, not the collection URI:
            req.resourcename = req.resourcename + '/' + policy.id;
            req.resource = {
                name: req.resourcename,
                account: id,
                roles: []
            };
        }
        res.header('Location', sprintf('/%s/policies/%s',
                                    req.account.login,
                                    encodeURIComponent(policy.id)));

        log.debug('POST %s => %j', req.path(), policy);
        res.send(201, policy);
        return next();
    });
}

function get(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    if (req.accountMgmt) {
        resources.getRoleTags(req, res);
    }

    return ufds.getPolicy(id, req.params.policy, function (err, policy) {
        if (err) {
            return next(err);
        }

        policy = translatePolicy(policy);
        log.debug('GET %s => %j', req.path(), policy);
        res.send(policy);
        return next();
    });
}

function list(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);
    if (req.accountMgmt) {
        resources.getRoleTags(req, res);
    }
    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    return ufds.listPolicies(id, function (err, policies) {
        if (err) {
            return next(err);
        }

        policies = policies.map(translatePolicy);
        log.debug('GET %s => %j', req.path(), policies);
        res.send(policies);
        return next();

    });
}

function update(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    var params = parseParams(req);

    // Validate the provided rules:
    if (req.params.rules) {
        var validRules = validApertureRules(req.params.rules);
        if (validRules !== true) {
            return next(new InvalidArgumentError(validRules));
        }
    }

    return ufds.modifyPolicy(id, req.params.policy, params,
            function (err, policy) {
        if (err) {
            return next(err);
        }

        policy = translatePolicy(policy);
        log.debug('POST %s => %j', req.path(), policy);
        res.send(200, policy);
        return next();
    });
}

function del(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    return ufds.deletePolicy(id, req.params.policy, function (err) {
        if (err) {
            return next(err);
        }

        log.debug('DELETE %s -> ok', req.path());
        res.send(204);
        return next();
    });
}

function mount(server, before, config) {
    assert.argument(server, 'object', server);
    assert.ok(before);
    assert.ok(config);

    server.post({
        path: '/:account/policies',
        name: 'CreatePolicy',
        contentType: [
            'multipart/form-data',
            'application/octet-stream',
            'application/json',
            'text/plain'
        ]
    }, guard(config, 'account_mgmt'), before, create,
    resources.updateResource);

    server.get({
        path: '/:account/policies',
        name: 'ListPolicies'
    }, guard(config, 'account_mgmt'), before, list);

    server.head({
        path: '/:account/policies',
        name: 'HeadPolicies'
    }, guard(config, 'account_mgmt'), before, list);

    server.get({
        path: '/:account/policies/:policy',
        name: 'GetPolicy'
    }, guard(config, 'account_mgmt'), before, get);

    server.head({
        path: '/:account/policies/:policy',
        name: 'HeadPolicy'
    }, guard(config, 'account_mgmt'), before, get);

    server.post({
        path: '/:account/policies/:policy',
        name: 'UpdatePolicy'
    }, guard(config, 'account_mgmt'), before, update,
    resources.updateResource);

    server.del({
        path: '/:account/policies/:policy',
        name: 'DeletePolicy'
    }, guard(config, 'account_mgmt'), before, del,
    resources.deleteResource);

    return server;
}

// --- API

module.exports = {
    mount: mount,
    preloadPolicies: preloadPolicies
};
<commit_msg>PUBAPI-952: Make possible deletion of policy.description by sending an empty description param with the HTTP request<commit_after>/*
 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
 *
 * This file defines routes and helpers for Account Policies.
 * These "policies" match the UFDS sdcAccountPolicy objectclass.
 *
 * Alongside the main routes and a helper to translate from
 * UFDS sdcAccountPolicy to CloudAPI policy, the file also provides
 * a method to selectively preload all of some of the account
 * policies using either the uuids or the names.
 */

var assert = require('assert');
var path = require('path');
var fs = require('fs');
var util = require('util'),
    sprintf = util.format;

var restify = require('restify'),
    MissingParameterError = restify.MissingParameterError,
    InvalidArgumentError = restify.InvalidArgumentError;
var bleedingEdge = require('./bleeding-edge'),
    guard = bleedingEdge.bleedingEdgeGuard;
var resources = require('./resources');
var aperture = require('aperture');
var apertureConfig = require('aperture-config').config;

// --- Globals

var USER_FMT = 'uuid=%s, ou=users, o=smartdc';
var SUB_USER_FMT = 'uuid=%s, ' + USER_FMT;
var POLICY_FMT = 'policy-uuid=%s, ' + USER_FMT;

// --- Helpers

// UFDS to CloudAPI policy
function translatePolicy(policy) {
    if (!policy) {
        return {};
    }

    var r = {
        name: policy.name,
        id: policy.uuid,
        rules: policy.rule,
        description: policy.description
    };

    if (typeof (r.rules) === 'string') {
        r.rules = [r.rules];
    }

    return (r);
}

function parseParams(req) {
    var entry = {};

    entry.name = req.params.name;

    if (req.params.rules) {
        try {
            entry.rule = JSON.parse(req.params.rules);
        } catch (e1) {
            entry.rule = req.params.rules;
        }
    }

    if (typeof (req.params.description) !== 'undefined') {
        entry.description = req.params.description;
    }

    return (entry);
}

function validApertureRules(rules) {
    var parser = aperture.createParser({
        types: aperture.types,
        typeTable: apertureConfig.typeTable
    });

    if (!Array.isArray(rules)) {
        rules = [rules];
    }

    var errs = [];
    rules.forEach(function (r) {
        try {
            parser.parse(r);
        } catch (e) {
            errs.push(e.message);
        }
    });

    if (errs.length) {
        return (errs.join(', '));
    } else {
        return true;
    }
}

// --- Functions

/**
 * Preload (and cache into the request object) the given policies.
 *
 * Returns an Array of CloudAPI -UFDS- policies.
 *
 * @param {Object} req (required) the current request object.
 * @param {Array} names an array of names of the policies to retrieve. This
 *  array can contain either the names, the UUIDs or the DNs of the policies.
 * @param {Object} options optional set of search options. Notably, the
 *  @property {string} options.searchby (optional) must be provided when the
 *  given array of names contains DNs or UUIDs. For these cases, the values of
 *  options.searchby must be, respectively, 'dn' or 'uuid'.
 * @param {Function} cb callback if the form f(err, policies)
 * @throws {TypeError} on bad input.
 */
function preloadPolicies(req, names, options, cb) {
    assert.ok(req.sdc);
    assert.ok(req.account);
    assert.ok(names.length);

    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    // Avoid re-loading already loaded policies
    var cached = [];
    if (!req.cache) {
        req.cache = {};
    }
    if (!req.cache.policies) {
        req.cache.policies = {};
    }

    if (typeof (options) === 'function') {
        cb = options;
        options = {};
    }

    if (!options.searchby) {
        options.searchby = 'name';
    }

    if (options.searchby === 'dn') {
        names = names.map(function (m) {
            /* JSSTYLED */
            var RE = /^policy\-uuid=([^,]+)/;
            var res = RE.exec(m);
            if (res !== null) {
                return (res[1]);
            } else {
                return m;
            }
        });
        options.searchby = 'uuid';
    }

    // Lokup cache here, and skip policies already preloaded:
    names = names.filter(function (n) {
        if (req.cache.policies[n]) {
            cached.push(req.cache.policies[n]);
            return false;
        } else {
            return true;
        }
    });

    // At this point, if we've loaded all the policies we could return:
    if (!names.length) {
        return cb(null, cached);
    }

    var filter;

    if (names.length === 1) {
        filter = '(&(objectclass=sdcaccountpolicy)(' + options.searchby + '=' +
                    names[0] + '))';
    } else {
        filter = '(&(objectclass=sdcaccountpolicy)(|(' + options.searchby +
                    '=' + names.join(')(' + options.searchby + '=') + ')))';
    }

    var opts = {
        scope: 'one',
        filter: filter
    };

    var dn = sprintf(USER_FMT, id);
    return ufds.search(dn, opts, function (err, policies) {
        if (err) {
            cb(err);
        } else {
            policies = policies.map(translatePolicy);
            // Store into cache, just in case we may need them later:
            policies.forEach(function (u) {
                req.cache.policies[u.id] = req.cache.policies[u.name] = u;
            });
            // Finally, if we had already preloaded policies, merge here:
            if (cached.length) {
                policies = policies.concat(cached);
            }
            cb(null, policies);
        }
    });
}

function create(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;
    var errors = [];

    if (!req.params.name) {
        errors.push('name is required');
    }

    if (!req.params.rules) {
        errors.push('rules is required');
    }

    if (errors.length) {
        return next(new MissingParameterError(
                'Request is missing required parameters: ' +
                errors.join(', ')));
    }

    var entry = parseParams(req);
    entry.account = id;

    // Validate the provided rules:
    var validRules = validApertureRules(entry.rule);
    if (validRules !== true) {
        return next(new InvalidArgumentError(validRules));
    }

    return ufds.addPolicy(id, entry, function (err, policy) {
        if (err) {
            log.error({err: err}, 'Create policy error');
            if (err.statusCode === 409 &&
                (err.body.code === 'MissingParameter' ||
                err.body.code === 'InvalidArgument')) {
                return next(err);
            } else {
                return next(new InvalidArgumentError('policy is invalid'));
            }
        }

        policy = translatePolicy(policy);

        if (req.headers['role-tag']) {
            // The resource we want to save is the individual one we've
            // just created, not the collection URI:
            req.resourcename = req.resourcename + '/' + policy.id;
            req.resource = {
                name: req.resourcename,
                account: id,
                roles: []
            };
        }
        res.header('Location', sprintf('/%s/policies/%s',
                                    req.account.login,
                                    encodeURIComponent(policy.id)));

        log.debug('POST %s => %j', req.path(), policy);
        res.send(201, policy);
        return next();
    });
}

function get(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    if (req.accountMgmt) {
        resources.getRoleTags(req, res);
    }

    return ufds.getPolicy(id, req.params.policy, function (err, policy) {
        if (err) {
            return next(err);
        }

        policy = translatePolicy(policy);
        log.debug('GET %s => %j', req.path(), policy);
        res.send(policy);
        return next();
    });
}

function list(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);
    if (req.accountMgmt) {
        resources.getRoleTags(req, res);
    }
    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    return ufds.listPolicies(id, function (err, policies) {
        if (err) {
            return next(err);
        }

        policies = policies.map(translatePolicy);
        log.debug('GET %s => %j', req.path(), policies);
        res.send(policies);
        return next();

    });
}

function update(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    var params = parseParams(req);

    // Validate the provided rules:
    if (req.params.rules) {
        var validRules = validApertureRules(req.params.rules);
        if (validRules !== true) {
            return next(new InvalidArgumentError(validRules));
        }
    }

    if (params.description === '') {
        params.description = null;
    }

    return ufds.modifyPolicy(id, req.params.policy, params,
            function (err, policy) {
        if (err) {
            return next(err);
        }

        policy = translatePolicy(policy);
        log.debug('POST %s => %j', req.path(), policy);
        res.send(200, policy);
        return next();
    });
}

function del(req, res, next) {
    assert.ok(req.sdc);
    assert.ok(req.account);

    var log = req.log;
    var ufds = req.sdc.ufds_master;
    var id = req.account.uuid;

    return ufds.deletePolicy(id, req.params.policy, function (err) {
        if (err) {
            return next(err);
        }

        log.debug('DELETE %s -> ok', req.path());
        res.send(204);
        return next();
    });
}

function mount(server, before, config) {
    assert.argument(server, 'object', server);
    assert.ok(before);
    assert.ok(config);

    server.post({
        path: '/:account/policies',
        name: 'CreatePolicy',
        contentType: [
            'multipart/form-data',
            'application/octet-stream',
            'application/json',
            'text/plain'
        ]
    }, guard(config, 'account_mgmt'), before, create,
    resources.updateResource);

    server.get({
        path: '/:account/policies',
        name: 'ListPolicies'
    }, guard(config, 'account_mgmt'), before, list);

    server.head({
        path: '/:account/policies',
        name: 'HeadPolicies'
    }, guard(config, 'account_mgmt'), before, list);

    server.get({
        path: '/:account/policies/:policy',
        name: 'GetPolicy'
    }, guard(config, 'account_mgmt'), before, get);

    server.head({
        path: '/:account/policies/:policy',
        name: 'HeadPolicy'
    }, guard(config, 'account_mgmt'), before, get);

    server.post({
        path: '/:account/policies/:policy',
        name: 'UpdatePolicy'
    }, guard(config, 'account_mgmt'), before, update,
    resources.updateResource);

    server.del({
        path: '/:account/policies/:policy',
        name: 'DeletePolicy'
    }, guard(config, 'account_mgmt'), before, del,
    resources.deleteResource);

    return server;
}

// --- API

module.exports = {
    mount: mount,
    preloadPolicies: preloadPolicies
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import FlatButton from 'material-ui/FlatButton';
import { FormattedMessage } from 'react-intl';
import styled from 'styled-components';
import config from 'config'; // eslint-disable-line require-path-exists/exists
import DrawerProjects from './drawer/Projects';
import { stringHelper } from '../customHelpers';
import UserMenuItems from './UserMenuItems';
import UserUtil from './user/UserUtil';
import CheckContext from '../CheckContext';
import {
  Row,
  Offset,
  OffsetBothSides,
  HeaderTitle,
  white,
  black05,
  units,
  caption,
  avatarSize,
  avatarStyle,
  proBadgeStyle,
} from '../styles/js/shared';

// TODO Fix a11y issues
/* eslint jsx-a11y/click-events-have-key-events: 0 */
class DrawerNavigation extends Component {
  constructor(props) {
    super(props);

    this.state = {
      showAddProj: false,
    };
  }

  getCurrentUser() {
    return new CheckContext(this).getContextStore().currentUser;
  }

  handleAddProj(e) {
    this.setState({ showAddProj: !this.state.showAddProj });
    e.stopPropagation();
  }

  handleClickUpgrade = () => {
    window.open(stringHelper('UPGRADE_URL'));
  };

  render() {
    const { inTeamContext, loggedIn, drawerToggle } = this.props;

    // This component now renders based on teamPublicFragment
    // and decides whether to include <Project> which has its own team route/relay
    //
    // See DrawerNavigation
    //
    // — @chris with @alex 2017-10-3

    const { currentUserIsMember } = this.props;

    const drawerHeaderHeight = units(14);

    const styles = {
      drawerFooter: {
        display: 'flex',
        alignItems: 'flex-start',
        justifyContent: 'space-between',
        backgroundColor: white,
        padding: `${units(2)}`,
        flexWrap: 'wrap',
      },
      drawerFooterLink: {
        font: caption,
      },
      drawerProjects: {
        overflow: 'auto',
        marginBottom: 'auto',
      },
      drawerProjectsAndFooter: {
        display: 'flex',
        flexDirection: 'column',
      },
    };

    const DrawerHeader = styled.div`
      height: ${drawerHeaderHeight};
      background-color: ${black05};
      padding: ${units(2)};
    `;

    const TeamAvatar = styled.div`
      ${avatarStyle}
      width: ${props => (props.size ? props.size : avatarSize)};
      height: ${props => (props.size ? props.size : avatarSize)};
      position: relative;
      .team__badge {
        ${proBadgeStyle}
      }
    `;

    const TosMenuItem = (

        <FormattedMessage id="headerActions.tos" defaultMessage="Terms" />

    );

    const privacyMenuItem = (

        <FormattedMessage id="headerActions.privacyPolicy" defaultMessage="Privacy" />

    );

    const aboutMenuItem = (

        <FormattedMessage id="headerActions.about" defaultMessage="About" />

    );

    const contactMenuItem = (

        <FormattedMessage id="headerActions.contactHuman" defaultMessage="Contact" />

    );

    const productGuidesMenuItem = (

        <MenuItem
          primaryText={
            <FormattedMessage id="headerActions.productGuides" defaultMessage="Product Guides" />
          }
        />

    );

    const checkLogo = ;

    const userIsOwner =
      loggedIn &&
      inTeamContext &&
      UserUtil.myRole(this.getCurrentUser(), this.props.team.slug) === 'owner';

    const showUpgradeButton =
      userIsOwner &&
      config.appName === 'check' &&
      this.props.team.plan === 'free';

    return (
      <Drawer {...this.props}>

          {inTeamContext ?
            <DrawerHeader>
              <Link
                className="team-header__drawer-team-link"
                style={{ cursor: 'pointer' }}
                to={`/${this.props.team.slug}/`}
              >
                <Row>
                  <TeamAvatar
                    style={{ backgroundImage: `url(${this.props.team.avatar})` }}
                    size={units(7)}
                  >
                    { this.props.team.plan === 'pro' ? PRO : null}
                  </TeamAvatar>
                  <OffsetBothSides>
                    <HeaderTitle>{this.props.team.name}</HeaderTitle>
                  </OffsetBothSides>
                </Row>
              </Link>
            </DrawerHeader> :
            <DrawerHeader>
              <Row style={{ alignItems: 'flex-start', justifyContent: 'space-between' }}>
                <Offset>
                  {loggedIn && checkLogo}
                </Offset>
              </Row>
            </DrawerHeader>}

              {inTeamContext && (currentUserIsMember || !this.props.team.private)
                ? <DrawerProjects
                  team={this.props.team.slug}
                  userIsOwner={userIsOwner}
                  showAddProj={this.state.showAddProj}
                  handleAddProj={this.handleAddProj.bind(this)}
                />
                : null}

            {loggedIn ?
<UserMenuItems hideContactMenuItem {...this.props} />
 : null}

            {productGuidesMenuItem}

            { showUpgradeButton ?
              <FlatButton
                label={
                  <FormattedMessage
                    id="drawer.upgradeButton"
                    defaultMessage="Upgrade to PRO"
                  />
                }
                onClick={this.handleClickUpgrade}
                primary
              /> : null
            }

              {TosMenuItem}
              {privacyMenuItem}
              {aboutMenuItem}
              {contactMenuItem}

      </Drawer>
    );
  }
}

DrawerNavigation.contextTypes = {
  store: PropTypes.object,
};

export default DrawerNavigation;
<commit_msg>#6750 Flex justify content on drawer column<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router';
import Drawer from 'material-ui/Drawer';
import MenuItem from 'material-ui/MenuItem';
import FlatButton from 'material-ui/FlatButton';
import { FormattedMessage } from 'react-intl';
import styled from 'styled-components';
import config from 'config'; // eslint-disable-line require-path-exists/exists
import DrawerProjects from './drawer/Projects';
import { stringHelper } from '../customHelpers';
import UserMenuItems from './UserMenuItems';
import UserUtil from './user/UserUtil';
import CheckContext from '../CheckContext';
import {
  Row,
  Offset,
  OffsetBothSides,
  HeaderTitle,
  white,
  black05,
  units,
  caption,
  avatarSize,
  avatarStyle,
  proBadgeStyle,
} from '../styles/js/shared';

// TODO Fix a11y issues
/* eslint jsx-a11y/click-events-have-key-events: 0 */
class DrawerNavigation extends Component {
  constructor(props) {
    super(props);

    this.state = {
      showAddProj: false,
    };
  }

  getCurrentUser() {
    return new CheckContext(this).getContextStore().currentUser;
  }

  handleAddProj(e) {
    this.setState({ showAddProj: !this.state.showAddProj });
    e.stopPropagation();
  }

  handleClickUpgrade = () => {
    window.open(stringHelper('UPGRADE_URL'));
  };

  render() {
    const { inTeamContext, loggedIn, drawerToggle } = this.props;

    // This component now renders based on teamPublicFragment
    // and decides whether to include <Project> which has its own team route/relay
    //
    // See DrawerNavigation
    //
    // — @chris with @alex 2017-10-3

    const { currentUserIsMember } = this.props;

    const drawerHeaderHeight = units(14);

    const styles = {
      drawerFooter: {
        display: 'flex',
        alignItems: 'flex-start',
        justifyContent: 'space-between',
        backgroundColor: white,
        padding: `${units(2)}`,
        flexWrap: 'wrap',
      },
      drawerFooterLink: {
        font: caption,
      },
      drawerProjects: {
        overflow: 'auto',
        marginBottom: 'auto',
      },
      drawerProjectsAndFooter: {
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'space-between',
        height: `calc(100vh - ${drawerHeaderHeight})`,
      },
    };

    const DrawerHeader = styled.div`
      height: ${drawerHeaderHeight};
      background-color: ${black05};
      padding: ${units(2)};
    `;

    const TeamAvatar = styled.div`
      ${avatarStyle}
      width: ${props => (props.size ? props.size : avatarSize)};
      height: ${props => (props.size ? props.size : avatarSize)};
      position: relative;
      .team__badge {
        ${proBadgeStyle}
      }
    `;

    const TosMenuItem = (

        <FormattedMessage id="headerActions.tos" defaultMessage="Terms" />

    );

    const privacyMenuItem = (

        <FormattedMessage id="headerActions.privacyPolicy" defaultMessage="Privacy" />

    );

    const aboutMenuItem = (

        <FormattedMessage id="headerActions.about" defaultMessage="About" />

    );

    const contactMenuItem = (

        <FormattedMessage id="headerActions.contactHuman" defaultMessage="Contact" />

    );

    const productGuidesMenuItem = (

        <MenuItem
          primaryText={
            <FormattedMessage id="headerActions.productGuides" defaultMessage="Product Guides" />
          }
        />

    );

    const checkLogo = ;

    const userIsOwner =
      loggedIn &&
      inTeamContext &&
      UserUtil.myRole(this.getCurrentUser(), this.props.team.slug) === 'owner';

    const showUpgradeButton =
      userIsOwner &&
      config.appName === 'check' &&
      this.props.team.plan === 'free';

    return (
      <Drawer {...this.props}>

          {inTeamContext ?
            <DrawerHeader>
              <Link
                className="team-header__drawer-team-link"
                style={{ cursor: 'pointer' }}
                to={`/${this.props.team.slug}/`}
              >
                <Row>
                  <TeamAvatar
                    style={{ backgroundImage: `url(${this.props.team.avatar})` }}
                    size={units(7)}
                  >
                    { this.props.team.plan === 'pro' ? PRO : null}
                  </TeamAvatar>
                  <OffsetBothSides>
                    <HeaderTitle>{this.props.team.name}</HeaderTitle>
                  </OffsetBothSides>
                </Row>
              </Link>
            </DrawerHeader> :
            <DrawerHeader>
              <Row style={{ alignItems: 'flex-start', justifyContent: 'space-between' }}>
                <Offset>
                  {loggedIn && checkLogo}
                </Offset>
              </Row>
            </DrawerHeader>}

              {inTeamContext && (currentUserIsMember || !this.props.team.private)
                ? <DrawerProjects
                  team={this.props.team.slug}
                  userIsOwner={userIsOwner}
                  showAddProj={this.state.showAddProj}
                  handleAddProj={this.handleAddProj.bind(this)}
                />
                : null}

              {loggedIn ?
<UserMenuItems hideContactMenuItem {...this.props} />
 : null}

              {productGuidesMenuItem}

              {showUpgradeButton ?
                <FlatButton
                  label={
                    <FormattedMessage
                      id="drawer.upgradeButton"
                      defaultMessage="Upgrade to PRO"
                    />
                  }
                  onClick={this.handleClickUpgrade}
                  primary
                  fullWidth
                /> : null
              }

                {TosMenuItem}
                {privacyMenuItem}
                {aboutMenuItem}
                {contactMenuItem}

      </Drawer>
    );
  }
}

DrawerNavigation.contextTypes = {
  store: PropTypes.object,
};

export default DrawerNavigation;
<|endoftext|>