<commit_before>import _ from 'messages'
import * as complexMatcher from 'complex-matcher'
import ActionButton from 'action-button'
import ceil from 'lodash/ceil'
import debounce from 'lodash/debounce'
import Ellipsis, { EllipsisContainer } from 'ellipsis'
import forEach from 'lodash/forEach'
import Icon from 'icon'
import isEmpty from 'lodash/isEmpty'
import keys from 'lodash/keys'
import map from 'lodash/map'
import size from 'lodash/size'
import Tags from 'tags'
import Tooltip from 'tooltip'
import React, { Component } from 'react'
import {
  addTag,
  editVm,
  migrateVm,
  migrateVms,
  removeTag,
  restartVms,
  startVm,
  startVms,
  stopVm,
  stopVms
} from 'xo'
import { Link } from 'react-router'
import { Row, Col } from 'grid'
import { Text, Select } from 'editable'
import {
  SelectHost,
  SelectPool,
  SelectTag
} from 'select-objects'
import {
  BlockLink,
  connectStore,
  formatSize,
  invoke,
  osFamily
} from 'utils'
import {
  createFilter,
  createGetObject,
  createSort,
  createPager,
  createSelector,
  hosts,
  pools,
  tags,
  vms
} from 'selectors'

import {
  Button,
  DropdownButton,
  MenuItem,
  OverlayTrigger,
  Pagination,
  Popover
} from 'react-bootstrap-4/lib'

import styles from './index.css'

@connectStore({
  container: createGetObject((state, props) => props.vm.$container)
})
class VmItem extends Component {
  componentWillMount () {
    this.setState({ collapsed: true })
  }

  _addTag = tag => addTag(this.props.vm.id, tag)
  _isRunning = vm => vm && vm.power_state === 'Running'
  _migrateVm = host => migrateVm(this.props.vm, host)
  _removeTag = tag => removeTag(this.props.vm.id, tag)
  _setNameDescription = nameDescription => editVm(this.props.vm, { name_description: nameDescription })
  _setNameLabel = nameLabel => editVm(this.props.vm, { name_label: nameLabel })
  _start = () => startVm(this.props.vm)
  _stop = () => stopVm(this.props.vm)
  _toggleCollapse = () => this.setState({ collapsed: !this.state.collapsed })
  _onSelect = () => this.props.onSelect(this.props.vm.id)

  render () {
    const { vm, container, expandAll, selected, hosts } = this.props
    return

      <BlockLink to={`/vms/${vm.id}`}>
        <Row>
          <Col smallSize={10} mediumSize={9} largeSize={5}>
            <EllipsisContainer>
              <input type='checkbox' checked={selected} onChange={this._onSelect} value={vm.id} />

              <Tooltip
                content={isEmpty(vm.current_operations)
                  ? _(`powerState${vm.power_state}`)
                  :
{_(`powerState${vm.power_state}`)}{' ('}{map(vm.current_operations)[0]}{')'}

                }
              >
                {isEmpty(vm.current_operations)
                  ? <Icon icon={`${vm.power_state.toLowerCase()}`} />
                  : <Icon icon='busy' />
                }
              </Tooltip>

              <Ellipsis>
                <Text onChange={this._setNameLabel} placeholder={_('vmHomeNamePlaceholder')} useLongClick>
                  {vm.name_label}
                </Text>
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={4} className='hidden-md-down'>
            <EllipsisContainer>

                {this._isRunning(vm)
                  ?
                    <Tooltip content={_('stopVmLabel')}>

                        <Icon icon='vm-stop' size='1' />

                    </Tooltip>

                  :
                    <Tooltip content={_('startVmLabel')}>

                        <Icon icon='vm-start' size='1' />

                    </Tooltip>

                }

              <Icon icon={vm.os_version && vm.os_version.distro && osFamily(vm.os_version.distro)} fixedWidth />

              <Ellipsis>
                <Text onChange={this._setNameDescription} placeholder={_('vmHomeDescriptionPlaceholder')} useLongClick>
                  {vm.name_description}
                </Text>
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={2} className='hidden-sm-down'>
            <EllipsisContainer>
              <Ellipsis>
                {this._isRunning(vm)
                  ? <Select onChange={this._migrateVm} options={hosts} labelProp='name_label' defaultValue={container} useLongClick>
                    <Link to={`/${container.type}s/${container.id}`}>{container.name_label}</Link>
                  </Select>
                  : <Link to={`/${container.type}s/${container.id}`}>{container.name_label}</Link>
                }
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={1} className={styles.itemExpandRow}>

              <Icon icon='nav' fixedWidth />

          </Col>
        </Row>
      </BlockLink>
      {!this.state.collapsed || expandAll
        ? <Row>
          <Col mediumSize={4} className={styles.itemExpanded}>

              {vm.CPUs.number}x <Icon icon='cpu' />
              {formatSize(vm.memory.size)} <Icon icon='memory' />
              {isEmpty(vm.snapshots)
                ? null
                : {vm.snapshots.length}x <Icon icon='vm-snapshot' />
              }
              {vm.docker ? <Icon icon='vm-docker' /> : null}

          </Col>
          <Col largeSize={4} className={styles.itemExpanded}>
            {map(vm.addresses, address => {address})}
          </Col>
          <Col mediumSize={4}>

              <Tags labels={vm.tags} onDelete={this._removeTag} onAdd={this._addTag} />

          </Col>
        </Row>
        : null
      }

  }
}

const VMS_PER_PAGE = 20

@connectStore({
  pools,
  hosts,
  vms,
  tags
})
export default class Home extends Component {
  static contextTypes = {
    router: React.PropTypes.object
  }

  constructor (props) {
    super(props)

    this.state = {
      activePage: 1,
      displayActions: false,
      expandAll: false,
      sortBy: 'name_label',
      sortOrder: 'asc'
    }

    this.getFilteredVms = createSort(
      createFilter(
        () => this.props.vms,
        createSelector(
          () => this.filter || '',
          complexMatcher.create
        ),
        true
      ),
      () => this.state.sortBy,
      () => this.state.sortOrder
    )

    this.getCurrentPageVms = createPager(
      this.getFilteredVms,
      () => this.state.activePage,
      VMS_PER_PAGE
    )

    this._isSelected = {}
  }

  get filter () {
    return this.props.location.query.s
  }
  set filter (value) {
    this.context.router.push({
      ...this.props.location,
      query: { s: value }
    })
    this.page = 1
    this._selectAllVms(false)
  }

  get page () {
    return this.state.page
  }
  set page (activePage) {
    this.setState({ activePage })
  }

  componentWillMount () {
    if (this.filter == null) {
      this.filter = 'power_state:running '
    }
  }

  // Filter
  _onFilterChange = invoke(
    debounce(filter => { this.filter = filter }, 500),
    setFilter => event => setFilter(event.target.value)
  )
  setFilter (filter) {
    this.refs.filter.value = filter
    this.refs.filter.focus()
    this.filter = filter
  }

  _expandAll = () => this.setState({ expandAll: !this.state.expandAll })

  _filterBusy = () => this.setFilter('current_operations:"" ')
  _filterHalted = () => this.setFilter('!power_state:running ')
  _filterHvm = () => this.setFilter('virtualizationMode:hvm ')
  _filterNone = () => this.setFilter('')
  _filterRunning = () => this.setFilter('power_state:running ')
  _filterTags = () => this.setFilter('tags:')

  _onPageSelection = (_, event) => { this.page = event.eventKey }

  _sortByName = () => this.setState({ sortBy: 'name_label', sortOrder: 'asc' })
  _sortByPowerState = () => this.setState({ sortBy: 'power_state', sortOrder: 'desc' })
  _sortByRam = () => this.setState({ sortBy: 'memory.size', sortOrder: 'desc' })
  _sortByVcpus = () => this.setState({ sortBy: 'CPUs.number', sortOrder: 'desc' })

  _updateSelectedPools = pools => { this.setState({ selectedPools: pools }) }
  _updateSelectedHosts = hosts => { this.setState({ selectedHosts: hosts }) }
  _updateSelectedTags = tags => { this.setState({ selectedTags: tags }) }

  // Checkboxes
  _updateMasterCheckbox () {
    const masterCheckbox = this.refs.masterCheckbox
    if (!masterCheckbox) {
      return
    }
    const noneChecked = isEmpty(this._isSelected)
    masterCheckbox.checked = !noneChecked
    masterCheckbox.indeterminate = !noneChecked && size(this._isSelected) !== this.getFilteredVms().length
    this.setState({ displayActions: !noneChecked })
  }
  _selectVm = (id, checked) => {
    const shouldBeChecked = checked === undefined ? !this._isSelected[id] : checked
    shouldBeChecked ? this._isSelected[id] = true : delete this._isSelected[id]
    this.forceUpdate()
    this._updateMasterCheckbox()
  }
  _selectAllVms = (checked) => {
    const shouldBeChecked = checked === undefined ? !size(this._isSelected) : checked
    this._isSelected = {}
    forEach(this.getFilteredVms(), vm => {
      shouldBeChecked && (this._isSelected[vm.id] = true)
    })
    this.forceUpdate()
    this._updateMasterCheckbox()
  }

