<commit_before>const express = require('express')
const path = require('path')
const os = require('os')
const PaperUtils = require('./view/paperutils')
const CIESubjects = require('./view/CIESubjects')
const sspdf = require('./lib/sspdf')
const fs = require('fs')
const SVGO = require('svgo')
const cheerio = require('cheerio')
require('./dist-server/serverrender')
const serverRender = global.serverRender
global.serverRender = null

const svgo = new SVGO()

let indexPath = path.join(__dirname, 'dist/index.html')
let indexHtml = fs.readFileSync(indexPath)
if (process.env.NODE_ENV !== 'production') {
  fs.watch(indexPath, list => {
    fs.readFile(indexPath, { encoding: 'utf8' }, (err, data) => {
      if (err) {
        console.error(err)
        process.exit(1)
      } else {
        indexHtml = data
      }
    })
  })
}

module.exports = (db, mongoose) => {
  const {PastPaperDoc, PastPaperIndex, PastPaperFeedback, PastPaperRequestRecord} = require('./lib/dbModel.js')(db, mongoose)
  let rMain = express.Router()

  function statusInfo () {
    return Promise.all([PastPaperDoc.count({}), PastPaperIndex.count({}), Promise.resolve(os.loadavg())])
      .then(([docCount, indexCount, loadAvg]) => {
        return Promise.resolve({docCount, indexCount, loadAvg: loadAvg.map(num => Math.round(num * 100) / 100)})
      }, err => Promise.reject(err))
  }

  rMain.use(function (req, res, next) {
    console.log(`Serving ${req.method.toUpperCase()} ${req.path} on ${req.hostname} for ${req.ip}...`)
    if (req.hostname.match(/^www\./)) {
      res.redirect('https://schsrch.xyz' + req.path)
    } else {
      next()
    }
  })
  function saveRecord (rec) {
    return rec.save().then(() => {}, err => console.log('Error saving record: ' + err))
  }
  rMain.get('/', function (req, res) {
    res.type('html')
    let $ = cheerio.load(indexHtml)
    $('.react-root').html(serverRender({})) // We want this to be static so that service worker don't end up caching old data
    res.send($.html())
    let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/'})
    saveRecord(rec)
  })
  rMain.use('/resources', express.static(path.join(__dirname, 'dist')))
  // rMain.use('/resources', express.static(path.join(__dirname, 'view/public')))
  rMain.get('/sw.js', function (req, res) {
    res.set('cache-control', 'max-age=0')
    res.sendFile(path.join(__dirname, 'dist/sw.js'))
  })

  rMain.get('/status/', function (req, res, next) {
    statusInfo().then(rst => res.send(rst), err => next(err))
  })

  function doSearch (query) {
    function findRelated (doc) {
      return PastPaperDoc.find({subject: doc.subject, time: doc.time, paper: doc.paper, variant: doc.variant}, {_id: true, type: true, fileType: true, numPages: true}, {doc: false})
        .then(rst => Promise.resolve(rst.filter(x => x.type !== doc.type)))
    }
    return new Promise((resolve, reject) => {
      let match
      if ((match = query.match(/^!!index!([0-9a-f]+)$/))) {
        let id = match[1]
        PastPaperIndex.findOne({_id: id}).then(rstIndex => {
          if (!rstIndex) {
            resolve({
              response: 'text',
              list: []
            })
          } else {
            PastPaperDoc.findOne({_id: rstIndex.doc}, {doc: false}).then(rstDoc => {
              if (!rstDoc) {
                resolve({
                  response: 'text',
                  list: []
                })
              } else {
                findRelated(rstDoc).then(rstRelated => {
                  resolve({
                    response: 'text',
                    list: [{doc: rstDoc, index: rstIndex, related: rstRelated}]
                  })
                }, err => resolve(({ response: 'text', list: [{doc: rstDoc, index: rstIndex, related: []}] })))
              }
            }, err => reject({response: 'error', err: err.toString()}))
          }
        }, err => reject({response: 'error', err: err.toString()}))
      } else if (query.match(/^\d{4}$/)) {
        fetchPP(query, null, null, null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})$/))) {
        fetchPP(match[1], match[2])
      } else if ((match = query.match(/^(\d{4})[_ ](\d)$/))) {
        fetchPP(match[1], null, match[2], null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]+)$/))) {
        fetchPP(match[1], null, null, null, match[2])
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ]([a-z]+)$/))) {
        fetchPP(match[1], match[2], null, null, match[3])
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ]*(paper[_ ]*)?(\d)$/))) {
        fetchPP(match[1], match[2], match[4], null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ]*(paper[_ ]*)?(\d)[_ ]*(\d)$/))) {
        fetchPP(match[1], match[2], match[4], match[5], null)
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ]([a-z]+)[_ ](\d)[_ ]*(\d)$/))) {
        fetchPP(match[1], match[2], match[4], match[5], match[3])
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ](\d)(\d)[_ ]([a-z]+)$/))) {
        fetchPP(match[1], match[2], match[3], match[4], match[5])
      } else if ((match = query.match(/^(\d{4})[_ ]([a-z]\d{1,2})[_ ]([a-z]+)[_ ](\d)$/))) {
        fetchPP(match[1], match[2], match[4], null, match[3])
      } else if ((match = query.toUpperCase().match(/^(\d{4})\/(\d{2})\/([A-Z]\/[A-Z]|SP)\/(\d{2})$/))) {
        let month = PaperUtils.odashMonthToMyMonth(match[3])
        let time = month + match[4]
        let [paper, variant] = match[2].split('')
        fetchPP(match[1], time, paper, variant, null)
      } else {
        PastPaperIndex.search(query).then(results => {
          Promise.all(results.map(rst => new Promise((resolve, reject) => {
            findRelated(rst.doc).then(related => {
              resolve({doc: rst.doc, index: rst.index, related: related})
            }, err => {
              resolve({doc: rst.doc, index: rst.index, related: []})
            })
          }))).then(rst => resolve({
            response: 'text',
            list: rst
          }), err => reject({response: 'error', err: err.toString()}))
        }).catch(err => {
          reject({response: 'error', err: err.toString()})
        })
      }

      function fetchPP (subject, time, paper, variant, type) {
        let finder = {}
        subject && (finder.subject = subject)
        let tMat = null
        if (time && (tMat = time.match(/^([a-z])(\d)$/))) {
          let mo = tMat[1]
          let yr = '0' + tMat[2]
          time = mo + yr
        }
        time && (finder.time = time.toLowerCase())
        if (parseInt(paper) === 0 && Number.isSafeInteger(parseInt(variant)) && parseInt(variant) !== 0) {
          paper = variant
          variant = '0'
        }
        paper && (finder.paper = parseInt(paper))
        variant && (finder.variant = parseInt(variant))
        type && (finder.type = type.toLowerCase())
        PastPaperDoc.find(finder, {doc: false}).limit(51).then(rst => {
          if (rst.length >= 50) {
            resolve({
              response: 'overflow'
            })
            return
          }
          resolve({
            response: 'pp',
            list: rst
          })
        }, err => {
          reject({response: 'error', err: err.toString()})
        })
      }
    })
  }

  rMain.get('/search/:query', function (req, res, next) {
    let query = req.params.query.toString().trim()
    doSearch(query).then(rst => res.send(rst), err => {
      res.status(500)
      res.send(err)
    })
    let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/search/', search: query})
    saveRecord(rec)
  })
  rMain.get('/disclaim/', function (req, res, next) {
    res.type('html')
    let $ = cheerio.load(indexHtml)
    $('.react-root').html(serverRender({view: 'disclaim'}))
    res.send($.html())
  })
  rMain.get('/formsearch/', function (req, res, next) {
    let query = req.query.query.toString().trim()
    if (query.length === 0) {
      res.redirect('/')
      return
    }
    doSearch(query).then(rst => {
      res.type('html')
      let $ = cheerio.load(indexHtml)
      $('.react-root').html(serverRender({query: {query, result: JSON.parse(JSON.stringify(rst))}}))
      res.send($.html())
    }, err => {
      next(err.err || err)
    }).catch(err => next(err))
  })

  rMain.get('/fetchDoc/:id', function (req, res, next) {
    PastPaperDoc.findOne({_id: req.params.id}).then(doc => {
      let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/fetchDoc/', targetId: req.params.id})
      saveRecord(rec)
      if (!doc) {
        next()
        return
      }
      let fname = `${PaperUtils.setToString(doc)}_${doc.type}.${doc.fileType}`
      res.set('Content-Disposition', `inline; filename=${JSON.stringify(fname)}`)
      res.type(doc.fileType)
      res.send(doc.doc)
    }).catch(err => next(err))
  })
  rMain.get('/sspdf/:docid/:page', function (req, res, next) {
    let pn = parseInt(req.params.page)
    if (!Number.isSafeInteger(pn) || pn < 0) {
      next()
      return
    }
    PastPaperDoc.findOne({_id: req.params.docid}).then(doc => {
      if (!doc) {
        next()
        return
      }
      processSSPDF(doc, pn).then(sspdf => {
        res.set('Cache-Control', 'max-age=' + (10 * 24 * 60 * 60).toString())
        res.send(sspdf)
        let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/sspdf/', targetId: doc._id, targetPage: pn})
        saveRecord(rec)
      }, err => {
        next(err)
      })
    }).catch(err => next(err))
  })

  function processSSPDF (doc, pn) {
    return new Promise((resolve, reject) => {
      function postCache (stuff) {
        let result = stuff
        delete result.text
        delete result.rects
        result.doc = doc
        result.doc.doc = null
        return result
      }

      PastPaperIndex.find({doc: doc._id, page: pn}).then(ppIdxes => {
        if (!ppIdxes || ppIdxes.length < 1) {
          reject(new Error('PastPaperIndex not found.'))
          return
        }
        let ppIdx = ppIdxes[0]
        if (ppIdx.sspdfCache) {
          resolve(postCache(ppIdx.sspdfCache))
        } else {
          console.log(`Building sspdf for ${doc._id}::${pn} (idx//${ppIdx._id})`)
          let buff = doc.doc
          sspdf.getPage(buff, pn, function (err, result) {
            if (err) {
              reject(err)
            } else {
              result.rects = result.rects.map(rect => {
                function round (n) {
                  return Math.round(n * 100) / 100
                }
                rect.x1 = round(rect.x1)
                rect.x2 = round(rect.x2)
                rect.y1 = round(rect.y1)
                rect.y2 = round(rect.y2)
                return rect
              })
              let svg = result.svg.toString('utf-8')
              svgo.optimize(svg, rSvgo => {
                result.svg = rSvgo.data
                ppIdx.sspdfCache = result
                ppIdx.save(err => {
                  if (err) {
                    console.error('Unable to save sspdfCache: ' + err)
                  }
                  resolve(postCache(result))
                })
              })
            }
          })
        }
      }).catch(reject)
    })
  }

  rMain.post('/feedback/', function (req, res, next) {
    let ctype = req.get('Content-Type')
    let done = false
    if (ctype !== 'application/json') {
      res.status(415)
      res.send('Content type incorrect.')
      done = true
      return
    }
    let body = ''
    req.setEncoding('utf8')
    req.on('data', chunk => {
      if (done) return
      body += chunk
    })
    req.on('end', () => {
      if (done) return
      done = true
      body = body.trim()
      if (body.length === 0) {
        res.status(403)
        res.send('Content is empty.')
        return
      }
      let parsed = null
      try {
        parsed = JSON.parse(body)
        if (typeof parsed !== 'object') {
          throw new Error()
        }
      } catch (e) {
        res.status(403)
        res.send('Content is not valid JSON.')
        return
      }
      let fb = new PastPaperFeedback({
        time: Date.now(),
        ip: req.ip,
        email: parsed.email,
        text: parsed.text,
        search: parsed.search
      })
      fb.save().then(() => {
        res.status(200)
        res.end()
      }, err => {
        res.status(403)
        res.send(err.toString())
      })
    })
  })
  rMain.get('/robots.txt', function (req, res) {
    if (req.hostname.match(/^beta\./)) {
      res.sendFile(path.join(__dirname, 'view/betaRobots.txt'))
    } else {
      res.type('txt')
      res.send('')
    }
  })

  return rMain
}
<commit_msg>More robust search format<commit_after>const express = require('express')
const path = require('path')
const os = require('os')
const PaperUtils = require('./view/paperutils')
const CIESubjects = require('./view/CIESubjects')
const sspdf = require('./lib/sspdf')
const fs = require('fs')
const SVGO = require('svgo')
const cheerio = require('cheerio')
require('./dist-server/serverrender')
const serverRender = global.serverRender
global.serverRender = null

