<commit_before>const lwip = require('lwip');
const Pixel = require('../models/pixel');

const imageSize = 1000;

function PaintingHandler(app) {
    return {
        hasImage: false,
        imageHasChanged: false,
        image: null,
        outputImage: null,
        colours: [
            {r: 255, g: 255, b: 255},
            {r: 228, g: 228, b: 228},
            {r: 136, g: 136, b: 136},
            {r: 34, g: 34, b: 34},
            {r: 255, g: 167, b: 209},
            {r: 229, g: 0, b: 0},
            {r: 229, g: 149, b: 0},
            {r: 160, g: 106, b: 66},
            {r: 229, g: 217, b: 0},
            {r: 148, g: 224, b: 68},
            {r: 2, g: 190, b: 1},
            {r: 0, g: 211, b: 221},
            {r: 0, g: 131, b: 199},
            {r: 0, g: 0, b: 234},
            {r: 207, g: 110, b: 228},
            {r: 130, g: 0, b: 128},
        ],

        getBlankImage: function() {
            return new Promise((resolve, reject) => {
                lwip.create(imageSize, imageSize, "white", (err, image) => {
                    if (err) return reject(err);
                    resolve(image);
                });
            });
        },

        loadImageFromDatabase: function() {
            return new Promise((resolve, reject) => {
                let image = this.getBlankImage().then(image => {
                    Pixel.getAllPixels().then(pixels => {
                        let batch = image.batch();
                        pixels.forEach(pixel => {
                            let x = pixel.point.x, y = pixel.point.y;
                            if(x <= 0 || y <= 0 || x > 1000 || y > 1000) {
                                batch.setPixel(x, y, pixel.colour)
                            }
                        })
                        batch.exec((err, image) => {
                            if (err) return reject(err);
                            this.hasImage = true;
                            this.image = image;
                            this.imageBatch = this.image.batch();
                            resolve(image);
                        });
                    }).catch(err => reject(err));
                }).catch(err => {
                    reject(err);
                })
            });
        },

        getOutputImage: function() {
            return new Promise((resolve, reject) => {
                if (this.outputImage && !this.imageHasChanged) return resolve(this.outputImage);
                console.log("Generating new output image!");
                this.generateOutputImage().then((outputImage) => resolve(outputImage)).catch((err) => reject(err));
            })
        },

        generateOutputImage: function() {
            var a = this;
            return new Promise((resolve, reject) => {
                this.imageBatch.toBuffer("png", { compression: "fast", transparency: false }, (err, buffer) => {
                    if (err) return reject(err);
                    a.outputImage = buffer;
                    a.imageHasChanged = false;
                    resolve(buffer);
                })
            })
        },

        getColourRGB: function(colourID) {
            let colour = this.colours[colourID];
            if (!colour) return false;
            return colour;
        },

        doPaint: function(colour, x, y, user) {
            var a = this;
            return new Promise((resolve, reject) => {
                if(!this.hasImage) return reject({message: "Server not ready", code: "not_ready"});
                // Add to DB:
                user.addPixel(colour, x, y, (pixel, err) => {
                    if(err) return reject(err);
                    // Paint on live image:
                    a.imageBatch.setPixel(x, y, colour).exec((err, image) => {
                        if(image) {
                            a.imageHasChanged = true;
                            a.generateOutputImage();
                        }
                    });
                    // Send notice to all clients:
                    app.websocketServer.broadcast("tile_placed", {x: x, y: y, colour: colour});
                    resolve();
                });
            });
        }
    }
}

PaintingHandler.prototype = Object.create(PaintingHandler.prototype);

module.exports = PaintingHandler;<commit_msg>Fix database loading<commit_after>const lwip = require('lwip');
const Pixel = require('../models/pixel');

const imageSize = 1000;

function PaintingHandler(app) {
    return {
        hasImage: false,
        imageHasChanged: false,
        image: null,
        outputImage: null,
        colours: [
            {r: 255, g: 255, b: 255},
            {r: 228, g: 228, b: 228},
            {r: 136, g: 136, b: 136},
            {r: 34, g: 34, b: 34},
            {r: 255, g: 167, b: 209},
            {r: 229, g: 0, b: 0},
            {r: 229, g: 149, b: 0},
            {r: 160, g: 106, b: 66},
            {r: 229, g: 217, b: 0},
            {r: 148, g: 224, b: 68},
            {r: 2, g: 190, b: 1},
            {r: 0, g: 211, b: 221},
            {r: 0, g: 131, b: 199},
            {r: 0, g: 0, b: 234},
            {r: 207, g: 110, b: 228},
            {r: 130, g: 0, b: 128},
        ],

        getBlankImage: function() {
            return new Promise((resolve, reject) => {
                lwip.create(imageSize, imageSize, "white", (err, image) => {
                    if (err) return reject(err);
                    resolve(image);
                });
            });
        },

        loadImageFromDatabase: function() {
            return new Promise((resolve, reject) => {
                let image = this.getBlankImage().then(image => {
                    Pixel.getAllPixels().then(pixels => {
                        let batch = image.batch();
                        pixels.forEach(pixel => {
                            let x = pixel.point.x, y = pixel.point.y;
                            if(x > 0 || y > 0 || x <= 1000 || y <= 1000) {
                                batch.setPixel(x, y, pixel.colour)
                            }
                        })
                        batch.exec((err, image) => {
                            if (err) return reject(err);
                            this.hasImage = true;
                            this.image = image;
                            this.imageBatch = this.image.batch();
                            resolve(image);
                        });
                    }).catch(err => reject(err));
                }).catch(err => {
                    reject(err);
                })
            });
        },

        getOutputImage: function() {
            return new Promise((resolve, reject) => {
                if (this.outputImage && !this.imageHasChanged) return resolve(this.outputImage);
                console.log("Generating new output image!");
                this.generateOutputImage().then((outputImage) => resolve(outputImage)).catch((err) => reject(err));
            })
        },

        generateOutputImage: function() {
            var a = this;
            return new Promise((resolve, reject) => {
                this.imageBatch.toBuffer("png", { compression: "fast", transparency: false }, (err, buffer) => {
                    if (err) return reject(err);
                    a.outputImage = buffer;
                    a.imageHasChanged = false;
                    resolve(buffer);
                })
            })
        },

        getColourRGB: function(colourID) {
            let colour = this.colours[colourID];
            if (!colour) return false;
            return colour;
        },

        doPaint: function(colour, x, y, user) {
            var a = this;
            return new Promise((resolve, reject) => {
                if(!this.hasImage) return reject({message: "Server not ready", code: "not_ready"});
                // Add to DB:
                user.addPixel(colour, x, y, (pixel, err) => {
                    if(err) return reject(err);
                    // Paint on live image:
                    a.imageBatch.setPixel(x, y, colour).exec((err, image) => {
                        if(image) {
                            a.imageHasChanged = true;
                            a.generateOutputImage();
                        }
                    });
                    // Send notice to all clients:
                    app.websocketServer.broadcast("tile_placed", {x: x, y: y, colour: colour});
                    resolve();
                });
            });
        }
    }
}

PaintingHandler.prototype = Object.create(PaintingHandler.prototype);

module.exports = PaintingHandler;<|endoftext|>


<commit_before>import { dbAdapter } from './models'
import { serializeUser } from './serializers/v2/user'

export class DummyPublisher {
  userUpdated() {}
  postCreated() {}
  postDestroyed() {}
  postUpdated() {}
  commentCreated() {}
  commentDestroyed() {}
  commentUpdated() {}
  likeAdded() {}
  likeRemoved() {}
  postHidden() {}
  postUnhidden() {}
  commentLikeAdded() {}
  commentLikeRemoved() {}
  globalUserUpdated() {}
}

export default class pubSub {
  constructor(publisher) {
    this.publisher = publisher
  }

  setPublisher(publisher) {
    this.publisher = publisher;
  }

  async updateUnreadDirects(userId) {
    const unreadDirectsNumber = await dbAdapter.getUnreadDirectsNumber(userId);
    const user = { id: userId, unreadDirectsNumber };
    const payload = JSON.stringify({ user });
    await this.publisher.userUpdated(payload);
  }

  async updateUnreadNotifications(userIntId) {
    const [{ uid: userId }] = await dbAdapter.getUsersIdsByIntIds([userIntId]);
    const unreadNotificationsNumber = await dbAdapter.getUnreadEventsNumber(userId);
    const user = { id: userId, unreadNotificationsNumber };
    const payload = JSON.stringify({ user });
    await this.publisher.userUpdated(payload);
  }

  async newPost(postId) {
    const payload = JSON.stringify({ postId })
    await this.publisher.postCreated(payload)
  }

  async destroyPost(postId, rooms) {
    const payload = JSON.stringify({ postId, rooms })
    await this.publisher.postDestroyed(payload)
  }

  async updatePost(postId) {
    const payload = JSON.stringify({ postId })
    await this.publisher.postUpdated(payload)
  }

  async newComment(comment, timelines) {
    const timelineIds = timelines.map((t) => t.id)
    const payload = JSON.stringify({ commentId: comment.id, timelineIds })
    await this.publisher.commentCreated(payload)
  }

  async destroyComment(commentId, postId) {
    const payload = JSON.stringify({ postId, commentId })
    await this.publisher.commentDestroyed(payload)
  }

  async updateComment(commentId) {
    const payload = JSON.stringify({ commentId })
    await this.publisher.commentUpdated(payload)
  }

  async newLike(post, userId, timelines) {
    const timelineIds = timelines.map((t) => t.id)
    const payload = JSON.stringify({ userId, postId: post.id, timelineIds })
    await this.publisher.likeAdded(payload)
  }

  async removeLike(postId, userId, rooms) {
    const payload = JSON.stringify({ userId, postId, rooms })
    await this.publisher.likeRemoved(payload)
  }

  async hidePost(userId, postId) {
    await this.publisher.postHidden(JSON.stringify({ userId, postId }))
  }

  async unhidePost(userId, postId) {
    await this.publisher.postUnhidden(JSON.stringify({ userId, postId }))
  }

  async newCommentLike(commentId, postId, likerUUID) {
    const payload = JSON.stringify({ commentId, postId, likerUUID });
    await this.publisher.commentLikeAdded(payload);
  }

