<commit_before>var fs = require('fs')
var haml = require('haml')
var clutch = require('clutch')
var querystring = require('querystring')
var models = require('./models')

db = process.db

if (!db.find('streamName', 'alerts')[0]) {
  new models.Stream('alerts')
}

var header = haml(fs.readFileSync('views/layouts/header.haml', 'utf8'))
var application = haml(fs.readFileSync('views/layouts/application.haml', 'utf8'))

function tails(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'})
  res.end(header({ yield: application() }))
}

function favicon(req, res) {
  res.writeHead(200, {'Content-Type': 'image/gif'})
  res.end()
}

function serveStatic(req, res, dir, file) {
  fs.readFile('./public/' + dir + '/' + file, function (err, data) {
    if (err) {
      console.log(err)
      res.writeHead(404, {'Content-Type': 'text/plain'})
    } else {
      if (dir == 'scripts') {
        res.writeHead(200, {'Content-Type': 'text/javascript'})
      } else if (dir == 'stylesheets') {
        res.writeHead(200, {'Content-Type': 'text/css'})
      } else if (dir == 'images') {
        res.writeHead(200, {'Content-Type': 'image/png'})
      } else {
        res.writeHead(200, {'Content-Type': 'text/html'})
      }
      res.write(data)
    }
    res.end()
  })
}