const svgo = new SVGO()

let indexPath = path.join(__dirname, 'dist/index.html')
let indexHtml = fs.readFileSync(indexPath)
if (process.env.NODE_ENV !== 'production') {
  fs.watch(indexPath, list => {
    fs.readFile(indexPath, { encoding: 'utf8' }, (err, data) => {
      if (err) {
        console.error(err)
        process.exit(1)
      } else {
        indexHtml = data
      }
    })
  })
}

module.exports = (db, mongoose) => {
  const {PastPaperDoc, PastPaperIndex, PastPaperFeedback, PastPaperRequestRecord} = require('./lib/dbModel.js')(db, mongoose)
  let rMain = express.Router()

  function statusInfo () {
    return Promise.all([PastPaperDoc.count({}), PastPaperIndex.count({}), Promise.resolve(os.loadavg())])
      .then(([docCount, indexCount, loadAvg]) => {
        return Promise.resolve({docCount, indexCount, loadAvg: loadAvg.map(num => Math.round(num * 100) / 100)})
      }, err => Promise.reject(err))
  }

  rMain.use(function (req, res, next) {
    console.log(`Serving ${req.method.toUpperCase()} ${req.path} on ${req.hostname} for ${req.ip}...`)
    if (req.hostname.match(/^www\./)) {
      res.redirect('https://schsrch.xyz' + req.path)
    } else {
      next()
    }
  })
  function saveRecord (rec) {
    return rec.save().then(() => {}, err => console.log('Error saving record: ' + err))
  }
  rMain.get('/', function (req, res) {
    res.type('html')
    let $ = cheerio.load(indexHtml)
    $('.react-root').html(serverRender({})) // We want this to be static so that service worker don't end up caching old data
    res.send($.html())
    let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/'})
    saveRecord(rec)
  })
  rMain.use('/resources', express.static(path.join(__dirname, 'dist')))
  // rMain.use('/resources', express.static(path.join(__dirname, 'view/public')))
  rMain.get('/sw.js', function (req, res) {
    res.set('cache-control', 'max-age=0')
    res.sendFile(path.join(__dirname, 'dist/sw.js'))
  })

  rMain.get('/status/', function (req, res, next) {
    statusInfo().then(rst => res.send(rst), err => next(err))
  })

  function doSearch (query) {
    function findRelated (doc) {
      return PastPaperDoc.find({subject: doc.subject, time: doc.time, paper: doc.paper, variant: doc.variant}, {_id: true, type: true, fileType: true, numPages: true}, {doc: false})
        .then(rst => Promise.resolve(rst.filter(x => x.type !== doc.type)))
    }
    return new Promise((resolve, reject) => {
      let match
      if ((match = query.match(/^!!index!([0-9a-f]+)$/))) {
        let id = match[1]
        PastPaperIndex.findOne({_id: id}).then(rstIndex => {
          if (!rstIndex) {
            resolve({
              response: 'text',
              list: []
            })
          } else {
            PastPaperDoc.findOne({_id: rstIndex.doc}, {doc: false}).then(rstDoc => {
              if (!rstDoc) {
                resolve({
                  response: 'text',
                  list: []
                })
              } else {
                findRelated(rstDoc).then(rstRelated => {
                  resolve({
                    response: 'text',
                    list: [{doc: rstDoc, index: rstIndex, related: rstRelated}]
                  })
                }, err => resolve(({ response: 'text', list: [{doc: rstDoc, index: rstIndex, related: []}] })))
              }
            }, err => reject({response: 'error', err: err.toString()}))
          }
        }, err => reject({response: 'error', err: err.toString()}))
      } else if (query.match(/^\d{4}$/)) {
        fetchPP(query, null, null, null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})$/))) {
        fetchPP(match[1], match[2])
      } else if ((match = query.match(/^(\d{4})[_ ](\d)$/))) {
        fetchPP(match[1], null, match[2], null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]+)$/))) {
        fetchPP(match[1], null, null, null, match[2])
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ]*([a-z]+)$/))) {
        fetchPP(match[1], match[2], null, null, match[3])
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ]*(p?a?p?e?r?[_ ]*)?(\d)$/))) {
        fetchPP(match[1], match[2], match[4], null, null)
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ]*(p?a?p?e?r?[_ ]*)?(\d)[_ ]*(\d)$/))) {
        fetchPP(match[1], match[2], match[4], match[5], null)
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ]*([a-z]+)[_ ]*(\d)[_ ]*(\d)$/))) {
        fetchPP(match[1], match[2], match[4], match[5], match[3])
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ](\d)(\d)[_ ]*([a-z]+)$/))) {
        fetchPP(match[1], match[2], match[3], match[4], match[5])
      } else if ((match = query.match(/^(\d{4})[_ ]*([a-z]\d{1,2})[_ ]*([a-z]+)[_ ]*(\d)$/))) {
        fetchPP(match[1], match[2], match[4], null, match[3])
      } else if ((match = query.toUpperCase().match(/^(\d{4})\/(\d{2})\/([A-Z]\/[A-Z]|SP)\/(\d{2})$/))) {
        let month = PaperUtils.odashMonthToMyMonth(match[3])
        let time = month + match[4]
        let [paper, variant] = match[2].split('')
        fetchPP(match[1], time, paper, variant, null)
      } else {
        PastPaperIndex.search(query).then(results => {
          Promise.all(results.map(rst => new Promise((resolve, reject) => {
            findRelated(rst.doc).then(related => {
              resolve({doc: rst.doc, index: rst.index, related: related})
            }, err => {
              resolve({doc: rst.doc, index: rst.index, related: []})
            })
          }))).then(rst => resolve({
            response: 'text',
            list: rst
          }), err => reject({response: 'error', err: err.toString()}))
        }).catch(err => {
          reject({response: 'error', err: err.toString()})
        })
      }

      function fetchPP (subject, time, paper, variant, type) {
        let finder = {}
        subject && (finder.subject = subject)
        let tMat = null
        if (time && (tMat = time.match(/^([a-z])(\d)$/))) {
          let mo = tMat[1]
          let yr = '0' + tMat[2]
          time = mo + yr
        }
        time && (finder.time = time.toLowerCase())
        if (parseInt(paper) === 0 && Number.isSafeInteger(parseInt(variant)) && parseInt(variant) !== 0) {
          paper = variant
          variant = '0'
        }
        paper && (finder.paper = parseInt(paper))
        variant && (finder.variant = parseInt(variant))
        type && (finder.type = type.toLowerCase())
        PastPaperDoc.find(finder, {doc: false}).limit(51).then(rst => {
          if (rst.length >= 50) {
            resolve({
              response: 'overflow'
            })
            return
          }
          resolve({
            response: 'pp',
            list: rst
          })
        }, err => {
          reject({response: 'error', err: err.toString()})
        })
      }
    })
  }

  rMain.get('/search/:query', function (req, res, next) {
    let query = req.params.query.toString().trim()
    doSearch(query).then(rst => res.send(rst), err => {
      res.status(500)
      res.send(err)
    })
    let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/search/', search: query})
    saveRecord(rec)
  })
  rMain.get('/disclaim/', function (req, res, next) {
    res.type('html')
    let $ = cheerio.load(indexHtml)
    $('.react-root').html(serverRender({view: 'disclaim'}))
    res.send($.html())
  })
  rMain.get('/formsearch/', function (req, res, next) {
    let query = req.query.query.toString().trim()
    if (query.length === 0) {
      res.redirect('/')
      return
    }
    doSearch(query).then(rst => {
      res.type('html')
      let $ = cheerio.load(indexHtml)
      $('.react-root').html(serverRender({query: {query, result: JSON.parse(JSON.stringify(rst))}}))
      res.send($.html())
    }, err => {
      next(err.err || err)
    }).catch(err => next(err))
  })

  rMain.get('/fetchDoc/:id', function (req, res, next) {
    PastPaperDoc.findOne({_id: req.params.id}).then(doc => {
      let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/fetchDoc/', targetId: req.params.id})
      saveRecord(rec)
      if (!doc) {
        next()
        return
      }
      let fname = `${PaperUtils.setToString(doc)}_${doc.type}.${doc.fileType}`
      res.set('Content-Disposition', `inline; filename=${JSON.stringify(fname)}`)
      res.type(doc.fileType)
      res.send(doc.doc)
    }).catch(err => next(err))
  })
  rMain.get('/sspdf/:docid/:page', function (req, res, next) {
    let pn = parseInt(req.params.page)
    if (!Number.isSafeInteger(pn) || pn < 0) {
      next()
      return
    }
    PastPaperDoc.findOne({_id: req.params.docid}).then(doc => {
      if (!doc) {
        next()
        return
      }
      processSSPDF(doc, pn).then(sspdf => {
        res.set('Cache-Control', 'max-age=' + (10 * 24 * 60 * 60).toString())
        res.send(sspdf)
        let rec = new PastPaperRequestRecord({ip: req.ip, time: Date.now(), requestType: '/sspdf/', targetId: doc._id, targetPage: pn})
        saveRecord(rec)
      }, err => {
        next(err)
      })
    }).catch(err => next(err))
  })

  function processSSPDF (doc, pn) {
    return new Promise((resolve, reject) => {
      function postCache (stuff) {
        let result = stuff
        delete result.text
        delete result.rects
        result.doc = doc
        result.doc.doc = null
        return result
      }

      PastPaperIndex.find({doc: doc._id, page: pn}).then(ppIdxes => {
        if (!ppIdxes || ppIdxes.length < 1) {
          reject(new Error('PastPaperIndex not found.'))
          return
        }
        let ppIdx = ppIdxes[0]
        if (ppIdx.sspdfCache) {
          resolve(postCache(ppIdx.sspdfCache))
        } else {
          console.log(`Building sspdf for ${doc._id}::${pn} (idx//${ppIdx._id})`)
          let buff = doc.doc
          sspdf.getPage(buff, pn, function (err, result) {
            if (err) {
              reject(err)
            } else {
              result.rects = result.rects.map(rect => {
                function round (n) {
                  return Math.round(n * 100) / 100
                }
                rect.x1 = round(rect.x1)
                rect.x2 = round(rect.x2)
                rect.y1 = round(rect.y1)
                rect.y2 = round(rect.y2)
                return rect
              })
              let svg = result.svg.toString('utf-8')
              svgo.optimize(svg, rSvgo => {
                result.svg = rSvgo.data
                ppIdx.sspdfCache = result
                ppIdx.save(err => {
                  if (err) {
                    console.error('Unable to save sspdfCache: ' + err)
                  }
                  resolve(postCache(result))
                })
              })
            }
          })
        }
      }).catch(reject)
    })
  }

  rMain.post('/feedback/', function (req, res, next) {
    let ctype = req.get('Content-Type')
    let done = false
    if (ctype !== 'application/json') {
      res.status(415)
      res.send('Content type incorrect.')
      done = true
      return
    }
    let body = ''
    req.setEncoding('utf8')
    req.on('data', chunk => {
      if (done) return
      body += chunk
    })
    req.on('end', () => {
      if (done) return
      done = true
      body = body.trim()
      if (body.length === 0) {
        res.status(403)
        res.send('Content is empty.')
        return
      }
      let parsed = null
      try {
        parsed = JSON.parse(body)
        if (typeof parsed !== 'object') {
          throw new Error()
        }
      } catch (e) {
        res.status(403)
        res.send('Content is not valid JSON.')
        return
      }
      let fb = new PastPaperFeedback({
        time: Date.now(),
        ip: req.ip,
        email: parsed.email,
        text: parsed.text,
        search: parsed.search
      })
      fb.save().then(() => {
        res.status(200)
        res.end()
      }, err => {
        res.status(403)
        res.send(err.toString())
      })
    })
  })
  rMain.get('/robots.txt', function (req, res) {
    if (req.hostname.match(/^beta\./)) {
      res.sendFile(path.join(__dirname, 'view/betaRobots.txt'))
    } else {
      res.type('txt')
      res.send('')
    }
  })

  return rMain
}
<|endoftext|>