  async removeCommentLike(commentId, postId, unlikerUUID) {
    const payload = JSON.stringify({ commentId, postId, unlikerUUID });
    await this.publisher.commentLikeRemoved(payload);
  }

  async globalUserUpdate(userId) {
    const user = await dbAdapter.getUserById(userId);
    const payload = JSON.stringify(serializeUser(user));
    await this.publisher.globalUserUpdated(payload);
  }
}
<commit_msg>Change signatore of newLike pubsub method<commit_after>import { dbAdapter } from './models'
import { serializeUser } from './serializers/v2/user'

export class DummyPublisher {
  userUpdated() {}
  postCreated() {}
  postDestroyed() {}
  postUpdated() {}
  commentCreated() {}
  commentDestroyed() {}
  commentUpdated() {}
  likeAdded() {}
  likeRemoved() {}
  postHidden() {}
  postUnhidden() {}
  commentLikeAdded() {}
  commentLikeRemoved() {}
  globalUserUpdated() {}
}

export default class pubSub {
  constructor(publisher) {
    this.publisher = publisher
  }

  setPublisher(publisher) {
    this.publisher = publisher;
  }

  async updateUnreadDirects(userId) {
    const unreadDirectsNumber = await dbAdapter.getUnreadDirectsNumber(userId);
    const user = { id: userId, unreadDirectsNumber };
    const payload = JSON.stringify({ user });
    await this.publisher.userUpdated(payload);
  }

  async updateUnreadNotifications(userIntId) {
    const [{ uid: userId }] = await dbAdapter.getUsersIdsByIntIds([userIntId]);
    const unreadNotificationsNumber = await dbAdapter.getUnreadEventsNumber(userId);
    const user = { id: userId, unreadNotificationsNumber };
    const payload = JSON.stringify({ user });
    await this.publisher.userUpdated(payload);
  }

  async newPost(postId) {
    const payload = JSON.stringify({ postId })
    await this.publisher.postCreated(payload)
  }

  async destroyPost(postId, rooms) {
    const payload = JSON.stringify({ postId, rooms })
    await this.publisher.postDestroyed(payload)
  }

  async updatePost(postId) {
    const payload = JSON.stringify({ postId })
    await this.publisher.postUpdated(payload)
  }

  async newComment(comment, timelines) {
    const timelineIds = timelines.map((t) => t.id)
    const payload = JSON.stringify({ commentId: comment.id, timelineIds })
    await this.publisher.commentCreated(payload)
  }

  async destroyComment(commentId, postId) {
    const payload = JSON.stringify({ postId, commentId })
    await this.publisher.commentDestroyed(payload)
  }

  async updateComment(commentId) {
    const payload = JSON.stringify({ commentId })
    await this.publisher.commentUpdated(payload)
  }

  async newLike(post, userId) {
    const payload = JSON.stringify({ userId, postId: post.id })
    await this.publisher.likeAdded(payload)
  }

  async removeLike(postId, userId, rooms) {
    const payload = JSON.stringify({ userId, postId, rooms })
    await this.publisher.likeRemoved(payload)
  }

  async hidePost(userId, postId) {
    await this.publisher.postHidden(JSON.stringify({ userId, postId }))
  }

  async unhidePost(userId, postId) {
    await this.publisher.postUnhidden(JSON.stringify({ userId, postId }))
  }

  async newCommentLike(commentId, postId, likerUUID) {
    const payload = JSON.stringify({ commentId, postId, likerUUID });
    await this.publisher.commentLikeAdded(payload);
  }

  async removeCommentLike(commentId, postId, unlikerUUID) {
    const payload = JSON.stringify({ commentId, postId, unlikerUUID });
    await this.publisher.commentLikeRemoved(payload);
  }