  render () {
    const { vms } = this.props
    if (isEmpty(vms)) {
      return
There are no VMs

    }

    const { pools, hosts, tags } = this.props
    const { activePage } = this.state
    const filteredVms = this.getFilteredVms()
    const currentPageVms = this.getCurrentPageVms()
    return

      <Row className={styles.itemRowHeader}>
        <Col mediumSize={6}>

              <DropdownButton id='filter' bsStyle='secondary' title={_('homeFilters')}>
                <MenuItem onClick={this._filterRunning}>
                  {_('homeFilterRunningVms')}
                </MenuItem>
                <MenuItem onClick={this._filterHalted}>
                  {_('homeFilterNonRunningVms')}
                </MenuItem>
                <MenuItem onClick={this._filterBusy}>
                  {_('homeFilterPendingVms')}
                </MenuItem>
                <MenuItem onClick={this._filterHvm}>
                  {_('homeFilterHvmGuests')}
                </MenuItem>
                <MenuItem onClick={this._filterTags}>
                  {_('homeFilterTags')}
                </MenuItem>
              </DropdownButton>

            <input
              autoFocus
              className='form-control'
              defaultValue={this.filter}
              onChange={this._onFilterChange}
              ref='filter'
              type='text'
            />

              <button
                className='btn btn-secondary'
                onClick={this._filterNone}>
                <Icon icon='clear-search' />
              </button>

        </Col>
        <Col mediumSize={6} className='text-xs-right'>
          <Link
            className='btn btn-success'
            to='/new/vm'>
            <Icon icon='vm-new' /> {_('homeNewVm')}
          </Link>
        </Col>
      </Row>

        <Row className={styles.itemContainerHeader}>
          <Col smallsize={11} mediumSize={3}>
            <input type='checkbox' onChange={() => this._selectAllVms()} ref='masterCheckbox' />

              {size(this._isSelected)
                ? _('homeSelectedVms', { selected: size(this._isSelected), total: vms.length, vmIcon: <Icon icon='vm' /> })
                : _('homeDisplayedVms', { displayed: filteredVms.length, total: vms.length, vmIcon: <Icon icon='vm' /> })
              }

          </Col>
          <Col mediumSize={8} className='text-xs-right hidden-sm-down'>
          {this.state.displayActions
            ?

              <ActionButton btnStyle='secondary' handler={stopVms} handlerParam={keys(this._isSelected)} icon='vm-stop' />
              <ActionButton btnStyle='secondary' handler={startVms} handlerParam={keys(this._isSelected)} icon='vm-start' />
              <ActionButton btnStyle='secondary' handler={restartVms} handlerParam={keys(this._isSelected)} icon='vm-reboot' />
              <ActionButton btnStyle='secondary' handler={migrateVms} handlerParam={keys(this._isSelected)} icon='vm-migrate' />

            :

              {pools.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='poolPopover'>
                      <SelectPool
                        multi
                        options={pools}
                        onChange={this._updateSelectedPools}
                        value={this.state.selectedPools}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='pool' /> {_('homeAllPools')} ({pools.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              {hosts.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='HostPopover'>
                      <SelectHost
                        multi
                        options={hosts}
                        onChange={this._updateSelectedHosts}
                        value={this.state.selectedHosts}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='host' /> {_('homeAllHosts')} ({hosts.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              {tags.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='tagPopover'>
                      <SelectTag
                        multi
                        options={tags}
                        onChange={this._updateSelectedTags}
                        value={this.state.selectedTags}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='tags' /> {_('homeAllTags')} ({tags.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              <DropdownButton bsStyle='link' id='sort' title={_('homeSortBy')}>
                <MenuItem onClick={this._sortByName}>
                  {_('homeSortByName')}
                </MenuItem>
                <MenuItem onClick={this._sortByPowerState}>
                  {_('homeSortByPowerstate')}
                </MenuItem>
                <MenuItem onClick={this._sortByRam}>
                  {_('homeSortByRAM')}
                </MenuItem>
                <MenuItem onClick={this._sortByVcpus}>
                  {_('homeSortByvCPUs')}
                </MenuItem>
              </DropdownButton>

          }
          </Col>
          <Col smallsize={1} mediumSize={1} className='text-xs-right'>
            <button className='btn btn-secondary'
              onClick={this._expandAll}>
              <Icon icon='nav' />
            </button>
          </Col>
        </Row>
        {map(currentPageVms, vm =>
          <VmItem vm={vm} key={vm.id} expandAll={this.state.expandAll} onSelect={this._selectVm} selected={this._isSelected[vm.id]} hosts={hosts} />
        )}

      {filteredVms.length > VMS_PER_PAGE && <Row>

            <Pagination
              first
              last
              prev
              next
              ellipsis
              boundaryLinks
              maxButtons={5}
              items={ceil(filteredVms.length / VMS_PER_PAGE)}
              activePage={activePage}
              onSelect={this._onPageSelection} />

      </Row>}

  }
}
<commit_msg>style(home): remove double line breaks<commit_after>import _ from 'messages'
import * as complexMatcher from 'complex-matcher'
import ActionButton from 'action-button'
import ceil from 'lodash/ceil'
import debounce from 'lodash/debounce'
import Ellipsis, { EllipsisContainer } from 'ellipsis'
import forEach from 'lodash/forEach'
import Icon from 'icon'
import isEmpty from 'lodash/isEmpty'
import keys from 'lodash/keys'
import map from 'lodash/map'
import size from 'lodash/size'
import Tags from 'tags'
import Tooltip from 'tooltip'
import React, { Component } from 'react'
import {
  addTag,
  editVm,
  migrateVm,
  migrateVms,
  removeTag,
  restartVms,
  startVm,
  startVms,
  stopVm,
  stopVms
} from 'xo'
import { Link } from 'react-router'
import { Row, Col } from 'grid'
import { Text, Select } from 'editable'
import {
  SelectHost,
  SelectPool,
  SelectTag
} from 'select-objects'
import {
  BlockLink,
  connectStore,
  formatSize,
  invoke,
  osFamily
} from 'utils'
import {
  createFilter,
  createGetObject,
  createSort,
  createPager,
  createSelector,
  hosts,
  pools,
  tags,
  vms
} from 'selectors'

import {
  Button,
  DropdownButton,
  MenuItem,
  OverlayTrigger,
  Pagination,
  Popover
} from 'react-bootstrap-4/lib'

import styles from './index.css'

@connectStore({
  container: createGetObject((state, props) => props.vm.$container)
})
class VmItem extends Component {
  componentWillMount () {
    this.setState({ collapsed: true })
  }

  _addTag = tag => addTag(this.props.vm.id, tag)
  _isRunning = vm => vm && vm.power_state === 'Running'
  _migrateVm = host => migrateVm(this.props.vm, host)
  _removeTag = tag => removeTag(this.props.vm.id, tag)
  _setNameDescription = nameDescription => editVm(this.props.vm, { name_description: nameDescription })
  _setNameLabel = nameLabel => editVm(this.props.vm, { name_label: nameLabel })
  _start = () => startVm(this.props.vm)
  _stop = () => stopVm(this.props.vm)
  _toggleCollapse = () => this.setState({ collapsed: !this.state.collapsed })
  _onSelect = () => this.props.onSelect(this.props.vm.id)

  render () {
    const { vm, container, expandAll, selected, hosts } = this.props
    return

      <BlockLink to={`/vms/${vm.id}`}>
        <Row>
          <Col smallSize={10} mediumSize={9} largeSize={5}>
            <EllipsisContainer>
              <input type='checkbox' checked={selected} onChange={this._onSelect} value={vm.id} />

              <Tooltip
                content={isEmpty(vm.current_operations)
                  ? _(`powerState${vm.power_state}`)
                  :
{_(`powerState${vm.power_state}`)}{' ('}{map(vm.current_operations)[0]}{')'}

                }
              >
                {isEmpty(vm.current_operations)
                  ? <Icon icon={`${vm.power_state.toLowerCase()}`} />
                  : <Icon icon='busy' />
                }
              </Tooltip>

              <Ellipsis>
                <Text onChange={this._setNameLabel} placeholder={_('vmHomeNamePlaceholder')} useLongClick>
                  {vm.name_label}
                </Text>
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={4} className='hidden-md-down'>
            <EllipsisContainer>

                {this._isRunning(vm)
                  ?
                    <Tooltip content={_('stopVmLabel')}>

                        <Icon icon='vm-stop' size='1' />

                    </Tooltip>

                  :
                    <Tooltip content={_('startVmLabel')}>

                        <Icon icon='vm-start' size='1' />

                    </Tooltip>

                }

              <Icon icon={vm.os_version && vm.os_version.distro && osFamily(vm.os_version.distro)} fixedWidth />

              <Ellipsis>
                <Text onChange={this._setNameDescription} placeholder={_('vmHomeDescriptionPlaceholder')} useLongClick>
                  {vm.name_description}
                </Text>
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={2} className='hidden-sm-down'>
            <EllipsisContainer>
              <Ellipsis>
                {this._isRunning(vm)
                  ? <Select onChange={this._migrateVm} options={hosts} labelProp='name_label' defaultValue={container} useLongClick>
                    <Link to={`/${container.type}s/${container.id}`}>{container.name_label}</Link>
                  </Select>
                  : <Link to={`/${container.type}s/${container.id}`}>{container.name_label}</Link>
                }
              </Ellipsis>
            </EllipsisContainer>
          </Col>
          <Col mediumSize={1} className={styles.itemExpandRow}>

              <Icon icon='nav' fixedWidth />

          </Col>
        </Row>
      </BlockLink>
      {!this.state.collapsed || expandAll
        ? <Row>
          <Col mediumSize={4} className={styles.itemExpanded}>

              {vm.CPUs.number}x <Icon icon='cpu' />
              {formatSize(vm.memory.size)} <Icon icon='memory' />
              {isEmpty(vm.snapshots)
                ? null
                : {vm.snapshots.length}x <Icon icon='vm-snapshot' />
              }
              {vm.docker ? <Icon icon='vm-docker' /> : null}

          </Col>
          <Col largeSize={4} className={styles.itemExpanded}>
            {map(vm.addresses, address => {address})}
          </Col>
          <Col mediumSize={4}>

              <Tags labels={vm.tags} onDelete={this._removeTag} onAdd={this._addTag} />

          </Col>
        </Row>
        : null
      }

  }
}

const VMS_PER_PAGE = 20

@connectStore({
  pools,
  hosts,
  vms,
  tags
})
export default class Home extends Component {
  static contextTypes = {
    router: React.PropTypes.object
  }

  constructor (props) {
    super(props)

    this.state = {
      activePage: 1,
      displayActions: false,
      expandAll: false,
      sortBy: 'name_label',
      sortOrder: 'asc'
    }

    this.getFilteredVms = createSort(
      createFilter(
        () => this.props.vms,
        createSelector(
          () => this.filter || '',
          complexMatcher.create
        ),
        true
      ),
      () => this.state.sortBy,
      () => this.state.sortOrder
    )

    this.getCurrentPageVms = createPager(
      this.getFilteredVms,
      () => this.state.activePage,
      VMS_PER_PAGE
    )

    this._isSelected = {}
  }

  get filter () {
    return this.props.location.query.s
  }
  set filter (value) {
    this.context.router.push({
      ...this.props.location,
      query: { s: value }
    })
    this.page = 1
    this._selectAllVms(false)
  }

  get page () {
    return this.state.page
  }
  set page (activePage) {
    this.setState({ activePage })
  }

  componentWillMount () {
    if (this.filter == null) {
      this.filter = 'power_state:running '
    }
  }

  // Filter
  _onFilterChange = invoke(
    debounce(filter => { this.filter = filter }, 500),
    setFilter => event => setFilter(event.target.value)
  )
  setFilter (filter) {
    this.refs.filter.value = filter
    this.refs.filter.focus()
    this.filter = filter
  }

  _expandAll = () => this.setState({ expandAll: !this.state.expandAll })

  _filterBusy = () => this.setFilter('current_operations:"" ')
  _filterHalted = () => this.setFilter('!power_state:running ')
  _filterHvm = () => this.setFilter('virtualizationMode:hvm ')
  _filterNone = () => this.setFilter('')
  _filterRunning = () => this.setFilter('power_state:running ')
  _filterTags = () => this.setFilter('tags:')

  _onPageSelection = (_, event) => { this.page = event.eventKey }

  _sortByName = () => this.setState({ sortBy: 'name_label', sortOrder: 'asc' })
  _sortByPowerState = () => this.setState({ sortBy: 'power_state', sortOrder: 'desc' })
  _sortByRam = () => this.setState({ sortBy: 'memory.size', sortOrder: 'desc' })
  _sortByVcpus = () => this.setState({ sortBy: 'CPUs.number', sortOrder: 'desc' })

  _updateSelectedPools = pools => { this.setState({ selectedPools: pools }) }
  _updateSelectedHosts = hosts => { this.setState({ selectedHosts: hosts }) }
  _updateSelectedTags = tags => { this.setState({ selectedTags: tags }) }

  // Checkboxes
  _updateMasterCheckbox () {
    const masterCheckbox = this.refs.masterCheckbox
    if (!masterCheckbox) {
      return
    }
    const noneChecked = isEmpty(this._isSelected)
    masterCheckbox.checked = !noneChecked
    masterCheckbox.indeterminate = !noneChecked && size(this._isSelected) !== this.getFilteredVms().length
    this.setState({ displayActions: !noneChecked })
  }
  _selectVm = (id, checked) => {
    const shouldBeChecked = checked === undefined ? !this._isSelected[id] : checked
    shouldBeChecked ? this._isSelected[id] = true : delete this._isSelected[id]
    this.forceUpdate()
    this._updateMasterCheckbox()
  }
  _selectAllVms = (checked) => {
    const shouldBeChecked = checked === undefined ? !size(this._isSelected) : checked
    this._isSelected = {}
    forEach(this.getFilteredVms(), vm => {
      shouldBeChecked && (this._isSelected[vm.id] = true)
    })
    this.forceUpdate()
    this._updateMasterCheckbox()
  }

  render () {
    const { vms } = this.props
    if (isEmpty(vms)) {
      return
There are no VMs

    }

    const { pools, hosts, tags } = this.props
    const { activePage } = this.state
    const filteredVms = this.getFilteredVms()
    const currentPageVms = this.getCurrentPageVms()
    return

      <Row className={styles.itemRowHeader}>
        <Col mediumSize={6}>

              <DropdownButton id='filter' bsStyle='secondary' title={_('homeFilters')}>
                <MenuItem onClick={this._filterRunning}>
                  {_('homeFilterRunningVms')}
                </MenuItem>
                <MenuItem onClick={this._filterHalted}>
                  {_('homeFilterNonRunningVms')}
                </MenuItem>
                <MenuItem onClick={this._filterBusy}>
                  {_('homeFilterPendingVms')}
                </MenuItem>
                <MenuItem onClick={this._filterHvm}>
                  {_('homeFilterHvmGuests')}
                </MenuItem>
                <MenuItem onClick={this._filterTags}>
                  {_('homeFilterTags')}
                </MenuItem>
              </DropdownButton>

            <input
              autoFocus
              className='form-control'
              defaultValue={this.filter}
              onChange={this._onFilterChange}
              ref='filter'
              type='text'
            />

              <button
                className='btn btn-secondary'
                onClick={this._filterNone}>
                <Icon icon='clear-search' />
              </button>

        </Col>
        <Col mediumSize={6} className='text-xs-right'>
          <Link
            className='btn btn-success'
            to='/new/vm'>
            <Icon icon='vm-new' /> {_('homeNewVm')}
          </Link>
        </Col>
      </Row>

        <Row className={styles.itemContainerHeader}>
          <Col smallsize={11} mediumSize={3}>
            <input type='checkbox' onChange={() => this._selectAllVms()} ref='masterCheckbox' />

              {size(this._isSelected)
                ? _('homeSelectedVms', { selected: size(this._isSelected), total: vms.length, vmIcon: <Icon icon='vm' /> })
                : _('homeDisplayedVms', { displayed: filteredVms.length, total: vms.length, vmIcon: <Icon icon='vm' /> })
              }

          </Col>
          <Col mediumSize={8} className='text-xs-right hidden-sm-down'>
          {this.state.displayActions
            ?

              <ActionButton btnStyle='secondary' handler={stopVms} handlerParam={keys(this._isSelected)} icon='vm-stop' />
              <ActionButton btnStyle='secondary' handler={startVms} handlerParam={keys(this._isSelected)} icon='vm-start' />
              <ActionButton btnStyle='secondary' handler={restartVms} handlerParam={keys(this._isSelected)} icon='vm-reboot' />
              <ActionButton btnStyle='secondary' handler={migrateVms} handlerParam={keys(this._isSelected)} icon='vm-migrate' />

            :

              {pools.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='poolPopover'>
                      <SelectPool
                        multi
                        options={pools}
                        onChange={this._updateSelectedPools}
                        value={this.state.selectedPools}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='pool' /> {_('homeAllPools')} ({pools.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              {hosts.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='HostPopover'>
                      <SelectHost
                        multi
                        options={hosts}
                        onChange={this._updateSelectedHosts}
                        value={this.state.selectedHosts}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='host' /> {_('homeAllHosts')} ({hosts.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              {tags.length
               ? (
                <OverlayTrigger
                  trigger='click'
                  rootClose
                  placement='bottom'
                  overlay={
                    <Popover className={styles.selectObject} id='tagPopover'>
                      <SelectTag
                        multi
                        options={tags}
                        onChange={this._updateSelectedTags}
                        value={this.state.selectedTags}
                      />
                    </Popover>
                  }
                >
                  <Button className='btn-link'><Icon icon='tags' /> {_('homeAllTags')} ({tags.length})</Button>
                </OverlayTrigger>
               ) : null
              }

              <DropdownButton bsStyle='link' id='sort' title={_('homeSortBy')}>
                <MenuItem onClick={this._sortByName}>
                  {_('homeSortByName')}
                </MenuItem>
                <MenuItem onClick={this._sortByPowerState}>
                  {_('homeSortByPowerstate')}
                </MenuItem>
                <MenuItem onClick={this._sortByRam}>
                  {_('homeSortByRAM')}
                </MenuItem>
                <MenuItem onClick={this._sortByVcpus}>
                  {_('homeSortByvCPUs')}
                </MenuItem>
              </DropdownButton>

          }
          </Col>
          <Col smallsize={1} mediumSize={1} className='text-xs-right'>
            <button className='btn btn-secondary'
              onClick={this._expandAll}>
              <Icon icon='nav' />
            </button>
          </Col>
        </Row>
        {map(currentPageVms, vm =>
          <VmItem vm={vm} key={vm.id} expandAll={this.state.expandAll} onSelect={this._selectVm} selected={this._isSelected[vm.id]} hosts={hosts} />
        )}

      {filteredVms.length > VMS_PER_PAGE && <Row>

            <Pagination
              first
              last
              prev
              next
              ellipsis
              boundaryLinks
              maxButtons={5}
              items={ceil(filteredVms.length / VMS_PER_PAGE)}
              activePage={activePage}
              onSelect={this._onPageSelection} />

      </Row>}

  }
}
<|endoftext|>


<commit_before>'user strict';

var config = require('./config/config'),
   express = require('express'),
bodyParser = require('body-parser'),
   request = require("request"),
       app = express(),
  slackSvc = require('./services/slack'),
      cors = require('cors'),
      firebaseSvc = require('./services/firebase');

var corsOptions = {
  origin: [ 'http://127.0.0.1:8081'
    ,'http://127.0.0.1'
    ,'http://localhost'
  ]
};

app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

app.get('/', function (req, res){
  res.send('Hello World!');
});

app.get('/members', cors(corsOptions), function (req, res){
  var respond = function(members){
    res.send(members);
  }

  slackSvc.getSlackMembers(respond);
});

app.get('/set_members', function(req,res){
  var respond = function(){
    res.send('Members Saved!');
  }

  slackSvc.setSlackMembers(channelId,respond);
});

app.post('/new_message', function (req, res){
  //console.log(req.body);

  if (slackSvc.checkToken(req.body.token)){
    var payload = {
      room:  req.body.channel_name,
      token: req.body.token,
      userId: req.body.user_id,
      message: req.body.text,
      username: req.body.user_name,
      timestamp: req.body.timestamp
    }

    if (payload.message == ''){
      return res.send('No message provided');
    }

    slackSvc.getUserProfile(payload,firebaseSvc.pushToFirebase);

    res.send('success');
  } else {
    res.send('Token is incorrect');
  }

});

var server = app.listen(3002, function (){
  var host = server.address().address;
  var port = server.address().port;

  slackSvc.setSlackMembers('',function(){});
  console.log('Example app listening at http://%s:%s', host, port);
})
<commit_msg>Adds other ports to configuration (testing)<commit_after>'user strict';

var config = require('./config/config'),
   express = require('express'),
bodyParser = require('body-parser'),
   request = require("request"),
       app = express(),
  slackSvc = require('./services/slack'),
      cors = require('cors'),
      firebaseSvc = require('./services/firebase');

var corsOptions = {
  origin: [
     'http://127.0.0.1:8081'
    ,'http://127.0.0.1:8080'
    ,'http://localhost'
    ,'http://localhost:8080'
  ]
};

app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

app.get('/', function (req, res){
  res.send('Hello World!');
});

app.get('/members', cors(corsOptions), function (req, res){
  var respond = function(members){
    res.send(members);
  }

  slackSvc.getSlackMembers(respond);
});

app.get('/set_members', function(req,res){
  var respond = function(){
    res.send('Members Saved!');
  }

  slackSvc.setSlackMembers(channelId,respond);
});

app.post('/new_message', function (req, res){
  //console.log(req.body);

  if (slackSvc.checkToken(req.body.token)){
    var payload = {
      room:  req.body.channel_name,
      token: req.body.token,
      userId: req.body.user_id,
      message: req.body.text,
      username: req.body.user_name,
      timestamp: req.body.timestamp
    }

    if (payload.message == ''){
      return res.send('No message provided');
    }

    slackSvc.getUserProfile(payload,firebaseSvc.pushToFirebase);

    res.send('success');
  } else {
    res.send('Token is incorrect');
  }

});

var server = app.listen(3002, function (){
  var host = server.address().address;
  var port = server.address().port;

  slackSvc.setSlackMembers('',function(){});
  console.log('Example app listening at http://%s:%s', host, port);
})
<|endoftext|>


<commit_before>/*
 * Copyright 2017 Redlink GmbH
 *
 * 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.
 *
 */
var conversation = 'conversations',
    configuration = 'configuration',
    client = 'client';

// create all clients
db.getCollection(conversation).aggregate([
    { $project: { _id: '$context.domain' } },
    { $group: { _id: '$_id'}},
    { $project: {
        _id: { $literal: new ObjectId() },
        name: '$_id',
        lastUpdate: { $literal: ISODate() },
        defaultClient: { $literal: false }
    } },
    { $out: client}
]);
db.getCollection(client).find().forEach(function(c) {
    db.getCollection(conversation).update(
        { 'context.domain': c.name },
        { $set: { owner: c._id }},
        { multi: true }
    );
    db.getCollection(configuration).update(
        { client: c._id },
        { $setOnInsert: {
            created: new ISODate(),
            modified: new ISODate(),
            config: {
                // TODO(westei): add default config here!
            }
        }},
        { upsert: true }
    );
});
<commit_msg>Issue #56: Added a default configuration for Clients created by the `0.3 > 0.5` migration script<commit_after>/*
 * Copyright 2017 Redlink GmbH
 *
 * 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.
 *
 */
var conversation = 'conversations',
    configuration = 'configuration',
    client = 'client';

// create all clients
db.getCollection(conversation).aggregate([
    { $project: { _id: '$context.domain' } },
    { $group: { _id: '$_id'}},
    { $project: {
        _id: { $literal: new ObjectId() },
        name: '$_id',
        lastUpdate: { $literal: ISODate() },
        defaultClient: { $literal: false }
    } },
    { $out: client}
]);
db.getCollection(client).find().forEach(function(c) {
    db.getCollection(conversation).update(
        { 'context.domain': c.name },
        { $set: { owner: c._id }},
        { multi: true }
    );
    db.getCollection(configuration).update(
        { client: c._id },
        { $setOnInsert: {
            created: new ISODate(),
            modified: new ISODate(),
            config: {
        		"queryBuilder" : [
        			{
        				"name" : "conversationmlt",
        				"displayName" : "Related Conversations",
        				"type" : "conversationmlt",
        				"enabled" : true,
        				"unbound" : false,
        				"configuration" : {

        				}
        			},
        			{
        				"solrEndpoint" : "http://host.domain.org:8983/solr/change-me",
        				"search" : {
        					"title" : {
        						"enabled" : false,
        						"field" : ""
        					},
        					"fullText" : {
        						"enabled" : true,
        						"field" : ""
        					},
        					"spatial" : {
        						"enabled" : true,
        						"locationNameField" : ""
        					},
        					"temporal" : {
        						"enabled" : false
        					},
        					"related" : {
        						"enabled" : false,
        						"fields" : [ ]
        					}
        				},
        				"defaults" : {
        					"rows" : 10,
        					"fields" : "*,score"
        				},
        				"result" : {
        					"mappings" : {
        						"title": "title",
        				        "description": "description",
        				        "type": "type",
        				        "doctype": "doctype",
        				        "thumb": "thumb",
        				        "link": "link",
        				        "date": "date",
        				        "source": "source"
        					},
        				},
        				"name" : "db-search-endpoint",
        				"displayName" : "DB Search Endpoint",
        				"type" : "solrsearch",
        				"enabled" : false,
        				"unbound" : false,
        				"configuration" : {

        				},
        				"_class" : "io.redlink.smarti.query.solr.SolrEndpointConfiguration"
        			},
        			{
        				"name" : "conversationsearch",
        				"displayName" : "conversationsearch",
        				"type" : "conversationsearch",
        				"enabled" : true,
        				"unbound" : false,
        				"configuration" : {

        				}
        			}
        		]
        	}
        }},
        { upsert: true }
    );
});
<|endoftext|>


<commit_before>// Run this before other modules
if (process.env.NEW_RELIC_LICENSE_KEY) {
  require('newrelic')
}

process.title = 'streetmix'

const compression = require('compression')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const config = require('config')
const path = require('path')
const uuid = require('uuid/v4')
const controllers = require('./app/controllers')
const resources = require('./app/resources')
const requestHandlers = require('./lib/request_handlers')
const initRedisClient = require('./lib/redis')
const initMongoDB = require('./lib/db')
const exec = require('child_process').exec

const client = initRedisClient()
initMongoDB()

const app = module.exports = express()

// Get the timestamp of this server's start time to use as a cachebusting filename.
const cacheTimestamp = Date.now()
app.locals.cacheTimestamp = cacheTimestamp

process.on('uncaughtException', function (error) {
  console.log(error)
  console.trace()

  if (client.connected) {
    client.on('end', function () {
      process.exit(1)
    })
  } else {
    process.exit(1)
  }
})

// Provide a message after a Ctrl-C
// Note: various sources tell us that this does not work on Windows
process.on('SIGINT', function () {
  if (app.locals.config.env === 'development') {
    console.log('Stopping Streetmix!')
    exec('npm stop')
  }

  if (client.connected) {
    client.on('end', process.exit)
  } else {
    process.exit()
  }
})

app.locals.config = config

// Not all headers from `helmet` are on by default. These turns on specific
// off-by-default headers for better security as recommended by https://securityheaders.io/
const helmetConfig = {
  frameguard: false, // Allow Streetmix to be iframed in 3rd party sites
  hsts: {
    maxAge: 5184000, // 60 days
    includeSubDomains: false // we don't have a wildcard ssl cert
  },
  referrerPolicy: {
    policy: 'no-referrer-when-downgrade'
  }
}

// CSP directives are defined separately so we can generate nonces
const csp = {
  directives: {
    defaultSrc: ["'self'"],
    styleSrc: [
      "'self'",
      "'unsafe-inline'",
      'fonts.googleapis.com',
      '*.typekit.net'
    ],
    scriptSrc: [
      "'self'",
      'platform.twitter.com',
      'https://www.google-analytics.com',
      'cdn.mxpnl.com',
      'streetmix.auth0.com',
      '*.basemaps.cartocdn.com',
      'api.geocode.earth',
      (req, res) => "'nonce-" + res.locals.nonce.google_analytics + "'",
      (req, res) => "'nonce-" + res.locals.nonce.mixpanel + "'"
    ],
    childSrc: ['platform.twitter.com'],
    frameSrc: ["'self'", 'streetmix.github.io'],
    imgSrc: [
      "'self'",
      'data:',
      'pbs.twimg.com',
      'syndication.twitter.com',
      's.gravatar.com',
      'https://www.google-analytics.com',
      '*.basemaps.cartocdn.com'
    ],
    fontSrc: [
      "'self'",
      'fonts.gstatic.com',
      '*.typekit.net'
    ],
    connectSrc: [
      "'self'",
      'api.mixpanel.com',
      'api.geocode.earth',
      'syndication.twitter.com',
      'https://www.google-analytics.com',
      'app.getsentry.com',
      'streetmix.auth0.com'
    ]
  }
}

// Allow arbitrary injected code (e.g. Redux dispatches from dev tools) in development
if (app.locals.config.env === 'development') {
  csp.directives.scriptSrc.push("'unsafe-eval'")
  // Allows websockets for hot-module reloading (note: ports are assigned randomly by Parcel)
  csp.directives.connectSrc.push('ws:')
}

app.use(helmet(helmetConfig))
app.use(express.json())
app.use(compression())
app.use(cookieParser())
app.use(cookieSession({ secret: config.cookie_session_secret }))

app.use(requestHandlers.login_token_parser)
app.use(requestHandlers.request_log)
app.use(requestHandlers.request_id_echo)

// Generate nonces for inline scripts
app.use(function (req, res, next) {
  res.locals.nonce = {
    google_analytics: uuid(),
    mixpanel: uuid()
  }
  next()
})

// Set Redis client for when requesting the geoip
app.use('/services/geoip', function (req, res, next) {
  req.redisClient = client
  next()
})

// Set CSP directives
app.use(helmet.contentSecurityPolicy(csp))

// Rewrite requests with timestamp
app.use(function (req, res, next) {
  // Matches a filename like styles.2395934243.css
  // Accepts optional `?29090424` query string used by Parcel's hot-module reloader
  req.url = req.url.replace(/\/([^/]+)\.[0-9]+\.(css|js)(\?[0-9]+)?$/, '/$1.$2')
  next()
})

app.set('view engine', 'hbs')
app.set('views', path.join(__dirname, '/app/views'))

app.get('/help/about', function (req, res) {
  res.redirect('https://www.opencollective.com/streetmix/')
})

app.get('/map', function (req, res) {
  res.redirect('https://streetmix.github.io/map/')
})

app.get('/privacy-policy', express.static(path.join(__dirname, '/public/pages'), { fallthrough: false }))
app.get('/terms-of-service', express.static(path.join(__dirname, '/public/pages'), { fallthrough: false }))

app.get('/twitter-sign-in', controllers.twitter_sign_in.get)
app.get(config.twitter.oauth_callback_uri, controllers.twitter_sign_in_callback.get)
// Auth0
app.get(config.auth0.callback_uri, controllers.auth0_sign_in_callback.get)

app.post('/api/v1/users', resources.v1.users.post)
app.get('/api/v1/users/:user_id', resources.v1.users.get)
app.put('/api/v1/users/:user_id', resources.v1.users.put)
app.delete('/api/v1/users/:user_id/login-token', resources.v1.users.delete)
app.get('/api/v1/users/:user_id/streets', resources.v1.users_streets.get)

app.post('/api/v1/streets', resources.v1.streets.post)
app.get('/api/v1/streets', resources.v1.streets.find)
app.head('/api/v1/streets', resources.v1.streets.find)

app.delete('/api/v1/streets/:street_id', resources.v1.streets.delete)
app.head('/api/v1/streets/:street_id', resources.v1.streets.get)
app.get('/api/v1/streets/:street_id', resources.v1.streets.get)
app.put('/api/v1/streets/:street_id', resources.v1.streets.put)

app.get('/api/v1/geo', cors(), resources.v1.geo.get)

app.get('/services/geoip', resources.services.geoip.get)

app.get('/api/v1/translate/:locale_code/:resource_name', resources.v1.translate.get)

app.get('/api/v1/flags', resources.v1.flags.get)

// Catch all for all broken api paths, direct to 404 response.
app.get('/api/*', function (req, res) {
  res.status(404).json({ status: 404, error: 'Not found. Did you mispell something?' })
})

// SVG bundled images served directly from packages
app.get('/assets/images/icons.svg', function (req, res) {
  res.sendFile(path.join(__dirname, '/node_modules/@streetmix/icons/dist/icons.svg'))
})

app.get('/assets/images/images.svg', function (req, res) {
  res.sendFile(path.join(__dirname, '/node_modules/@streetmix/illustrations/dist/images.svg'))
})

app.use('/assets', express.static(path.join(__dirname, '/build')))
app.use(express.static(path.join(__dirname, '/public')))

// Catch all for all broken assets, direct to 404 response.
app.get('/assets/*', function (req, res) {
  res.status(404).render('404', {})
})

// Allow hot-module reloading (HMR) in non-production environments
if (config.env !== 'production') {
  const runBundle = require('./app/bundle')
  runBundle(app)
}

// Catch-all
app.use(function (req, res) {
  res.render('main', {})
})
<commit_msg>Enable CORS requests for /api/users<commit_after>// Run this before other modules
if (process.env.NEW_RELIC_LICENSE_KEY) {
  require('newrelic')
}

process.title = 'streetmix'

const compression = require('compression')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const config = require('config')
const path = require('path')
const uuid = require('uuid/v4')
const controllers = require('./app/controllers')
const resources = require('./app/resources')
const requestHandlers = require('./lib/request_handlers')
const initRedisClient = require('./lib/redis')
const initMongoDB = require('./lib/db')
const exec = require('child_process').exec

const client = initRedisClient()
initMongoDB()

const app = module.exports = express()

// Get the timestamp of this server's start time to use as a cachebusting filename.
const cacheTimestamp = Date.now()
app.locals.cacheTimestamp = cacheTimestamp

process.on('uncaughtException', function (error) {
  console.log(error)
  console.trace()

  if (client.connected) {
    client.on('end', function () {
      process.exit(1)
    })
  } else {
    process.exit(1)
  }
})

// Provide a message after a Ctrl-C
// Note: various sources tell us that this does not work on Windows
process.on('SIGINT', function () {
  if (app.locals.config.env === 'development') {
    console.log('Stopping Streetmix!')
    exec('npm stop')
  }

  if (client.connected) {
    client.on('end', process.exit)
  } else {
    process.exit()
  }
})

app.locals.config = config

// Not all headers from `helmet` are on by default. These turns on specific
// off-by-default headers for better security as recommended by https://securityheaders.io/
const helmetConfig = {
  frameguard: false, // Allow Streetmix to be iframed in 3rd party sites
  hsts: {
    maxAge: 5184000, // 60 days
    includeSubDomains: false // we don't have a wildcard ssl cert
  },
  referrerPolicy: {
    policy: 'no-referrer-when-downgrade'
  }
}

// CSP directives are defined separately so we can generate nonces
const csp = {
  directives: {
    defaultSrc: ["'self'"],
    styleSrc: [
      "'self'",
      "'unsafe-inline'",
      'fonts.googleapis.com',
      '*.typekit.net'
    ],
    scriptSrc: [
      "'self'",
      'platform.twitter.com',
      'https://www.google-analytics.com',
      'cdn.mxpnl.com',
      'streetmix.auth0.com',
      '*.basemaps.cartocdn.com',
      'api.geocode.earth',
      (req, res) => "'nonce-" + res.locals.nonce.google_analytics + "'",
      (req, res) => "'nonce-" + res.locals.nonce.mixpanel + "'"
    ],
    childSrc: ['platform.twitter.com'],
    frameSrc: ["'self'", 'streetmix.github.io'],
    imgSrc: [
      "'self'",
      'data:',
      'pbs.twimg.com',
      'syndication.twitter.com',
      's.gravatar.com',
      'https://www.google-analytics.com',
      '*.basemaps.cartocdn.com'
    ],
    fontSrc: [
      "'self'",
      'fonts.gstatic.com',
      '*.typekit.net'
    ],
    connectSrc: [
      "'self'",
      'api.mixpanel.com',
      'api.geocode.earth',
      'syndication.twitter.com',
      'https://www.google-analytics.com',
      'app.getsentry.com',
      'streetmix.auth0.com'
    ]
  }
}

// Allow arbitrary injected code (e.g. Redux dispatches from dev tools) in development
if (app.locals.config.env === 'development') {
  csp.directives.scriptSrc.push("'unsafe-eval'")
  // Allows websockets for hot-module reloading (note: ports are assigned randomly by Parcel)
  csp.directives.connectSrc.push('ws:')
}

app.use(helmet(helmetConfig))
app.use(express.json())
app.use(compression())
app.use(cookieParser())
app.use(cookieSession({ secret: config.cookie_session_secret }))

app.use(requestHandlers.login_token_parser)
app.use(requestHandlers.request_log)
app.use(requestHandlers.request_id_echo)

// Generate nonces for inline scripts
app.use(function (req, res, next) {
  res.locals.nonce = {
    google_analytics: uuid(),
    mixpanel: uuid()
  }
  next()
})

// Set Redis client for when requesting the geoip
app.use('/services/geoip', function (req, res, next) {
  req.redisClient = client
  next()
})

// Set CSP directives
app.use(helmet.contentSecurityPolicy(csp))

// Rewrite requests with timestamp
app.use(function (req, res, next) {
  // Matches a filename like styles.2395934243.css
  // Accepts optional `?29090424` query string used by Parcel's hot-module reloader
  req.url = req.url.replace(/\/([^/]+)\.[0-9]+\.(css|js)(\?[0-9]+)?$/, '/$1.$2')
  next()
})

app.set('view engine', 'hbs')
app.set('views', path.join(__dirname, '/app/views'))

app.get('/help/about', function (req, res) {
  res.redirect('https://www.opencollective.com/streetmix/')
})

app.get('/map', function (req, res) {
  res.redirect('https://streetmix.github.io/map/')
})

app.get('/privacy-policy', express.static(path.join(__dirname, '/public/pages'), { fallthrough: false }))
app.get('/terms-of-service', express.static(path.join(__dirname, '/public/pages'), { fallthrough: false }))

app.get('/twitter-sign-in', controllers.twitter_sign_in.get)
app.get(config.twitter.oauth_callback_uri, controllers.twitter_sign_in_callback.get)
// Auth0
app.get(config.auth0.callback_uri, controllers.auth0_sign_in_callback.get)

app.post('/api/v1/users', cors(), resources.v1.users.post)
app.get('/api/v1/users/:user_id', cors(), resources.v1.users.get)
app.put('/api/v1/users/:user_id', cors(), resources.v1.users.put)
app.delete('/api/v1/users/:user_id/login-token', cors(), resources.v1.users.delete)
app.get('/api/v1/users/:user_id/streets', cors(), resources.v1.users_streets.get)

app.post('/api/v1/streets', resources.v1.streets.post)
app.get('/api/v1/streets', resources.v1.streets.find)
app.head('/api/v1/streets', resources.v1.streets.find)

app.delete('/api/v1/streets/:street_id', resources.v1.streets.delete)
app.head('/api/v1/streets/:street_id', resources.v1.streets.get)
app.get('/api/v1/streets/:street_id', resources.v1.streets.get)
app.put('/api/v1/streets/:street_id', resources.v1.streets.put)

app.get('/api/v1/geo', cors(), resources.v1.geo.get)

app.get('/services/geoip', resources.services.geoip.get)

app.get('/api/v1/translate/:locale_code/:resource_name', resources.v1.translate.get)

app.get('/api/v1/flags', resources.v1.flags.get)

// Catch all for all broken api paths, direct to 404 response.
app.get('/api/*', function (req, res) {
  res.status(404).json({ status: 404, error: 'Not found. Did you mispell something?' })
})

// SVG bundled images served directly from packages
app.get('/assets/images/icons.svg', function (req, res) {
  res.sendFile(path.join(__dirname, '/node_modules/@streetmix/icons/dist/icons.svg'))
})

app.get('/assets/images/images.svg', function (req, res) {
  res.sendFile(path.join(__dirname, '/node_modules/@streetmix/illustrations/dist/images.svg'))
})

app.use('/assets', express.static(path.join(__dirname, '/build')))
app.use(express.static(path.join(__dirname, '/public')))

// Catch all for all broken assets, direct to 404 response.
app.get('/assets/*', function (req, res) {
  res.status(404).render('404', {})
})

// Allow hot-module reloading (HMR) in non-production environments
if (config.env !== 'production') {
  const runBundle = require('./app/bundle')
  runBundle(app)
}

// Catch-all
app.use(function (req, res) {
  res.render('main', {})
})
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

/**
 * Module dependencies.
 */
var SwaggerExpress = require('swagger-express-mw');
var SwaggerUi = require('swagger-tools/middleware/swagger-ui');

if (process.env.NEW_RELIC_LICENSE_KEY && process.env.NEW_RELIC_LICENSE_KEY !== '') {
  require('newrelic');
}

var express = require('express');
var path = require('path');
//var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = require('express')();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);

module.exports = app; // for testing

var config = {
  appRoot: __dirname, // required config
};

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err,
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {},
  });
});

SwaggerExpress.create(config, function(err, swaggerExpress) {
  if (err) {
    throw err;
  }

  // add swagger-ui
  app.use(new SwaggerUi(swaggerExpress.runner.swagger));

  // install middleware
  swaggerExpress.register(app);

  var port = process.env.VCAP_APP_PORT || 3000;
  app.listen(port);

  //The console logging must be removed as the test xml file will not be generated correctly, which will cause the build to fail.
  console.log('Listening port ' + port);
  console.log('To access the api directly, try this:');
  console.log('curl http://127.0.0.1:' + port + '/applications\n');
});

// catch 404 and forward to error handler
app.use(function(req, res) {
  var err = new Error('404 - Not Found!');
  err.status = 404;
  res.render('404', {
    message: err.message,
    error: {},
  });
});
<commit_msg>jshint fix<commit_after>/*jslint node: true */
/*jshint unused: false */
'use strict';

/**
 * Module dependencies.
 */
var SwaggerExpress = require('swagger-express-mw');
var SwaggerUi = require('swagger-tools/middleware/swagger-ui');

if (process.env.NEW_RELIC_LICENSE_KEY && process.env.NEW_RELIC_LICENSE_KEY !== '') {
  require('newrelic');
}

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var app = require('express')();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);

module.exports = app; // for testing

var config = {
  appRoot: __dirname, // required config
};

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err,
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {},
  });
});

SwaggerExpress.create(config, function(err, swaggerExpress) {
  if (err) {
    throw err;
  }

  // add swagger-ui
  app.use(new SwaggerUi(swaggerExpress.runner.swagger));

  // install middleware
  swaggerExpress.register(app);

  var port = process.env.VCAP_APP_PORT || 3000;
  app.listen(port);

  //The console logging must be removed as the test xml file will not be generated correctly, which will cause the build to fail.
  console.log('Listening port ' + port);
  console.log('To access the api directly, try this:');
  console.log('curl http://127.0.0.1:' + port + '/applications\n');
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('404 - Not Found!');
  err.status = 404;
  res.render('404', {
    message: err.message,
    error: {},
  });
});
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var express = require('express');
var http = require('http');
var path = require('path');
var restler = require('restler');
var app = express();

var apiUri = process.env.ROUTING_API_URL;

// all environments
app.set('port', process.env.PORT_WWW || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' === app.get('env')) {
    app.use(express.errorHandler());
}

var routes = require('./routes')(app);
var addRoute = require('./routes/addRoute')(app, {apiUri: apiUri});

http.createServer(app).listen(app.get('port'), function () {
    "use strict";
    console.log('Express server listening on port ' + app.get('port'));
});

app.all('/restProxy/*', function (req, res) {
    "use strict";
    var path = req.url;
    path = path.replace("restProxy/", "");
    var url = apiUri + path;
    console.log(url);
    restler.get(url, {

    }).on('complete', function (data) {
        console.log(data);
        res.json(data);
    });

});

<commit_msg>Export server app for testing purposes<commit_after>
/**
 * Module dependencies.
 */

var express = require('express');
var http = require('http');
var path = require('path');
var restler = require('restler');
var app = module.exports = express();

var apiUri = process.env.ROUTING_API_URL;

// all environments
app.set('port', process.env.PORT_WWW || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' === app.get('env')) {
    app.use(express.errorHandler());
}

var routes = require('./routes')(app);
var addRoute = require('./routes/addRoute')(app, {apiUri: apiUri});

http.createServer(app).listen(app.get('port'), function () {
    "use strict";
    console.log('Express server listening on port ' + app.get('port'));
});

app.all('/restProxy/*', function (req, res) {
    "use strict";
    var path = req.url;
    path = path.replace("restProxy/", "");
    var url = apiUri + path;
    console.log(url);
    restler.get(url, {

    }).on('complete', function (data) {
        console.log(data);
        res.json(data);
    });

});

<|endoftext|>


<commit_before>var express = require('express');
var julia = require('node-julia')
var app = express();

app.get('/', function(req, res){
res.json({'message': 'Welcome to the basic JuliaDroid backend. Hit /api/0.1/compute with a Julia expression, for best results.'});
});

var server = app.listen(3000, function() {
console.log('The JuliaDroid backend is now listening on port %d', server.address().port);
});<commit_msg>Added basic support for running Julia code from the API.<commit_after>var express = require('express');
var julia = require('node-julia')
var app = express();

app.get('/', function(req, res){
res.json({'message': 'Welcome to the basic JuliaDroid backend. Hit /api/0.1/compute with a Julia expression, for best results.'});
});

app.get('/api/0.1/compute/:julia_expr', function(req, res){
	julia_expr_result = julia.eval(req.param("julia_expr"));
	res.json({'result': julia_expr_result});
});

var server = app.listen(3000, function() {
console.log('The JuliaDroid backend is now listening on port %d', server.address().port);
});<|endoftext|>


<commit_before>const request = require('request');
const token = process.env.FB_PAGE_ACCESS_TOKEN;
const songs = require('./songs/index');
var levenshtein = require('fast-levenshtein');
const async = require('async');

module.exports = {
  removeDuplicates: function(string){
    return  string.replace(/[^\w\s]|(.)(?=\1)/gi, "");
  },
  removePunctAndLowerCase: function(string){
    return string.replace(/[^a-zA-Z ]/gi, "").toLowerCase();
  },
  checkifEqual: function(string1, string2,levenshteinIndex ) {
    let cleanedString1 = this.removeDuplicates(this.removePunctAndLowerCase(string1));
    let cleanedString2 = this.removeDuplicates(this.removePunctAndLowerCase(string2));

    let trial1 = cleanedString1 === cleanedString2;
    let trial2 = (levenshtein.get(cleanedString1, cleanedString2) <levenshteinIndex);

    return (trial1 || trial2);
  },
  getlNextline: function(line) {
    var indexIThink = -1;
    for (let x = 1; x < 3 ; x ++ ){
      for (let i = 0; i < Object.keys(songs).length; i++ ){
        // return string if match in song[i]
        // console.log("LOGING: ", songs[i][1]);
          indexIThink = (songs[i])[1].findIndex(item => this.checkifEqual(line, item, x));
          if (indexIThink != -1){
            let name = songs[i][0];
            let currentLine = songs[i][1][indexIThink];
            let nextLine = songs[i][1][indexIThink + 1];
            let response = "["+songs[i][0]+"]"+ "\n\n"+ currentLine+ "\n"+nextLine;
            return response;
        }
      }
    }

    return "Hey Pubma! Do you know what song this is!";
  },
  sendTextMessage: function(sender, text) {
    let messageData = {
      text: text
    }
    request({
      url: 'https://graph.facebook.com/v2.10/me/messages',
      qs: {
        access_token: token
      },
      method: 'POST',
      json: {
        recipient: {
          id: sender
        },
        message: messageData,
      }
    }, function(error, response, body) {
      if (error) {
        console.log('Error sending messages: ', error)
      } else if (response.body.error) {
        console.log('Error: ', response.body.error)
      }
    })
  },
  sendGenericMessage: function(sender) {
    let messageData = {
      "attachment": {
        "type": "template",
        "payload": {
          "template_type": "generic",
          "elements": [{
            "title": "First card",
            "subtitle": "Element #1 of an hscroll",
            "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
            "buttons": [{
              "type": "web_url",
              "url": "https://www.messenger.com",
              "title": "web url"
            }, {
              "type": "postback",
              "title": "Postback",
              "payload": "Payload for first element in a generic bubble",
            }],
          }, {
            "title": "Second card",
            "subtitle": "Element #2 of an hscroll",
            "image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
            "buttons": [{
              "type": "postback",
              "title": "Postback",
              "payload": "Payload for second element in a generic bubble",
            }],
          }]
        }
      }
    }
    request({
      url: 'https://graph.facebook.com/v2.10/me/messages',
      qs: {
        access_token: token
      },
      method: 'POST',
      json: {
        recipient: {
          id: sender
        },
        message: messageData,
      }
    }, function(error, response, body) {
      if (error) {
        console.log('Error sending messages: ', error)
      } else if (response.body.error) {
        console.log('Error: ', response.body.error)
      }
    })
  },
  messPostback: function(senderID, posback){
    if (posback.payload == "GREETINGS_POSTBACK"){
      this.sendTextMessage(senderID, "Hello stranger! Pumba and I want to welcome you our fanpage! :)" );
      this.sendTextMessage(senderID, "We can together all night long! Try and message us 'hakuna matata'! " );
    }else {
      this.sendTextMessage(senderID, {
        text: "Postback from" + senderID+ JSON.stringify(postback)
      })

    }
  },
  typingBubble: function(senderID, length , callback){
    var sendBubbles = function() {
      request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {
          access_token: token
        },
        method: 'POST',
        json: {
           recipient: {
               id: senderID
           },
           sender_action: "typing_on"
         }
       }, function(error, response, body) {
        if (error) {
         console.log("TYPING DIDNT WORK"+error);
         return;
       }
       if (response.statusCode == 200) {
         console.log("TYPING WORKED!\n",body);
       } else {
         console.log("receive status code : " + response.statusCode);
       }
     });
   };

    async.series([
      console.log("#######\nTYPING\n#######"),
      sendBubbles(),
      console.log("#######\nCALBACKING\n#######"),
      setTimeout(callback(), 150)

    ]);

    }

};
<commit_msg>callback fixes again<commit_after>const request = require('request');
const token = process.env.FB_PAGE_ACCESS_TOKEN;
const songs = require('./songs/index');
var levenshtein = require('fast-levenshtein');
const async = require('async');
const delay = require('delay');

module.exports = {
  removeDuplicates: function(string){
    return  string.replace(/[^\w\s]|(.)(?=\1)/gi, "");
  },
  removePunctAndLowerCase: function(string){
    return string.replace(/[^a-zA-Z ]/gi, "").toLowerCase();
  },
  checkifEqual: function(string1, string2,levenshteinIndex ) {
    let cleanedString1 = this.removeDuplicates(this.removePunctAndLowerCase(string1));
    let cleanedString2 = this.removeDuplicates(this.removePunctAndLowerCase(string2));

    let trial1 = cleanedString1 === cleanedString2;
    let trial2 = (levenshtein.get(cleanedString1, cleanedString2) <levenshteinIndex);

    return (trial1 || trial2);
  },
  getlNextline: function(line) {
    var indexIThink = -1;
    for (let x = 1; x < 3 ; x ++ ){
      for (let i = 0; i < Object.keys(songs).length; i++ ){
        // return string if match in song[i]
        // console.log("LOGING: ", songs[i][1]);
          indexIThink = (songs[i])[1].findIndex(item => this.checkifEqual(line, item, x));
          if (indexIThink != -1){
            let name = songs[i][0];
            let currentLine = songs[i][1][indexIThink];
            let nextLine = songs[i][1][indexIThink + 1];
            let response = "["+songs[i][0]+"]"+ "\n\n"+ currentLine+ "\n"+nextLine;
            return response;
        }
      }
    }

    return "Hey Pubma! Do you know what song this is!";
  },
  sendTextMessage: function(sender, text) {
    let messageData = {
      text: text
    }
    request({
      url: 'https://graph.facebook.com/v2.10/me/messages',
      qs: {
        access_token: token
      },
      method: 'POST',
      json: {
        recipient: {
          id: sender
        },
        message: messageData,
      }
    }, function(error, response, body) {
      if (error) {
        console.log('Error sending messages: ', error)
      } else if (response.body.error) {
        console.log('Error: ', response.body.error)
      }
    })
  },
  sendGenericMessage: function(sender) {
    let messageData = {
      "attachment": {
        "type": "template",
        "payload": {
          "template_type": "generic",
          "elements": [{
            "title": "First card",
            "subtitle": "Element #1 of an hscroll",
            "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
            "buttons": [{
              "type": "web_url",
              "url": "https://www.messenger.com",
              "title": "web url"
            }, {
              "type": "postback",
              "title": "Postback",
              "payload": "Payload for first element in a generic bubble",
            }],
          }, {
            "title": "Second card",
            "subtitle": "Element #2 of an hscroll",
            "image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
            "buttons": [{
              "type": "postback",
              "title": "Postback",
              "payload": "Payload for second element in a generic bubble",
            }],
          }]
        }
      }
    }
    request({
      url: 'https://graph.facebook.com/v2.10/me/messages',
      qs: {
        access_token: token
      },
      method: 'POST',
      json: {
        recipient: {
          id: sender
        },
        message: messageData,
      }
    }, function(error, response, body) {
      if (error) {
        console.log('Error sending messages: ', error)
      } else if (response.body.error) {
        console.log('Error: ', response.body.error)
      }
    })
  },
  messPostback: function(senderID, posback){
    if (posback.payload == "GREETINGS_POSTBACK"){
      this.sendTextMessage(senderID, "Hello stranger! Pumba and I want to welcome you our fanpage! :)" );
      this.sendTextMessage(senderID, "We can together all night long! Try and message us 'hakuna matata'! " );
    }else {
      this.sendTextMessage(senderID, {
        text: "Postback from" + senderID+ JSON.stringify(postback)
      })

    }
  },
  typingBubble: function(senderID, length , callback){
    var sendBubbles = function() {
      request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {
          access_token: token
        },
        method: 'POST',
        json: {
           recipient: {
               id: senderID
           },
           sender_action: "typing_on"
         }
       }, function(error, response, body) {
        if (error) {
         console.log("TYPING DIDNT WORK"+error);
         return;
       }
       if (response.statusCode == 200) {
         console.log("TYPING WORKED!\n",body);
       } else {
         console.log("receive status code : " + response.statusCode);
       }
     });
   };

    async.series([
      console.log("#######\nTYPING\n#######"),
      sendBubbles(),
      console.log("#######\nCALBACKING\n#######"),
      delay(100),
      console.log("#######\nDELAYING\n########")
      callback()

    ]);

    }

};
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var express = require('express'),
routes = require('./routes'),
config = require('./config'),
util = require('util'),
everyauth = require('everyauth'),
io = require('socket.io'),
parseCookie = require('connect').utils.parseCookie;

// Session store
var RedisStore = require('connect-redis')(express);
var sessionStore = new RedisStore();

everyauth.tumblr
    .consumerKey(config.consumerKey)
    .consumerSecret(config.consumerSecret)
    .findOrCreateUser( function (sess, accessToken, accessSecret, user) {
        return true;
    })
    .redirectPath('/');

var app = module.exports = express.createServer();
// Configuration

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.logger());
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({
		'store': sessionStore,
        'secret': config.session_secret,
        'key': 'express.sid'
    }));
    app.use(everyauth.middleware());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    app.use(express.errorHandler());
});