<commit_before>'use strict';

var join      = require('path').join
var EventEmitter = require('events')
//var Obv       = require('obv')

var pull      = require('pull-stream')
var timestamp = require('monotonic-timestamp')
var explain   = require('explain-error')
//var createFeed = require('ssb-feed')
var ref       = require('ssb-ref')
var ssbKeys   = require('ssb-keys')
var Notify    = require('pull-notify')

var isFeedId = ref.isFeedId
var isMsgId  = ref.isMsgId
var isBlobId = ref.isBlobId

var u         = require('./util')
var stdopts   = u.options
var Format    = u.formatStream
//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

var isArray = Array.isArray

function isObject (o) {
  return o && 'object' === typeof o && !Array.isArray(o)
}

function getVMajor () {
  var version = require('./package.json').version
  return (version.split('.')[0])|0
}

module.exports = function (_db, opts, keys, path) {
  path = path || _db.location

  keys = keys || ssbKeys.generate()

  var db = require('./db')(join(opts.path || path, 'flume'), keys, opts)

  //legacy database
  if(_db) require('./legacy')(_db, db)
  else db.ready.set(true)

  db.sublevel = function (a, b) {
    return _db.sublevel(a, b)
  }

  //UGLY HACK, but...
  //fairly sure that something up the stack expects ssb to be an event emitter.
  db.__proto__ = new EventEmitter()

  db.opts = opts

  var _get = db.get

  db.get = function (key, cb) {
    if(ref.isMsg(key))
      return db.keys.get(key, function (err, seq) {
        if(err) cb(err)
        else cb(null, seq && seq.value)
      })
    else if(Number.isInteger(key))
      _get(key, cb) //seq
    else
      throw new Error('secure-scuttlebutt.get: key *must* be a ssb message id or a flume offset')
  }

  db.add = function (msg, cb) {
    db.queue(msg, function (err, data) {
      if(err) cb(err)
      else db.flush(function () { cb(null, data) })
    })
  }

  db.createFeed = function (keys) {
    if(!keys) keys = ssbKeys.generate()
    function add (content, cb) {
      //LEGACY: hacks to support add as a continuable
      if(!cb)
        return function (cb) { add (content, cb) }

      db.append({content: content, keys: keys}, cb)
    }
    return {
      add: add, publish: add,
      id: keys.id, keys: keys
    }
  }

  db.createLogStream = function (opts) {
    return db.stream(opts)
  }

  //pull in the features that are needed to pass the tests
  //and that sbot, etc uses but are slow.
  require('./extras')(db, opts, keys)

  //writeStream - used in (legacy) replication.
  db.createWriteStream = function (cb) {
    return pull(
      pull.asyncMap(function (data, cb) {
        db.queue(data, function (err, msg) {
          if(err) {
            db.emit('invalid', err, msg)
          }
          setImmediate(cb)
        })
      }),
      pull.drain(null, function (err) {
        if(err) return cb(err)
        db.flush(cb)
      })
    )
  }

  db.createHistoryStream = db.clock.createHistoryStream

  //called with [id, seq] or "<id>:<seq>"
  db.getAtSequence = function (seqid, cb) {
    db.clock.get(isString(seqid) ? seqid.split(':') : seqid, cb)
  }

  db.getVectorClock = function (_, cb) {
    if(!cb) cb = _
    db.last.get(function (err, h) {
      if(err) return cb(err)
      var clock = {}
      for(var k in h)
        clock[k] = h[k].sequence
      cb(null, clock)
    })

  }

  if(_db) {
    var close = db.close
    db.close = function (cb) {
      var n = 2
      _db.close(next); close(next)

      function next (err) {
        if(err && n>0) {
          n = -1
          return cb(err)
        }
        if(--n) return
        cb()
      }

    }

  }
  return db
}