  async globalUserUpdate(userId) {
    const user = await dbAdapter.getUserById(userId);
    const payload = JSON.stringify(serializeUser(user));
    await this.publisher.globalUserUpdated(payload);
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Johannes Zellner webmaster@nebulon.de - All Rights Reserved

"use strict";

/*
 **************************************************
 * QuickJS Helper
 **************************************************
 */

// ensure namespace
if (!Quick) {
    var Quick = {};
}

Quick.debug = false;
Quick.verbose = false;

Quick.run = function () {
    Quick.useQueryFlags();
    Quick.compileScriptTags();
    Quick.Engine.start();
};

Quick.useQueryFlags = function() {
    // TODO improve detection
    Quick.verbose = (window.location.href.indexOf("verbose") >= 0);
    Quick.debug = (window.location.href.indexOf("debug") >= 0);
};

Quick.compileScriptTagElement = function(script) {
    var tokens = Quick.Tokenizer.parse(script.text);
    Quick.Compiler.compileAndRender(tokens, {}, function (error, result) {
        if (error) {
            console.error("QuickJS compile error: " + error.line + ": " + error.message);
            console.error(" -- " + error.context);
        } else {
            try {
                if (Quick.verbose || Quick.debug) {
                    console.log("----------------------");
                    console.log(result);
                    console.log("----------------------");
                    console.log("eval...");
                    var o = new Date();
                    eval(result);
                    var n = new Date();
                    console.log("done, eval took time: ", (n - o), "ms");
                } else {
                    eval(result);
                }
            } catch (e) {
                console.error("QuickJS error in generated JavaScript: " + e);
                console.error(e);
            }
        }
    });
};

Quick.compileScriptTags = function(scriptType) {
    var type = scriptType ? scriptType : "text/jml";

    for (var i = 0; i < window.document.scripts.length; ++i) {
        var script = window.document.scripts[i];
        if (script.type === type) {
            Quick.compileScriptTagElement(script);
        }
    }
};
<commit_msg>Script tags can specify a module as well<commit_after>// Copyright (c) 2012 Johannes Zellner webmaster@nebulon.de - All Rights Reserved

"use strict";

/*
 **************************************************
 * QuickJS Helper
 **************************************************
 */

// ensure namespace
if (!Quick) {
    var Quick = {};
}

Quick.debug = false;
Quick.verbose = false;

Quick.run = function () {
    Quick.useQueryFlags();
    Quick.compileScriptTags();
    Quick.Engine.start();
};

Quick.useQueryFlags = function() {
    // TODO improve detection
    Quick.verbose = (window.location.href.indexOf("verbose") >= 0);
    Quick.debug = (window.location.href.indexOf("debug") >= 0);
};

Quick.compileScriptTagElement = function(script) {
    var tokens = Quick.Tokenizer.parse(script.text);
    var moduleName = script.attributes.module && script.attributes.module.textContent;
    Quick.Compiler.compileAndRender(tokens, { module: moduleName }, function (error, result) {
        if (error) {
            console.error("QuickJS compile error: " + error.line + ": " + error.message);
            console.error(" -- " + error.context);
        } else {
            try {
                if (Quick.verbose || Quick.debug) {
                    console.log("----------------------");
                    console.log(result);
                    console.log("----------------------");
                    console.log("eval...");
                    var o = new Date();
                    eval(result);
                    var n = new Date();
                    console.log("done, eval took time: ", (n - o), "ms");
                } else {
                    eval(result);
                }
            } catch (e) {
                console.error("QuickJS error in generated JavaScript: " + e);
                console.error(e);
            }
        }
    });
};

Quick.compileScriptTags = function(scriptType) {
    var type = scriptType ? scriptType : "text/jml";

    for (var i = 0; i < window.document.scripts.length; ++i) {
        var script = window.document.scripts[i];
        if (script.type === type) {
            Quick.compileScriptTagElement(script);
        }
    }
};
<|endoftext|>


<commit_before>module.exports = {
  lookup: function (req, res) {
    return Invitation.where({token: req.param('token')}).fetch({withRelated: 'community'})
    .then(invitation => {
      if (!invitation) {
        return res.status(422).send('bad token')
      }

      if (invitation.isUsed()) {
        return res.status(422).send('used token')
      }

      return res.ok(invitation.relations.community.pick('id', 'name', 'slug', 'avatar_url'))
    })
  },

  use: function (req, res) {
    return Invitation.where({token: req.param('token')}).fetch()
    .then(function (invitation) {
      if (!invitation) {
        return res.status(422).send('bad token')
      }

      if (invitation.isUsed()) {
        return res.status(422).send('used token')
      }

      // user is logged in; apply the invitation
      if (UserSession.isLoggedIn(req)) {
        return bookshelf.transaction(trx => {
          return invitation.use(req.session.userId, {transacting: trx})
          .then(invitation =>
            Post.createWelcomePost(req.session.userId, invitation.get('community_id'), trx))
        })
        .then(() => res.ok({}))
        .catch(err => {
          if (err.message && err.message.contains('duplicate key value')) {
            res.status(422).send('already a member')
          } else {
            throw err
          }
        })
      }

      // return invitation data so that the front-end can store it
      // and re-use it after completing signup or login
      return invitation.load('community').then(function () {
        req.session.invitationId = invitation.id
        res.ok(_.merge(invitation.toJSON(), {
          signup: true
        }))
      })
    })
    .catch(res.serverError)
  }

}
<commit_msg>return membership data when using an invitation<commit_after>module.exports = {
  lookup: function (req, res) {
    return Invitation.where({token: req.param('token')}).fetch({withRelated: 'community'})
    .then(invitation => {
      if (!invitation) {
        return res.status(422).send('bad token')
      }

      if (invitation.isUsed()) {
        return res.status(422).send('used token')
      }

      return res.ok(invitation.relations.community.pick('id', 'name', 'slug', 'avatar_url'))
    })
  },

  use: function (req, res) {
    return Invitation.where({token: req.param('token')}).fetch()
    .then(function (invitation) {
      if (!invitation) {
        return res.status(422).send('bad token')
      }

      if (invitation.isUsed()) {
        return res.status(422).send('used token')
      }

      // user is logged in; apply the invitation
      if (UserSession.isLoggedIn(req)) {
        return bookshelf.transaction(trx => {
          return invitation.use(req.session.userId, {transacting: trx})
          .tap(membership => Post.createWelcomePost(req.session.userId, invitation.get('community_id'), trx))
        })
        .then(membership => membership.load('community').then(() => res.ok(membership)))
        .catch(err => {
          if (err.message && err.message.contains('duplicate key value')) {
            res.status(422).send('already a member')
          } else {
            throw err
          }
        })
      }

      // return invitation data so that the front-end can store it
      // and re-use it after completing signup or login
      return invitation.load('community').then(function () {
        req.session.invitationId = invitation.id
        res.ok(_.merge(invitation.toJSON(), {
          signup: true
        }))
      })
    })
    .catch(res.serverError)
  }

}
<|endoftext|>


<commit_before>$(function() {
        $("input[class^='datepicker']").datepicker();

        // Display/hide question if poll is selected
        if (!$("#id_baseline_poll").val()) {
            $("#id_baseline_question").parent().parent().hide();
        }
        $("#id_baseline_poll").on("change", function() {
          if(this.value) {
            $("#id_baseline_question").parent().parent().show();
          }
          else {
            $("#id_baseline_question").parent().parent().hide();
          }
        });

        // Display/hide question if poll is selected
        if (!$("#id_follow_up_poll").val()) {
            $("#id_follow_up_question").parent().parent().hide();
        }
        $("#id_follow_up_poll").on("change", function() {
          if(this.value) {
            $("#id_follow_up_question").parent().parent().show();
          }
          else {
            $("#id_follow_up_question").parent().parent().hide();
          }
        });
    });
<commit_msg>Adjusting space issues on js file<commit_after>$(function() {
    $("input[class^='datepicker']").datepicker();

    // Display/hide question if poll is selected
    if (!$("#id_baseline_poll").val()) {
        $("#id_baseline_question").parent().parent().hide();
    }
    $("#id_baseline_poll").on("change", function() {
      if(this.value) {
        $("#id_baseline_question").parent().parent().show();
      }
      else {
        $("#id_baseline_question").parent().parent().hide();
      }
    });

    // Display/hide question if poll is selected
    if (!$("#id_follow_up_poll").val()) {
        $("#id_follow_up_question").parent().parent().hide();
    }
    $("#id_follow_up_poll").on("change", function() {
      if(this.value) {
        $("#id_follow_up_question").parent().parent().show();
      }
      else {
        $("#id_follow_up_question").parent().parent().hide();
      }
    });
});
<|endoftext|>


<commit_before>"use strict";

var _ = require('mori');
var Router = require('react-router');
var React = require('react');
var mori = require("mori");
var UnitCell = require('../board/UnitCell.react.js');
var GameStore = require('../../stores/GameStore.js');
var ProfileLink = require('../common/ProfileLink.react.js');
var GameActions = require('../../actions/GameActions.js');

module.exports = React.createClass({

  render: function () {
    var css = "btn btn-default";
    if(_.isEmpty(GameStore.currentActions)) {
      css += " disabled";
    }
    return (
      Reset
    );
  },

  click: function click(ev) {
    GameActions.resetActions();
  }

});
<commit_msg>Only show reset if current player's turn<commit_after>"use strict";

var _ = require('mori');
var Router = require('react-router');
var React = require('react');
var mori = require("mori");
var UnitCell = require('../board/UnitCell.react.js');
var GameStore = require('../../stores/GameStore.js');
var ProfileLink = require('../common/ProfileLink.react.js');
var GameActions = require('../../actions/GameActions.js');

module.exports = React.createClass({

  render: function () {
    var css = "btn btn-default";
    if(_.isEmpty(GameStore.currentActions)) {
      css += " disabled";
    }
    if(!GameStore.isCurrentUserTurn()) {
      css = "hide";
    }
    return (
      Reset
    );
  },

  click: function click(ev) {
    GameActions.resetActions();
  }

});
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fs = require('fs');
var glob = require('glob');
var path = require('path');
var http = require('http');
var express = require('express');
var hbs = require('handlebars');
var marked = require('marked');
var args = require('../src/arguments');
var merge = require('../src/merge');
hbs.registerHelper (
	'markdown', function(text) {
		if(!text) {
			return '';
		}
		return new hbs.SafeString (
			marked (
				text,
				{
					gfm: true,
					sanitize: true,
					breaks: true,
					tables: true
				}
			)
		);
	}
);
var app = express();
if(app.get('env') === 'development') {
	app.use(express.logger());
}
app.use (
	express.static (
		path.resolve(process.cwd(), args['templates-dir'])
	)
);
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use (
	function(req, res, next) {
		res.send_error = function(err) {
			if(err.bad_request) {
				res.status(400);
			}
			else
			if(err.not_found) {
				res.status(404);
			}
			else {
				res.status(500);
			}
			if(err instanceof Error) {
				res.send(err.toString());
			}
			else {
				res.send(err);
			}
		};
		next();
	}
);
function render(shell, page, models, cookies, cb) {
	var shell_template;
	var page_template;
	var model_data = {};
	var partials = {};
	(function load_shell() {
		if(!shell) {
			load_page();
		}
		else {
			var file_name = shell + '.hbs';
			var path = args['templates-dir'] + '/' + file_name;
			fs.readFile (
				path, 'utf8', function(err, template) {
					if(err) {
						cb(err);
						return;
					}
					shell_template = template;
					load_page();
				}
			);
		}
	})();
	function load_page() {
		var file_name = page + '.hbs';
		var path = args['templates-dir'] + '/' + file_name;
		fs.readFile (
			path, 'utf8', function(err, template) {
				if(err) {
					cb(err);
					return;
				}
				page_template = template;
				load_models();
			}
		);
	}
	function load_models() {
		var load_count = 0;
		(function load_model(err, model) {
			if(err) {
				cb(err);
				return;
			}
			if(model) {
				try {
					var loaded_model = JSON.parse(model);
					model_data = merge(model_data, loaded_model);
				}
				catch(err) {
					cb(err);
				}
			}
			if(load_count < models.length) {
				var file_name = models[load_count++] + '.json';
				var path = args['templates-dir']
						+ '/' + args['wysia-subdir']
						+ '/' + file_name;
				fs.readFile(path, 'utf8', load_model);
			}
			else {
				merge_cookies();
			}
		})();
	}
	function merge_cookies() {
		if(!cookies) {
			load_partials();
			return;
		}
		try {
			model_data = merge(model_data, cookies);
		}
		catch(err) {
			cb(err);
			return;
		}
		load_partials();
	}
	function load_partials() {
		var glob_ = args['templates-dir'] + '/*.partial.hbs';
		var partial_files;
		glob (
			glob_, function(err, files) {
				if(err) {
					cb(err);
					return;
				}
				partial_files = files;
				load_partial();
			}
		);
		var load_count = 0;
		function load_partial(err, name, partial) {
			if(err) {
				cb(err);
				return;
			}
			if(partial) {
				partials[name] = partial;
			}
			if(load_count < partial_files.length) {
				var path_ = partial_files[load_count++];
				var name = path.basename(path_, '.partial.hbs');
				fs.readFile (
					path_, 'utf8', function(err, partial) {
						load_partial(err, name, partial);
					}
				);
			}
			else {
				render_();
			}
		}
	}
	function render_() {
		try {
			hbs.partials = {};
			for(var name in partials) {
				var partial = partials[name];
				hbs.registerPartial(name, partial);
			}
			var html = hbs.compile(page_template)(model_data);
			if(shell_template) {
				model_data.page_html = html;
				html = hbs.compile(shell_template)(model_data);
			}
			cb(null, html);
		}
		catch(err) {
			cb(err);
		}
	}
}
function handler(req, res) {
	var shell = req.params.shell || null;
	var page = req.params.page;
	var models = [];
	if(req.params.models) {
		models = req.params.models.split(',');
	}
	var cookies = {};
	if(req.headers.cookie) {
		try {
			cookies = JSON.parse(unescape(req.headers.cookie));
		}
		catch(err) {
			console.error("Failed to parse cookies:", req.headers.cookie + ".");
		}
	}
	render (
		shell, page, models, cookies, function(err, html) {
			if(err) {
				res.send_error(err);
				return;
			}
			res.send(html);
		}
	);
}
function post_redirect(req, res) {
	res.redirect(req.url);
}
app.get('/:shell,:page', handler);
app.post('/:shell,:page', post_redirect);
app.get('/:shell,:page/:models', handler);
app.post('/:shell,:page/:models', post_redirect);
app.get('/:page', handler);
app.post('/:page', post_redirect);
app.get('/:page/:models', handler);
app.post('/:page/:models', post_redirect);
app.listen(args.port);
console.log("Wysia started on port", args.port + ".");
<commit_msg>refactor: Rename handler to get_handler.<commit_after>#!/usr/bin/env node
var fs = require('fs');
var glob = require('glob');
var path = require('path');
var http = require('http');
var express = require('express');
var hbs = require('handlebars');
var marked = require('marked');
var args = require('../src/arguments');
var merge = require('../src/merge');
hbs.registerHelper (
	'markdown', function(text) {
		if(!text) {
			return '';
		}
		return new hbs.SafeString (
			marked (
				text,
				{
					gfm: true,
					sanitize: true,
					breaks: true,
					tables: true
				}
			)
		);
	}
);
var app = express();
if(app.get('env') === 'development') {
	app.use(express.logger());
}
app.use (
	express.static (
		path.resolve(process.cwd(), args['templates-dir'])
	)
);
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use (
	function(req, res, next) {
		res.send_error = function(err) {
			if(err.bad_request) {
				res.status(400);
			}
			else
			if(err.not_found) {
				res.status(404);
			}
			else {
				res.status(500);
			}
			if(err instanceof Error) {
				res.send(err.toString());
			}
			else {
				res.send(err);
			}
		};
		next();
	}
);
function render(shell, page, models, cookies, cb) {
	var shell_template;
	var page_template;
	var model_data = {};
	var partials = {};
	(function load_shell() {
		if(!shell) {
			load_page();
		}
		else {
			var file_name = shell + '.hbs';
			var path = args['templates-dir'] + '/' + file_name;
			fs.readFile (
				path, 'utf8', function(err, template) {
					if(err) {
						cb(err);
						return;
					}
					shell_template = template;
					load_page();
				}
			);
		}
	})();
	function load_page() {
		var file_name = page + '.hbs';
		var path = args['templates-dir'] + '/' + file_name;
		fs.readFile (
			path, 'utf8', function(err, template) {
				if(err) {
					cb(err);
					return;
				}
				page_template = template;
				load_models();
			}
		);
	}
	function load_models() {
		var load_count = 0;
		(function load_model(err, model) {
			if(err) {
				cb(err);
				return;
			}
			if(model) {
				try {
					var loaded_model = JSON.parse(model);
					model_data = merge(model_data, loaded_model);
				}
				catch(err) {
					cb(err);
				}
			}
			if(load_count < models.length) {
				var file_name = models[load_count++] + '.json';
				var path = args['templates-dir']
						+ '/' + args['wysia-subdir']
						+ '/' + file_name;
				fs.readFile(path, 'utf8', load_model);
			}
			else {
				merge_cookies();
			}
		})();
	}
	function merge_cookies() {
		if(!cookies) {
			load_partials();
			return;
		}
		try {
			model_data = merge(model_data, cookies);
		}
		catch(err) {
			cb(err);
			return;
		}
		load_partials();
	}
	function load_partials() {
		var glob_ = args['templates-dir'] + '/*.partial.hbs';
		var partial_files;
		glob (
			glob_, function(err, files) {
				if(err) {
					cb(err);
					return;
				}
				partial_files = files;
				load_partial();
			}
		);
		var load_count = 0;
		function load_partial(err, name, partial) {
			if(err) {
				cb(err);
				return;
			}
			if(partial) {
				partials[name] = partial;
			}
			if(load_count < partial_files.length) {
				var path_ = partial_files[load_count++];
				var name = path.basename(path_, '.partial.hbs');
				fs.readFile (
					path_, 'utf8', function(err, partial) {
						load_partial(err, name, partial);
					}
				);
			}
			else {
				render_();
			}
		}
	}
	function render_() {
		try {
			hbs.partials = {};
			for(var name in partials) {
				var partial = partials[name];
				hbs.registerPartial(name, partial);
			}
			var html = hbs.compile(page_template)(model_data);
			if(shell_template) {
				model_data.page_html = html;
				html = hbs.compile(shell_template)(model_data);
			}
			cb(null, html);
		}
		catch(err) {
			cb(err);
		}
	}
}
function get_handler(req, res) {
	var shell = req.params.shell || null;
	var page = req.params.page;
	var models = [];
	if(req.params.models) {
		models = req.params.models.split(',');
	}
	var cookies = {};
	if(req.headers.cookie) {
		try {
			cookies = JSON.parse(unescape(req.headers.cookie));
		}
		catch(err) {
			console.error("Failed to parse cookies:", req.headers.cookie + ".");
		}
	}
	render (
		shell, page, models, cookies, function(err, html) {
			if(err) {
				res.send_error(err);
				return;
			}
			res.send(html);
		}
	);
}
function post_redirect(req, res) {
	res.redirect(req.url);
}
app.get('/:shell,:page', get_handler);
app.post('/:shell,:page', post_redirect);
app.get('/:shell,:page/:models', get_handler);
app.post('/:shell,:page/:models', post_redirect);
app.get('/:page', get_handler);
app.post('/:page', post_redirect);
app.get('/:page/:models', get_handler);
app.post('/:page/:models', post_redirect);
app.listen(args.port);
console.log("Wysia started on port", args.port + ".");
<|endoftext|>


<commit_before>import Ember from 'ember';

var Router = Ember.Router.extend({
  location: HospitalrunENV.locationType
});

Router.map(function() {
    this.resource('admin', function() {
        this.route('address');
        this.route('lookup', { path: '/' });
        this.resource('users', function() {
            this.route('edit', { path: "/edit/:user_id" });
        });
         this.route('query');
    });

    this.resource('appointments', function() {
        //this.route('calendar'); //currently not working in prod build
        this.route('edit', { path: "/edit/:appointment_id" });
        this.route('search');
        this.route('today');
    });

    this.route('finishgauth', { path: "/finishgauth/:s1/:s2/:k/:t/:i/:p" });

    this.route('index', { path: '/' });

    this.resource('imaging', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:imaging_id" });
    });

    this.resource('inventory', function() {
        this.route('barcode', { path: "/barcode/:inventory_id" });
        this.route('completed');
        this.route('delivery', { path: "/delivery/:inv-request_id" });
        this.route('edit', { path: "/edit/:inventory_id" });
        this.route('listing');
        this.route('reports');
        this.route('request', { path: "/request/:inv-request_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('invoices', { path: '/invoice' }, function() {
        this.route('edit', { path: "/edit/:invoice_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('labs', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:lab_id" });
    });

    this.route('login');

    this.resource('medication', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:medication_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('patients', function() {
        this.route('edit', { path: "/edit/:patient_id" });
        this.route('reports');
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('visits', function() {
        this.route('edit', { path: "/edit/:visit_id" });
    });
});

export default Router;
<commit_msg>fixing formats<commit_after>import Ember from 'ember';

var Router = Ember.Router.extend({
  location: HospitalrunENV.locationType
});

Router.map(function() {
    this.resource('admin', function() {
        this.route('address');
        this.route('lookup', { path: '/' });
        this.resource('users', function() {
            this.route('edit', { path: "/edit/:user_id" });
        });
         this.route('query');
    });

    this.resource('appointments', function() {
        //this.route('calendar'); //currently not working in prod build
        this.route('edit', { path: "/edit/:appointment_id" });
        this.route('search');
        this.route('today');
    });

    this.route('finishgauth', { path: "/finishgauth/:s1/:s2/:k/:t/:i/:p" });

    this.route('index', { path: '/' });

    this.resource('imaging', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:imaging_id" });
    });

    this.resource('inventory', function() {
        this.route('barcode', { path: "/barcode/:inventory_id" });
        this.route('completed');
        this.route('delivery', { path: "/delivery/:inv-request_id" });
        this.route('edit', { path: "/edit/:inventory_id" });
        this.route('listing');
        this.route('reports');
        this.route('request', { path: "/request/:inv-request_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('invoices', function() {
        this.route('edit', { path: "/edit/:invoice_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('labs', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:lab_id" });
    });

    this.route('login');

    this.resource('medication', function() {
        this.route('completed');
        this.route('edit', { path: "/edit/:medication_id" });
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('patients', function() {
        this.route('edit', { path: "/edit/:patient_id" });
        this.route('reports');
        this.route('search', { path: "/search/:search_text" });
    });

    this.resource('visits', function() {
        this.route('edit', { path: "/edit/:visit_id" });
    });
});

export default Router;
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash'),
  uuid = require('node-uuid');

var Router = require('koa-router'),
  body = require('koa-better-body');

module.exports = function BikeshedsController (helpers) {
  var middleware = helpers.middleware,
    auth = middleware.auth(),
    loadBikeshed = middleware.load('Bikeshed'),
    authLoadBikeshed = middleware.load('Bikeshed', {parent: 'User'});

  var jsonBody = body(),
    multiBody = body({
      multipart: true,
      formidable: {
        multiples: false
      }
    });

  var bikeshedRoutes = new Router()

    // public
    .get('/bikesheds', index)
    .get('/bikesheds/:bikeshed', loadBikeshed, show)
    .get('/bikesheds/:bikeshed/bikes', loadBikeshed, score)

    // private
    .post('/bikesheds', auth, jsonBody, create)
    .del('/bikesheds/:bikeshed', auth, authLoadBikeshed, destroy)
    .post('/bikesheds/:bikeshed', auth, authLoadBikeshed, multiBody, add)
    .patch('/bikesheds/:bikeshed', auth, authLoadBikeshed, jsonBody, patch)
    .post('/bikesheds/:bikeshed/bikes', auth, loadBikeshed, jsonBody, rate)
    .put('/bikesheds/:bikeshed/bikes', auth, loadBikeshed, jsonBody, change)
    .get('/bikesheds/:bikeshed/bikes/votes', auth, loadBikeshed, votes);
    // .del('/bikesheds/:bikeshed/bikes/:bike', auth, authLoadBikeshed, authLoadBike, remove);

  return bikeshedRoutes.middleware();
};

/**
 * GET /bikesheds
 * Public
 * Parameters: sortBy, direction, page, per
 *  per: default 12, [1..96]
 *  page: default 1, [1..]
 *  sortBy: default id, [id, name, createdAt, updatedAt]
 *  direction: default DESC, [DESC, ASC]
 */
function* index () {
  var Bikeshed = this.models.Bikeshed,
    query = this.request.query,
    page = _.parseInt(query.page),
    per = _.parseInt(query.per),
    sortBy = query.sortBy,
    direction = (query.direction || '').toUpperCase();

  page = page >= 1 ? page : 1;
  per = per >= 1 ? (per < 96 ? per : 96) : 12;
  direction = _.contains(['ASC', 'DESC'], direction) ? direction : 'DESC';
  sortBy = _.contains(['id', 'name', 'createdAt', 'updatedAt'], sortBy) ? sortBy : 'id';

  var result = yield Bikeshed.findAndCountAll({
    where: {status: {ne: 'incomplete'}},
    order: [[sortBy, direction]],
    offset: (page - 1) * per,
    limit: per
  });

  this.body = {
    list: result.rows,
    count: result.count,
    page: page,
    pages: Math.ceil(result.count / per) || 1,
    per: per,
    sortBy: sortBy,
    direction: direction
  };
}

/**
 * POST /bikesheds
 * Protected
 * Body: {name: string, body: string}
 */
function* create () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var fields = _.assign({UserId: this.state.user.id},
    _.pick(this.request.body.fields, ['name', 'body']));

  var bikeshed = this.models.Bikeshed.build(fields),
    bikeshedValidation = yield bikeshed.validate();
  if (bikeshedValidation) {
    this.body = bikeshedValidation;
    this.status = 422;
  } else {
    this.body = yield bikeshed.save();
    this.status = 201;
  }
}

/**
 * GET /bikesheds/:bikeshed
 * Public
 */
function* show () {
  this.body = this.state.bikeshed;
}

/**
 * POST /bikesheds/:bikeshed
 * Protected
 * Body: {name: string, body: string, image: file}
 */
function* add () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var bikeshed = this.state.bikeshed;
  if (bikeshed.status !== 'incomplete') {
    this.throw(403, 'can only add bikes to incomplete bikeshed');
  } else if (bikeshed.size >= 5) {
    this.throw(403, 'cannot insert over 5 bikes per bikeshed');
  }

  var image = _.values(this.request.body.files)[0],
    fields = _.assign({
      BikeshedId: this.state.bikeshed.id, imageType: image && image.type
    }, _.pick(this.request.body.fields, ['name', 'body']));

  var bike = this.models.Bike.build(fields),
    bikeValidation = yield bike.validate();
  if (bikeValidation) {
    this.body = bikeValidation;
    if (_.where(bikeValidation.errors, {path: 'imageType'})) {
      this.throw(415);
    } else {
      this.throw(422);
    }
  }

  var s3Options = {};
  if (image) {
    bike.imageName = uuid.v4();
    s3Options.upload = {
      localFile: image.path,
      s3Params: {
        ACL: 'public-read',
        ContentType: bike.imageType,
        Bucket: bike.bucket,
        Key: bike.key
      }
    };
    s3Options.destroy = {
      Delete: {Objects: [{Key: bike.key}]},
      Bucket: bike.bucket
    };
  }

  var t = yield this.models.sequelize.transaction();
  try {
    bike = yield bike.save({transaction: t});
    if (image) yield this.s3.attemptUpload(s3Options);
    yield t.commit();
  } catch (err) {
    yield t.rollback();
    if (err.message === 'cannot insert over 5 bikes per bikeshed') {
      this.throw(403, err.message);
    } else if (err.message === 'can only add bikes to incomplete bikeshed') {
      this.throw(403, err.message);
    } else if (err.message === 'could not serialize access due to concurrent update') {
      this.throw(409, err.message);
    } else {
      this.throw(503);
    }
  }
  this.body = bike;
  this.status = 201;
}

/**
 * PATCH /biksheds/:bikeshed
 * Protected
 * Body: {name: string, body: string, status: string}
 */
function* patch () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var bikeshed = this.state.bikeshed,
    {name, body, status} = _.pick(this.request.body.fields, ['name', 'body', 'status']);

  if ((name || body) && bikeshed.status !== 'incomplete')
    this.throw(422, 'can only update name and body on incomplete bikeshed');

  if (bikeshed.status === 'incomplete') {
    if (_.isString(name)) bikeshed.name = name;
    if (_.isString(body)) bikeshed.body = body;
  }

  if (bikeshed.status === 'incomplete' && status === 'open') bikeshed.openedAt = new Date();
  if (bikeshed.status === 'open' && status === 'closed') bikeshed.closedAt = new Date();
  if (_.isString(status)) bikeshed.status = status;

  var validation = yield bikeshed.validate();
  if (validation) {
    this.body = validation;
    this.throw(422);
  }

  this.body = yield bikeshed.save();
  this.status = 200;
}

/**
 * DELETE /bikeshed/:bikeshed
 * Protected
 */
function* destroy () {
  yield this.state.bikeshed.destroy();
  this.status = 204;
}

/**
 * GET /bikesheds/:bikeshed/bikes
 * Public
 */
function* score () {
  var BikeshedId = this.state.bikeshed.id;
  this.body = yield this.models.Bike.findAll({
    order: [['score', 'ASC']], where: {BikeshedId}
  });
}

/**
 * POST /bikesheds/:bikeshed/bikes
 * Protected
 * Body: {[BikeId]: {value: number}}
 * Example: {1:{value:0}, 2:{value:1}, 3:{value:2}}
 */
function* rate () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var {retry} = this.helpers,
    {Vote, Bike, sequelize} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id,
    UserId = user.id;

  if (bikeshed.status !== 'open') {
    this.throw(403, 'bikeshed must be open');
  } else if (yield Vote.count({where: {BikeshedId, UserId}})) {
    this.throw(403, 'already voted');
  }

  var bikes = yield Bike.findAll({where: {BikeshedId}});
  var votes = _.pairs(this.request.body.fields)
  .map(function (pair) {
    var BikeId = _.parseInt(pair[0]), {value} = _.pick(pair[1], ['value']);
    return Vote.build({BikeshedId, UserId, BikeId, value});
  });

  if (bikes.length !== votes.length) {
    this.throw(422, 'must vote for each bike');
  } else if (_.difference(_.pluck(votes, 'BikeId'), _.pluck(bikes, 'id')).length) {
    this.throw(422, 'must vote on bikes');
  } else if (_.difference(_.range(votes.length), _.pluck(votes, 'value')).length) {
    this.throw(422, 'must have unique value per bike');
  }

  var validations = (yield votes.map(vote => vote.validate())).filter(vote => vote);
  if (validations.length) {
    this.body = validations;
    this.throw(422);
  }

  var saveVotes = function* saveVotes () {
    var result, transaction = yield sequelize.transaction();
    try {
      result = yield votes.map(vote => vote.save({transaction}));
      yield transaction.commit();
    } catch (err) {
      yield transaction.rollback();
      throw err;
    }
    return result;
  };

  this.body = yield retry(saveVotes);
  this.status = 201;
}

/**
 * PUT /bikesheds/:bikeshed/bikes
 * Protected
 * Body: {[BikeId]: {value: number}}
 * Example: {1:{value:0}, 2:{value:1}, 3:{value:2}}
 */
function* change () {
  if (!this.request.body.fields) {
    this.throw(400, 'empty body');
  } else if (this.state.bikeshed.status !== 'open') {
    this.throw(403, 'bikeshed must be open');
  }

  var {retry} = this.helpers,
    {Vote, sequelize} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id,
    UserId = user.id;

  var fields = _.mapValues(this.request.body.fields, (field) => _.pick(field, 'value')),
    votes = yield Vote.findAll({where: {BikeshedId, UserId}});

  if (!votes.length) {
    this.throw(403, 'must vote first');
  } else if (votes.length !== _.keys(fields).length) {
    this.throw(422, 'must vote on bikeshed bikes');
  } else if (_.difference(votes.map(vote => vote.BikeId.toString()), _.keys(fields)).length) {
    this.throw(422, 'must vote on each bike');
  } else if (_.difference(_.range(votes.length), _.pluck(fields, 'value')).length) {
    this.throw(422, 'must use unique value per bike');
  }

  votes.forEach(vote => vote.value = fields[vote.BikeId].value);

  var validations = (yield votes.map(vote => vote.validate())).filter(vote => vote);
  if (validations.length) {
    this.body = validations;
    this.throw(422);
  }

  var saveVotes = function* saveVotes () {
    var result, transaction = yield sequelize.transaction();
    try {
      result = yield votes.map(vote => vote.save({transaction}));
      yield transaction.commit();
    } catch (err) {
      yield transaction.rollback();
      throw err;
    }
    return result;
  };

  this.body = yield retry(saveVotes);
  this.status = 200;
}

/**
 * GET /bikesheds/:bikeshed/bikes/votes
 * Protected
 */
function* votes () {
  var {Vote} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id, UserId = user.id;

  var list = yield Vote.findAll({where: {BikeshedId, UserId}});
  this.body = Vote.asObject(list);
}

// TODO: add trigger for this to work
// /**
//  * DELETE /bikesheds/:bikeshed/bikes/:bike
//  * Protected
//  */
// function* remove () {
//   if (this.state.bikeshed.status !== 'incomplete') {
//     this.throw(403, 'can only remove bikes from incomplete bikesheds');
//   }

//   yield this.state.bike.destroy();
//   this.status = 204;
// }
<commit_msg>refactor bikeshed index for infinite scrolling<commit_after>'use strict';

var _ = require('lodash'),
  uuid = require('node-uuid');

var Router = require('koa-router'),
  body = require('koa-better-body');

module.exports = function BikeshedsController (helpers) {
  var middleware = helpers.middleware,
    auth = middleware.auth(),
    loadBikeshed = middleware.load('Bikeshed'),
    authLoadBikeshed = middleware.load('Bikeshed', {parent: 'User'});

  var jsonBody = body(),
    multiBody = body({
      multipart: true,
      formidable: {
        multiples: false
      }
    });

  var bikeshedRoutes = new Router()

    // public
    .get('/bikesheds', index)
    .get('/bikesheds/:bikeshed', loadBikeshed, show)
    .get('/bikesheds/:bikeshed/bikes', loadBikeshed, score)

    // private
    .post('/bikesheds', auth, jsonBody, create)
    .del('/bikesheds/:bikeshed', auth, authLoadBikeshed, destroy)
    .post('/bikesheds/:bikeshed', auth, authLoadBikeshed, multiBody, add)
    .patch('/bikesheds/:bikeshed', auth, authLoadBikeshed, jsonBody, patch)
    .post('/bikesheds/:bikeshed/bikes', auth, loadBikeshed, jsonBody, rate)
    .put('/bikesheds/:bikeshed/bikes', auth, loadBikeshed, jsonBody, change)
    .get('/bikesheds/:bikeshed/bikes/votes', auth, loadBikeshed, votes);
    // .del('/bikesheds/:bikeshed/bikes/:bike', auth, authLoadBikeshed, authLoadBike, remove);

  return bikeshedRoutes.middleware();
};

/**
 * GET /bikesheds
 * Public
 * Parameters: last, limit
 *  limit: default 12, [1..96]
 *  last: default Date.now(), unix timestamp in milliseconds
 */
function* index () {
  var {Bikeshed} = this.models,
    {last, limit} = this.query;

  var bikesheds = yield Bikeshed.findAll({
    limit: limit >= 1 ? (limit < 96 ? limit : 96) : 12,
    order: [['openedAt', 'DESC']],
    where: {
      status: {ne: 'incomplete'},
      openedAt: {
        lt: new Date(_.parseInt(last) || Date.now()),
        ne: null
      }
    }
  });

  this.body = bikesheds;
}

/**
 * POST /bikesheds
 * Protected
 * Body: {name: string, body: string}
 */
function* create () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var fields = _.assign({UserId: this.state.user.id},
    _.pick(this.request.body.fields, ['name', 'body']));

  var bikeshed = this.models.Bikeshed.build(fields),
    bikeshedValidation = yield bikeshed.validate();
  if (bikeshedValidation) {
    this.body = bikeshedValidation;
    this.status = 422;
  } else {
    this.body = yield bikeshed.save();
    this.status = 201;
  }
}

/**
 * GET /bikesheds/:bikeshed
 * Public
 */
function* show () {
  this.body = this.state.bikeshed;
}

/**
 * POST /bikesheds/:bikeshed
 * Protected
 * Body: {name: string, body: string, image: file}
 */
function* add () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var bikeshed = this.state.bikeshed;
  if (bikeshed.status !== 'incomplete') {
    this.throw(403, 'can only add bikes to incomplete bikeshed');
  } else if (bikeshed.size >= 5) {
    this.throw(403, 'cannot insert over 5 bikes per bikeshed');
  }

  var image = _.values(this.request.body.files)[0],
    fields = _.assign({
      BikeshedId: this.state.bikeshed.id, imageType: image && image.type
    }, _.pick(this.request.body.fields, ['name', 'body']));

  var bike = this.models.Bike.build(fields),
    bikeValidation = yield bike.validate();
  if (bikeValidation) {
    this.body = bikeValidation;
    if (_.where(bikeValidation.errors, {path: 'imageType'})) {
      this.throw(415);
    } else {
      this.throw(422);
    }
  }

  var s3Options = {};
  if (image) {
    bike.imageName = uuid.v4();
    s3Options.upload = {
      localFile: image.path,
      s3Params: {
        ACL: 'public-read',
        ContentType: bike.imageType,
        Bucket: bike.bucket,
        Key: bike.key
      }
    };
    s3Options.destroy = {
      Delete: {Objects: [{Key: bike.key}]},
      Bucket: bike.bucket
    };
  }

  var t = yield this.models.sequelize.transaction();
  try {
    bike = yield bike.save({transaction: t});
    if (image) yield this.s3.attemptUpload(s3Options);
    yield t.commit();
  } catch (err) {
    yield t.rollback();
    if (err.message === 'cannot insert over 5 bikes per bikeshed') {
      this.throw(403, err.message);
    } else if (err.message === 'can only add bikes to incomplete bikeshed') {
      this.throw(403, err.message);
    } else if (err.message === 'could not serialize access due to concurrent update') {
      this.throw(409, err.message);
    } else {
      this.throw(503);
    }
  }
  this.body = bike;
  this.status = 201;
}

/**
 * PATCH /biksheds/:bikeshed
 * Protected
 * Body: {name: string, body: string, status: string}
 */
function* patch () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var bikeshed = this.state.bikeshed,
    {name, body, status} = _.pick(this.request.body.fields, ['name', 'body', 'status']);

  if ((name || body) && bikeshed.status !== 'incomplete')
    this.throw(422, 'can only update name and body on incomplete bikeshed');

  if (bikeshed.status === 'incomplete') {
    if (_.isString(name)) bikeshed.name = name;
    if (_.isString(body)) bikeshed.body = body;
  }

  if (bikeshed.status === 'incomplete' && status === 'open') bikeshed.openedAt = new Date();
  if (bikeshed.status === 'open' && status === 'closed') bikeshed.closedAt = new Date();
  if (_.isString(status)) bikeshed.status = status;

  var validation = yield bikeshed.validate();
  if (validation) {
    this.body = validation;
    this.throw(422);
  }

  this.body = yield bikeshed.save();
  this.status = 200;
}

/**
 * DELETE /bikeshed/:bikeshed
 * Protected
 */
function* destroy () {
  yield this.state.bikeshed.destroy();
  this.status = 204;
}

/**
 * GET /bikesheds/:bikeshed/bikes
 * Public
 */
function* score () {
  var BikeshedId = this.state.bikeshed.id;
  this.body = yield this.models.Bike.findAll({
    order: [['score', 'ASC']], where: {BikeshedId}
  });
}

/**
 * POST /bikesheds/:bikeshed/bikes
 * Protected
 * Body: {[BikeId]: {value: number}}
 * Example: {1:{value:0}, 2:{value:1}, 3:{value:2}}
 */
function* rate () {
  if (!this.request.body.fields) this.throw(400, 'empty body');

  var {retry} = this.helpers,
    {Vote, Bike, sequelize} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id,
    UserId = user.id;

  if (bikeshed.status !== 'open') {
    this.throw(403, 'bikeshed must be open');
  } else if (yield Vote.count({where: {BikeshedId, UserId}})) {
    this.throw(403, 'already voted');
  }

  var bikes = yield Bike.findAll({where: {BikeshedId}});
  var votes = _.pairs(this.request.body.fields)
  .map(function (pair) {
    var BikeId = _.parseInt(pair[0]), {value} = _.pick(pair[1], ['value']);
    return Vote.build({BikeshedId, UserId, BikeId, value});
  });

  if (bikes.length !== votes.length) {
    this.throw(422, 'must vote for each bike');
  } else if (_.difference(_.pluck(votes, 'BikeId'), _.pluck(bikes, 'id')).length) {
    this.throw(422, 'must vote on bikes');
  } else if (_.difference(_.range(votes.length), _.pluck(votes, 'value')).length) {
    this.throw(422, 'must have unique value per bike');
  }

  var validations = (yield votes.map(vote => vote.validate())).filter(vote => vote);
  if (validations.length) {
    this.body = validations;
    this.throw(422);
  }

  var saveVotes = function* saveVotes () {
    var result, transaction = yield sequelize.transaction();
    try {
      result = yield votes.map(vote => vote.save({transaction}));
      yield transaction.commit();
    } catch (err) {
      yield transaction.rollback();
      throw err;
    }
    return result;
  };

  this.body = yield retry(saveVotes);
  this.status = 201;
}

/**
 * PUT /bikesheds/:bikeshed/bikes
 * Protected
 * Body: {[BikeId]: {value: number}}
 * Example: {1:{value:0}, 2:{value:1}, 3:{value:2}}
 */
function* change () {
  if (!this.request.body.fields) {
    this.throw(400, 'empty body');
  } else if (this.state.bikeshed.status !== 'open') {
    this.throw(403, 'bikeshed must be open');
  }

  var {retry} = this.helpers,
    {Vote, sequelize} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id,
    UserId = user.id;

  var fields = _.mapValues(this.request.body.fields, (field) => _.pick(field, 'value')),
    votes = yield Vote.findAll({where: {BikeshedId, UserId}});

  if (!votes.length) {
    this.throw(403, 'must vote first');
  } else if (votes.length !== _.keys(fields).length) {
    this.throw(422, 'must vote on bikeshed bikes');
  } else if (_.difference(votes.map(vote => vote.BikeId.toString()), _.keys(fields)).length) {
    this.throw(422, 'must vote on each bike');
  } else if (_.difference(_.range(votes.length), _.pluck(fields, 'value')).length) {
    this.throw(422, 'must use unique value per bike');
  }

  votes.forEach(vote => vote.value = fields[vote.BikeId].value);

  var validations = (yield votes.map(vote => vote.validate())).filter(vote => vote);
  if (validations.length) {
    this.body = validations;
    this.throw(422);
  }

  var saveVotes = function* saveVotes () {
    var result, transaction = yield sequelize.transaction();
    try {
      result = yield votes.map(vote => vote.save({transaction}));
      yield transaction.commit();
    } catch (err) {
      yield transaction.rollback();
      throw err;
    }
    return result;
  };

  this.body = yield retry(saveVotes);
  this.status = 200;
}

/**
 * GET /bikesheds/:bikeshed/bikes/votes
 * Protected
 */
function* votes () {
  var {Vote} = this.models,
    {bikeshed, user} = this.state,
    BikeshedId = bikeshed.id, UserId = user.id;

  var list = yield Vote.findAll({where: {BikeshedId, UserId}});
  this.body = Vote.asObject(list);
}

// TODO: add trigger for this to work
// /**
//  * DELETE /bikesheds/:bikeshed/bikes/:bike
//  * Protected
//  */
// function* remove () {
//   if (this.state.bikeshed.status !== 'incomplete') {
//     this.throw(403, 'can only remove bikes from incomplete bikesheds');
//   }

//   yield this.state.bike.destroy();
//   this.status = 204;
// }
<|endoftext|>


<commit_before>describe("iD.svg.Midpoints", function () {
    var surface,
        projection = Object,
        filter = d3.functor(true);

    beforeEach(function () {
        surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
            .call(iD.svg.Surface());
    });

    it("finds the location of the midpoints", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [50, 0]}),
            line = iD.Way({nodes: [a.id, b.id]}),
            graph = iD.Graph([a, b, line]);

        surface.call(iD.svg.Midpoints(projection), graph, [line], filter);

        expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]);
    });

    it("doesn't create midpoints on segments with pixel length less than 40", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [39, 0]}),
            line = iD.Way({nodes: [a.id, b.id]}),
            graph = iD.Graph([a, b, line]);

        surface.call(iD.svg.Midpoints(projection), graph, [line], filter);

        expect(surface.selectAll('.midpoint')[0]).to.have.length(0);
    });

    it("binds a datum whose 'ways' property lists ways which include the segement", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [50, 0]}),
            c = iD.Node({loc: [1, 1]}),
            d = iD.Node({loc: [2, 2]}),
            l1 = iD.Way({nodes: [a.id, b.id]}),
            l2 = iD.Way({nodes: [b.id, a.id]}),
            l3 = iD.Way({nodes: [c.id, a.id, b.id, d.id]}),
            l4 = iD.Way({nodes: [a.id, d.id, b.id]}),
            graph = iD.Graph([a, b, c, d, l1, l2, l3, l4]),
            ab = function (d) { return d.id === [a.id, b.id].sort().join("-"); };

        surface.call(iD.svg.Midpoints(projection), graph, [l1, l2, l3, l4], filter);

        expect(surface.selectAll('.midpoint').filter(ab).datum().ways).to.eql([
            {id: l1.id, index: 1},
            {id: l2.id, index: 1},
            {id: l3.id, index: 2}]);
    });
});
<commit_msg>Fix svg/midpoint tests<commit_after>describe("iD.svg.Midpoints", function () {
    var surface,
        projection = Object,
        filter = d3.functor(true);

    beforeEach(function () {
        surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
            .call(iD.svg.Surface());
    });

    it("finds the location of the midpoints", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [50, 0]}),
            line = iD.Way({nodes: [a.id, b.id]}),
            graph = iD.Graph([a, b, line]);

        // If no vertices are drawn, no midpoints are drawn. This dependence needs to be removed
        surface.call(iD.svg.Vertices(projection), graph, [a], filter);
        surface.call(iD.svg.Midpoints(projection), graph, [line], filter);

        expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]);
    });

    it("doesn't create midpoints on segments with pixel length less than 40", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [39, 0]}),
            line = iD.Way({nodes: [a.id, b.id]}),
            graph = iD.Graph([a, b, line]);

        surface.call(iD.svg.Midpoints(projection), graph, [line], filter);

        expect(surface.selectAll('.midpoint')[0]).to.have.length(0);
    });

    it("binds a datum whose 'ways' property lists ways which include the segement", function () {
        var a = iD.Node({loc: [0, 0]}),
            b = iD.Node({loc: [50, 0]}),
            c = iD.Node({loc: [1, 1]}),
            d = iD.Node({loc: [2, 2]}),
            l1 = iD.Way({nodes: [a.id, b.id]}),
            l2 = iD.Way({nodes: [b.id, a.id]}),
            l3 = iD.Way({nodes: [c.id, a.id, b.id, d.id]}),
            l4 = iD.Way({nodes: [a.id, d.id, b.id]}),
            graph = iD.Graph([a, b, c, d, l1, l2, l3, l4]),
            ab = function (d) { return d.id === [a.id, b.id].sort().join("-"); };

        // If no vertices are drawn, no midpoints are drawn. This dependence needs to be removed
        surface.call(iD.svg.Vertices(projection), graph, [a], filter);
        surface.call(iD.svg.Midpoints(projection), graph, [l1, l2, l3, l4], filter);

        expect(surface.selectAll('.midpoint').filter(ab).datum().ways).to.eql([
            {id: l1.id, index: 1},
            {id: l2.id, index: 1},
            {id: l3.id, index: 2}]);
    });
});
<|endoftext|>