everyauth.helpExpress(app);

// Routes

app.get('/', routes.index);

app.listen(3000, function(){
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

var sio = io.listen(app);
sio.set('authorization', function(data, accept) {
    if (data.headers.cookie) {
        data.cookie = parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['express.sid'];
        // (literally) get the session data from the session store
        sessionStore.get(data.sessionID, function (err, session) {
            if (err || !session) {
                // if we cannot grab a session, turn down the connection
                accept('Error', false);
            } else {
                // save the session data and accept the connection
                data.session = session;
                accept(null, true);
            }
        });
    } else {
       return accept('No cookie transmitted.', false);
    }
});

sio.sockets.on('connection', function(socket) {
    console.log('got handshake:\n'+util.inspect(socket.handshake.session, false, null, true));
    socket.on('get_likes', function(data, fn) {
        console.log('getting likes');
        fn('hallo welt');
    });
});
<commit_msg>get likes asynchronously<commit_after>
/**
 * Module dependencies.
 */

var express = require('express'),
routes = require('./routes'),
config = require('./config'),
util = require('util'),
everyauth = require('everyauth'),
io = require('socket.io'),
Tumblr = require('tumblr2'),
parseCookie = require('connect').utils.parseCookie;

// Session store
var RedisStore = require('connect-redis')(express);
var sessionStore = new RedisStore();

everyauth.tumblr
    .consumerKey(config.consumerKey)
    .consumerSecret(config.consumerSecret)
    .findOrCreateUser( function (sess, accessToken, accessSecret, user) {
        return true;
    })
    .redirectPath('/');

var app = module.exports = express.createServer();
// Configuration

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.logger());
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({
		'store': sessionStore,
        'secret': config.session_secret,
        'key': 'express.sid'
    }));
    app.use(everyauth.middleware());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    app.use(express.errorHandler());
});