<commit_msg>Modify createLogStream to be createRawLogStream<commit_after>'use strict';

var join      = require('path').join
var EventEmitter = require('events')
//var Obv       = require('obv')

var pull      = require('pull-stream')
var timestamp = require('monotonic-timestamp')
var explain   = require('explain-error')
//var createFeed = require('ssb-feed')
var ref       = require('ssb-ref')
var ssbKeys   = require('ssb-keys')
var Notify    = require('pull-notify')

var isFeedId = ref.isFeedId
var isMsgId  = ref.isMsgId
var isBlobId = ref.isBlobId

var u         = require('./util')
var stdopts   = u.options
var Format    = u.formatStream
//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

var isArray = Array.isArray

function isObject (o) {
  return o && 'object' === typeof o && !Array.isArray(o)
}

function getVMajor () {
  var version = require('./package.json').version
  return (version.split('.')[0])|0
}

module.exports = function (_db, opts, keys, path) {
  path = path || _db.location

  keys = keys || ssbKeys.generate()

  var db = require('./db')(join(opts.path || path, 'flume'), keys, opts)

  //legacy database
  if(_db) require('./legacy')(_db, db)
  else db.ready.set(true)

  db.sublevel = function (a, b) {
    return _db.sublevel(a, b)
  }

  //UGLY HACK, but...
  //fairly sure that something up the stack expects ssb to be an event emitter.
  db.__proto__ = new EventEmitter()

  db.opts = opts

  var _get = db.get

  db.get = function (key, cb) {
    if(ref.isMsg(key))
      return db.keys.get(key, function (err, seq) {
        if(err) cb(err)
        else cb(null, seq && seq.value)
      })
    else if(Number.isInteger(key))
      _get(key, cb) //seq
    else
      throw new Error('secure-scuttlebutt.get: key *must* be a ssb message id or a flume offset')
  }

  db.add = function (msg, cb) {
    db.queue(msg, function (err, data) {
      if(err) cb(err)
      else db.flush(function () { cb(null, data) })
    })
  }

  db.createFeed = function (keys) {
    if(!keys) keys = ssbKeys.generate()
    function add (content, cb) {
      //LEGACY: hacks to support add as a continuable
      if(!cb)
        return function (cb) { add (content, cb) }

      db.append({content: content, keys: keys}, cb)
    }
    return {
      add: add, publish: add,
      id: keys.id, keys: keys
    }
  }

  db.createRawLogStream = function (opts) {
    return db.stream(opts)
  }

  //pull in the features that are needed to pass the tests
  //and that sbot, etc uses but are slow.
  require('./extras')(db, opts, keys)

  //writeStream - used in (legacy) replication.
  db.createWriteStream = function (cb) {
    return pull(
      pull.asyncMap(function (data, cb) {
        db.queue(data, function (err, msg) {
          if(err) {
            db.emit('invalid', err, msg)
          }
          setImmediate(cb)
        })
      }),
      pull.drain(null, function (err) {
        if(err) return cb(err)
        db.flush(cb)
      })
    )
  }

  db.createHistoryStream = db.clock.createHistoryStream

  //called with [id, seq] or "<id>:<seq>"
  db.getAtSequence = function (seqid, cb) {
    db.clock.get(isString(seqid) ? seqid.split(':') : seqid, cb)
  }

  db.getVectorClock = function (_, cb) {
    if(!cb) cb = _
    db.last.get(function (err, h) {
      if(err) return cb(err)
      var clock = {}
      for(var k in h)
        clock[k] = h[k].sequence
      cb(null, clock)
    })

  }

  if(_db) {
    var close = db.close
    db.close = function (cb) {
      var n = 2
      _db.close(next); close(next)

      function next (err) {
        if(err && n>0) {
          n = -1
          return cb(err)
        }
        if(--n) return
        cb()
      }

    }

  }
  return db
}