<commit_before>var api = require("./api");

module.exports = function(app) {

	app.post('/api/check_price', api.checkPrice);
};

<commit_msg>indention<commit_after>var api = require("./api");

module.exports = function(app) {
    app.post('/api/check_price', api.checkPrice);
};

<|endoftext|>


<commit_before>var vscode = require("vscode");
var request = require("request");
var qs = require("querystring");
var utils = require("./utils");
var _ = require("underscore");

function HoogleRequestConfig(query, resultsCallback) {
  var extSettings = vscode.workspace.getConfiguration("hoogle-vscode");

  this.maxResults = extSettings.get("maxResults");
  this.url = extSettings.get("url");
  this.verbose = extSettings.get("verbose");

  this.resultsCallback = resultsCallback;
  this.query = query;
}

function HoogleResultItemV4(location = "", result = "", docs = "") {
  this.location = location;
  this.result = result;
  this.docs = docs;
  this.isModuleType = false;
  this.isPackageType = false;

  //  v4 results don't have "type" identifiers in the response, so we'll have to parse
  //  some information out manually.

  //  check if it's a module result
  if (this.result.includes("module ")) {
    this.isModuleType = true;
  } else if (this.result.includes("package ")) {
    this.isPackageType = true;
  }

  this.isModule = function () {
    return this.isModuleType;
  }

  this.isPackage = function () {
    return this.isPackageType;
  }

  this.getPackageName = function () {
    if (this.isPackageType) {
      return this.result;
    }

    var splitComponents = this.location.split("/");

    //  get the package name from the URL. :(
    var index = _.findIndex(splitComponents, function (item) {
      return item === "archive";
    });

    //  there is no "archive" component in the URL,
    //  so check if there is a "package" component
    if (index === -1) {
      index = _.findIndex(splitComponents, function (item) {
        return item === "package";
      });
    }

    if (index === -1) {
      return "Unknown Package";
    } else {
      if (splitComponents[index + 1]) {
        return "package " + splitComponents[index + 1]
      }

      return "Unknown Package";
    }
  }

  this.getModuleName = function () {
    if (this.isModuleType) {
      return this.result.replace("module ", "");
    }

    var splitComponents = this.location.split("/");

    if (splitComponents.length < 1) {
      return "Unknown Module";
    }

    var last = splitComponents[splitComponents.length - 1];

    var splitOnOctothorpe = last.split("#");

    if (splitOnOctothorpe.length === 0) {
      return "Unknown Module"
    }

    var packageWithHTML = splitOnOctothorpe[0];
    var packageName = packageWithHTML.replace(".html", "");
    return packageName;
  }

  this.getQueryResult = function () {
    return this.result;
  }
}