function createStream(req, res) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end' , function() {
    var name = querystring.parse(requestString).name
    if (name) {
      var stream = db.find('streamName', name).pop()
      if (!stream || stream.streamEnabled == false) {
        new models.Stream(name)
        res.writeHead(201, {'Content-Type': 'text/plain'})
        res.write(name)
      } else {
        res.writeHead(409, 'Stream already exists', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(400, 'Missing field - name', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

function getStreams(req, res) {
  var streams = db.find('streamEnabled', true)
  var result = {}
  for (i in streams) {
    var stream = streams[i]
      result[stream.streamName] = {
        name: stream.streamName,
        terms: stream.streamTerms,
        forwarding: {
          enabled: stream.streamForwarding,
          token: stream.streamLogglyToken
        }
      }
  }
  res.writeHead(200, {'Content-Type': 'application/json'})
  res.end(JSON.stringify(result))
}

function removeStream(req, res, name) {
  var stream = db.find('streamName', name).pop()
  if (stream && stream.streamEnabled == true) {
    stream.disable()
    res.writeHead(204)
  } else {
    res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
  }
  res.end()
}

function createTerm(req, res, name) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end', function() {
    var term = querystring.parse(requestString).term
    if (term) {
      var stream = db.find('streamName', name).pop()
      if (stream) {
        if (stream.streamTerms.indexOf(term) == -1) {
          stream.createTerm(term)
          res.writeHead(201, {'Content-Type': 'text/plain'})
	} else {
          res.writeHead(409, 'Term already exists', {'Content-Type': 'text/plain'})
	}
      } else {
        res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(400, 'Missing field - term', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

function removeTerm(req, res, name, term) {
  var stream = db.find('streamName', name).pop()
  if (stream) {
    stream.removeTerm(term)
    res.writeHead(204)
  } else {
    res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
  }
  res.end()
}

function toggleForwarding(req, res, name) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end', function() {
    var token = querystring.parse(requestString).token
    var stream = db.find('streamName', name).pop()
    if (stream) {
      if (token) {
        stream.toggleForwarding(token)
        res.writeHead(200, {'Content-Type': 'text/plain'})
        res.write(stream.streamForwarding.toString())
      } else {
        res.writeHead(400, 'Missing field - token', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

exports.urls = clutch.route404([['GET /$', tails],
				['GET /favicon.ico', favicon],
				['POST /streams$', createStream],
				['POST /streams/(.*)/terms$', createTerm],
				['POST /streams/(.*)/forwarding$', toggleForwarding],
				['GET /streams$', getStreams],
				['DELETE /streams/(.*)/terms/(.*)$', removeTerm],
				['DELETE /streams/(.*)$', removeStream],
				['GET /(.*)/(.*)$', serveStatic]])
<commit_msg>begin routes cleanup<commit_after>var fs = require('fs')
var haml = require('haml')
var clutch = require('clutch')
var querystring = require('querystring')
var models = require('./models')

db = process.db

if (!db.find('streamName', 'alerts')[0]) {
  new models.Stream('alerts')
}

var header = haml(fs.readFileSync('views/layouts/header.haml', 'utf8'))
var application = haml(fs.readFileSync('views/layouts/application.haml', 'utf8'))

function tails(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'})
  res.end(header({ yield: application() }))
}

function favicon(req, res) {
  res.writeHead(200, {'Content-Type': 'image/gif'})
  res.end()
}

function getStatic(req, res, dir, file) {
  fs.readFile('./public/' + dir + '/' + file, function (err, data) {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/plain'})
    } else {
      switch (dir) {
        case 'scripts':
          res.writeHead(200, {'Content-Type': 'text/javascript'})
          break
        case 'stylesheets':
          res.writeHead(200, {'Content-Type': 'text/css'})
          break
        case 'images':
          res.writeHead(200, {'Content-Type': 'image/png'})
          break
        default:
          res.writeHead(200, {'Content-Type': 'text/html'})
      }
      res.write(data)
    }
    res.end()
  })
}

function createStream(req, res) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end' , function() {
    var name = querystring.parse(requestString).name
    if (name) {
      var stream = db.find('streamName', name).pop()
      if (!stream || stream.streamEnabled == false) {
        new models.Stream(name)
        res.writeHead(201, {'Content-Type': 'text/plain'})
        res.write(name)
      } else {
        res.writeHead(409, 'Stream already exists', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(400, 'Missing field - name', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

function getStreams(req, res) {
  var streams = db.find('streamEnabled', true)
  var result = {}
  for (i in streams) {
    var stream = streams[i]
      result[stream.streamName] = {
        name: stream.streamName,
        terms: stream.streamTerms,
        forwarding: {
          enabled: stream.streamForwarding,
          token: stream.streamLogglyToken
        }
      }
  }
  res.writeHead(200, {'Content-Type': 'application/json'})
  res.end(JSON.stringify(result))
}

function removeStream(req, res, name) {
  var stream = db.find('streamName', name).pop()
  if (stream && stream.streamEnabled == true) {
    stream.disable()
    res.writeHead(204)
  } else {
    res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
  }
  res.end()
}

function createTerm(req, res, name) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end', function() {
    var term = querystring.parse(requestString).term
    if (term) {
      var stream = db.find('streamName', name).pop()
      if (stream) {
        if (stream.streamTerms.indexOf(term) == -1) {
          stream.createTerm(term)
          res.writeHead(201, {'Content-Type': 'text/plain'})
	} else {
          res.writeHead(409, 'Term already exists', {'Content-Type': 'text/plain'})
	}
      } else {
        res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(400, 'Missing field - term', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

function removeTerm(req, res, name, term) {
  var stream = db.find('streamName', name).pop()
  if (stream) {
    stream.removeTerm(term)
    res.writeHead(204)
  } else {
    res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
  }
  res.end()
}

function toggleForwarding(req, res, name) {
  var requestString = ''
  req.on('data', function(chunk) {
    requestString += chunk
  })
  req.on('end', function() {
    var token = querystring.parse(requestString).token
    var stream = db.find('streamName', name).pop()
    if (stream) {
      if (token) {
        stream.toggleForwarding(token)
        res.writeHead(200, {'Content-Type': 'text/plain'})
        res.write(stream.streamForwarding.toString())
      } else {
        res.writeHead(400, 'Missing field - token', {'Content-Type': 'text/plain'})
      }
    } else {
      res.writeHead(404, 'Stream does not exist', {'Content-Type': 'text/plain'})
    }
    res.end()
  })
}

exports.urls = clutch.route404([['GET /$', tails],
				['GET /favicon.ico', favicon],
				['POST /streams$', createStream],
				['POST /streams/(.*)/terms$', createTerm],
				['POST /streams/(.*)/forwarding$', toggleForwarding],
				['GET /streams$', getStreams],
				['DELETE /streams/(.*)/terms/(.*)$', removeTerm],
				['DELETE /streams/(.*)$', removeStream],
				['GET /(.*)/(.*)$', getStatic]])
<|endoftext|>


<commit_before>import Router from 'koa-router'
import React, { PropTypes } from 'react'
import _ from 'lodash'
import { renderToString } from 'react-dom/server'
import { MenuConfig } from './components/config/menu-config'
import { ComponentsIndex } from './components/config/components-index'
  /*菜单*/
import { Navigation } from './components/navigation.jsx'

/** api的路由逻辑**/
import hotelApi from './components/server/api/hotel'
import sampleApi from './components/server/api/sample'
import pringlesApi from './components/server/api/pringles'
import advApi from './components/server/api/adv'
import suiteApi from './components/server/api/suite'

import casesApi from './components/server/api/cases.js'
import followPhotoSeasonApi from './components/server/api/followPhotoSeason.js'
import followPhotoApi from './components/server/api/followPhoto.js'
import pringlesSeasonApi from './components/server/api/pringlesSeason.js'
import followVideoApi from './components/server/api/followVideo.js'
import followVideoSeasonApi from './components/server/api/followVideoSeason.js'
  /**
    api 资源路由
  **/
export const apiRouter = new Router({
    'prefix': '/api'
  }) // 单个的export 必须在声明时。
apiRouter.get('/', function* apiRoot(next) {
  yield next
  // 列出所有资源到列表
  this.body = {
    '/api/adv/all':'广告',
    '/api/sample/all':'作品',
    '/api/pringles/all':'客片',
    '/api/pringlesSeason/list':'客片分季',
    '/api/hotel/all':'酒店',
    '/api/suite/all':'套系',
    '/api/cases/all':'实景案例',
    '/api/followPhoto/all':'婚礼跟拍',
    '/api/followPhotoSeason/all':'婚礼跟拍分季',
    '/api/followVideo/all': '婚礼视频',
    '/api/followVideoSeason/all': '婚礼视频分季'
  }
})

/** 把api的router在此生成 **/
const apiRouterList = [
  advApi,
  hotelApi,
  sampleApi,
  pringlesApi,
  pringlesSeasonApi,
  suiteApi,
  casesApi,
  followPhotoApi,
  followVideoApi,
  followPhotoSeasonApi,
  followVideoSeasonApi
]
_.each(apiRouterList,(route,index)=>{
  _.each(route,(value,key)=>{
    apiRouter[key.split('+')[0]](key.split('+')[1], value)
  })
})

/**
 platform 主站的页面路由
**/

const siteRouter = new Router()
  /**
    templateName: ejs模板名称
    menuKey MenuConfig中配置的link字段
    parentKey MenuConfig中的顶层模块的key
  */
let renderOption = (templateName, menuKey, parentKey) => {
    return {
      'reactMarkup': renderToString(ComponentsIndex[templateName]),
      'reactNavMarkup': renderToString(<Navigation menuKey={parentKey ||'/'} currentKey={menuKey} />),
      'main': templateName // 客户端渲染使用的脚本名称和模板名称一致
    }
  }
  /**
  使用ejs引擎进行静态模板渲染
  在服务端。 所有的模块都是静态依赖导入。 目前采用手动方式。 只更改 components-index.js
  当前还是手动写此文件。等把流程跑通，会改为脚本生成此文件。 进一步减少工作量

  1. 配置人员在 menu-config.js 中新增菜单。 需要填写url结构，中文，因为名称
  2. 配置人员在 components-index.js 中指名 ejs模板和组件的对应关系
  3. routes根据 MenuConfig 和 ComponentsIndex 构建路由表
  4. 在components里面增加新的jsx
  5. 默认情况下。ejs会使用default.html进行jsx页面渲染。除非必要， 才需要用户新增自己的ejs模板页面
    例如：新的活动页（静态）

  i
  **/
  /** 首页 **/
siteRouter.get('/', function* index(next) {
  yield this.render('modules/default', renderOption('home', '/', '/'))
})

/** /home 也是首页 **/
siteRouter.get('/home', function* index(next) {
  yield this.render('modules/default', renderOption('home', '/home', '/home'))
})

siteRouter.get('/shot', function* index(next) {
  yield this.render('modules/default', renderOption('shot', '/shot', '/shot'))
})

/** 作品 **/
siteRouter.get('/sample', function* index(next) {
  yield this.render('modules/default', renderOption('sample', '/sample', '/shot'))
})

/** 客片 **/
siteRouter.get('/pringles', function* index(next) {
    yield this.render('modules/default', renderOption('pringles', '/pringles', '/shot'))
  })
  /* 套系 */
siteRouter.get('/suite', function* index(next) {
  yield this.render('modules/default', renderOption('suite', '/suite', '/shot'))
})

/** 婚宴预订 **/
// 列表
siteRouter.get('/hotel', function* index(next) {
    yield this.render('modules/default', renderOption('hotel', '/hotel', '/hotel'))
  })
  // 提交婚宴预订需求
siteRouter.get('/hotel-require', function* index(next) {
  yield this.render('modules/default', renderOption('hotel-require', '/hotel-require', '/hotel'))
})

/** 婚庆定制 **/
siteRouter.get('/scheme', function* index(next) {
    yield this.render('modules/default', renderOption('scheme', '/scheme', '/scheme'))
  })
  /**  实景案例 **/
siteRouter.get('/cases', function* index(next) {
    yield this.render('modules/default', renderOption('cases', '/cases', '/scheme'))
  })
  /** 婚礼跟拍 **/
siteRouter.get('/weddingpat', function* index(next) {
    yield this.render('modules/default', renderOption('weddingpat', '/weddingpat', '/scheme'))
  })
  /** 婚礼视频 **/
siteRouter.get('/weddingvideo', function* index(next) {
    yield this.render('modules/default', renderOption('weddingvideo', '/weddingvideo', '/scheme'))
  })
  /** 提交婚庆需求 **/
siteRouter.get('/scheme-require', function* index(next) {
  yield this.render('modules/default', renderOption('scheme-require', '/scheme-require', '/scheme'))
})

/** 礼服 **/
siteRouter.get('/dress', function* index(next) {
  yield this.render('modules/default', renderOption('dress', '/dress', '/dress'))
})

siteRouter.get('/dress-details', function* index(next) {
    yield this.render('modules/default', renderOption('dress-details', '/dress', '/dress'))
  })
  /** 微电影 **/
siteRouter.get('/movie', function* index(next) {
    yield this.render('modules/default', renderOption('movie', '/movie', '/movie'))
  })
  /** 婚礼用品 **/
siteRouter.get('/supply', function* index(next) {
    yield this.render('modules/default', renderOption('supply', '/supply', '/supply'))
  })
  /** 婚车租赁 **/
siteRouter.get('/car', function* index(next) {
  yield this.render('modules/default', renderOption('car', '/car', '/car'))
})

export { siteRouter }
<commit_msg>新增四大金刚缓冲层<commit_after>import Router from 'koa-router'
import React, { PropTypes } from 'react'
import _ from 'lodash'
import { renderToString } from 'react-dom/server'
import { MenuConfig } from './components/config/menu-config'
import { ComponentsIndex } from './components/config/components-index'
  /*菜单*/
import { Navigation } from './components/navigation.jsx'

/** api的路由逻辑**/
import hotelApi from './components/server/api/hotel'
import sampleApi from './components/server/api/sample'
import pringlesApi from './components/server/api/pringles'
import advApi from './components/server/api/adv'
import suiteApi from './components/server/api/suite'

import casesApi from './components/server/api/cases.js'
import followPhotoSeasonApi from './components/server/api/followPhotoSeason.js'
import followPhotoApi from './components/server/api/followPhoto.js'
import pringlesSeasonApi from './components/server/api/pringlesSeason.js'
import followVideoApi from './components/server/api/followVideo.js'
import followVideoSeasonApi from './components/server/api/followVideoSeason.js'

import photographerApi from './components/server/api/f4/photographer.js'
import cameraApi from './components/server/api/f4/camera.js'
import dresserApi from './components/server/api/f4/dresser.js'
import hostApi from './components/server/api/f4/host.js'

  /**
    api 资源路由
  **/
export const apiRouter = new Router({
    'prefix': '/api'
  }) // 单个的export 必须在声明时。
apiRouter.get('/', function* apiRoot(next) {
  yield next
  // 列出所有资源到列表
  this.body = {
    '/api/adv/all':'广告',
    '/api/sample/all':'作品',
    '/api/pringles/all':'客片',
    '/api/pringlesSeason/list':'客片分季',
    '/api/hotel/all':'酒店',
    '/api/suite/all':'套系',
    '/api/cases/all':'实景案例',
    '/api/followPhoto/all':'婚礼跟拍',
    '/api/followPhotoSeason/all':'婚礼跟拍分季',
    '/api/followVideo/all': '婚礼视频',
    '/api/followVideoSeason/all': '婚礼视频分季',
    '/api/f4/photographer': '四大金刚-摄影师作品',
    '/api/f4/camera': '四大金刚-摄像师作品',
    '/api/f4/dresser': '四大金刚-化妆师作品',
    '/api/f4/host': '四大金刚-主持师作品'
  }
})

/** 把api的router在此生成 **/
const apiRouterList = [
  advApi,
  hotelApi,
  sampleApi,
  pringlesApi,
  pringlesSeasonApi,
  suiteApi,
  casesApi,
  followPhotoApi,
  followVideoApi,
  followPhotoSeasonApi,
  followVideoSeasonApi,
  photographerApi,
  cameraApi,
  dresserApi,
  hostApi
]
_.each(apiRouterList,(route,index)=>{
  _.each(route,(value,key)=>{
    apiRouter[key.split('+')[0]](key.split('+')[1], value)
  })
})

/**
 platform 主站的页面路由
**/

const siteRouter = new Router()
  /**
    templateName: ejs模板名称
    menuKey MenuConfig中配置的link字段
    parentKey MenuConfig中的顶层模块的key
  */
let renderOption = (templateName, menuKey, parentKey) => {
    return {
      'reactMarkup': renderToString(ComponentsIndex[templateName]),
      'reactNavMarkup': renderToString(<Navigation menuKey={parentKey ||'/'} currentKey={menuKey} />),
      'main': templateName // 客户端渲染使用的脚本名称和模板名称一致
    }
  }
  /**
  使用ejs引擎进行静态模板渲染
  在服务端。 所有的模块都是静态依赖导入。 目前采用手动方式。 只更改 components-index.js
  当前还是手动写此文件。等把流程跑通，会改为脚本生成此文件。 进一步减少工作量

  1. 配置人员在 menu-config.js 中新增菜单。 需要填写url结构，中文，因为名称
  2. 配置人员在 components-index.js 中指名 ejs模板和组件的对应关系
  3. routes根据 MenuConfig 和 ComponentsIndex 构建路由表
  4. 在components里面增加新的jsx
  5. 默认情况下。ejs会使用default.html进行jsx页面渲染。除非必要， 才需要用户新增自己的ejs模板页面
    例如：新的活动页（静态）

  i
  **/
  /** 首页 **/
siteRouter.get('/', function* index(next) {
  yield this.render('modules/default', renderOption('home', '/', '/'))
})

/** /home 也是首页 **/
siteRouter.get('/home', function* index(next) {
  yield this.render('modules/default', renderOption('home', '/home', '/home'))
})

siteRouter.get('/shot', function* index(next) {
  yield this.render('modules/default', renderOption('shot', '/shot', '/shot'))
})

/** 作品 **/
siteRouter.get('/sample', function* index(next) {
  yield this.render('modules/default', renderOption('sample', '/sample', '/shot'))
})

/** 客片 **/
siteRouter.get('/pringles', function* index(next) {
    yield this.render('modules/default', renderOption('pringles', '/pringles', '/shot'))
  })
  /* 套系 */
siteRouter.get('/suite', function* index(next) {
  yield this.render('modules/default', renderOption('suite', '/suite', '/shot'))
})

/** 婚宴预订 **/
// 列表
siteRouter.get('/hotel', function* index(next) {
    yield this.render('modules/default', renderOption('hotel', '/hotel', '/hotel'))
  })
  // 提交婚宴预订需求
siteRouter.get('/hotel-require', function* index(next) {
  yield this.render('modules/default', renderOption('hotel-require', '/hotel-require', '/hotel'))
})

/** 婚庆定制 **/
siteRouter.get('/scheme', function* index(next) {
    yield this.render('modules/default', renderOption('scheme', '/scheme', '/scheme'))
  })
  /**  实景案例 **/
siteRouter.get('/cases', function* index(next) {
    yield this.render('modules/default', renderOption('cases', '/cases', '/scheme'))
  })
  /** 婚礼跟拍 **/
siteRouter.get('/weddingpat', function* index(next) {
    yield this.render('modules/default', renderOption('weddingpat', '/weddingpat', '/scheme'))
  })
  /** 婚礼视频 **/
siteRouter.get('/weddingvideo', function* index(next) {
    yield this.render('modules/default', renderOption('weddingvideo', '/weddingvideo', '/scheme'))
  })
  /** 提交婚庆需求 **/
siteRouter.get('/scheme-require', function* index(next) {
  yield this.render('modules/default', renderOption('scheme-require', '/scheme-require', '/scheme'))
})

/** 礼服 **/
siteRouter.get('/dress', function* index(next) {
  yield this.render('modules/default', renderOption('dress', '/dress', '/dress'))
})

siteRouter.get('/dress-details', function* index(next) {
    yield this.render('modules/default', renderOption('dress-details', '/dress', '/dress'))
  })
  /** 微电影 **/
siteRouter.get('/movie', function* index(next) {
    yield this.render('modules/default', renderOption('movie', '/movie', '/movie'))
  })
  /** 婚礼用品 **/
siteRouter.get('/supply', function* index(next) {
    yield this.render('modules/default', renderOption('supply', '/supply', '/supply'))
  })
  /** 婚车租赁 **/
siteRouter.get('/car', function* index(next) {
  yield this.render('modules/default', renderOption('car', '/car', '/car'))
})

export { siteRouter }
<|endoftext|>


<commit_before>var checkin = require('./checkin.js'),
    getDetails = require('./getDetails.js'),
    offers = require('./offers.js'),
    register = require('./register.js'),
    del = require('./del.js'),
    groups = require('./groups.js');

exports.getRoutes = function(server){
 var users = "/users",
        business = "/business",
        offers = '/offers'

   // The way this works by sending a parameter of "business" and looks up how many points to add from couchDB
    server.get({
        path: users + "/test"
    }, function(req, res, next) {
        req.send('works')
        req.end();
    });
    // The way this works by sending a parameter of "business" and looks up how many points to add from couchDB
    server.put({
        path: users + "/checkin"
    }, function(req, res, next) {
        checkin.checkin(req, res, next);
    });
    // Get details for user
    server.get({
        path: users + "/get/:username"
    }, function(req, res, next) {
        getDetails.getDetails(req, res, next, 'users');
    });
    // Get details for business
    server.get({
        path: business + "/get/:businessname"
    }, function(req, res, next) {
        getDetails.getDetails(req, res, next, 'business');
    });
    //Register user
    server.post({
        path: users
    }, function(req, res, next) {
        if(req.authorization.scheme !== 'Basic') {
            return next(new restify.UnauthorizedError('Basic HTTP auth required'));
            failed = true;
        } else {
            register.register(req, res, next, 'users');
        }
    });
    // Register business.
    server.post({
        path: business
    }, function(req, res, next) {
        if(req.authorization.scheme !== 'Basic') {
            return next(new restify.UnauthorizedError('Basic HTTP auth required'));
            failed = true;
        } else {
            register.register(req, res, next, 'business');
        }
    });
    // Delete user
    server.del({
        path: users
    }, function(req, res, next) {
        del.del(req, res, next, 'users');
    });
    // Delete business
    server.del({
        path: business
    }, function(req, res, next) {
        del.del(req, res, next, 'business');
    });
    //user/creategroup?username=username&groupname=name&description=description&competition=freshers
    server.post({
        path: users + "/groups"
    }, function(req, res, next) {
        groups.creategroup(req, res, next);
    });
    //?username=username&groupname=test21
    server.get({
        path: users + "/getgroup"
    }, function(req, res, next) {
        groups.showgroup(req, res, next);
    });
    //?username=username&competition=freshers
    server.get({
        path: users + "/getgroups"
    }, function(req, res, next) {
        groups.showcompetitiongroup(req, res, next);
    });
    //?username=username&groupname=test21
    server.put({
        path: users + "/joingroup"
    }, function(req, res, next) {
        groups.joinGroup(req, res, next);
    });
    //Create Offer
    server.post({
        path: business + offers
    }, function(req, res, next) {
        offer.addOffer(req, res, next);
    });
    //Get all Offers
    server.get({
        path: business + offers + '/:businessname'
    }, function(req, res, next) {
        offer.getAllOffers(req, res, next);
    });
    //Redeem Offer
    server.put({
        path: business + offers + '/redeem'
    }, function(req, res, next) {
        offer.redeemOffer(req, res, next);
    });
 }
<commit_msg>Changed offers to offer<commit_after>var checkin = require('./checkin.js'),
    getDetails = require('./getDetails.js'),
    offer = require('./offers.js'),
    register = require('./register.js'),
    del = require('./del.js'),
    groups = require('./groups.js');

exports.getRoutes = function(server){
 var users = "/users",
        business = "/business",
        offers = '/offers'

   // The way this works by sending a parameter of "business" and looks up how many points to add from couchDB
    server.get({
        path: users + "/test"
    }, function(req, res, next) {
        req.send('works')
        req.end();
    });
    // The way this works by sending a parameter of "business" and looks up how many points to add from couchDB
    server.put({
        path: users + "/checkin"
    }, function(req, res, next) {
        checkin.checkin(req, res, next);
    });
    // Get details for user
    server.get({
        path: users + "/get/:username"
    }, function(req, res, next) {
        getDetails.getDetails(req, res, next, 'users');
    });
    // Get details for business
    server.get({
        path: business + "/get/:businessname"
    }, function(req, res, next) {
        getDetails.getDetails(req, res, next, 'business');
    });
    //Register user
    server.post({
        path: users
    }, function(req, res, next) {
        if(req.authorization.scheme !== 'Basic') {
            return next(new restify.UnauthorizedError('Basic HTTP auth required'));
            failed = true;
        } else {
            register.register(req, res, next, 'users');
        }
    });
    // Register business.
    server.post({
        path: business
    }, function(req, res, next) {
        if(req.authorization.scheme !== 'Basic') {
            return next(new restify.UnauthorizedError('Basic HTTP auth required'));
            failed = true;
        } else {
            register.register(req, res, next, 'business');
        }
    });
    // Delete user
    server.del({
        path: users
    }, function(req, res, next) {
        del.del(req, res, next, 'users');
    });
    // Delete business
    server.del({
        path: business
    }, function(req, res, next) {
        del.del(req, res, next, 'business');
    });
    //user/creategroup?username=username&groupname=name&description=description&competition=freshers
    server.post({
        path: users + "/groups"
    }, function(req, res, next) {
        groups.creategroup(req, res, next);
    });
    //?username=username&groupname=test21
    server.get({
        path: users + "/getgroup"
    }, function(req, res, next) {
        groups.showgroup(req, res, next);
    });
    //?username=username&competition=freshers
    server.get({
        path: users + "/getgroups"
    }, function(req, res, next) {
        groups.showcompetitiongroup(req, res, next);
    });
    //?username=username&groupname=test21
    server.put({
        path: users + "/joingroup"
    }, function(req, res, next) {
        groups.joinGroup(req, res, next);
    });
    //Create Offer
    server.post({
        path: business + offers
    }, function(req, res, next) {
        offer.addOffer(req, res, next);
    });
    //Get all Offers
    server.get({
        path: business + offers + '/:businessname'
    }, function(req, res, next) {
        offer.getAllOffers(req, res, next);
    });
    //Redeem Offer
    server.put({
        path: business + offers + '/redeem'
    }, function(req, res, next) {
        offer.redeemOffer(req, res, next);
    });
 }
<|endoftext|>


<commit_before>app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

/*
app.get('/rawMSC', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('scratchTools/dumpMSC.jade');
});
*/

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}
console.log(cycle)
console.log(steps)
console.log(durations)
	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"] " + steps[i]]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"] " + durations[i]]);
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});<commit_msg>weird cycle registration bug<commit_after>app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

/*
app.get('/rawMSC', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('scratchTools/dumpMSC.jade');
});
*/

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}
console.log(cycle)

	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"] " + steps[i]]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"] " + durations[i]]);
		console.log("set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"] " + steps[i])
		console.log("set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"] " + durations[i])
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});<|endoftext|>


<commit_before>/**
 * Created by 3er on 1/5/15.
 */

// Since Node 0.8, .existsSync() moved from path to fs:
var path = require('path');
var fs = require('fs');
var walk = require('walk');
var config = require('./config/oped');
var PRIVATE = require('./config/private');
var async = require('async');
var _existsSync = fs.existsSync || path.existsSync;

var _ = require('underscore');
var moment = require('moment');
var formidable = require('formidable');

var chokidar = require('chokidar');
var checklist = require('./checkVideoUrl').checklist;
var replace = require('./checkVideoUrl').replace;
// qiniu
var qiniu = require('qiniu')
qiniu.conf.ACCESS_KEY = PRIVATE.qiniu.access_key
qiniu.conf.SECRET_KEY = PRIVATE.qiniu.secret_key

var compress = require('./compress');

var generateURL = function (ver, key) {
    var deadline = Math.floor(Date.now() / 1000) + ver.expiration;
    var link = encodeURI('http://' + ver.domain + '/' + key + '?e=' + deadline);
    var token = qiniu.conf.ACCESS_KEY + ':' +
        qiniu.util.base64ToUrlSafe(qiniu.util.hmacSha1(link, qiniu.conf.SECRET_KEY));
    return link +
        '&token=' + token;
}

var generateInfoURL = function (ver, key) {
    var deadline = Math.floor(Date.now() / 1000) + ver.expiration;
    var link = encodeURI('http://' + ver.domain + '/' + key + '?avinfo&e=' + deadline);
    var token = qiniu.conf.ACCESS_KEY + ':' +
        qiniu.util.base64ToUrlSafe(qiniu.util.hmacSha1(link, qiniu.conf.SECRET_KEY));
    return link +
        '&token=' + token;
}

var generateCompressScripts = function (path, oped) {
    var cmd = compress.generate(path, oped);
    // console.log(cmd);
    return cmd;
}
var deleteAsync = function (key, cb) {
    var rmQiniu = function (reso, key, next) {
        var client = new qiniu.rs.Client();
        client.remove(PRIVATE.qiniu[reso].bucket, key, function (err) {
            if (err) {
                next(err)
            }
            else {
                //console.log('a')
                next()
            }
        });
    };

    var rmLocal = function (reso, key, next) {
        var filePath = config.dir.rsync + reso + '/' + key;
        fs.unlink(filePath, function (err) {
            if (err) {
                next(err);
            }
            else {
                // console.log('b')
                next();
            }
        });
    };
    async.parallel([
            function (next) {
                rmQiniu('origin', key, next)
            }, function (next) {
                rmQiniu('high', key, next)
            }, function (next) {
                rmQiniu('medium', key, next)
            }, function (next) {
                rmQiniu('low', key, next)
            }, function (next) {
                rmQiniu('mobile',key,next)
            },
            function (next) {
                rmLocal('originNew', key, next)
            }, function (next) {
                rmLocal('highNew', key, next)
            }, function (next) {
                rmLocal('mediumNew', key, next)
            }, function (next) {
                rmLocal('lowNew', key, next)
            },function(next){
                rmLocal('mobileNew',key,next)
            }
        ], cb
    );

}

var deleteList = [];

module.exports = function (app) {
    var testAdd = config.dir.rsync + 'mobileNew/';

    var watcher = chokidar.watch(testAdd, {ignored: /\.DS_Store/, persistent: true});

    //watcher.add(['/1.txt', '2.txt', '3.txt']);
    watcher.on('add', function (path) {
        var testArr = _.map(deleteList, function (item) {
            return testAdd + item;
        });
        var judger = _.find(testArr, function (asis) {
            return asis === path;
        });

        if (judger !== undefined) {
            var delKey = path.replace(/^.*[\/]/, '');
            deleteAsync(delKey, function (err, result) {
                if (err) {
                    console.log(err);
                }
                //reserved console log which indicates the delete process
                console.log('delete success: ' + path);
                var index = deleteList.indexOf(delKey);

                if (index > -1) {
                    deleteList.splice(index, 1);
                }
            });
        }
    });
    app.get('/checklist', function (req, res) {
        checklist(function (err, data) {
            if (err) {res.status(500).json(err);}
            else {
                res.status(200).json(data);
            }
        })

    });
    app.post('/replace', function (req, res) {
        var data = req.body;
        replace(data, function (err) {
            if (err) {
                res.status(500);
                res.end();
            }
            else {
                res.status(200);
                res.end();
            }

        })
    })

    // http api
    app.get('/video/opeds', function (req, res) {
        res.status(200).json(config.opeds);
    });

    app.post('/video/upload', function (req, res) {
        var dir = config.dir;
        // headers
        res.setHeader('Pragma', 'no-cache');
        res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
        res.setHeader('Content-Disposition', 'inline; filename="files.json"');

        // init
        var ret = {files: []};
        var form = new formidable.IncomingForm();
        form.encoding = 'utf-8';
        // 把mov转为mp4
        form.keepExtensions = false;

        var command = new compress.oped();

        // make upload directory
        form.uploadDir = dir.upload + moment().format('YYYYMMDDhhmmss/');

        // TODO: Exception判断
        fs.mkdirSync(form.uploadDir);

        // handle uplaod
        form.on('fileBegin', function (name, file) {
            var filter = new RegExp("[~!@#$^&*()=|{}':;',\\[\\].<>/?]");
            file.name = file.name.replace(/\.[^/.]+$/g, '').replace(/-/g, "_").replace(/\s+/g,'');
            if(filter.test(file.name)){
                ret.error = '视频名不能包含英文标点、括号（可以用中文输入法的标点，括号等）';
                res.status(500).json({error:ret.error});
            }
            file.name = file.name + '.mp4';
            //console.log(file.name)
            file.path = form.uploadDir + file.name;

            ret.files.push({name: file.name, path: file.path});
            if (_existsSync(file.path) || _existsSync(config.dir.rsync + 'originNew/' + file.name)) {
                ret.files[0].error = '文件已存在，不能覆盖';
                //console.log(ret.files[0].error);
            }
        }).on('field', function (name, value) {
            // 生成片头片尾命令
            command[name] = value;
        }).on('file', function (name, file) {
//                console.log(file.path);
            ret.files[0].size = file.size;
        }).on('aborted', function () {
            ret.files.forEach(function (file) {
                fs.unlinkSync(file.path);
            });
            fs.rmdirSync(path.dirname(ret.files[0].path));
            //console.log('删除文件夹')
        }).on('error', function (e) {
            ret.files[0].error = e;
            // console.log(e);
        }).on('progress', function (bytesReceived) {
        }).on('end', function () {
            var error = ret.files[0].error;
	    if (!error) {
                res.status(201).json(ret);
		if (_existsSync(form.uploadDir)) {
                    generateCompressScripts(ret.files[0].path, command)
                }
            }else{
		res.status(500).json(error);
                ret.files.forEach(function (file) {
                    fs.unlinkSync(file.path);
                });
                fs.rmdir(path.dirname(ret.files[0].path));
            }
        }).parse(req);
    });

    app.get('/qiniu/link/origin/:key', function (req, res) {
        var l = generateURL(PRIVATE.qiniu['origin'], req.param('key'), qiniu);
        res.redirect(l);
    });

    app.get('/qiniu/info/origin/:key', function (req, res) {
//        console.log(req.param('ver'));
//        console.log(req.param('key'));
        var l = generateInfoURL(PRIVATE.qiniu['high'], req.param('key'), qiniu);
        res.redirect(l);
    });

    app.post('/qiniu/list', function (req, res) {
        var marker = null;
        qiniu.rsf.listPrefix(PRIVATE.qiniu.origin.bucket, '', marker, 999999, function (err, ret) {
            if (err) {
                res.status(500).send(err);
                console.log(err);
            } else {
                // process ret.marker & ret.items
//           console.log(ret.marker);
//          console.log(ret.items);

                var retr = _.chain(ret.items)
                    .sortBy(function (item) {
                        return item.key;
                    })
//                    .each(function (item) {
//                        item.link = generateURL(item, qiniu, PRIVATE.origin)
//                    })
                    .value();
                res.status(200).send({
                    current: 1,
                    rowCount: -1,
                    rows: retr,
                    total: retr.length
                });
            }
        });
    });
    app.delete('/qiniu/list/:key', function (req, res) {
        var key = req.params.key;
        deleteAsync(key, function (err) {

            if (err) console.log(err);
            res.status(200);
            res.end('delete success')

        });

    });

    app.post('/video/compressing/:key', function (req, res) {
        deleteList.push(req.params.key);
        _.uniq(deleteList);
        res.status(201);
        res.end('cancel success');
    });

    app.post('/video/compressing', function (req, res) {
        // mock
        var arr = [];
        var filters = [
            '.DS_Store', 'command','outputOri.mp4','outputH.mp4','outputL.mp4','outputM.mp4','outputMo.mp4'
        ]

        var options = {
            listeners: {
                names: function (root, nodeNamesArray) {
                    _.chain(nodeNamesArray)
                        .flatten()
                        .difference(filters)
                        .reject(function (item) {
                            return (item.length == 14) && (item.indexOf('201') == 0);
                        })
                        .each(function (item) {
                            arr.push({key: item, progress: "compress"})
                        });
                }, directories: function (root, dirStatsArray, next) {
                    next();
                }, files: function (root, fileStats, next) {
                    next();
                }, errors: function (root, nodeStatsArray, next) {
                    next();
                }
            }
        };

        walker = walk.walkSync(config.dir.upload, options);

//        console.log("all done");

        var retr = arr;
        var tempKeys = _.object(deleteList, ['']);
        var temp = _.filter(retr, function (item) {
            return !(item.key in tempKeys);
        });
//            _.chain(arr)
//            .sortBy(function (item) {
//                return item.progress;
//            })
//            .value();

        res.status(200).send({
            current: 1,
            rowCount: -1,
            rows: temp,
            total: 2
        });
    });
}
<commit_msg>fix bugs: add file name test<commit_after>/**
 * Created by 3er on 1/5/15.
 */

// Since Node 0.8, .existsSync() moved from path to fs:
var path = require('path');
var fs = require('fs');
var walk = require('walk');
var config = require('./config/oped');
var PRIVATE = require('./config/private');
var async = require('async');
var _existsSync = fs.existsSync || path.existsSync;

var _ = require('underscore');
var moment = require('moment');
var formidable = require('formidable');

var chokidar = require('chokidar');
var checklist = require('./checkVideoUrl').checklist;
var replace = require('./checkVideoUrl').replace;
// qiniu
var qiniu = require('qiniu')
qiniu.conf.ACCESS_KEY = PRIVATE.qiniu.access_key
qiniu.conf.SECRET_KEY = PRIVATE.qiniu.secret_key

var compress = require('./compress');

var generateURL = function (ver, key) {
    var deadline = Math.floor(Date.now() / 1000) + ver.expiration;
    var link = encodeURI('http://' + ver.domain + '/' + key + '?e=' + deadline);
    var token = qiniu.conf.ACCESS_KEY + ':' +
        qiniu.util.base64ToUrlSafe(qiniu.util.hmacSha1(link, qiniu.conf.SECRET_KEY));
    return link +
        '&token=' + token;
}

var generateInfoURL = function (ver, key) {
    var deadline = Math.floor(Date.now() / 1000) + ver.expiration;
    var link = encodeURI('http://' + ver.domain + '/' + key + '?avinfo&e=' + deadline);
    var token = qiniu.conf.ACCESS_KEY + ':' +
        qiniu.util.base64ToUrlSafe(qiniu.util.hmacSha1(link, qiniu.conf.SECRET_KEY));
    return link +
        '&token=' + token;
}

var generateCompressScripts = function (path, oped) {
    var cmd = compress.generate(path, oped);
    // console.log(cmd);
    return cmd;
}
var deleteAsync = function (key, cb) {
    var rmQiniu = function (reso, key, next) {
        var client = new qiniu.rs.Client();
        client.remove(PRIVATE.qiniu[reso].bucket, key, function (err) {
            if (err) {
                next(err)
            }
            else {
                //console.log('a')
                next()
            }
        });
    };

    var rmLocal = function (reso, key, next) {
        var filePath = config.dir.rsync + reso + '/' + key;
        fs.unlink(filePath, function (err) {
            if (err) {
                next(err);
            }
            else {
                // console.log('b')
                next();
            }
        });
    };
    async.parallel([
            function (next) {
                rmQiniu('origin', key, next)
            }, function (next) {
                rmQiniu('high', key, next)
            }, function (next) {
                rmQiniu('medium', key, next)
            }, function (next) {
                rmQiniu('low', key, next)
            }, function (next) {
                rmQiniu('mobile',key,next)
            },
            function (next) {
                rmLocal('originNew', key, next)
            }, function (next) {
                rmLocal('highNew', key, next)
            }, function (next) {
                rmLocal('mediumNew', key, next)
            }, function (next) {
                rmLocal('lowNew', key, next)
            },function(next){
                rmLocal('mobileNew',key,next)
            }
        ], cb
    );

}

var deleteList = [];

module.exports = function (app) {
    var testAdd = config.dir.rsync + 'mobileNew/';

    var watcher = chokidar.watch(testAdd, {ignored: /\.DS_Store/, persistent: true});

    //watcher.add(['/1.txt', '2.txt', '3.txt']);
    watcher.on('add', function (path) {
        var testArr = _.map(deleteList, function (item) {
            return testAdd + item;
        });
        var judger = _.find(testArr, function (asis) {
            return asis === path;
        });

        if (judger !== undefined) {
            var delKey = path.replace(/^.*[\/]/, '');
            deleteAsync(delKey, function (err, result) {
                if (err) {
                    console.log(err);
                }
                //reserved console log which indicates the delete process
                console.log('delete success: ' + path);
                var index = deleteList.indexOf(delKey);

                if (index > -1) {
                    deleteList.splice(index, 1);
                }
            });
        }
    });
    app.get('/checklist', function (req, res) {
        checklist(function (err, data) {
            if (err) {res.status(500).json(err);}
            else {
                res.status(200).json(data);
            }
        })

    });
    app.post('/replace', function (req, res) {
        var data = req.body;
        replace(data, function (err) {
            if (err) {
                res.status(500);
                res.end();
            }
            else {
                res.status(200);
                res.end();
            }

        })
    })

    // http api
    app.get('/video/opeds', function (req, res) {
        res.status(200).json(config.opeds);
    });

    app.post('/video/upload', function (req, res) {
        var dir = config.dir;
        // headers
        res.setHeader('Pragma', 'no-cache');
        res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
        res.setHeader('Content-Disposition', 'inline; filename="files.json"');

        // init
        var ret = {files: []};
        var form = new formidable.IncomingForm();
        form.encoding = 'utf-8';
        // 把mov转为mp4
        form.keepExtensions = false;

        var command = new compress.oped();

        // make upload directory
        form.uploadDir = dir.upload + moment().format('YYYYMMDDhhmmss/');

        // TODO: Exception判断
        fs.mkdirSync(form.uploadDir);

        // handle uplaod
        form.on('fileBegin', function (name, file) {
            var filter = new RegExp("[~!@#$^&*()=|{}':;',\\[\\].<>/?]");
            file.name = file.name.replace(/\.[^/.]+$/g, '').replace(/-/g, "_").replace(/\s+/g,'');
            if(filter.test(file.name)){
                ret.files[0].error = '视频名不能包含英文标点、括号（可以用中文输入法的标点，括号等）';
            }
            file.name = file.name + '.mp4';
            //console.log(file.name)
            file.path = form.uploadDir + file.name;

            ret.files.push({name: file.name, path: file.path});
            if (_existsSync(file.path) || _existsSync(config.dir.rsync + 'originNew/' + file.name)) {
                ret.files[0].error = '文件已存在，不能覆盖';
                //console.log(ret.files[0].error);
            }
        }).on('field', function (name, value) {
            // 生成片头片尾命令
            command[name] = value;
        }).on('file', function (name, file) {
//                console.log(file.path);
            ret.files[0].size = file.size;
        }).on('aborted', function () {
            ret.files.forEach(function (file) {
                fs.unlinkSync(file.path);
            });
            fs.rmdirSync(path.dirname(ret.files[0].path));
            //console.log('删除文件夹')
        }).on('error', function (e) {
            ret.files[0].error = e;
            // console.log(e);
        }).on('progress', function (bytesReceived) {
        }).on('end', function () {
            var error = ret.files[0].error;
	    if (!error) {
            res.status(201).json(ret);
            if (_existsSync(form.uploadDir)) {
                generateCompressScripts(ret.files[0].path, command)
            }
        }else{
            ret.files.forEach(function (file) {
                fs.unlinkSync(file.path);
            });
            fs.rmdir(path.dirname(ret.files[0].path));
            res.status(500).json(error);
        }
        }).parse(req);
    });

    app.get('/qiniu/link/origin/:key', function (req, res) {
        var l = generateURL(PRIVATE.qiniu['origin'], req.param('key'), qiniu);
        res.redirect(l);
    });

    app.get('/qiniu/info/origin/:key', function (req, res) {
//        console.log(req.param('ver'));
//        console.log(req.param('key'));
        var l = generateInfoURL(PRIVATE.qiniu['high'], req.param('key'), qiniu);
        res.redirect(l);
    });

    app.post('/qiniu/list', function (req, res) {
        var marker = null;
        qiniu.rsf.listPrefix(PRIVATE.qiniu.origin.bucket, '', marker, 999999, function (err, ret) {
            if (err) {
                res.status(500).send(err);
                console.log(err);
            } else {
                // process ret.marker & ret.items
//           console.log(ret.marker);
//          console.log(ret.items);

                var retr = _.chain(ret.items)
                    .sortBy(function (item) {
                        return item.key;
                    })
//                    .each(function (item) {
//                        item.link = generateURL(item, qiniu, PRIVATE.origin)
//                    })
                    .value();
                res.status(200).send({
                    current: 1,
                    rowCount: -1,
                    rows: retr,
                    total: retr.length
                });
            }
        });
    });
    app.delete('/qiniu/list/:key', function (req, res) {
        var key = req.params.key;
        deleteAsync(key, function (err) {

            if (err) console.log(err);
            res.status(200);
            res.end('delete success')

        });

    });

    app.post('/video/compressing/:key', function (req, res) {
        deleteList.push(req.params.key);
        _.uniq(deleteList);
        res.status(201);
        res.end('cancel success');
    });

    app.post('/video/compressing', function (req, res) {
        // mock
        var arr = [];
        var filters = [
            '.DS_Store', 'command','outputOri.mp4','outputH.mp4','outputL.mp4','outputM.mp4','outputMo.mp4','mktoutputH.mp4',
            'mktoutputL.mp4',"mktoutputM.mp4"
        ]

        var options = {
            listeners: {
                names: function (root, nodeNamesArray) {
                    _.chain(nodeNamesArray)
                        .flatten()
                        .difference(filters)
                        .reject(function (item) {
                            return (item.length == 14) && (item.indexOf('201') == 0);
                        })
                        .each(function (item) {
                            arr.push({key: item, progress: "compress"})
                        });
                }, directories: function (root, dirStatsArray, next) {
                    next();
                }, files: function (root, fileStats, next) {
                    next();
                }, errors: function (root, nodeStatsArray, next) {
                    next();
                }
            }
        };

        walker = walk.walkSync(config.dir.upload, options);

//        console.log("all done");

        var retr = arr;
        var tempKeys = _.object(deleteList, ['']);
        var temp = _.filter(retr, function (item) {
            return !(item.key in tempKeys);
        });
//            _.chain(arr)
//            .sortBy(function (item) {
//                return item.progress;
//            })
//            .value();

        res.status(200).send({
            current: 1,
            rowCount: -1,
            rows: temp,
            total: 2
        });
    });
}
<|endoftext|>


<commit_before>

function raw_data_transformation(args){
    'use strict';

    function nonarray_obj(d){
        return (d instanceof Object && !(d instanceof Array));
    }

    //
    if (args.chart_type == 'line'){
        var is_unnested_obj_array = (args.data[0] instanceof Object && !(args.data[0] instanceof Array));
        var is_unnested_array_of_arrays = (
            args.data[0] instanceof Array &&
            !(args.data[0][0] instanceof Object &&
            !(args.data[0][0] instanceof Date)));

        if(
            is_unnested_obj_array || is_unnested_array_of_arrays){
            // && (!(args.data[0][0] instanceof Array) || args.data[0] instanceof Object )
            args.data = [args.data];
        }
    } else {
        if (!(args.data[0] instanceof Array)){
            args.data = [args.data];
        }
    }

    if (args.y_accessor instanceof Array){
        args.data = args.data.map(function(_d){
            return args.y_accessor.map(function(ya){
                return _d.map(function(di){
                    di = clone(di);
                    if (di[ya]==undefined){
                        return undefined;
                    }
                    di['multiline_y_accessor'] = di[ya];
                    return di;
                }).filter(function(di){
                    return di != undefined;
                })
            })
        })[0];

        args.y_accessor = 'multiline_y_accessor';
    }

    //sort x-axis data
    if (args.chart_type == 'line'){
        for(var i=0; i<args.data.length; i++) {
            args.data[i].sort(function(a, b) {
                return a[args.x_accessor] - b[args.x_accessor];
            });
        }
    }

    return this
}

function process_line(args) {
    'use strict';
    //are we replacing missing y values with zeros?

    //do we have a time-series?
    var is_time_series = ($.type(args.data[0][0][args.x_accessor]) == 'date')
            ? true
            : false;

    if(args.missing_is_zero && args.chart_type == 'line' && is_time_series) {
        for(var i=0;i<args.data.length;i++) {
            var first = args.data[i][0];
            var last = args.data[i][args.data[i].length-1];
            //initialize our new array for storing the processed data
            var processed_data = [];

            //we'll be starting from the day after our first date
            var start_date = clone(first[args.x_accessor]).setDate(first[args.x_accessor].getDate() + 1);

            //if we've set a max_x, add data points up to there
            var from = (args.min_x) ? args.min_x : start_date;
            var upto = (args.max_x) ? args.max_x : last[args.x_accessor];
            for (var d = new Date(from); d <= upto; d.setDate(d.getDate() + 1)) {
                var o = {};
                d.setHours(0, 0, 0, 0);

                //add the first date item (judge me not, world)
                //we'll be starting from the day after our first date
                if(Date.parse(d) == Date.parse(new Date(start_date))) {
                    processed_data.push(clone(args.data[i][0]));
                }

                //check to see if we already have this date in our data object
                var existing_o = null;
                $.each(args.data[i], function(i, val) {
                    if(Date.parse(val.date) == Date.parse(new Date(d))) {
                        existing_o = val;

                        return false;
                    }
                })

                //if we don't have this date in our data object, add it and set it to zero
                if(!existing_o) {
                    o[args.x_accessor] = new Date(d);
                    o[args.y_accessor] = 0;
                    processed_data.push(o);
                }
                //otherwise, use the existing object for that date
                else {
                    processed_data.push(existing_o);
                }

                //add the last data item
                if(Date.parse(d) == Date.parse(new Date(last[args.x_accessor]))) {
                    processed_data.push(last);
                }
            }

            //update our date object
            args.data[i] = processed_data;
        }
    }

    return this;
}

function process_histogram(args){
    'use strict';
    // if args.binned=False, then we need to bin the data appropriately.
    // if args.binned=True, then we need to make sure to compute the relevant computed data.
    // the outcome of either of these should be something in args.computed_data.
    // the histogram plotting function will be looking there for the data to plot.

    // we need to compute an array of objects.
    // each object has an x, y, and dx.

    // histogram data is always single dimension
    var our_data = args.data[0];
    var extracted_data;
    if (args.binned==false){
        // use d3's built-in layout.histogram functionality to compute what you need.

        if (typeof(our_data[0]) == 'object'){
            // we are dealing with an array of objects. Extract the data value of interest.
            extracted_data = our_data
                .map(function(d){
                    return d[args.x_accessor];
                });
        } else if (typeof(our_data[0]) == 'number'){
            // we are dealing with a simple array of numbers. No extraction needed.
            extracted_data = our_data;
        }
        else {
            console.log('TypeError: expected an array of numbers, found ' + typeof(our_data[0]));
            return;
        }

        var hist = d3.layout.histogram()
        if (args.bins){
            hist = hist.bins(args.bins);
        }
        args.processed_data = hist(extracted_data)
            .map(function(d){
                // extract only the data we need per data point.
                return {'x': d['x'], 'y':d['y'], 'dx': d['dx']};
            })
    } else {
        // here, we just need to reconstruct the array of objects
        // take the x accessor and y accessor.
        // pull the data as x and y. y is count.

        args.processed_data = our_data.map(function(d){
            return {'x': d[args.x_accessor], 'y': d[args.y_accessor]}
        });
        var this_pt;
        var next_pt;
        // we still need to compute the dx component for each data point
        for (var i=0; i < args.processed_data.length; i++){
            this_pt = args.processed_data[i];
            if (i == args.processed_data.length-1){
                this_pt.dx = args.processed_data[i-1].dx;
            } else {
                next_pt = args.processed_data[i+1];
                this_pt.dx = next_pt.x - this_pt.x;
            }
        }
    }
    args.data = [args.processed_data];
    args.x_accessor = args.processed_x_accessor;
    args.y_accessor = args.processed_y_accessor;
    return this;
}

function process_categorical_variables(args){
    // For use with bar charts, etc.
    'use strict';
    var extracted_data, processed_data={}, pd=[];
    var our_data = args.data[0];
    args.categorical_variables = [];

    if (args.binned == false){
        if (typeof(our_data[0]) == 'object') {
            // we are dealing with an array of objects. Extract the data value of interest.
            extracted_data = our_data
                .map(function(d){
                    return d[args.y_accessor];
                });
        } else {
            extracted_data = our_data;
        }
        var this_dp;
        for (var i=0; i< extracted_data.length; i++){
            this_dp=extracted_data[i];
            if (args.categorical_variables.indexOf(this_dp) == -1) args.categorical_variables.push(this_dp)
            if (!processed_data.hasOwnProperty(this_dp)) processed_data[this_dp]=0;

            processed_data[this_dp]+=1;
        }
        processed_data = Object.keys(processed_data).map(function(d){
            var obj = {};
            obj[args.x_accessor] = processed_data[d];
            obj[args.y_accessor] = d;
            return obj;
        })
    } else {
        // nothing needs to really happen here.
        processed_data = our_data;
        args.categorical_variables = d3.set(processed_data.map(function(d){
            return d[args.y_accessor];
        })).values();
        args.categorical_variables.reverse();
    }
    args.data = [processed_data];
    return this;
}

function process_point(args){
    'use strict';
    var data = args.data[0];
    var x = data.map(function(d){return d[args.x_accessor]});
    var y = data.map(function(d){return d[args.y_accessor]});
    if (args.least_squares){
        args.ls_line = least_squares(x,y);
    };

    //args.lowess_line = lowess_robust(x,y, .5, 100)
    return this;

}
<commit_msg>bit of code cleanup in process.js<commit_after>

function raw_data_transformation(args){
    'use strict';

    // We need to account for a few data format cases:
    // 1. [{key:__, value:__}, ...]                              // unnested obj-arrays
    // 2. [[{key:__, value:__}, ...], [{key:__, value:__}, ...]] // nested obj-arrays
    // 3. [[4323, 2343],..]                                      // unnested 2d array
    // 4. [[[4323, 2343],..] , [[4323, 2343],..]]                // nested 2d array
    if (args.chart_type == 'line'){
        var is_unnested_obj_array = (args.data[0] instanceof Object && !(args.data[0] instanceof Array));
        var is_unnested_array_of_arrays = (
            args.data[0] instanceof Array &&
            !(args.data[0][0] instanceof Object &&
            !(args.data[0][0] instanceof Date)));

        if(
            is_unnested_obj_array || is_unnested_array_of_arrays){
            args.data = [args.data];
        }
    } else {
        if (!(args.data[0] instanceof Array)){
            args.data = [args.data];
        }
    }

    if (args.y_accessor instanceof Array){
        args.data = args.data.map(function(_d){
            return args.y_accessor.map(function(ya){
                return _d.map(function(di){
                    di = clone(di);
                    if (di[ya]==undefined){
                        return undefined;
                    }
                    di['multiline_y_accessor'] = di[ya];
                    return di;
                }).filter(function(di){
                    return di != undefined;
                })
            })
        })[0];

        args.y_accessor = 'multiline_y_accessor';
    }

    //sort x-axis data
    if (args.chart_type == 'line'){
        for(var i=0; i<args.data.length; i++) {
            args.data[i].sort(function(a, b) {
                return a[args.x_accessor] - b[args.x_accessor];
            });
        }
    }

    return this
}

function process_line(args) {
    'use strict';
    //are we replacing missing y values with zeros?

    //do we have a time-series?
    var is_time_series = ($.type(args.data[0][0][args.x_accessor]) == 'date')
            ? true
            : false;

    if(args.missing_is_zero && args.chart_type == 'line' && is_time_series) {
        for(var i=0;i<args.data.length;i++) {
            var first = args.data[i][0];
            var last = args.data[i][args.data[i].length-1];
            //initialize our new array for storing the processed data
            var processed_data = [];

            //we'll be starting from the day after our first date
            var start_date = clone(first[args.x_accessor]).setDate(first[args.x_accessor].getDate() + 1);

            //if we've set a max_x, add data points up to there
            var from = (args.min_x) ? args.min_x : start_date;
            var upto = (args.max_x) ? args.max_x : last[args.x_accessor];
            for (var d = new Date(from); d <= upto; d.setDate(d.getDate() + 1)) {
                var o = {};
                d.setHours(0, 0, 0, 0);

                //add the first date item (judge me not, world)
                //we'll be starting from the day after our first date
                if(Date.parse(d) == Date.parse(new Date(start_date))) {
                    processed_data.push(clone(args.data[i][0]));
                }

                //check to see if we already have this date in our data object
                var existing_o = null;
                $.each(args.data[i], function(i, val) {
                    if(Date.parse(val.date) == Date.parse(new Date(d))) {
                        existing_o = val;

                        return false;
                    }
                })

                //if we don't have this date in our data object, add it and set it to zero
                if(!existing_o) {
                    o[args.x_accessor] = new Date(d);
                    o[args.y_accessor] = 0;
                    processed_data.push(o);
                }
                //otherwise, use the existing object for that date
                else {
                    processed_data.push(existing_o);
                }

                //add the last data item
                if(Date.parse(d) == Date.parse(new Date(last[args.x_accessor]))) {
                    processed_data.push(last);
                }
            }

            //update our date object
            args.data[i] = processed_data;
        }
    }

    return this;
}

function process_histogram(args){
    'use strict';
    // if args.binned=False, then we need to bin the data appropriately.
    // if args.binned=True, then we need to make sure to compute the relevant computed data.
    // the outcome of either of these should be something in args.computed_data.
    // the histogram plotting function will be looking there for the data to plot.

    // we need to compute an array of objects.
    // each object has an x, y, and dx.

    // histogram data is always single dimension
    var our_data = args.data[0];
    var extracted_data;
    if (args.binned==false){
        // use d3's built-in layout.histogram functionality to compute what you need.

        if (typeof(our_data[0]) == 'object'){
            // we are dealing with an array of objects. Extract the data value of interest.
            extracted_data = our_data
                .map(function(d){
                    return d[args.x_accessor];
                });
        } else if (typeof(our_data[0]) == 'number'){
            // we are dealing with a simple array of numbers. No extraction needed.
            extracted_data = our_data;
        }
        else {
            console.log('TypeError: expected an array of numbers, found ' + typeof(our_data[0]));
            return;
        }

        var hist = d3.layout.histogram()
        if (args.bins){
            hist = hist.bins(args.bins);
        }
        args.processed_data = hist(extracted_data)
            .map(function(d){
                // extract only the data we need per data point.
                return {'x': d['x'], 'y':d['y'], 'dx': d['dx']};
            })
    } else {
        // here, we just need to reconstruct the array of objects
        // take the x accessor and y accessor.
        // pull the data as x and y. y is count.

        args.processed_data = our_data.map(function(d){
            return {'x': d[args.x_accessor], 'y': d[args.y_accessor]}
        });
        var this_pt;
        var next_pt;
        // we still need to compute the dx component for each data point
        for (var i=0; i < args.processed_data.length; i++){
            this_pt = args.processed_data[i];
            if (i == args.processed_data.length-1){
                this_pt.dx = args.processed_data[i-1].dx;
            } else {
                next_pt = args.processed_data[i+1];
                this_pt.dx = next_pt.x - this_pt.x;
            }
        }
    }
    args.data = [args.processed_data];
    args.x_accessor = args.processed_x_accessor;
    args.y_accessor = args.processed_y_accessor;
    return this;
}

function process_categorical_variables(args){
    // For use with bar charts, etc.
    'use strict';
    var extracted_data, processed_data={}, pd=[];
    var our_data = args.data[0];
    args.categorical_variables = [];

    if (args.binned == false){
        if (typeof(our_data[0]) == 'object') {
            // we are dealing with an array of objects. Extract the data value of interest.
            extracted_data = our_data
                .map(function(d){
                    return d[args.y_accessor];
                });
        } else {
            extracted_data = our_data;
        }
        var this_dp;
        for (var i=0; i< extracted_data.length; i++){
            this_dp=extracted_data[i];
            if (args.categorical_variables.indexOf(this_dp) == -1) args.categorical_variables.push(this_dp)
            if (!processed_data.hasOwnProperty(this_dp)) processed_data[this_dp]=0;

            processed_data[this_dp]+=1;
        }
        processed_data = Object.keys(processed_data).map(function(d){
            var obj = {};
            obj[args.x_accessor] = processed_data[d];
            obj[args.y_accessor] = d;
            return obj;
        })
    } else {
        // nothing needs to really happen here.
        processed_data = our_data;
        args.categorical_variables = d3.set(processed_data.map(function(d){
            return d[args.y_accessor];
        })).values();
        args.categorical_variables.reverse();
    }
    args.data = [processed_data];
    return this;
}

function process_point(args){
    'use strict';
    var data = args.data[0];
    var x = data.map(function(d){return d[args.x_accessor]});
    var y = data.map(function(d){return d[args.y_accessor]});
    if (args.least_squares){
        args.ls_line = least_squares(x,y);
    };

    //args.lowess_line = lowess_robust(x,y, .5, 100)
    return this;

}
<|endoftext|>


<commit_before>import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as importedActions from './actions';
import getDisplayName from './getDisplayName';
import {initialState} from './reducer';
import deepEqual from 'deep-equal';
import bindActionData from './bindActionData';
import getValues from './getValues';
import isValid from './isValid';
import readFields from './readFields';
import handleSubmit from './handleSubmit';
import asyncValidation from './asyncValidation';
import silenceEvents from './events/silenceEvents';
import silenceEvent from './events/silenceEvent';

/**
 * Creates a HOC that knows how to create redux-connected sub-components.
 */
const createHigherOrderComponent = (config, isReactNative, React, WrappedComponent) => {
  const {Component, PropTypes} = React;
  return (reduxMountPoint, formName, formKey) => {
    class ReduxForm extends Component {
      static displayName = `ReduxForm(${getDisplayName(WrappedComponent)})`;
      static propTypes = {
        // props:
        asyncBlurFields: PropTypes.arrayOf(PropTypes.string),
        asyncValidate: PropTypes.func,
        dispatch: PropTypes.func.isRequired,
        fields: PropTypes.arrayOf(PropTypes.string).isRequired,
        form: PropTypes.object,
        initialValues: PropTypes.object,
        onSubmit: PropTypes.func,
        validate: PropTypes.func,
        readonly: PropTypes.bool,
        returnRejectedSubmitPromise: PropTypes.bool,

        // actions:
        blur: PropTypes.func.isRequired,
        change: PropTypes.func.isRequired,
        destroy: PropTypes.func.isRequired,
        focus: PropTypes.func.isRequired,
        initialize: PropTypes.func.isRequired,
        reset: PropTypes.func.isRequired,
        startAsyncValidation: PropTypes.func.isRequired,
        startSubmit: PropTypes.func.isRequired,
        stopAsyncValidation: PropTypes.func.isRequired,
        stopSubmit: PropTypes.func.isRequired,
        touch: PropTypes.func.isRequired,
        untouch: PropTypes.func.isRequired
      }

      static defaultProps = {
        asyncBlurFields: [],
        form: initialState,
        readonly: false,
        returnRejectedSubmitPromise: false,
        validate: () => ({})
      }

      constructor(props) {
        super(props);
        // bind functions
        this.asyncValidate = this.asyncValidate.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.fields = readFields(props, {}, this.asyncValidate, isReactNative);
      }

      componentWillMount() {
        const {initialize, initialValues} = this.props;
        if (initialValues) {
          initialize(initialValues);
        }
      }

      componentWillReceiveProps(nextProps) {
        if (!deepEqual(this.props.fields, nextProps.fields) || !deepEqual(this.props.form, nextProps.form)) {
          this.fields = readFields(nextProps, this.fields, this.asyncValidate, isReactNative);
        }
      }

      componentWillUnmount() {
        if (config.destroyOnUnmount) {
          this.props.destroy();
        }
      }

      static WrappedComponent = WrappedComponent;

      asyncValidate(name, value) {
        const {asyncValidate, dispatch, fields, form, startAsyncValidation, stopAsyncValidation, validate} = this.props;
        if (asyncValidate) {
          const values = getValues(fields, form);
          if (name) {
            values[name] = value;
          }
          const syncErrors = validate(values, this.props);

          // if blur validating, only run async validate if sync validation passes
          if (!name || isValid(syncErrors[name])) {
            return asyncValidation(() =>
              asyncValidate(values, dispatch), startAsyncValidation, stopAsyncValidation);
          }
        }
      }

      handleSubmit(submitOrEvent) {
        const {onSubmit, fields, form} = this.props;
        const check = submit => {
          if (!submit || typeof submit !== 'function') {
            throw new Error('You must either pass handleSubmit() an onSubmit function or pass onSubmit as a prop');
          }
          return submit;
        };
        const values = getValues(fields, form);
        return silenceEvent(submitOrEvent) ?
          // submitOrEvent is an event: fire submit
          handleSubmit(check(onSubmit), values, this.props, this.asyncValidate) :
          // submitOrEvent is the submit function: return deferred submit thunk
          silenceEvents(() => handleSubmit(check(submitOrEvent), values, this.props, this.asyncValidate));
      }

      render() {
        const allFields = this.fields;
        const {asyncBlurFields, blur, change, destroy, focus, fields, form, initialValues, initialize, onSubmit, reset,
          startAsyncValidation, startSubmit, stopAsyncValidation, stopSubmit, touch, untouch, validate,
          ...passableProps} = this.props;
        const {allPristine, allValid, errors, formError, values} = allFields._meta;

        return (<WrappedComponent {...{
          ...passableProps, // contains dispatch

          // State:
          active: form._active,
          asyncValidating: form._asyncValidating,
          dirty: !allPristine,
          error: formError,
          errors,
          fields: allFields,
          formKey,
          invalid: !allValid,
          pristine: allPristine,
          submitting: form._submitting,
          valid: allValid,
          values,

          // Actions:
          asyncValidate: silenceEvents(() => this.asyncValidate()),
          // ^ doesn't just pass this.asyncValidate to disallow values passing
          destroyForm: silenceEvents(destroy),
          handleSubmit: this.handleSubmit,
          initializeForm: silenceEvents(initialize),
          resetForm: silenceEvents(reset),
          touch: silenceEvents((...touchFields) => touch(...touchFields)),
          touchAll: silenceEvents(() => touch(...fields)),
          untouch: silenceEvents((...untouchFields) => untouch(...untouchFields)),
          untouchAll: silenceEvents(() => untouch(...fields))
        }}/>);
      }
    }

    // bind touch flags to blur and change
    const unboundActions = {
      ...importedActions,
      blur: bindActionData(importedActions.blur, {
        touch: !!config.touchOnBlur
      }),
      change: bindActionData(importedActions.change, {
        touch: !!config.touchOnChange
      })
    };

    // make redux connector with or without form key
    const decorate = formKey !== undefined && formKey !== null ?
      connect(
        state => {
          if (!state[reduxMountPoint]) {
            throw new Error(`You need to mount the redux-form reducer at "${reduxMountPoint}"`);
          }
          return {
            form: state[reduxMountPoint] &&
            state[reduxMountPoint][formName] &&
            state[reduxMountPoint][formName][formKey]
          };
        },
        dispatch => ({
          ...bindActionCreators(bindActionData(unboundActions, {form: formName, key: formKey}), dispatch),
          dispatch
        })
      ) :
      connect(
        state => {
          if (!state[reduxMountPoint]) {
            throw new Error(`You need to mount the redux-form reducer at "${reduxMountPoint}"`);
          }
          return {form: state[reduxMountPoint] && state[reduxMountPoint][formName]};
        },
        dispatch => ({
          ...bindActionCreators(bindActionData(unboundActions, {form: formName}), dispatch),
          dispatch
        })
      );

    return decorate(ReduxForm);
  };
};

export default createHigherOrderComponent;
<commit_msg>allow initialValues to be in the `mapPropsToValues` form<commit_after>import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as importedActions from './actions';
import getDisplayName from './getDisplayName';
import {initialState} from './reducer';
import deepEqual from 'deep-equal';
import bindActionData from './bindActionData';
import getValues from './getValues';
import isValid from './isValid';
import readFields from './readFields';
import handleSubmit from './handleSubmit';
import asyncValidation from './asyncValidation';
import silenceEvents from './events/silenceEvents';
import silenceEvent from './events/silenceEvent';

/**
 * Creates a HOC that knows how to create redux-connected sub-components.
 */
const createHigherOrderComponent = (config, isReactNative, React, WrappedComponent) => {
  const {Component, PropTypes} = React;
  return (reduxMountPoint, formName, formKey) => {
    class ReduxForm extends Component {
      static displayName = `ReduxForm(${getDisplayName(WrappedComponent)})`;
      static propTypes = {
        // props:
        asyncBlurFields: PropTypes.arrayOf(PropTypes.string),
        asyncValidate: PropTypes.func,
        dispatch: PropTypes.func.isRequired,
        fields: PropTypes.arrayOf(PropTypes.string).isRequired,
        form: PropTypes.object,
        initialValues: PropTypes.object,
        onSubmit: PropTypes.func,
        validate: PropTypes.func,
        readonly: PropTypes.bool,
        returnRejectedSubmitPromise: PropTypes.bool,

        // actions:
        blur: PropTypes.func.isRequired,
        change: PropTypes.func.isRequired,
        destroy: PropTypes.func.isRequired,
        focus: PropTypes.func.isRequired,
        initialize: PropTypes.func.isRequired,
        reset: PropTypes.func.isRequired,
        startAsyncValidation: PropTypes.func.isRequired,
        startSubmit: PropTypes.func.isRequired,
        stopAsyncValidation: PropTypes.func.isRequired,
        stopSubmit: PropTypes.func.isRequired,
        touch: PropTypes.func.isRequired,
        untouch: PropTypes.func.isRequired
      }

      static defaultProps = {
        asyncBlurFields: [],
        form: initialState,
        readonly: false,
        returnRejectedSubmitPromise: false,
        validate: () => ({})
      }

      constructor(props) {
        super(props);
        // bind functions
        this.asyncValidate = this.asyncValidate.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.fields = readFields(props, {}, this.asyncValidate, isReactNative);
      }

      componentWillMount() {
        const {initialize, initialValues} = this.props;
        if (initialValues) {
          initialize(typeof initialValues === 'function' ? initialValues(this.props) : initialValues);
        }
      }

      componentWillReceiveProps(nextProps) {
        if (!deepEqual(this.props.fields, nextProps.fields) || !deepEqual(this.props.form, nextProps.form)) {
          this.fields = readFields(nextProps, this.fields, this.asyncValidate, isReactNative);
        }
      }

      componentWillUnmount() {
        if (config.destroyOnUnmount) {
          this.props.destroy();
        }
      }

      static WrappedComponent = WrappedComponent;

      asyncValidate(name, value) {
        const {asyncValidate, dispatch, fields, form, startAsyncValidation, stopAsyncValidation, validate} = this.props;
        if (asyncValidate) {
          const values = getValues(fields, form);
          if (name) {
            values[name] = value;
          }
          const syncErrors = validate(values, this.props);

          // if blur validating, only run async validate if sync validation passes
          if (!name || isValid(syncErrors[name])) {
            return asyncValidation(() =>
              asyncValidate(values, dispatch), startAsyncValidation, stopAsyncValidation);
          }
        }
      }

      handleSubmit(submitOrEvent) {
        const {onSubmit, fields, form} = this.props;
        const check = submit => {
          if (!submit || typeof submit !== 'function') {
            throw new Error('You must either pass handleSubmit() an onSubmit function or pass onSubmit as a prop');
          }
          return submit;
        };
        const values = getValues(fields, form);
        return silenceEvent(submitOrEvent) ?
          // submitOrEvent is an event: fire submit
          handleSubmit(check(onSubmit), values, this.props, this.asyncValidate) :
          // submitOrEvent is the submit function: return deferred submit thunk
          silenceEvents(() => handleSubmit(check(submitOrEvent), values, this.props, this.asyncValidate));
      }

      render() {
        const allFields = this.fields;
        const {asyncBlurFields, blur, change, destroy, focus, fields, form, initialValues, initialize, onSubmit, reset,
          startAsyncValidation, startSubmit, stopAsyncValidation, stopSubmit, touch, untouch, validate,
          ...passableProps} = this.props;
        const {allPristine, allValid, errors, formError, values} = allFields._meta;

        return (<WrappedComponent {...{
          ...passableProps, // contains dispatch

          // State:
          active: form._active,
          asyncValidating: form._asyncValidating,
          dirty: !allPristine,
          error: formError,
          errors,
          fields: allFields,
          formKey,
          invalid: !allValid,
          pristine: allPristine,
          submitting: form._submitting,
          valid: allValid,
          values,

          // Actions:
          asyncValidate: silenceEvents(() => this.asyncValidate()),
          // ^ doesn't just pass this.asyncValidate to disallow values passing
          destroyForm: silenceEvents(destroy),
          handleSubmit: this.handleSubmit,
          initializeForm: silenceEvents(initialize),
          resetForm: silenceEvents(reset),
          touch: silenceEvents((...touchFields) => touch(...touchFields)),
          touchAll: silenceEvents(() => touch(...fields)),
          untouch: silenceEvents((...untouchFields) => untouch(...untouchFields)),
          untouchAll: silenceEvents(() => untouch(...fields))
        }}/>);
      }
    }

    // bind touch flags to blur and change
    const unboundActions = {
      ...importedActions,
      blur: bindActionData(importedActions.blur, {
        touch: !!config.touchOnBlur
      }),
      change: bindActionData(importedActions.change, {
        touch: !!config.touchOnChange
      })
    };

    // make redux connector with or without form key
    const decorate = formKey !== undefined && formKey !== null ?
      connect(
        state => {
          if (!state[reduxMountPoint]) {
            throw new Error(`You need to mount the redux-form reducer at "${reduxMountPoint}"`);
          }
          return {
            form: state[reduxMountPoint] &&
            state[reduxMountPoint][formName] &&
            state[reduxMountPoint][formName][formKey]
          };
        },
        dispatch => ({
          ...bindActionCreators(bindActionData(unboundActions, {form: formName, key: formKey}), dispatch),
          dispatch
        })
      ) :
      connect(
        state => {
          if (!state[reduxMountPoint]) {
            throw new Error(`You need to mount the redux-form reducer at "${reduxMountPoint}"`);
          }
          return {form: state[reduxMountPoint] && state[reduxMountPoint][formName]};
        },
        dispatch => ({
          ...bindActionCreators(bindActionData(unboundActions, {form: formName}), dispatch),
          dispatch
        })
      );

    return decorate(ReduxForm);
  };
};

export default createHigherOrderComponent;
<|endoftext|>


<commit_before>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const EventPool = RG.EventPool;

const Listener = function(eventName) {
    this.notified = false;
    this.eventName = eventName;

    this.hasNotify = true;

    this.notify = function(name) {
        if (name === this.eventName) {
            this.notified = true;
        }
    };

    this.clearNotify = function() {
        this.notified = false;
    };
};

const EventEmitter = function() {
    this.pool = null;

    this.emit = function(name, args) {
        this.pool.emitEvent(name, args);
    };
};

describe('How events bubble in the system', () => {

    let pool = null;
    let listener = null;
    let emitter = null;

    beforeEach(() => {
        pool = new EventPool();
        listener = new Listener('ActualEvent');
        pool.listenEvent(listener.eventName, listener);
        emitter = new EventEmitter();
        emitter.pool = pool;

    });

    it('can indicate number of listeners', () => {
        expect(pool.getNumListeners()).to.equal(1);
    });

    it('Sends notification to listener', () => {
        const empty = {};

        RG.suppressErrorMessages = true;
        pool.listenEvent('TestEvent', empty);
        RG.suppressErrorMessages = false;

        emitter.emit('TestEvent', {data: 'abcd'});

        expect(listener.notified).to.equal(false);
        emitter.emit('ActualEvent', {data: 'abcd'});
        expect(listener.notified).to.equal(true);

        listener.clearNotify();
        expect(listener.notified).to.equal(false);
        emitter.emit('RandomEvent', {data: 'abcd'});

        // Works also with symbols
        const symEvent = Symbol();
        const symListener = new Listener(symEvent);
        pool.listenEvent(symListener.eventName, symListener);

        expect(symListener.notified).to.equal(false);
        emitter.emit(symEvent, {data: 'sym data'});
        expect(symListener.notified).to.equal(true);
    });

    it('can have its listeners removed', () => {
        const listeners = [];
        for (let i = 0; i < 10; i++) {
            const listener = new Listener('ActualEvent');
            listeners.push(listener);
            pool.listenEvent(listener.eventName, listener);
        }

        const EVENT = Symbol();
        for (let i = 0; i < 10; i++) {
            const listener = new Listener(EVENT);
            listeners.push(listener);
            pool.listenEvent(listener.eventName, listener);
        }

        const numListeners = pool.getNumListeners();
        pool.removeListener(listener);
        expect(pool.getNumListeners()).to.equal(numListeners - 1);

        expect(listener.notified).to.equal(false);
        emitter.emit('ActualEvent', {data: 'abcd'});
        expect(listener.notified).to.equal(false);
        emitter.emit(EVENT, {data: 'abcd'});

        listeners.forEach(listener => {
            expect(listener.notified).to.equal(true);
            pool.removeListener(listener);
            listener.clearNotify();
        });

        expect(pool.getNumListeners()).to.equal(0);

        emitter.emit('ActualEvent', {data: 'abcd'});
        listeners.forEach(listener => {
            expect(listener.notified).to.equal(false);
        });

    });
});

<commit_msg>Added a unit test to check deletion of actors.<commit_after>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const EventPool = RG.EventPool;

const Listener = function(eventName) {
    this.notified = false;
    this.eventName = eventName;

    this.hasNotify = true;

    this.notify = function(name) {
        if (name === this.eventName) {
            this.notified = true;
        }
    };

    this.clearNotify = function() {
        this.notified = false;
    };
};

const EventEmitter = function() {
    this.pool = null;

    this.emit = function(name, args) {
        this.pool.emitEvent(name, args);
    };
};

describe('EventPool', () => {

    let pool = null;
    let listener = null;
    let emitter = null;

    beforeEach(() => {
        pool = new EventPool();
        listener = new Listener('ActualEvent');
        pool.listenEvent(listener.eventName, listener);
        emitter = new EventEmitter();
        emitter.pool = pool;

    });

    it('can indicate number of listeners', () => {
        expect(pool.getNumListeners()).to.equal(1);
    });

    it('Sends notification to listener', () => {
        const empty = {};

        RG.suppressErrorMessages = true;
        pool.listenEvent('TestEvent', empty);
        RG.suppressErrorMessages = false;

        emitter.emit('TestEvent', {data: 'abcd'});

        expect(listener.notified).to.equal(false);
        emitter.emit('ActualEvent', {data: 'abcd'});
        expect(listener.notified).to.equal(true);

        listener.clearNotify();
        expect(listener.notified).to.equal(false);
        emitter.emit('RandomEvent', {data: 'abcd'});

        // Works also with symbols
        const symEvent = Symbol();
        const symListener = new Listener(symEvent);
        pool.listenEvent(symListener.eventName, symListener);

        expect(symListener.notified).to.equal(false);
        emitter.emit(symEvent, {data: 'sym data'});
        expect(symListener.notified).to.equal(true);
    });

    it('can have its listeners removed', () => {
        const listeners = [];
        for (let i = 0; i < 10; i++) {
            const listener = new Listener('ActualEvent');
            listeners.push(listener);
            pool.listenEvent(listener.eventName, listener);
        }

        const EVENT = Symbol();
        for (let i = 0; i < 10; i++) {
            const listener = new Listener(EVENT);
            listeners.push(listener);
            pool.listenEvent(listener.eventName, listener);
        }

        const numListeners = pool.getNumListeners();
        pool.removeListener(listener);
        expect(pool.getNumListeners()).to.equal(numListeners - 1);

        expect(listener.notified).to.equal(false);
        emitter.emit('ActualEvent', {data: 'abcd'});
        expect(listener.notified).to.equal(false);
        emitter.emit(EVENT, {data: 'abcd'});

        listeners.forEach(listener => {
            expect(listener.notified).to.equal(true);
            pool.removeListener(listener);
            listener.clearNotify();
        });

        expect(pool.getNumListeners()).to.equal(0);

        emitter.emit('ActualEvent', {data: 'abcd'});
        listeners.forEach(listener => {
            expect(listener.notified).to.equal(false);
        });

    });

    it('deletes listeners internally', () => {
        expect(pool.getNumEventsListened()).to.equal(1);
        let listeners = pool.getListeners(listener.eventName);
        expect(listeners.length).to.equal(1);
        pool.removeListener(listener);
        listeners = pool.getListeners(listener.eventName);
        expect(listeners.length).to.equal(0);
        expect(pool.getNumEventsListened()).to.equal(0);
    });

});

<|endoftext|>