<|endoftext|>


<commit_before>(function(root, factory) {
  if (typeof exports !== 'undefined') {
    // Node.js
    module.exports = factory(root);
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(function() {
      // If Basbosa is loaded, do not register a global logger
      if (typeof Basbosa === 'undefined') {
        return root.BasbosaValidation = factory(root);
      }
      return factory(root);
    });
  } else {
    // Browser globals
    root.BasbosaValidation = factory(root);
  }
}(this, function(root) {

	var BasbosaValidation = function() {}, instance;
	var _ = require('underscore');
	var Async = require('async');
	BasbosaValidation.prototype.Rules = {
		urlPattern : new RegExp("((http|https)(:\/\/))?([a-zA-Z0-9]+[.]{1}){2}[a-zA-z0-9]+(\/{1}[a-zA-Z0-9]+)*\/?", "i"),
		isObjectId : function(obj, field, options, cb) {
			// Checks if field is an object id
			// (i.e. a 12 byte hex number, taking into consideration that it's represented in a string)
			// Check if field is a string (includes checking if it's present)
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if (obj.length != 24) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// checking that each character represents a hex numbers using a regular expression
				if(cb === 'function')	cb(/[\da-f]{24}/.test(obj));
				return  /[\da-f]{24}/.test(obj);
			} else {
				if (!this.string(obj, field)) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// Check if length is 24 characters (i.e. 12 bytes)
				if (obj[field].length != 24) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// checking that each character represents a hex numbers using a regular expression
				if(cb === 'function')	cb(/[\da-f]{24}/.test(obj[field]));
				return  /[\da-f]{24}/.test(obj[field]);
			}

		},
		isPresent: function(obj, field, options, cb) {
			// Checks if field exists in a obj or not

			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(cb === 'function')	cb(_.has(obj, field));
			return _.has(obj, field);
		},

		string: function(obj, field, options, cb) {
			// Checks if field inside obj is a string or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if(cb === 'function') cb(_.isString(field));
				return  _.isString(field);
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && _.isString(obj[field]));
				return this.isPresent(obj, field) && _.isString(obj[field]);
			}

		},
		numeric: function(obj, field, options, cb) {
			// Checks if field inside obj is an integer or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if(cb === 'function') cb(_.isNumber(obj));
				return  _.isNumber(obj);
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && _.isNumber(obj[field]));
				return this.isPresent(obj, field) && _.isNumber(obj[field]);
			}

		},
		url: function(obj, field, options, cb) {
			var self = this;
			// Checks if field inside obj is a url or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb(self.urlPattern.test(field));
				return (self.urlPattern.test(field));
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && self.urlPattern.test(obj[field]));
				return this.isPresent(obj, field) && self.urlPattern.test(obj[field]);
			}

		},
		/**
		 * @method isLargerThan used to check if the length of any string  is larger than specific number.
		 * @param {String} obj hold the message  that contain specific string that need t check on it.
		 * @param {String} field hold the string that need to check on it.
		 * @param {Number} min hold the number that need to limit the length of the string by it.
		 */
		maxLength: function(obj, field, options, cb) {
			// Checks if field inside obj is larger than the min value
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb((field.length >= options));
				return (field.length >= options);
			} else {
				if(cb === 'function') cb(this.isPresent(obj, field) && (obj[field].length >= options));
				return this.isPresent(obj, field) && (obj[field].length >= options);
			}

		},
		email :  function(obj, field, options, cb) {
			if (typeof field === 'function') {
		    cb = field;
		    options	= {};
		    field = {};
		  }
			if (typeof options === 'function') {
		    cb = options;
		    options = {};
		  }

			if(cb === 'function') {
				cb(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(obj));
			}
			return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(obj);
		},
		minLength: function(obj, field, options, cb) {
			var self = this;
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb(field.length <= options);
				return field.length <= options;
			} else {
				if(cb === 'function') cb(self.isPresent(obj, field) && (obj[field].length <= options));
				// Checks if field inside obj is smaller than the max value
				return self.isPresent(obj, field) && (obj[field].length <= options);
			}
		},
		rang: function(obj, field, options, cb) {
			// Checks if field inside obj is within the min and max values
			if(typeof options === 'function') {
				cb = options;
				options = field;
				field = obj;
				obj = undefined;
			}
			if(cb === 'function')	cb(this.minLength(obj, field, options.max) && this.maxLength(obj, field, options.min));
			return this.minLength(obj, field, options.max) && this.maxLength(obj, field, options.min);
		},

	};
	BasbosaValidation.prototype.validate = function(validator, msg, callback) {
	//Does the actual validation
		if(_.isEmpty(validator)) {
			// We either drop or pass a message with an empty validator here, except what happens
			// for authn.socket? There is nothing being passed in it
			// return true; was originally like this

			typeof callback === 'funcrion' && callback(false);
			return false; // now any message with empty validator will simply be dropped

		}	else { // Validate
			var validation_results = new Array();
			_.each(validator, function(fields) {
				_.each(fields, function(validators, key) {
					_.each(validators, function(obj) {
						// obj could be a function or an array that contains a function + extra paramters to be given
						// while invoking that function later on in the validation process
						// so first we check if it's an array
						if(_.isArray(obj)) {
							// handle this
							var func = _.first(obj);
							var args = _.union( [msg, key], _.rest(obj, 1) ); // We are ignoring the first item in obj array
							// since this is the validation function name that'll be called below
							if( func.length < _.size( args ) ) { // Arguments passed in validator must not be more
								// than expected function arguments
								typeof callback === 'funcrion' && callback(false);
								return false;
							} else if( func.length > _.size( args ) ) { // or less
								typeof callback === 'funcrion' && callback(false);
								return false;
							} else { // If we reach this final else, then they are equal
								validation_results.push( func.apply(null, args ) );
							}
						} else {
							// must have been a function
							validation_results.push(obj(msg, key));
						}
					});

				});

			});

			if (_.all(validation_results, _.identity)) {
				typeof callback === 'funcrion' && callback(true);
				return true;
			} else {
				typeof callback === 'funcrion' && callback(false);
				return false;
			}
		}
		console.log('hereeeeeeeeeee');
	};
	if (typeof instance === 'undefined') instance = new BasbosaValidation;
  if (typeof Basbosa !== 'undefined') Basbosa.add('Logger', instance);
  return instance;
}));<commit_msg>add basbosavalidation object to basbosa<commit_after>(function(root, factory) {
  if (typeof exports !== 'undefined') {
    // Node.js
    module.exports = factory(root);
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(function() {
      // If Basbosa is loaded, do not register a global logger
      if (typeof Basbosa === 'undefined') {
        return root.BasbosaValidation = factory(root);
      }
      return factory(root);
    });
  } else {
    // Browser globals
    root.BasbosaValidation = factory(root);
  }
}(this, function(root) {

	var BasbosaValidation = function() {}, instance;
	var _ = require('underscore');
	var Async = require('async');
	BasbosaValidation.prototype.Rules = {
		urlPattern : new RegExp("((http|https)(:\/\/))?([a-zA-Z0-9]+[.]{1}){2}[a-zA-z0-9]+(\/{1}[a-zA-Z0-9]+)*\/?", "i"),
		isObjectId : function(obj, field, options, cb) {
			// Checks if field is an object id
			// (i.e. a 12 byte hex number, taking into consideration that it's represented in a string)
			// Check if field is a string (includes checking if it's present)
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if (obj.length != 24) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// checking that each character represents a hex numbers using a regular expression
				if(cb === 'function')	cb(/[\da-f]{24}/.test(obj));
				return  /[\da-f]{24}/.test(obj);
			} else {
				if (!this.string(obj, field)) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// Check if length is 24 characters (i.e. 12 bytes)
				if (obj[field].length != 24) {
					if(cb === 'function')	cb(false);
					return false;
				}
				// checking that each character represents a hex numbers using a regular expression
				if(cb === 'function')	cb(/[\da-f]{24}/.test(obj[field]));
				return  /[\da-f]{24}/.test(obj[field]);
			}

		},
		isPresent: function(obj, field, options, cb) {
			// Checks if field exists in a obj or not

			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(cb === 'function')	cb(_.has(obj, field));
			return _.has(obj, field);
		},

		string: function(obj, field, options, cb) {
			// Checks if field inside obj is a string or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if(cb === 'function') cb(_.isString(field));
				return  _.isString(field);
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && _.isString(obj[field]));
				return this.isPresent(obj, field) && _.isString(obj[field]);
			}

		},
		numeric: function(obj, field, options, cb) {
			// Checks if field inside obj is an integer or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(field === undefined) {
				if(cb === 'function') cb(_.isNumber(obj));
				return  _.isNumber(obj);
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && _.isNumber(obj[field]));
				return this.isPresent(obj, field) && _.isNumber(obj[field]);
			}

		},
		url: function(obj, field, options, cb) {
			var self = this;
			// Checks if field inside obj is a url or not
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb(self.urlPattern.test(field));
				return (self.urlPattern.test(field));
			} else {
				if(cb === 'function')	cb(this.isPresent(obj, field) && self.urlPattern.test(obj[field]));
				return this.isPresent(obj, field) && self.urlPattern.test(obj[field]);
			}

		},
		/**
		 * @method isLargerThan used to check if the length of any string  is larger than specific number.
		 * @param {String} obj hold the message  that contain specific string that need t check on it.
		 * @param {String} field hold the string that need to check on it.
		 * @param {Number} min hold the number that need to limit the length of the string by it.
		 */
		maxLength: function(obj, field, options, cb) {
			// Checks if field inside obj is larger than the min value
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb((field.length >= options));
				return (field.length >= options);
			} else {
				if(cb === 'function') cb(this.isPresent(obj, field) && (obj[field].length >= options));
				return this.isPresent(obj, field) && (obj[field].length >= options);
			}

		},
		email :  function(obj, field, options, cb) {
			if (typeof field === 'function') {
		    cb = field;
		    options	= {};
		    field = {};
		  }
			if (typeof options === 'function') {
		    cb = options;
		    options = {};
		  }

			if(cb === 'function') {
				cb(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(obj));
			}
			return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(obj);
		},
		minLength: function(obj, field, options, cb) {
			var self = this;
			if (typeof options === 'function') {
		    cb = options;
		    options = undefined;
		  }
			if(options === undefined) {
				options = field ;
				field = obj;
				obj = undefined;
			}
			if(obj ===	undefined) {
				if(cb === 'function') cb(field.length <= options);
				return field.length <= options;
			} else {
				if(cb === 'function') cb(self.isPresent(obj, field) && (obj[field].length <= options));
				// Checks if field inside obj is smaller than the max value
				return self.isPresent(obj, field) && (obj[field].length <= options);
			}
		},
		rang: function(obj, field, options, cb) {
			// Checks if field inside obj is within the min and max values
			if(typeof options === 'function') {
				cb = options;
				options = field;
				field = obj;
				obj = undefined;
			}
			if(cb === 'function')	cb(this.minLength(obj, field, options.max) && this.maxLength(obj, field, options.min));
			return this.minLength(obj, field, options.max) && this.maxLength(obj, field, options.min);
		},

	};
	BasbosaValidation.prototype.validate = function(validator, msg, callback) {
	//Does the actual validation
		if(_.isEmpty(validator)) {
			// We either drop or pass a message with an empty validator here, except what happens
			// for authn.socket? There is nothing being passed in it
			// return true; was originally like this

			typeof callback === 'funcrion' && callback(false);
			return false; // now any message with empty validator will simply be dropped

		}	else { // Validate
			var validation_results = new Array();
			_.each(validator, function(fields) {
				_.each(fields, function(validators, key) {
					_.each(validators, function(obj) {
						// obj could be a function or an array that contains a function + extra paramters to be given
						// while invoking that function later on in the validation process
						// so first we check if it's an array
						if(_.isArray(obj)) {
							// handle this
							var func = _.first(obj);
							var args = _.union( [msg, key], _.rest(obj, 1) ); // We are ignoring the first item in obj array
							// since this is the validation function name that'll be called below
							if( func.length < _.size( args ) ) { // Arguments passed in validator must not be more
								// than expected function arguments
								typeof callback === 'funcrion' && callback(false);
								return false;
							} else if( func.length > _.size( args ) ) { // or less
								typeof callback === 'funcrion' && callback(false);
								return false;
							} else { // If we reach this final else, then they are equal
								validation_results.push( func.apply(null, args ) );
							}
						} else {
							// must have been a function
							validation_results.push(obj(msg, key));
						}
					});

				});

			});

			if (_.all(validation_results, _.identity)) {
				typeof callback === 'funcrion' && callback(true);
				return true;
			} else {
				typeof callback === 'funcrion' && callback(false);
				return false;
			}
		}
		console.log('hereeeeeeeeeee');
	};
	if (typeof instance === 'undefined') instance = new BasbosaValidation;
  if (typeof Basbosa !== 'undefined') Basbosa.add('BasbosaValidation', instance);
  return instance;
}));<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var vow = require('vow');
var vowFs = require('vow-fs');