function HoogleResultItemV5(url, mod, package, item, doc, type) {
  this.location = url;
  this.module = mod;
  this.package = package;
  this.result = utils.removeHTMLandEntities(item);
  this.docs = doc;
  this.type = type;

  this.isModule = function () {
    return this.type === "module";
  }

  this.isPackage = function () {
    return this.type === "package";
  }

  this.getModuleName = function () {
    if (this.module && this.module.name) {
      return this.module.name;
    }

    return "Unknown Module";
  }

  this.getPackageName = function () {
    if (this.package && this.package.name) {
      return "package " + this.package.name;
    }

    return "Unknown Package";
  }

  this.getQueryResult = function () {
    return this.result;
  }
}

function HoogleResults(json = {}) {
  this.results = []

  //  try and see if the response has a version.
  //  if it does, and it's V4, then parse the results
  //  using the V4 type.
  if (json.version) {
    var versionNumbers = json.version.split(".");
    var major = versionNumbers[0];

    if (major === "4" && json.results) {
      for (var i = 0; i < json.results.length; i++) {
        var item = json.results[i];
        this.results.push(new HoogleResultItemV4(item.location, item.self, item.docs));
      }
    } else {
      vscode.window.showErrorMessage("Unknown response format from Hoogle!");
    }
  }
  //  otherwise, try and parse the result using
  //  the version 5 format.
  else {
    if (Array.isArray(json)) {
      json.forEach(function (resultItem) {
        var url = resultItem.url;
        var docs = resultItem.docs;
        var result = resultItem.item;
        var type = resultItem.type;

        if (!url || !result) {
          vscode.window.showErrorMessage("Unknown response format from Hoogle!");
        } else {
          this.results.push(new HoogleResultItemV5(url, resultItem.module, resultItem.package, result, docs, type));
        }
      }, this);
    } else {
      vscode.window.showErrorMessage("Unknown response format from Hoogle!");
    }
  }
}