everyauth.helpExpress(app);

// Routes

app.get('/', routes.index);

app.listen(3000, function(){
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

var sio = io.listen(app);
sio.set('authorization', function(data, accept) {
    if (data.headers.cookie) {
        data.cookie = parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['express.sid'];
        // (literally) get the session data from the session store
        sessionStore.get(data.sessionID, function (err, session) {
            if (err || !session) {
                // if we cannot grab a session, turn down the connection
                accept('Error', false);
            } else {
                // save the session data and accept the connection
                data.session = session;
                accept(null, true);
            }
        });
    } else {
       return accept('No cookie transmitted.', false);
    }
});

sio.sockets.on('connection', function(socket) {
    console.log('got handshake:\n'+util.inspect(socket.handshake.session, false, null, true));
    socket.on('get_likes', function(data, fn) {
        console.log('getting likes');
        new Tumblr(getOAuthConfig(socket.handshake.session)).getUserLikes(function(err, res) {
            console.log("got likes:\n"+util.inspect(res, false, null, true));
            fn({likes: res.liked_posts.length});
        });
    });
});

function getOAuthConfig(session) {
    var t = session.auth.tumblr;
    var c = {
        consumerKey: config.consumerKey,
            consumerSecret: config.consumerSecret,
            accessTokenKey: t.accessToken,
            accessTokenSecret: t.accessTokenSecret
        };
    console.log("got oauth config:\n" + util.inspect(c, false, null, true));
    return c;
}<|endoftext|>


<commit_before>var flatiron = require('flatiron');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var app = flatiron.app;
var find = require('./lib/find');
var async = require('async');
var npm = require('npm');

app.config.file({ file: path.join(__dirname, 'config', 'config.json') });

app.use(flatiron.plugins.cli, {
  source: path.join(__dirname, 'lib', 'commands'),
  usage: 'Empty Flatiron Application, please fill out commands',
  argv: {
    l: {
      description: 'list',
      boolean: true
    }
  }
});

function list (module, args) {
  async.waterfall([
    function (callback)       { find.root(module, callback); },
    function (root, callback) { find.docDir(root, callback); },
  ], function (err, data) {
    if (err) {
      app.log.error(err);
      return;
    }

    var dir = path.join(data[0], path.join.apply(null, args));

    fs.readdir(dir, function (err, files) {
      if (err) return app.log.error(err.message);

      if (_.size(files) == 0) {
        return app.log.error('No packages found!');
      }

      _.each(files, function (file) {
        console.log(file);
      });
    });
  });
}

function markdisp (data) {
  var marked = require('./deps/marked').setOptions({gfm: true, terminal: true});
  var moar = require('moar')({nowrap: true});
  moar.write('\n' + marked.parse(data));
  moar.end();
  moar.on('done', function () { process.exit(0); });
}

function listModules () {
  console.log("Available modules:".bold);
  npm.load({quiet: true, loglevel: 'silent'}, function (err, npm) {
    npm.commands.ls([], false, function (err, data) {
      if (err) return app.log.error(err);
    });
  });
}

function view (module, args) {
  async.waterfall([
    function (callback)       { find.root(module, callback); },
    function (root, callback) { find.docDir(root, callback); },
    function (dirs, callback) { find.file(dirs, args, module, callback); }
  ], function (err, data) {
    if (err) {
      app.log.error(err);
      return;
    }

    markdisp(data);
  });
}

app.init(function (err) {
  if (err) return app.log.error(err);

  var args = app.argv._;
  var module = args.shift();

  if (app.argv.l) {
    // list mode
    if (args.length > 0 || module) {
      list(module, args);
    } else {
      listModules();
    }
  } else {
    // view
    if (!module) {
      listModules();
    } else {
      var file = path.join(process.cwd(), module);
      path.exists(file, function (exists) {
        if (exists) {
          fs.readFile(file, 'utf8', function (err, data) {
            if (err) return app.log.error(err);
            markdisp(data);
          });
        } else {
          view(module, args);
        }
      });
    }
  }
});
<commit_msg>support for piping to stdin<commit_after>var flatiron = require('flatiron');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var app = flatiron.app;
var find = require('./lib/find');
var async = require('async');
var npm = require('npm');
var moar;

app.config.file({ file: path.join(__dirname, 'config', 'config.json') });

app.use(flatiron.plugins.cli, {
  source: path.join(__dirname, 'lib', 'commands'),
  usage: 'Empty Flatiron Application, please fill out commands',
  argv: {
    l: {
      description: 'list',
      boolean: true
    }
  }
});

function list (module, args) {
  async.waterfall([
    function (callback)       { find.root(module, callback); },
    function (root, callback) { find.docDir(root, callback); }
  ], function (err, data) {
    if (err) {
      app.log.error(err);
      return;
    }

    var dir = path.join(data[0], path.join.apply(null, args));

    fs.readdir(dir, function (err, files) {
      if (err) return app.log.error(err.message);

      if (_.size(files) === 0) {
        return app.log.error('No packages found!');
      }

      _.each(files, function (file) {
        console.log(file);
      });
    });
  });
}

function markdisp (data) {
  var marked = require('./deps/marked').setOptions({gfm: true, terminal: true});
  if (!moar) {
    moar = require('moar')({nowrap: true});
  }

  moar.write('\n' + marked.parse(data));
  moar.end();
  moar.on('done', function () { process.exit(0); });
}

function listModules () {
  console.log("Available modules:".bold);
  npm.load({quiet: true, loglevel: 'silent'}, function (err, npm) {
    npm.commands.ls([], false, function (err, data) {
      if (err) return app.log.error(err);
    });
  });
}

function view (module, args) {
  async.waterfall([
    function (callback)       { find.root(module, callback); },
    function (root, callback) { find.docDir(root, callback); },
    function (dirs, callback) { find.file(dirs, args, module, callback); }
  ], function (err, data) {
    if (err) {
      app.log.error(err);
      return;
    }

    markdisp(data);
  });
}

app.init(function (err) {
  if (err) return app.log.error(err);

  var args = app.argv._;
  var module = args.shift();

  if (app.argv.l) {
    // list mode
    if (args.length > 0 || module) {
      list(module, args);
    } else {
      listModules();
    }
  } else {
    // view

    if (!process.stdin.isTTY && process.platform !== "win32") {
      // we're getting piped some stuff, gather it up and send it over to
      // markdisp to be displayed

      // we have spawn less before resuming stdin, or it gets confused
      moar = require('moar')({nowrap: true});

      process.stdin.resume();
      process.stdin.setEncoding('utf8');
      var data = '';

      process.stdin.on('data', function (chunk) {
        data += chunk;
      });

      process.stdin.on('end', function () {
        markdisp(data);
      });
    }

    else if (!module) {
      // no module name provided, just give a list of modules
      listModules();
    }

    else {
      // we have some arguments.. check to see if they're a filename
      var file = path.join(process.cwd(), module);
      path.exists(file, function (exists) {

        if (exists) {
          // if so, read and display the file
          fs.readFile(file, 'utf8', function (err, data) {
            if (err) return app.log.error(err);
            markdisp(data);
          });
        }

        else {
          // otherwise send the arguments over to view() to do an actual
          // module lookup
          view(module, args);
        }
      });
    }
  }
});
<|endoftext|>