var techs = [
    'bemhtml',
    'css',
    'js'
];

/**
 * Создает файл для соответствующей технологии.
 *
 * @param  {string}   filePath
 * @param  {string}   tech     bemhtml|css|js.
 * @return {function}
 */
function appendTech(filePath) {
    return function (exist) {
        if (exist) {
            return;
        }

        return vowFs.write(filePath, '');
    };
}

/**
 * Получает список папок, которые необходимо создать.
 *
 * @param  {string} pathName
 * @return {array}
 */
function folderList(pathName) {
    pathName = path.resolve(pathName);

    var base = path.basename(pathName);
    var basePath = pathName.replace(RegExp(base + '$'), '');

    // блок
    if (/^([a-z\-]+)$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1)
        ];
    // модификатор блока
    } else if (/^([a-z\-]+)(_[a-z\-]+)(?:_[a-z\-]+)?$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2)
        ];
    // элемент блока
    } else if (/^([a-z\-]+)(__[a-z\-]+)$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2)
        ];
    // модификатор элемента
    } else if (/^([a-z\-]+)(__[a-z\-]+)(_[a-z\-]+)(?:_[a-z\-]+)?$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2),
            path.join(basePath, RegExp.$1, RegExp.$2, RegExp.$3)
        ];
    }
}