function HoogleRequestManager() {
  let mgr = this;

  mgr.isValidQuery = function (hoogleConfig) {
    return hoogleConfig.query && hoogleConfig.query !== "";
  }

  mgr.formatQuery = function (hoogleConfig) {
    if (hoogleConfig.query) {
      hoogleConfig.query = hoogleConfig.query.trim();
    }
  }

  mgr.getOptions = function (hoogleConfig) {
    return {
      mode: "json",
      count: hoogleConfig.maxResults,
      hoogle: hoogleConfig.query
    };
  }

  mgr.handleResponse = function (hoogleConfig) {
    return function (err, response, body) {
      if (err) {
        console.error("Hoogle Error", err);
        vscode.window.showErrorMessage("Something went wrong searching Hoogle!");
        return null;
      } else {
        if (hoogleConfig.verbose) {
          console.info("Unparsed", body);
        }

        var json = JSON.parse(body);

        if (hoogleConfig.verbose) {
          console.info("Parsed", json);
        }

        var results = new HoogleResults(json);

        if (hoogleConfig.verbose) {
          console.info("Results", results);
        }
        hoogleConfig.resultsCallback(results);
      }
    }
  }

  mgr.search = function (hoogleConfig) {
    mgr.formatQuery(hoogleConfig);
    if (!mgr.isValidQuery(hoogleConfig)) {
      return;
    }

    var opts = mgr.getOptions(hoogleConfig);
    var params = qs.stringify(opts);

    if (hoogleConfig.verbose) {
      console.info("Hoogle Params", params);
    }

    var requestURL = `${hoogleConfig.url}?${params}`;

    if (hoogleConfig.verbose) {
      console.info("Hoogle Request", requestURL);
    }
    request.get(requestURL, null, mgr.handleResponse(hoogleConfig));
  }
}

exports.HoogleRequestConfig = HoogleRequestConfig;
exports.HoogleRequestManager = HoogleRequestManager;
exports.HoogleResults = HoogleResults;<commit_msg>take the correct amount of results<commit_after>var vscode = require("vscode");
var request = require("request");
var qs = require("querystring");
var utils = require("./utils");
var _ = require("underscore");

function HoogleRequestConfig(query, resultsCallback) {
  var extSettings = vscode.workspace.getConfiguration("hoogle-vscode");

  this.maxResults = extSettings.get("maxResults");
  this.url = extSettings.get("url");
  this.verbose = extSettings.get("verbose");

  this.resultsCallback = resultsCallback;
  this.query = query;
}

function HoogleResultItemV4(location = "", result = "", docs = "") {
  this.location = location;
  this.result = result;
  this.docs = docs;
  this.isModuleType = false;
  this.isPackageType = false;

  //  v4 results don't have "type" identifiers in the response, so we'll have to parse
  //  some information out manually.

  //  check if it's a module result
  if (this.result.includes("module ")) {
    this.isModuleType = true;
  } else if (this.result.includes("package ")) {
    this.isPackageType = true;
  }

  this.isModule = function () {
    return this.isModuleType;
  }

  this.isPackage = function () {
    return this.isPackageType;
  }

  this.getPackageName = function () {
    if (this.isPackageType) {
      return this.result;
    }

    var splitComponents = this.location.split("/");

    //  get the package name from the URL. :(
    var index = _.findIndex(splitComponents, function (item) {
      return item === "archive";
    });

    //  there is no "archive" component in the URL,
    //  so check if there is a "package" component
    if (index === -1) {
      index = _.findIndex(splitComponents, function (item) {
        return item === "package";
      });
    }

    if (index === -1) {
      return "Unknown Package";
    } else {
      if (splitComponents[index + 1]) {
        return "package " + splitComponents[index + 1]
      }

      return "Unknown Package";
    }
  }

  this.getModuleName = function () {
    if (this.isModuleType) {
      return this.result.replace("module ", "");
    }

    var splitComponents = this.location.split("/");

    if (splitComponents.length < 1) {
      return "Unknown Module";
    }

    var last = splitComponents[splitComponents.length - 1];

    var splitOnOctothorpe = last.split("#");

    if (splitOnOctothorpe.length === 0) {
      return "Unknown Module"
    }

    var packageWithHTML = splitOnOctothorpe[0];
    var packageName = packageWithHTML.replace(".html", "");
    return packageName;
  }

  this.getQueryResult = function () {
    return this.result;
  }
}