exports.log = function (err) {
    console.log(err.stack || err);
};

/**
 * @param  {string} str
 * @param  {object} params
 */
exports.make = function (str) {
    var list = folderList(str);
    var promise = vow.resolve();

    list.forEach(function (pathName) {
        promise.then(vowFs.makeDir(pathName));
    });

    var ln = arguments.length;
    var basePath = list.pop();
    for (var a = 1; a < ln; ++a) {
        if (!arguments[a]) {
            continue;
        }

        var ext = techs[a - 1];
        var pathName = path.join(basePath, str + '.' + ext);
        promise
            .then(vowFs.exists(pathName))
            .then(appendTech(pathName, ext));
    }

    return promise;
};

// exports.rename = function () {};
<commit_msg>Поправил документацию<commit_after>'use strict';

var path = require('path');
var vow = require('vow');
var vowFs = require('vow-fs');

var techs = [
    'bemhtml',
    'css',
    'js'
];

/**
 * Создает файл для соответствующей технологии.
 *
 * @param  {string}   filePath
 * @param  {string}   tech     bemhtml|css|js.
 * @return {function}
 */
function appendTech(filePath) {
    return function (exist) {
        if (exist) {
            return;
        }

        return vowFs.write(filePath, '');
    };
}

/**
 * Получает список папок, которые необходимо создать.
 *
 * @param  {string} pathName
 * @return {array}
 */
function folderList(pathName) {
    pathName = path.resolve(pathName);

    var base = path.basename(pathName);
    var basePath = pathName.replace(RegExp(base + '$'), '');

    // блок
    if (/^([a-z\-]+)$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1)
        ];
    // модификатор блока
    } else if (/^([a-z\-]+)(_[a-z\-]+)(?:_[a-z\-]+)?$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2)
        ];
    // элемент блока
    } else if (/^([a-z\-]+)(__[a-z\-]+)$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2)
        ];
    // модификатор элемента
    } else if (/^([a-z\-]+)(__[a-z\-]+)(_[a-z\-]+)(?:_[a-z\-]+)?$/i.exec(base)) {
        return [
            path.join(basePath, RegExp.$1),
            path.join(basePath, RegExp.$1, RegExp.$2),
            path.join(basePath, RegExp.$1, RegExp.$2, RegExp.$3)
        ];
    }
}

/**
 * Логирует ошибки.
 *
 * @param  {*} err
 */
exports.log = function (err) {
    console.log(err.stack || err);
};

/**
 * Создает БЕМ сущность.
 *
 * @param  {string}  str
 * @param  {boolean} bemhtml
 * @param  {boolean} css
 * @param  {boolean} js
 * @return {promise}
 */
exports.make = function (str) {
    var list = folderList(str);
    var promise = vow.resolve();

    list.forEach(function (pathName) {
        promise.then(vowFs.makeDir(pathName));
    });

    var ln = arguments.length;
    var basePath = list.pop();
    for (var a = 1; a < ln; ++a) {
        if (!arguments[a]) {
            continue;
        }

        var ext = techs[a - 1];
        var pathName = path.join(basePath, str + '.' + ext);
        promise
            .then(vowFs.exists(pathName))
            .then(appendTech(pathName, ext));
    }

    return promise;
};

// exports.rename = function () {};
<|endoftext|>


<commit_before>var fs = require('fs');
var config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
var api_host = config.host;
var site_id = config.site;
var _ = require('lodash');
request = require('request-json');
var client = request.createClient(api_host);
//var async = require("async");
var Promise = require('promise');