function HoogleResultItemV5(url, mod, package, item, doc, type) {
  this.location = url;
  this.module = mod;
  this.package = package;
  this.result = utils.removeHTMLandEntities(item);
  this.docs = doc;
  this.type = type;

  this.isModule = function () {
    return this.type === "module";
  }

  this.isPackage = function () {
    return this.type === "package";
  }

  this.getModuleName = function () {
    if (this.module && this.module.name) {
      return this.module.name;
    }

    return "Unknown Module";
  }

  this.getPackageName = function () {
    if (this.package && this.package.name) {
      return "package " + this.package.name;
    }

    return "Unknown Package";
  }

  this.getQueryResult = function () {
    return this.result;
  }
}

function HoogleResults(json = {}, count = 5) {
  this.results = []

  //  try and see if the response has a version.
  //  if it does, and it's V4, then parse the results
  //  using the V4 type.
  if (json.version) {
    var versionNumbers = json.version.split(".");
    var major = versionNumbers[0];

    if (major === "4" && json.results) {
      for (var i = 0; i < json.results.length; i++) {
        var item = json.results[i];
        this.results.push(new HoogleResultItemV4(item.location, item.self, item.docs));
      }
    } else {
      vscode.window.showErrorMessage("Unknown response format from Hoogle!");
    }
  }
  //  otherwise, try and parse the result using
  //  the version 5 format.
  else {
    if (Array.isArray(json)) {
      json.forEach(function (resultItem) {
        var url = resultItem.url;
        var docs = resultItem.docs;
        var result = resultItem.item;
        var type = resultItem.type;

        if (!url || !result) {
          vscode.window.showErrorMessage("Unknown response format from Hoogle!");
        } else {
          this.results.push(new HoogleResultItemV5(url, resultItem.module, resultItem.package, result, docs, type));
        }
      }, this);
    } else {
      vscode.window.showErrorMessage("Unknown response format from Hoogle!");
    }
  }

  this.results = _.take(this.results, count);
}

function HoogleRequestManager() {
  let mgr = this;

  mgr.isValidQuery = function (hoogleConfig) {
    return hoogleConfig.query && hoogleConfig.query !== "";
  }

  mgr.formatQuery = function (hoogleConfig) {
    if (hoogleConfig.query) {
      hoogleConfig.query = hoogleConfig.query.trim();
    }
  }

  mgr.getOptions = function (hoogleConfig) {
    return {
      mode: "json",
      count: hoogleConfig.maxResults,
      hoogle: hoogleConfig.query
    };
  }

  mgr.handleResponse = function (hoogleConfig) {
    return function (err, response, body) {
      if (err) {
        console.error("Hoogle Error", err);
        vscode.window.showErrorMessage("Something went wrong searching Hoogle!");
        return null;
      } else {
        if (hoogleConfig.verbose) {
          console.info("Unparsed", body);
        }

        var json = JSON.parse(body);

        if (hoogleConfig.verbose) {
          console.info("Parsed", json);
        }

        var results = new HoogleResults(json, hoogleConfig.maxResults);

        if (hoogleConfig.verbose) {
          console.info("Results", results);
        }
        hoogleConfig.resultsCallback(results);
      }
    }
  }

  mgr.search = function (hoogleConfig) {
    mgr.formatQuery(hoogleConfig);
    if (!mgr.isValidQuery(hoogleConfig)) {
      return;
    }

    var opts = mgr.getOptions(hoogleConfig);
    var params = qs.stringify(opts);

    if (hoogleConfig.verbose) {
      console.info("Hoogle Params", params);
    }

    var requestURL = `${hoogleConfig.url}?${params}`;

    if (hoogleConfig.verbose) {
      console.info("Hoogle Request", requestURL);
    }
    request.get(requestURL, null, mgr.handleResponse(hoogleConfig));
  }
}

exports.HoogleRequestConfig = HoogleRequestConfig;
exports.HoogleRequestManager = HoogleRequestManager;
exports.HoogleResults = HoogleResults;<|endoftext|>


<commit_before>
describe("Version", function() {

    it("print version", function() {
		expect(xmlToJSON.version).toEqual("1.3");
    });

});

describe("Parsing - grokAttr=true, grokText=true", function() {

	var xml;
	var result;
	var options = {grokAttr: true, grokText: true};

	it("Setting up xml, options", function () {
		options = {};
		xml = ['<?xml version="1.0" encoding="UTF-8"?>',
			'<xml xmlns="http://default.namespace.uri">',
			'    ',
			'        one',
			'        true',
			'        false',
			'        <![CDATA[some <cdata>]]>two',
			'        <ns:c xmlns:ns="http://another.namespace" ns:id="3">three</ns:c>',
			'    ',
			'	 <e>true</e>',
			'	 <f>false</f>',
			'</xml>'].join('\n');

		console.debug(xml);
    	result = xmlToJSON.parseString(xml, options);
    	console.log(JSON.stringify(result))

		expect(result).toBeDefined();
	});

    it("reading text node", function() {
        expect(result.xml[0].a[0].b[0]._text).toEqual("one");
    });

    it("reading numeric attribute", function() {
        expect(result.xml[0].a[0].b[0]._attr.id._value).toEqual(1);
    });

    it("reading true attribute", function() {
        expect(result.xml[0].a[0].b[1]._attr.id._value).toEqual(true);
    });

    it("reading false attribute", function() {
        expect(result.xml[0].a[0].b[2]._attr.id._value).toEqual(false);
    });

    it("reading true node", function() {
        expect(result.xml[0].e[0]._text).toEqual(true);
    });

    it("reading false node", function() {
        expect(result.xml[0].f[0]._text).toEqual(false);
    });

});

describe("Parsing - grokAttr=false, grokTest=false", function() {

	var xml;
	var result;
	var options = {grokAttr: false, grokText: false};

	it("Setting up xml, options", function () {
		xml = ['<?xml version="1.0" encoding="UTF-8"?>',
			'<xml xmlns="http://default.namespace.uri">',
			'    ',
			'        one',
			'        true',
			'        false',
			'        <![CDATA[some <cdata>]]>two',
			'        <ns:c xmlns:ns="http://another.namespace" ns:id="3">three</ns:c>',
			'    ',
			'	 <e>true</e>',
			'	 <f>false</f>',
			'</xml>'].join('\n');

		console.debug(xml);
    	result = xmlToJSON.parseString(xml, options);
    	console.log(JSON.stringify(result))

		expect(result).toBeDefined();
	});

    it("reading text node", function() {
        expect(result.xml[0].a[0].b[0]._text).toEqual("one");
    });

    it("reading numeric attribute", function() {
        expect(result.xml[0].a[0].b[0]._attr.id._value).toEqual("1");
    });

    it("reading true attribute", function() {
        expect(result.xml[0].a[0].b[1]._attr.id._value).toEqual("true");
    });

    it("reading false attribute", function() {
        expect(result.xml[0].a[0].b[2]._attr.id._value).toEqual("false");
    });

    it("reading true node", function() {
        expect(result.xml[0].e[0]._text).toEqual("true");
    });

    it("reading false node", function() {
        expect(result.xml[0].f[0]._text).toEqual("false");
    });

});
<commit_msg>update version test<commit_after>
describe("Version", function() {

    it("print version", function() {
		expect(xmlToJSON.version).toMatch(/^1\.3/);
    });

});

describe("Parsing - grokAttr=true, grokText=true", function() {

	var xml;
	var result;
	var options = {grokAttr: true, grokText: true};

	it("Setting up xml, options", function () {
		options = {};
		xml = ['<?xml version="1.0" encoding="UTF-8"?>',
			'<xml xmlns="http://default.namespace.uri">',
			'    ',
			'        one',
			'        true',
			'        false',
			'        <![CDATA[some <cdata>]]>two',
			'        <ns:c xmlns:ns="http://another.namespace" ns:id="3">three</ns:c>',
			'    ',
			'	 <e>true</e>',
			'	 <f>false</f>',
			'</xml>'].join('\n');

		console.debug(xml);
    	result = xmlToJSON.parseString(xml, options);
    	console.log(JSON.stringify(result))

		expect(result).toBeDefined();
	});

    it("reading text node", function() {
        expect(result.xml[0].a[0].b[0]._text).toEqual("one");
    });

    it("reading numeric attribute", function() {
        expect(result.xml[0].a[0].b[0]._attr.id._value).toEqual(1);
    });

    it("reading true attribute", function() {
        expect(result.xml[0].a[0].b[1]._attr.id._value).toEqual(true);
    });

    it("reading false attribute", function() {
        expect(result.xml[0].a[0].b[2]._attr.id._value).toEqual(false);
    });

    it("reading true node", function() {
        expect(result.xml[0].e[0]._text).toEqual(true);
    });

    it("reading false node", function() {
        expect(result.xml[0].f[0]._text).toEqual(false);
    });

});

describe("Parsing - grokAttr=false, grokTest=false", function() {

	var xml;
	var result;
	var options = {grokAttr: false, grokText: false};

	it("Setting up xml, options", function () {
		xml = ['<?xml version="1.0" encoding="UTF-8"?>',
			'<xml xmlns="http://default.namespace.uri">',
			'    ',
			'        one',
			'        true',
			'        false',
			'        <![CDATA[some <cdata>]]>two',
			'        <ns:c xmlns:ns="http://another.namespace" ns:id="3">three</ns:c>',
			'    ',
			'	 <e>true</e>',
			'	 <f>false</f>',
			'</xml>'].join('\n');

		console.debug(xml);
    	result = xmlToJSON.parseString(xml, options);
    	console.log(JSON.stringify(result))

		expect(result).toBeDefined();
	});

    it("reading text node", function() {
        expect(result.xml[0].a[0].b[0]._text).toEqual("one");
    });

    it("reading numeric attribute", function() {
        expect(result.xml[0].a[0].b[0]._attr.id._value).toEqual("1");
    });

    it("reading true attribute", function() {
        expect(result.xml[0].a[0].b[1]._attr.id._value).toEqual("true");
    });

    it("reading false attribute", function() {
        expect(result.xml[0].a[0].b[2]._attr.id._value).toEqual("false");
    });

    it("reading true node", function() {
        expect(result.xml[0].e[0]._text).toEqual("true");
    });

    it("reading false node", function() {
        expect(result.xml[0].f[0]._text).toEqual("false");
    });

});
<|endoftext|>