var exports = module.exports = {

    assets: function (callback) {

      url = 'site/' + site_id + '/zget';
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },
    dataset: function (name, display, callback) {

      if(display && display != ''){
          url = 'siteitem/' + name + '/get_by_dataset?site=' + site_id + '&display=' + display;
      } else {
          url = 'siteitem/' + name + '/get_by_dataset?site=' + site_id;
      }
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    questions: function (name, is_legacy, callback) {

      if(is_legacy && is_legacy != '' && (is_legacy == true || is_legacy == "true" )){
          url = 'questions/' + name + '?use_lawatlas=true';
      } else {
          url= 'api/v3.0/questions/' + name;
      }
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    query: function (name, config, params, version, callback) {

        if(typeof version == 'undefined' || version == ''){
            version = "v3.0";
        }
        //is_legacy, state, jurisdictions, start_year, end_year
        url = "api/" + version + "/dataset/query/" + name + "?site_key=" + site_id;
        if ("use_lawatlas" in config) {
            url= url + '&use_lawatlas=true';
        }
        if ("state" in config) {
            url= url + '&state=' + config.state;
        }
        if("start_year" in config){
            url= url + '&StartYear=' + config.start_year;
        }
        if("end_year" in config){
            url= url + '&EndYear=' + config.end_year;
        }
        if("jurisdictions" in config){
			url= url + '&jurisdictions[]=' + config.jurisdictions;
        }

        if(typeof callback != 'undefined'){
            return Promise.resolve(exports.get_promise(url, params, "post"))
            .nodeify(callback);
        } else {
            return exports.get_promise(url, params, "post")
            .then(function(d){
              return d;
            });
        }
    },

    query_form: function (name, id, is_legacy, is_migrated, callback) {

        url = "api/v2.0/query/form/" + name + "/" + id + "?site_key=" + site_id;
        if(is_legacy && is_legacy != '' && (is_legacy == true || is_legacy == "true" )){
          url = url + '&is_lawatlas=true&use_lawatlas=true';
        }
        if(is_migrated && is_migrated != '' && (is_migrated == true || is_migrated == "true" )){
          url = url + '&is_migrated_lawatlas_dataset=true';
        }
        //console.log("Form URL");
        //console.log(url);
        if(typeof callback != 'undefined'){
            return Promise.resolve(exports.get_promise(url))
            .nodeify(callback);
        } else {
            return exports.get_promise(url)
            .then(function(d){
              return d;
            });
      }
    },

    display: function (name, display_id, preview_id, callback) {

      url = 'previewer/' + display_id + '/get?dataset=' + name + '&preview_id=' + preview_id;
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    law: function (name, id, callback) {
        url = 'lawGiver/' + name + '/' + id;
        if(typeof callback != 'undefined'){
            return Promise.resolve(exports.get_promise(url, {}, "post"))
            .nodeify(callback);
        } else {
            return exports.get_promise(url, {}, "post")
            .then(function(d){
              return d;
            });
        }
    },

    jurisdiction: function (id, callback) {
      url = 'jurisdiction/getOne?id=' + id;
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    jurisdiction_site_items: function (show_medals, callback) {
        if(show_medals){
            url = 'jurisdictionsiteitem/secondall';
        } else {
            url = 'jurisdictionsiteitem/all';
        }

      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    page: function (name, callback) {
      url = 'page/' + name + '/slug';
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    taxonomies: function (root, callback) {
      url = 'taxonomy/' + root + '/50status/items';
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    taxonomy: function (id, callback) {
      url = 'taxonomy/' + id + '/get';
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    related: function (name, callback) {
      url = 'taxonomy/' + name + '/related';
      if(typeof callback != 'undefined'){
        return Promise.resolve(exports.get_promise(url))
        .nodeify(callback);
      } else {
          return exports.get_promise(url)
          //return exports.dataset_promise(name, display)
            //.then(exports.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    //Common functions
    get_promise: function(url, params, method) {
        if(typeof params == 'undefined' || params == null){
            params = {};
        }
        if(method == "post"){

            var promise = new Promise(function (resolve, reject) {
              client.post(url, params, function (err, res, body) {
                if (err) reject(err);
                else resolve(res);
              });
            });

        } else {

            var promise = new Promise(function (resolve, reject) {
              client.get(url, function (err, res) {
                if (err) reject(err);
                else resolve(res);
              });
            });
        }

    return Promise.resolve(promise);

    },
    onFulfilled: function(result) {
      //console.log("Promise resolved");
      //console.log(result);
      return result;
    },
    onRejected: function(result) {
      console.error("Promise rejected");
      console.error(result);
      return null;
    }
};

<commit_msg>changed exports to MonqcleApi<commit_after>var fs = require('fs');
var config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
var api_host = config.host;
var site_id = config.site;
var _ = require('lodash');
request = require('request-json');
var client = request.createClient(api_host);
//var async = require("async");
var Promise = require('promise');

var MonqcleApi = module.exports = {

    assets: function (callback) {

      url = 'site/' + site_id + '/zget';
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },
    dataset: function (name, display, callback) {

      if(display && display != ''){
          url = 'siteitem/' + name + '/get_by_dataset?site=' + site_id + '&display=' + display;
      } else {
          url = 'siteitem/' + name + '/get_by_dataset?site=' + site_id;
      }
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    questions: function (name, is_legacy, callback) {

      if(is_legacy && is_legacy != '' && (is_legacy == true || is_legacy == "true" )){
          url = 'questions/' + name + '?use_lawatlas=true';
      } else {
          url= 'api/v3.0/questions/' + name;
      }
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    query: function (name, config, params, version, callback) {

        if(typeof version == 'undefined' || version == ''){
            version = "v3.0";
        }
        //is_legacy, state, jurisdictions, start_year, end_year
        url = "api/" + version + "/dataset/query/" + name + "?site_key=" + site_id;
        if ("use_lawatlas" in config) {
            url= url + '&use_lawatlas=true';
        }
        if ("state" in config) {
            url= url + '&state=' + config.state;
        }
        if("start_year" in config){
            url= url + '&StartYear=' + config.start_year;
        }
        if("end_year" in config){
            url= url + '&EndYear=' + config.end_year;
        }
        if("jurisdictions" in config){
			url= url + '&jurisdictions[]=' + config.jurisdictions;
        }

        if(typeof callback != 'undefined'){
            return Promise.resolve(MonqcleApi.get_promise(url, params, "post"))
            .nodeify(callback);
        } else {
            return MonqcleApi.get_promise(url, params, "post")
            .then(function(d){
              return d;
            });
        }
    },

    query_form: function (name, id, is_legacy, is_migrated, callback) {

        url = "api/v2.0/query/form/" + name + "/" + id + "?site_key=" + site_id;
        if(is_legacy && is_legacy != '' && (is_legacy == true || is_legacy == "true" )){
          url = url + '&is_lawatlas=true&use_lawatlas=true';
        }
        if(is_migrated && is_migrated != '' && (is_migrated == true || is_migrated == "true" )){
          url = url + '&is_migrated_lawatlas_dataset=true';
        }
        //console.log("Form URL");
        //console.log(url);
        if(typeof callback != 'undefined'){
            return Promise.resolve(MonqcleApi.get_promise(url))
            .nodeify(callback);
        } else {
            return MonqcleApi.get_promise(url)
            .then(function(d){
              return d;
            });
      }
    },

    display: function (name, display_id, preview_id, callback) {

      url = 'previewer/' + display_id + '/get?dataset=' + name + '&preview_id=' + preview_id;
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    law: function (name, id, callback) {
        url = 'lawGiver/' + name + '/' + id;
        if(typeof callback != 'undefined'){
            return Promise.resolve(MonqcleApi.get_promise(url, {}, "post"))
            .nodeify(callback);
        } else {
            return MonqcleApi.get_promise(url, {}, "post")
            .then(function(d){
              return d;
            });
        }
    },

    jurisdiction: function (id, callback) {
      url = 'jurisdiction/getOne?id=' + id;
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    jurisdiction_site_items: function (show_medals, callback) {
        if(show_medals){
            url = 'jurisdictionsiteitem/secondall';
        } else {
            url = 'jurisdictionsiteitem/all';
        }

      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    page: function (name, callback) {
      url = 'page/' + name + '/slug';
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    taxonomies: function (root, callback) {
      url = 'taxonomy/' + root + '/50status/items';
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    taxonomy: function (id, callback) {
      url = 'taxonomy/' + id + '/get';
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    related: function (name, callback) {
      url = 'taxonomy/' + name + '/related';
      if(typeof callback != 'undefined'){
        return Promise.resolve(MonqcleApi.get_promise(url))
        .nodeify(callback);
      } else {
          return MonqcleApi.get_promise(url)
          //return MonqcleApi.dataset_promise(name, display)
            //.then(MonqcleApi.parseResult)
            //.then(null, this.retryErrors)
            //.nodeify(callback)
            .then(function(d){
              //console.log(d);
              return d;
            });
      }
    },

    //Common functions
    get_promise: function(url, params, method) {
        if(typeof params == 'undefined' || params == null){
            params = {};
        }
        if(method == "post"){

            var promise = new Promise(function (resolve, reject) {
              client.post(url, params, function (err, res, body) {
                if (err) reject(err);
                else resolve(res);
              });
            });

        } else {

            var promise = new Promise(function (resolve, reject) {
              client.get(url, function (err, res) {
                if (err) reject(err);
                else resolve(res);
              });
            });
        }

    return Promise.resolve(promise);

    },
    onFulfilled: function(result) {
      //console.log("Promise resolved");
      //console.log(result);
      return result;
    },
    onRejected: function(result) {
      console.error("Promise rejected");
      console.error(result);
      return null;
    }
};

<|endoftext|>


<commit_before>'use strict';

const EventEmitter        = require('events');
const createPublicWebApp  = require('./web/public');
const createPrivateWebApp = require('./web/private');
const actions             = require('./core/actions');
const logger              = require('./lib/logger');

const emitter = new EventEmitter();
const githubSecret = process.env.GH_SECRET;

const publicWebApp  = createPublicWebApp(emitter, githubSecret);
const privateWebApp = createPrivateWebApp(actions);

actions.subscribeCheckersToEvents(emitter);

const publicPort = process.env.PORT || 8080;
publicWebApp.listen(publicPort, err => {
  if (err) logger.error('Error starting the public server', err);
  else logger.info(`Listening public server in ${publicPort}`);
});

const privatePort = process.PRIVATE_PORT || 8484;
privateWebApp.listen(privatePort, err => {
  if (err) logger.error('Error starting the private server', err);
  else logger.info(`Listening private server in ${privatePort}`);
});
<commit_msg>Fix PRIVATE_PORT env variable read<commit_after>'use strict';

const EventEmitter        = require('events');
const createPublicWebApp  = require('./web/public');
const createPrivateWebApp = require('./web/private');
const actions             = require('./core/actions');
const logger              = require('./lib/logger');

const emitter = new EventEmitter();
const githubSecret = process.env.GH_SECRET;

const publicWebApp  = createPublicWebApp(emitter, githubSecret);
const privateWebApp = createPrivateWebApp(actions);

actions.subscribeCheckersToEvents(emitter);

const publicPort = process.env.PORT || 8080;
publicWebApp.listen(publicPort, err => {
  if (err) logger.error('Error starting the public server', err);
  else logger.info(`Listening public server in ${publicPort}`);
});

const privatePort = process.env.PRIVATE_PORT || 8484;
privateWebApp.listen(privatePort, err => {
  if (err) logger.error('Error starting the private server', err);
  else logger.info(`Listening private server in ${privatePort}`);
});
<|endoftext|>