<commit_before>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');
const JSONbig = require('json-bigint');
const async = require('async');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;
const FB_TEXT_LIMIT = 640;
var barbrad = 'true';

class FacebookBot {
    constructor() {
        this.apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
        this.sessionIds = new Map();
        this.messagesDelay = 200;
    }

    doDataResponse(sender, facebookResponseData) {
        if (!Array.isArray(facebookResponseData)) {
            console.log('Response as formatted message');
            this.sendFBMessage(sender, facebookResponseData)
                .catch(err => console.error(err));
        } else {
            async.eachSeries(facebookResponseData, (facebookMessage, callback) => {
                if (facebookMessage.sender_action) {
                    console.log('Response as sender action');
                    this.sendFBSenderAction(sender, facebookMessage.sender_action)
                        .then(() => callback())
                        .catch(err => callback(err));
                }
                else {
                    console.log('Response as formatted message');
                    this.sendFBMessage(sender, facebookMessage)
                        .then(() => callback())
                        .catch(err => callback(err));
                }
            }, (err) => {
                if (err) {
                    console.error(err);
                } else {
                    console.log('Data response completed');
                }
            });
        }
    }

    doRichContentResponse(sender, messages) {
        let facebookMessages = []; // array with result messages

        for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
            let message = messages[messageIndex];

            switch (message.type) {
                //message.type 0 means text message
                case 0:
                    // speech: ["hi"]
                    // we have to get value from fulfillment.speech, because of here is raw speech
                    if (message.speech) {

                        let splittedText = this.splitResponse(message.speech);

                        splittedText.forEach(s => {
                            facebookMessages.push({text: s});
                        });
                    }

                    break;
                //message.type 1 means card message
                case 1: {
                    let carousel = [message];

                    for (messageIndex++; messageIndex < messages.length; messageIndex++) {
                        if (messages[messageIndex].type == 1) {
                            carousel.push(messages[messageIndex]);
                        } else {
                            messageIndex--;
                            break;
                        }
                    }

                    let facebookMessage = {};
                    carousel.forEach((c) => {
                        // buttons: [ {text: "hi", postback: "postback"} ], imageUrl: "", title: "", subtitle: ""

                        let card = {};

                        card.title = c.title;
                        card.image_url = c.imageUrl;
                        if (this.isDefined(c.subtitle)) {
                            card.subtitle = c.subtitle;
                        }
                        //If button is involved in.
                        if (c.buttons.length > 0) {
                            let buttons = [];
                            for (let buttonIndex = 0; buttonIndex < c.buttons.length; buttonIndex++) {
                                let button = c.buttons[buttonIndex];

                                if (button.text) {
                                    let postback = button.postback;
                                    if (!postback) {
                                        postback = button.text;
                                    }

                                    let buttonDescription = {
                                        title: button.text
                                    };

                                    if (postback.startsWith("http")) {
                                        buttonDescription.type = "web_url";
                                        buttonDescription.url = postback;
                                    } else {
                                        buttonDescription.type = "postback";
                                        buttonDescription.payload = postback;
                                    }

                                    buttons.push(buttonDescription);
                                }
                            }

                            if (buttons.length > 0) {
                                card.buttons = buttons;
                            }
                        }

                        if (!facebookMessage.attachment) {
                            facebookMessage.attachment = {type: "template"};
                        }

                        if (!facebookMessage.attachment.payload) {
                            facebookMessage.attachment.payload = {template_type: "generic", elements: []};
                        }

                        facebookMessage.attachment.payload.elements.push(card);
                    });

                    facebookMessages.push(facebookMessage);
                }

                    break;
                //message.type 2 means quick replies message
                case 2: {
                    if (message.replies && message.replies.length > 0) {
                        let facebookMessage = {};

                        facebookMessage.text = message.title ? message.title : 'Choose an item';
                        facebookMessage.quick_replies = [];

                        message.replies.forEach((r) => {
                            facebookMessage.quick_replies.push({
                                content_type: "text",
                                title: r,
                                payload: r
                            });
                        });

                        facebookMessages.push(facebookMessage);
                    }
                }

                    break;
                //message.type 3 means image message
                case 3:

                    if (message.imageUrl) {
                        let facebookMessage = {};

                        // "imageUrl": "http://example.com/image.jpg"
                        facebookMessage.attachment = {type: "image"};
                        facebookMessage.attachment.payload = {url: message.imageUrl};

                        facebookMessages.push(facebookMessage);
                    }

                    break;
                //message.type 4 means custom payload message
                case 4:
                    if (message.payload && message.payload.facebook) {
                        facebookMessages.push(message.payload.facebook);
                    }
                    break;

                default:
                    break;
            }
        }

        return new Promise((resolve, reject) => {
            async.eachSeries(facebookMessages, (msg, callback) => {
                    this.sendFBSenderAction(sender, "typing_on")
                        .then(() => this.sleep(this.messagesDelay))
                        .then(() => this.sendFBMessage(sender, msg))
                        .then(() => callback())
                        .catch(callback);
                },
                (err) => {
                    if (err) {
                        console.error(err);
                        reject(err);
                    } else {
                        console.log('Messages sent');
                        resolve();
                    }
                });
        });

    }

    doTextResponse(sender, responseText) {
        console.log('Response as text message');
        // facebook API limit for text length is 640,
        // so we must split message if needed
        let splittedText = this.splitResponse(responseText);

        async.eachSeries(splittedText, (textPart, callback) => {
            this.sendFBMessage(sender, {text: textPart})
                .then(() => callback())
                .catch(err => callback(err));
        });
    }
 //which webhook event
    getEventText(event) {
        if (event.message) {
            if (event.message.quick_reply && event.message.quick_reply.payload) {
                return event.message.quick_reply.payload;
            }

            if (event.message.text) {
                return event.message.text;
            }
        }

        if (event.postback) {
                if (event.postback.referral.ref) {
                    //console.log(event.postback.referral.ref);
                    //return event.postback.referral.ref;

                    //console.log(event.postback.payload);
                    console.log('testing');
                    //return event.postback.payload;
                    return 'testing';
                }

                else if (event.postback.payload)  {
                    //console.log(event.postback.payload);
                    //console.log(event.postback.referral.ref);
                    console.log('testing2');
                    //return event.postback.payload;
                    return 'testing2';

                }
             console.log('brad');

            }

        console.log('bra2');
        return null;
    console.log('brad3');
    }

    processEvent(event) {
        const sender = event.sender.id.toString();
        const text = this.getEventText(event);

        if (text) {

            // Handle a text message from the sender
            if (!this.sessionIds.has(sender)) {
                this.sessionIds.set(sender, uuid.v4());
            }

            console.log("Text", text);
            //send user's text to api.ai service
            let apiaiRequest = this.apiAiService.textRequest(text,
                {
                    sessionId: this.sessionIds.get(sender),
                    originalRequest: {
                        data: event,
                        source: "facebook"
                    }
                });

            //get response from api.ai
            apiaiRequest.on('response', (response) => {
                if (this.isDefined(response.result) && this.isDefined(response.result.fulfillment)) {
                    let responseText = response.result.fulfillment.speech;
                    let responseData = response.result.fulfillment.data;
                    let responseMessages = response.result.fulfillment.messages;

                    let action = response.result.action;

                    if (this.isDefined(responseData) && this.isDefined(responseData.facebook)) {
                        let facebookResponseData = responseData.facebook;
                        this.doDataResponse(sender, facebookResponseData);
                    } else if (this.isDefined(responseMessages) && responseMessages.length > 0) {
                        this.doRichContentResponse(sender, responseMessages);
                    }
                    else if (this.isDefined(responseText)) {
                        this.doTextResponse(sender, responseText);
                    }

                }
            });

            apiaiRequest.on('error', (error) => console.error(error));
            apiaiRequest.end();
        }
    }

    splitResponse(str) {
        if (str.length <= FB_TEXT_LIMIT) {
            return [str];
        }

        return this.chunkString(str, FB_TEXT_LIMIT);
    }

    chunkString(s, len) {
        let curr = len, prev = 0;

        let output = [];

        while (s[curr]) {
            if (s[curr++] == ' ') {
                output.push(s.substring(prev, curr));
                prev = curr;
                curr += len;
            }
            else {
                let currReverse = curr;
                do {
                    if (s.substring(currReverse - 1, currReverse) == ' ') {
                        output.push(s.substring(prev, currReverse));
                        prev = currReverse;
                        curr = currReverse + len;
                        break;
                    }
                    currReverse--;
                } while (currReverse > prev)
            }
        }
        output.push(s.substr(prev));
        return output;
    }

    sendFBMessage(sender, messageData) {
        return new Promise((resolve, reject) => {
            request({
                url: 'https://graph.facebook.com/v2.6/me/messages',
                qs: {access_token: FB_PAGE_ACCESS_TOKEN},
                method: 'POST',
                json: {
                    recipient: {id: sender},
                    message: messageData
                }
            }, (error, response) => {
                if (error) {
                    console.log('Error sending message: ', error);
                    reject(error);
                } else if (response.body.error) {
                    console.log('Error: ', response.body.error);
                    reject(new Error(response.body.error));
                }

                resolve();
            });
        });
    }

    sendFBSenderAction(sender, action) {
        return new Promise((resolve, reject) => {
            request({
                url: 'https://graph.facebook.com/v2.6/me/messages',
                qs: {access_token: FB_PAGE_ACCESS_TOKEN},
                method: 'POST',
                json: {
                    recipient: {id: sender},
                    sender_action: action
                }
            }, (error, response) => {
                if (error) {
                    console.error('Error sending action: ', error);
                    reject(error);
                } else if (response.body.error) {
                    console.error('Error: ', response.body.error);
                    reject(new Error(response.body.error));
                }

                resolve();
            });
        });
    }

    doSubscribeRequest() {
        request({
                method: 'POST',
                uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
            },
            (error, response, body) => {
                if (error) {
                    console.error('Error while subscription: ', error);
                } else {
                    console.log('Subscription result: ', response.body);
                }
            });
    }

    isDefined(obj) {
        if (typeof obj == 'undefined') {
            return false;
        }

        if (!obj) {
            return false;
        }

        return obj != null;
    }

    sleep(delay) {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(), delay);
        });
    }

}

let facebookBot = new FacebookBot();

const app = express();

app.use(bodyParser.text({type: 'application/json'}));

app.get('/webhook/', (req, res) => {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(() => {
            facebookBot.doSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', (req, res) => {
    try {
        const data = JSONbig.parse(req.body);

        if (data.entry) {
            let entries = data.entry;
            entries.forEach((entry) => {
                let messaging_events = entry.messaging;
                if (messaging_events) {
                    messaging_events.forEach((event) => {
                    if (event.message && !event.message.is_echo ||
                            event.postback && event.postback.payload) {
                            facebookBot.processEvent(event);
                        }
                    });
                }
            });
        }

        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, () => {
    console.log('Rest service ready on port ' + REST_PORT);
});

facebookBot.doSubscribeRequest();
<commit_msg>Update app.js<commit_after>'use strict';

const apiai = require('apiai');
const express = require('express');
const bodyParser = require('body-parser');
const uuid = require('node-uuid');
const request = require('request');
const JSONbig = require('json-bigint');
const async = require('async');

const REST_PORT = (process.env.PORT || 5000);
const APIAI_ACCESS_TOKEN = process.env.APIAI_ACCESS_TOKEN;
const APIAI_LANG = process.env.APIAI_LANG || 'en';
const FB_VERIFY_TOKEN = process.env.FB_VERIFY_TOKEN;
const FB_PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN;
const FB_TEXT_LIMIT = 640;
var barbrad = 'true';

class FacebookBot {
    constructor() {
        this.apiAiService = apiai(APIAI_ACCESS_TOKEN, {language: APIAI_LANG, requestSource: "fb"});
        this.sessionIds = new Map();
        this.messagesDelay = 200;
    }

    doDataResponse(sender, facebookResponseData) {
        if (!Array.isArray(facebookResponseData)) {
            console.log('Response as formatted message');
            this.sendFBMessage(sender, facebookResponseData)
                .catch(err => console.error(err));
        } else {
            async.eachSeries(facebookResponseData, (facebookMessage, callback) => {
                if (facebookMessage.sender_action) {
                    console.log('Response as sender action');
                    this.sendFBSenderAction(sender, facebookMessage.sender_action)
                        .then(() => callback())
                        .catch(err => callback(err));
                }
                else {
                    console.log('Response as formatted message');
                    this.sendFBMessage(sender, facebookMessage)
                        .then(() => callback())
                        .catch(err => callback(err));
                }
            }, (err) => {
                if (err) {
                    console.error(err);
                } else {
                    console.log('Data response completed');
                }
            });
        }
    }

    doRichContentResponse(sender, messages) {
        let facebookMessages = []; // array with result messages

        for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
            let message = messages[messageIndex];

            switch (message.type) {
                //message.type 0 means text message
                case 0:
                    // speech: ["hi"]
                    // we have to get value from fulfillment.speech, because of here is raw speech
                    if (message.speech) {

                        let splittedText = this.splitResponse(message.speech);

                        splittedText.forEach(s => {
                            facebookMessages.push({text: s});
                        });
                    }

                    break;
                //message.type 1 means card message
                case 1: {
                    let carousel = [message];

                    for (messageIndex++; messageIndex < messages.length; messageIndex++) {
                        if (messages[messageIndex].type == 1) {
                            carousel.push(messages[messageIndex]);
                        } else {
                            messageIndex--;
                            break;
                        }
                    }

                    let facebookMessage = {};
                    carousel.forEach((c) => {
                        // buttons: [ {text: "hi", postback: "postback"} ], imageUrl: "", title: "", subtitle: ""

                        let card = {};

                        card.title = c.title;
                        card.image_url = c.imageUrl;
                        if (this.isDefined(c.subtitle)) {
                            card.subtitle = c.subtitle;
                        }
                        //If button is involved in.
                        if (c.buttons.length > 0) {
                            let buttons = [];
                            for (let buttonIndex = 0; buttonIndex < c.buttons.length; buttonIndex++) {
                                let button = c.buttons[buttonIndex];

                                if (button.text) {
                                    let postback = button.postback;
                                    if (!postback) {
                                        postback = button.text;
                                    }

                                    let buttonDescription = {
                                        title: button.text
                                    };

                                    if (postback.startsWith("http")) {
                                        buttonDescription.type = "web_url";
                                        buttonDescription.url = postback;
                                    } else {
                                        buttonDescription.type = "postback";
                                        buttonDescription.payload = postback;
                                    }

                                    buttons.push(buttonDescription);
                                }
                            }

                            if (buttons.length > 0) {
                                card.buttons = buttons;
                            }
                        }

                        if (!facebookMessage.attachment) {
                            facebookMessage.attachment = {type: "template"};
                        }

                        if (!facebookMessage.attachment.payload) {
                            facebookMessage.attachment.payload = {template_type: "generic", elements: []};
                        }

                        facebookMessage.attachment.payload.elements.push(card);
                    });

                    facebookMessages.push(facebookMessage);
                }

                    break;
                //message.type 2 means quick replies message
                case 2: {
                    if (message.replies && message.replies.length > 0) {
                        let facebookMessage = {};

                        facebookMessage.text = message.title ? message.title : 'Choose an item';
                        facebookMessage.quick_replies = [];

                        message.replies.forEach((r) => {
                            facebookMessage.quick_replies.push({
                                content_type: "text",
                                title: r,
                                payload: r
                            });
                        });

                        facebookMessages.push(facebookMessage);
                    }
                }

                    break;
                //message.type 3 means image message
                case 3:

                    if (message.imageUrl) {
                        let facebookMessage = {};

                        // "imageUrl": "http://example.com/image.jpg"
                        facebookMessage.attachment = {type: "image"};
                        facebookMessage.attachment.payload = {url: message.imageUrl};

                        facebookMessages.push(facebookMessage);
                    }

                    break;
                //message.type 4 means custom payload message
                case 4:
                    if (message.payload && message.payload.facebook) {
                        facebookMessages.push(message.payload.facebook);
                    }
                    break;

                default:
                    break;
            }
        }

        return new Promise((resolve, reject) => {
            async.eachSeries(facebookMessages, (msg, callback) => {
                    this.sendFBSenderAction(sender, "typing_on")
                        .then(() => this.sleep(this.messagesDelay))
                        .then(() => this.sendFBMessage(sender, msg))
                        .then(() => callback())
                        .catch(callback);
                },
                (err) => {
                    if (err) {
                        console.error(err);
                        reject(err);
                    } else {
                        console.log('Messages sent');
                        resolve();
                    }
                });
        });

    }

    doTextResponse(sender, responseText) {
        console.log('Response as text message');
        // facebook API limit for text length is 640,
        // so we must split message if needed
        let splittedText = this.splitResponse(responseText);

        async.eachSeries(splittedText, (textPart, callback) => {
            this.sendFBMessage(sender, {text: textPart})
                .then(() => callback())
                .catch(err => callback(err));
        });
    }
 //which webhook event
    getEventText(event) {
        if (event.message) {
            if (event.message.quick_reply && event.message.quick_reply.payload) {
                return event.message.quick_reply.payload;
            }

            if (event.message.text) {
                return event.message.text;
            }
        }

        if (event.postback) {
                if (event.postback.referral.ref) {
                    console.log(event.postback.referral.ref);
                    return event.postback.referral.ref;

                    //console.log(event.postback.payload);
                    //console.log('testing');
                    //return event.postback.payload;
                    //return 'testing';
                }

                else if (event.postback.payload)  {
                    console.log(event.postback.payload);
                    //console.log(event.postback.referral.ref);
                    //console.log('testing2');
                    return event.postback.payload;
                    //return 'testing2';

                }
             console.log('brad');

            }

        console.log('bra2');
        return null;
    console.log('brad3');
    }

    processEvent(event) {
        const sender = event.sender.id.toString();
        const text = this.getEventText(event);

        if (text) {

            // Handle a text message from the sender
            if (!this.sessionIds.has(sender)) {
                this.sessionIds.set(sender, uuid.v4());
            }

            console.log("Text", text);
            //send user's text to api.ai service
            let apiaiRequest = this.apiAiService.textRequest(text,
                {
                    sessionId: this.sessionIds.get(sender),
                    originalRequest: {
                        data: event,
                        source: "facebook"
                    }
                });

            //get response from api.ai
            apiaiRequest.on('response', (response) => {
                if (this.isDefined(response.result) && this.isDefined(response.result.fulfillment)) {
                    let responseText = response.result.fulfillment.speech;
                    let responseData = response.result.fulfillment.data;
                    let responseMessages = response.result.fulfillment.messages;

                    let action = response.result.action;

                    if (this.isDefined(responseData) && this.isDefined(responseData.facebook)) {
                        let facebookResponseData = responseData.facebook;
                        this.doDataResponse(sender, facebookResponseData);
                    } else if (this.isDefined(responseMessages) && responseMessages.length > 0) {
                        this.doRichContentResponse(sender, responseMessages);
                    }
                    else if (this.isDefined(responseText)) {
                        this.doTextResponse(sender, responseText);
                    }

                }
            });

            apiaiRequest.on('error', (error) => console.error(error));
            apiaiRequest.end();
        }
    }

    splitResponse(str) {
        if (str.length <= FB_TEXT_LIMIT) {
            return [str];
        }

        return this.chunkString(str, FB_TEXT_LIMIT);
    }

    chunkString(s, len) {
        let curr = len, prev = 0;

        let output = [];

        while (s[curr]) {
            if (s[curr++] == ' ') {
                output.push(s.substring(prev, curr));
                prev = curr;
                curr += len;
            }
            else {
                let currReverse = curr;
                do {
                    if (s.substring(currReverse - 1, currReverse) == ' ') {
                        output.push(s.substring(prev, currReverse));
                        prev = currReverse;
                        curr = currReverse + len;
                        break;
                    }
                    currReverse--;
                } while (currReverse > prev)
            }
        }
        output.push(s.substr(prev));
        return output;
    }

    sendFBMessage(sender, messageData) {
        return new Promise((resolve, reject) => {
            request({
                url: 'https://graph.facebook.com/v2.6/me/messages',
                qs: {access_token: FB_PAGE_ACCESS_TOKEN},
                method: 'POST',
                json: {
                    recipient: {id: sender},
                    message: messageData
                }
            }, (error, response) => {
                if (error) {
                    console.log('Error sending message: ', error);
                    reject(error);
                } else if (response.body.error) {
                    console.log('Error: ', response.body.error);
                    reject(new Error(response.body.error));
                }

                resolve();
            });
        });
    }

    sendFBSenderAction(sender, action) {
        return new Promise((resolve, reject) => {
            request({
                url: 'https://graph.facebook.com/v2.6/me/messages',
                qs: {access_token: FB_PAGE_ACCESS_TOKEN},
                method: 'POST',
                json: {
                    recipient: {id: sender},
                    sender_action: action
                }
            }, (error, response) => {
                if (error) {
                    console.error('Error sending action: ', error);
                    reject(error);
                } else if (response.body.error) {
                    console.error('Error: ', response.body.error);
                    reject(new Error(response.body.error));
                }

                resolve();
            });
        });
    }

    doSubscribeRequest() {
        request({
                method: 'POST',
                uri: "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=" + FB_PAGE_ACCESS_TOKEN
            },
            (error, response, body) => {
                if (error) {
                    console.error('Error while subscription: ', error);
                } else {
                    console.log('Subscription result: ', response.body);
                }
            });
    }

    isDefined(obj) {
        if (typeof obj == 'undefined') {
            return false;
        }

        if (!obj) {
            return false;
        }

        return obj != null;
    }

    sleep(delay) {
        return new Promise((resolve, reject) => {
            setTimeout(() => resolve(), delay);
        });
    }

}

let facebookBot = new FacebookBot();

const app = express();

app.use(bodyParser.text({type: 'application/json'}));

app.get('/webhook/', (req, res) => {
    if (req.query['hub.verify_token'] == FB_VERIFY_TOKEN) {
        res.send(req.query['hub.challenge']);

        setTimeout(() => {
            facebookBot.doSubscribeRequest();
        }, 3000);
    } else {
        res.send('Error, wrong validation token');
    }
});

app.post('/webhook/', (req, res) => {
    try {
        const data = JSONbig.parse(req.body);

        if (data.entry) {
            let entries = data.entry;
            entries.forEach((entry) => {
                let messaging_events = entry.messaging;
                if (messaging_events) {
                    messaging_events.forEach((event) => {
                    if (event.message && !event.message.is_echo ||
                            event.postback && event.postback.payload) {
                            facebookBot.processEvent(event);
                        }
                    });
                }
            });
        }

        return res.status(200).json({
            status: "ok"
        });
    } catch (err) {
        return res.status(400).json({
            status: "error",
            error: err
        });
    }

});

app.listen(REST_PORT, () => {
    console.log('Rest service ready on port ' + REST_PORT);
});

facebookBot.doSubscribeRequest();
<|endoftext|>


<commit_before>/**
 * @file level command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license GPL-3.0
 */

exports.exec = async (Bastion, message, args) => {
  args = message.mentions.users.first() || message.author;

  let guildMemberModel = await Bastion.database.models.guildMember.findOne({
    attributes: [ 'experiencePoints', 'level' ],
    where: {
      userID: args.id,
      guildID: message.guild.id
    }
  });
  let level = 0, xp = 0;

  if (guildMemberModel) {
    level = guildMemberModel.dataValues.level;
    xp = guildMemberModel.dataValues.experiencePoints;
  }

  let description = message.author.id === args.id ? `**${args.tag}** you are currently in level **${level}**.` : `**${args.tag}** is currently in level **${level}**.`;
  let footer = message.author.id === args.id ? `Wanna go to the next level? Just gain ${Bastion.methods.getRequiredExpForLevel(parseInt(level, 10) + 1) - xp + 1} more XP.` : null;

  await message.channel.send({
    embed: {
      color: Bastion.colors.BLUE,
      description: description,
      footer: {
        text: footer
      }
    }
  });
};

exports.config = {
  aliases: [ 'lvl' ],
  enabled: true
};

exports.help = {
  name: 'level',
  description: 'Shows the current level of the specified user\'s account.',
  botPermission: '',
  userTextPermission: '',
  userVoicePermission: '',
  usage: 'level [@user-mention]',
  example: [ 'level', 'level @user#0001' ]
};
<commit_msg>commands(profile): update level command to reflect max level<commit_after>/**
 * @file level command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license GPL-3.0
 */

exports.exec = async (Bastion, message, args) => {
  args = message.mentions.users.first() || message.author;

  let guildMemberModel = await Bastion.database.models.guildMember.findOne({
    attributes: [ 'experiencePoints', 'level' ],
    where: {
      userID: args.id,
      guildID: message.guild.id
    }
  });
  let level = 0, xp = 0;

  if (guildMemberModel) {
    level = guildMemberModel.dataValues.level;
    xp = guildMemberModel.dataValues.experiencePoints;
  }

  let description = message.author.id === args.id ? `**${args.tag}** you are currently in level **${level}**.` : `**${args.tag}** is currently in level **${level}**.`;
  let footer = message.author.id === args.id && guildMemberModel.dataValues.experiencePoints !== '44444444444444' ? `Wanna go to the next level? Just gain ${Bastion.methods.getRequiredExpForLevel(parseInt(level, 10) + 1) - xp + 1} more XP.` : null;

  await message.channel.send({
    embed: {
      color: Bastion.colors.BLUE,
      description: description,
      footer: {
        text: footer
      }
    }
  });
};

exports.config = {
  aliases: [ 'lvl' ],
  enabled: true
};

exports.help = {
  name: 'level',
  description: 'Shows the current level of the specified user\'s account.',
  botPermission: '',
  userTextPermission: '',
  userVoicePermission: '',
  usage: 'level [@user-mention]',
  example: [ 'level', 'level @user#0001' ]
};
<|endoftext|>


<commit_before>go.app = function() {
    var vumigo = require('vumigo_v02');
    var _ = require("lodash");
    var Q = require("q");
    var App = vumigo.App;
    var Choice = vumigo.states.Choice;
    var ChoiceState = vumigo.states.ChoiceState;
    var MenuState = vumigo.states.MenuState;
    var FreeText = vumigo.states.FreeText;
    var EndState = vumigo.states.EndState;
    var LazyTranslator = vumigo.translate.LazyTranslator;
    var HttpApi = vumigo.http.api.HttpApi;
    var Extendable = vumigo.utils.Extendable;

    var $ = new LazyTranslator();

    var FloatState = FreeText.extend(function(self, name, opts) {
        opts = _.defaults(opts || {});
        self.additional_check = opts.check;
        FreeText.call(self, name, opts);

        self.check = function(input) {
            var x = parseFloat(input);
            if (_.isNaN(x)) {
                return App.$("Expected a number.");
            }
            return self.additional_check(x);
        };
    });

    var IntegerState = FreeText.extend(function(self, name, opts) {
        opts = _.defaults(opts || {});
        self.additional_check = opts.check;
        FreeText.call(self, name, opts);

        self.check = function(input) {
            var x = parseFloat(input);
            if (_.isNaN(x) || (x % 1 !== 0)) {
                return $("Expected a whole number.");
            }
            return self.additional_check(x);
        };
    });

    var SequentialStates = Extendable.extend(function (self, app, prefix) {
        self.app = app;
        self.prefix = prefix;
        self.states = [];

        self.add = function(suffix, creator) {
            var name =  self.prefix + suffix;
            self.states.push(name);
            return self.app.states.add(name, creator);
        };

        self.first = function() {
            return self.states[0];
        };

        self.next = function(name) {
            var idx = _(self.states).indexOf(name);
            idx = idx < self.states.length ? idx : 0;
            return self.states[idx + 1];
        };

        self.answer = function(user, suffix) {
            return user.answers[self.prefix + suffix];
        };
    });

    var CommCareApi = HttpApi.extend(function(self, im, api_url) {
        self.api_url = api_url;

        HttpApi.call(self, im);

        self.call_api = function(sender, message) {
            return self.get(self.api_url, {
                params: {
                    sender: sender,
                    message: message
                }
            });
        };

        self.make_template = function(answer_pairs) {
            return _.template(
                _.map(answer_pairs, function(pair) {
                    return pair[0] + "<%= answer('" + pair[1] + "') %>";
                }).join(" ")
            );
        };

        self.set_opening_balances = function(user, seq_states) {
            var template = self.make_template([
                ["set ", "school_id"],
                ["emis", "emis"],
                ["cer-o", "cereal:opening"],
                ["pul-o", "pulses:opening"],
                ["oil-o", "oil:opening"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };

        self.send_monthly_sms_1 = function(user, seq_states) {
            var template = self.make_template([
                ["hgsf1 ", "school_id"],
                ["sch", "days_in_session"], ["fed", "days_of_feeding"],
                ["enr-m", "enrollment_male"], ["enr-f", "enrollment_female"],
                ["att-m", "attendance_male"], ["att-f", "attedance_female"],
                ["ben-m", "beneficiaries_male"],
                ["ben-f", "beneficiaries_female"],
                ["nofed-a", "not_fed:lack_of_food"],
                ["nofed-b", "not_fed:lack_of_firewood"],
                ["nofed-c", "not_fed:lack_of_water"],
                ["nofed-d", "not_fed:cooks_absent"],
                ["nofed-e", "not_fed:pupils_dislike_food"],
                ["nofed-f", "not_fed:other"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };

        self.send_monthly_sms_2 = function(user, seq_states) {
            var template = self.make_template([
                ["hgsf2", "school_id"],
                ["cer-r", "cereal:received"], ["cer-u", ":used"],
                ["cer-l", ":losses"],
                ["pul-r", "pulses:received"], ["pul-u", "pulses:used"],
                ["pul-l", "pulses:losses"],
                ["oil-r", "oil:received"], ["oil-u", "oil:used"],
                ["oil-l", "oil:losses"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };
    });

    var DummyCommCareApi = CommCareApi.extend(function(self, im) {
        CommCareApi.call(self, im, null);

        self.call_api = function(sender, message) {
            return self.im.log([
                "Dummy send to ", sender, ": ", message].join(""));
        };
    });

    var GoApp = App.extend(function(self) {
        App.call(self, 'states:start');

        self.init = function() {
            if (!self.im.config.commcare_api) {
                self.commcare = new DummyCommCareApi(self.im);
            }
            else {
                self.commcare = new CommCareApi(
                    self.im,
                    self.im.config.commcare_api);
            }
        };

        // Utilities

        self.check_int = function(min, max) {
            return function(i) {
                if (_.isString(min)) {
                    min = self.im.user.answers['states:report:' + min];
                }
                else if (_.isFunction(min)) {
                    min = min.call(self, self.im.user);
                }
                if (_.isString(max)) {
                    max = self.im.user.answers['states:report:' + max];
                }
                else if (_.isFunction(max)) {
                    max = max.call(self, self.im.user);
                }
                if ((i < min) || (i > max)) {
                    return $("Number must be between {{ min }} and {{ max }}.")
                        .context({min: min, max: max});
                }
            };
        };

        // Start

        self.states.add('states:start', function(name) {
            return new MenuState(name, {
                question: $('Welcome to the World Feed Program.'),
                choices: [
                    new Choice('states:register', $('Register')),
                    new Choice('states:report', $('Report')),
                    new Choice('states:end', $('Exit'))],
            });
        });

        // Registration utilities

        self.reg_states = new SequentialStates(self, 'states:register:');

        self.add_reg_question = function(reg_name, opts) {
            opts = _.defaults(opts || {}, {
                state: IntegerState
            });
            self.reg_states.add(reg_name, function(name) {
                return new opts.state(name, {
                    question: opts.question,
                    check: opts.check,
                    next: self.reg_states.next(name)
                });
            });
        };

        self.add_reg_goods_question = function(reg_name, opts) {
            opts = _.defaults(opts || {}, {
                state: FloatState,
                check: self.check_int(0, 20000)
            });
            return self.add_reg_question(reg_name, opts);
        };

        // Registration

        self.states.add('states:register', function(name) {
            return self.states.create(self.reg_states.first());
        });

        self.add_reg_question('school_id', {
            state: FreeText,
            question: $('School ID:')
        });

        self.add_reg_question('emis', {
            state: FreeText,
            question: $('EMIS:')
        });

        self.add_reg_goods_question('cereal:opening', {
            question: $('Cereal opening (kg):'),
        });

        self.add_reg_goods_question('pulses:opening', {
            question: $('Pulses opening (kg):'),
        });

        self.add_reg_goods_question('oil:opening', {
            question: $('Oil opening (kg):'),
        });

        self.reg_states.add('end', function(name) {
            return new EndState(name, {
                text: $("Thanks for registering!"),
                next: 'states:start',
                events: {
                    'state:enter': function (state) {
                        return self.commcare.set_opening_balances(
                            self.im.user, self.reg_states);
                    }
                }
            });
        });

        // Report utilities

        self.report_states = new SequentialStates(self, 'states:report:');

        self.add_report_question = function(report_name, opts) {
            opts = _.defaults(opts || {}, {
                state: IntegerState
            });
            self.report_states.add(report_name, function(name) {
                return new opts.state(name, {
                    question: opts.question,
                    check: opts.check,
                    next: self.report_states.next(name)
                });
            });
        };

        self.add_report_goods_question = function(report_name, opts) {
            opts = _.defaults(opts || {}, {
                state: FloatState,
                check: self.check_int(0, 20000)
            });
            return self.add_report_question(report_name, opts);
        };

        self.add_report_total = function(total_name, opts) {
            opts = _.defaults(opts || {}, {
                values: []
            });
            self.report_states.add(total_name, function(name) {
                var total = _(opts.values)
                    .map(function (value) {
                        return self.im.user.answers['states:report:' + value];
                    })
                    .reduce(function (sum, n) { return sum + n; }, 0);
                return new ChoiceState(name, {
                    question: opts.question.context({total: total}),
                    choices: [
                        new Choice("continue", "Continue")
                    ],
                    next: self.report_states.next(name)
                });
            });
        };

        // Report states

        self.states.add('states:report', function(name) {
            return self.states.create(self.report_states.first());
        });

        self.add_report_question('school_id', {
            state: FreeText,
            question: $('School ID:')
        });

        self.add_report_question('days_in_session', {
            question: $('Number of school days in session:'),
            check: self.check_int(1, 31)
        });

        self.add_report_question('days_of_feeding', {
            question: $('Number of days food served:'),
            check: self.check_int(0, 'days_in_session')
        });

        self.add_report_question('enrollment_male', {
            question: $('Male enrollment:'),
            check: self.check_int(0, 10000)
        });

        self.add_report_question('enrollment_female', {
            question: $('Female enrollment:'),
            check: self.check_int(0, 10000)
        });

        self.add_report_total('enrollment_total', {
            question: $('Total enrollment: {{ total }}'),
            values: ['enrollment_male', 'enrollment_female'],
        });

        self.add_report_question('attendance_male', {
            question: $('Male attendance (highest):'),
            check: self.check_int(0, 'enrollment_male')
        });

        self.add_report_question('attendance_female', {
            question: $('Female attendance (highest):'),
            check: self.check_int(0, 'enrollment_female')
        });

        self.add_report_total('attendance_total', {
            question: $('Total attendance: {{ total }}'),
            values: ['attendance_male', 'attendance_female'],
        });

        self.add_report_question('beneficiaries_male', {
            question: $('Male beneficiaries (highest):'),
            check: self.check_int(0, 'attendance_male')
        });

        self.add_report_question('beneficiaries_female', {
            question: $('Female beneficiaries (highest):'),
            check: self.check_int(0, 'attendance_female')
        });

        self.add_report_total('beneficiaries_total', {
            question: $('Total beneficiaries: {{ total }}'),
            values: ['beneficiaries_male', 'beneficiaries_female'],
        });

        self.days_without_feeding = function (user) {
            return (user.answers['states:report:days_in_session'] -
                    user.answers['states:report:days_of_feeding']);
        };

        self.add_report_question('not_fed:lack_of_food', {
            question: $('Number of days pupils not fed for - Lack of food:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:lack_of_firewood', {
            question: $('Number of days pupils not fed for - Lack of firewood:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:lack_of_water', {
            question: $('Number of days pupils not fed for - Lack of water:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:cooks_absent', {
            question: $('Number of days pupils not fed for - Cooks absent:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:pupils_dislike_food', {
            question: $('Number of days pupils not fed for - Pupils dislike food:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:other', {
            question: $('Number of days pupils not fed for - Other:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_goods_question('cereal:received', {
            question: $('Cereal received (kg):'),
        });

        self.add_report_goods_question('cereal:used', {
            question: $('Cereal used (kg):'),
        });

        self.add_report_goods_question('cereal:losses', {
            question: $('Cereal lost (kg):'),
        });

        self.add_report_goods_question('pulses:received', {
            question: $('Pulses received (kg):'),
        });

        self.add_report_goods_question('pulses:used', {
            question: $('Pulses used (kg):'),
        });

        self.add_report_goods_question('pulses:losses', {
            question: $('Pulses lost (kg):'),
        });

        self.add_report_goods_question('oil:received', {
            question: $('Oil received (kg):'),
        });

        self.add_report_goods_question('oil:used', {
            question: $('Oil used (kg):'),
        });

        self.add_report_goods_question('oil:losses', {
            question: $('Oil lost (kg):'),
        });

        self.report_states.add('end', function(name) {
            return new EndState(name, {
                text: $("Thanks for the report!"),
                next: 'states:start',
            });
        });

        // End

        self.states.add('states:end', function(name) {
            return new EndState(name, {
                text: $('Bye!'),
                next: 'states:start',
                events: {
                    'state:enter': function (state) {
                        console.log("foo");
                        return Q.all([
                            self.commcare.send_monthly_sms_1(
                                self.im.user, self.report_states),
                            self.commcare.send_monthly_sms_2(
                                self.im.user, self.report_states)
                        ]);
                    }
                }
            });
        });
    });

    return {
        GoApp: GoApp
    };
}();
<commit_msg>Better logging from DummyCommCareApi.<commit_after>go.app = function() {
    var vumigo = require('vumigo_v02');
    var _ = require("lodash");
    var Q = require("q");
    var App = vumigo.App;
    var Choice = vumigo.states.Choice;
    var ChoiceState = vumigo.states.ChoiceState;
    var MenuState = vumigo.states.MenuState;
    var FreeText = vumigo.states.FreeText;
    var EndState = vumigo.states.EndState;
    var LazyTranslator = vumigo.translate.LazyTranslator;
    var HttpApi = vumigo.http.api.HttpApi;
    var Extendable = vumigo.utils.Extendable;

    var $ = new LazyTranslator();

    var FloatState = FreeText.extend(function(self, name, opts) {
        opts = _.defaults(opts || {});
        self.additional_check = opts.check;
        FreeText.call(self, name, opts);

        self.check = function(input) {
            var x = parseFloat(input);
            if (_.isNaN(x)) {
                return App.$("Expected a number.");
            }
            return self.additional_check(x);
        };
    });

    var IntegerState = FreeText.extend(function(self, name, opts) {
        opts = _.defaults(opts || {});
        self.additional_check = opts.check;
        FreeText.call(self, name, opts);

        self.check = function(input) {
            var x = parseFloat(input);
            if (_.isNaN(x) || (x % 1 !== 0)) {
                return $("Expected a whole number.");
            }
            return self.additional_check(x);
        };
    });

    var SequentialStates = Extendable.extend(function (self, app, prefix) {
        self.app = app;
        self.prefix = prefix;
        self.states = [];

        self.add = function(suffix, creator) {
            var name =  self.prefix + suffix;
            self.states.push(name);
            return self.app.states.add(name, creator);
        };

        self.first = function() {
            return self.states[0];
        };

        self.next = function(name) {
            var idx = _(self.states).indexOf(name);
            idx = idx < self.states.length ? idx : 0;
            return self.states[idx + 1];
        };

        self.answer = function(user, suffix) {
            return user.answers[self.prefix + suffix];
        };
    });

    var CommCareApi = HttpApi.extend(function(self, im, api_url) {
        self.api_url = api_url;

        HttpApi.call(self, im);

        self.call_api = function(sender, message) {
            return self.get(self.api_url, {
                params: {
                    sender: sender,
                    message: message
                }
            });
        };

        self.make_template = function(answer_pairs) {
            return _.template(
                _.map(answer_pairs, function(pair) {
                    return pair[0] + "<%= answer('" + pair[1] + "') %>";
                }).join(" ")
            );
        };

        self.set_opening_balances = function(user, seq_states) {
            var template = self.make_template([
                ["set ", "school_id"],
                ["emis", "emis"],
                ["cer-o", "cereal:opening"],
                ["pul-o", "pulses:opening"],
                ["oil-o", "oil:opening"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };

        self.send_monthly_sms_1 = function(user, seq_states) {
            var template = self.make_template([
                ["hgsf1 ", "school_id"],
                ["sch", "days_in_session"], ["fed", "days_of_feeding"],
                ["enr-m", "enrollment_male"], ["enr-f", "enrollment_female"],
                ["att-m", "attendance_male"], ["att-f", "attedance_female"],
                ["ben-m", "beneficiaries_male"],
                ["ben-f", "beneficiaries_female"],
                ["nofed-a", "not_fed:lack_of_food"],
                ["nofed-b", "not_fed:lack_of_firewood"],
                ["nofed-c", "not_fed:lack_of_water"],
                ["nofed-d", "not_fed:cooks_absent"],
                ["nofed-e", "not_fed:pupils_dislike_food"],
                ["nofed-f", "not_fed:other"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };

        self.send_monthly_sms_2 = function(user, seq_states) {
            var template = self.make_template([
                ["hgsf2", "school_id"],
                ["cer-r", "cereal:received"], ["cer-u", ":used"],
                ["cer-l", ":losses"],
                ["pul-r", "pulses:received"], ["pul-u", "pulses:used"],
                ["pul-l", "pulses:losses"],
                ["oil-r", "oil:received"], ["oil-u", "oil:used"],
                ["oil-l", "oil:losses"]
            ]);
            var message = template({
                answer: _.partial(seq_states.answer, user)
            });
            return self.call_api(user.addr, message);
        };
    });

    var DummyCommCareApi = CommCareApi.extend(function(self, im) {
        CommCareApi.call(self, im, null);

        self.call_api = function(sender, message) {
            return self.im.log([
                "Dummy CommCareApi call: sender=", sender,
                ", message='", message, "'"].join(""));
        };
    });

    var GoApp = App.extend(function(self) {
        App.call(self, 'states:start');

        self.init = function() {
            if (!self.im.config.commcare_api) {
                self.commcare = new DummyCommCareApi(self.im);
            }
            else {
                self.commcare = new CommCareApi(
                    self.im,
                    self.im.config.commcare_api);
            }
        };

        // Utilities

        self.check_int = function(min, max) {
            return function(i) {
                if (_.isString(min)) {
                    min = self.im.user.answers['states:report:' + min];
                }
                else if (_.isFunction(min)) {
                    min = min.call(self, self.im.user);
                }
                if (_.isString(max)) {
                    max = self.im.user.answers['states:report:' + max];
                }
                else if (_.isFunction(max)) {
                    max = max.call(self, self.im.user);
                }
                if ((i < min) || (i > max)) {
                    return $("Number must be between {{ min }} and {{ max }}.")
                        .context({min: min, max: max});
                }
            };
        };

        // Start

        self.states.add('states:start', function(name) {
            return new MenuState(name, {
                question: $('Welcome to the World Feed Program.'),
                choices: [
                    new Choice('states:register', $('Register')),
                    new Choice('states:report', $('Report')),
                    new Choice('states:end', $('Exit'))],
            });
        });

        // Registration utilities

        self.reg_states = new SequentialStates(self, 'states:register:');

        self.add_reg_question = function(reg_name, opts) {
            opts = _.defaults(opts || {}, {
                state: IntegerState
            });
            self.reg_states.add(reg_name, function(name) {
                return new opts.state(name, {
                    question: opts.question,
                    check: opts.check,
                    next: self.reg_states.next(name)
                });
            });
        };

        self.add_reg_goods_question = function(reg_name, opts) {
            opts = _.defaults(opts || {}, {
                state: FloatState,
                check: self.check_int(0, 20000)
            });
            return self.add_reg_question(reg_name, opts);
        };

        // Registration

        self.states.add('states:register', function(name) {
            return self.states.create(self.reg_states.first());
        });

        self.add_reg_question('school_id', {
            state: FreeText,
            question: $('School ID:')
        });

        self.add_reg_question('emis', {
            state: FreeText,
            question: $('EMIS:')
        });

        self.add_reg_goods_question('cereal:opening', {
            question: $('Cereal opening (kg):'),
        });

        self.add_reg_goods_question('pulses:opening', {
            question: $('Pulses opening (kg):'),
        });

        self.add_reg_goods_question('oil:opening', {
            question: $('Oil opening (kg):'),
        });

        self.reg_states.add('end', function(name) {
            return new EndState(name, {
                text: $("Thanks for registering!"),
                next: 'states:start',
                events: {
                    'state:enter': function (state) {
                        return self.commcare.set_opening_balances(
                            self.im.user, self.reg_states);
                    }
                }
            });
        });

        // Report utilities

        self.report_states = new SequentialStates(self, 'states:report:');

        self.add_report_question = function(report_name, opts) {
            opts = _.defaults(opts || {}, {
                state: IntegerState
            });
            self.report_states.add(report_name, function(name) {
                return new opts.state(name, {
                    question: opts.question,
                    check: opts.check,
                    next: self.report_states.next(name)
                });
            });
        };

        self.add_report_goods_question = function(report_name, opts) {
            opts = _.defaults(opts || {}, {
                state: FloatState,
                check: self.check_int(0, 20000)
            });
            return self.add_report_question(report_name, opts);
        };

        self.add_report_total = function(total_name, opts) {
            opts = _.defaults(opts || {}, {
                values: []
            });
            self.report_states.add(total_name, function(name) {
                var total = _(opts.values)
                    .map(function (value) {
                        return self.im.user.answers['states:report:' + value];
                    })
                    .reduce(function (sum, n) { return sum + n; }, 0);
                return new ChoiceState(name, {
                    question: opts.question.context({total: total}),
                    choices: [
                        new Choice("continue", "Continue")
                    ],
                    next: self.report_states.next(name)
                });
            });
        };

        // Report states

        self.states.add('states:report', function(name) {
            return self.states.create(self.report_states.first());
        });

        self.add_report_question('school_id', {
            state: FreeText,
            question: $('School ID:')
        });

        self.add_report_question('days_in_session', {
            question: $('Number of school days in session:'),
            check: self.check_int(1, 31)
        });

        self.add_report_question('days_of_feeding', {
            question: $('Number of days food served:'),
            check: self.check_int(0, 'days_in_session')
        });

        self.add_report_question('enrollment_male', {
            question: $('Male enrollment:'),
            check: self.check_int(0, 10000)
        });

        self.add_report_question('enrollment_female', {
            question: $('Female enrollment:'),
            check: self.check_int(0, 10000)
        });

        self.add_report_total('enrollment_total', {
            question: $('Total enrollment: {{ total }}'),
            values: ['enrollment_male', 'enrollment_female'],
        });

        self.add_report_question('attendance_male', {
            question: $('Male attendance (highest):'),
            check: self.check_int(0, 'enrollment_male')
        });

        self.add_report_question('attendance_female', {
            question: $('Female attendance (highest):'),
            check: self.check_int(0, 'enrollment_female')
        });

        self.add_report_total('attendance_total', {
            question: $('Total attendance: {{ total }}'),
            values: ['attendance_male', 'attendance_female'],
        });

        self.add_report_question('beneficiaries_male', {
            question: $('Male beneficiaries (highest):'),
            check: self.check_int(0, 'attendance_male')
        });

        self.add_report_question('beneficiaries_female', {
            question: $('Female beneficiaries (highest):'),
            check: self.check_int(0, 'attendance_female')
        });

        self.add_report_total('beneficiaries_total', {
            question: $('Total beneficiaries: {{ total }}'),
            values: ['beneficiaries_male', 'beneficiaries_female'],
        });

        self.days_without_feeding = function (user) {
            return (user.answers['states:report:days_in_session'] -
                    user.answers['states:report:days_of_feeding']);
        };

        self.add_report_question('not_fed:lack_of_food', {
            question: $('Number of days pupils not fed for - Lack of food:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:lack_of_firewood', {
            question: $('Number of days pupils not fed for - Lack of firewood:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:lack_of_water', {
            question: $('Number of days pupils not fed for - Lack of water:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:cooks_absent', {
            question: $('Number of days pupils not fed for - Cooks absent:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:pupils_dislike_food', {
            question: $('Number of days pupils not fed for - Pupils dislike food:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_question('not_fed:other', {
            question: $('Number of days pupils not fed for - Other:'),
            check: self.check_int(0, self.days_without_feeding),
        });

        self.add_report_goods_question('cereal:received', {
            question: $('Cereal received (kg):'),
        });

        self.add_report_goods_question('cereal:used', {
            question: $('Cereal used (kg):'),
        });

        self.add_report_goods_question('cereal:losses', {
            question: $('Cereal lost (kg):'),
        });

        self.add_report_goods_question('pulses:received', {
            question: $('Pulses received (kg):'),
        });

        self.add_report_goods_question('pulses:used', {
            question: $('Pulses used (kg):'),
        });

        self.add_report_goods_question('pulses:losses', {
            question: $('Pulses lost (kg):'),
        });

        self.add_report_goods_question('oil:received', {
            question: $('Oil received (kg):'),
        });

        self.add_report_goods_question('oil:used', {
            question: $('Oil used (kg):'),
        });

        self.add_report_goods_question('oil:losses', {
            question: $('Oil lost (kg):'),
        });

        self.report_states.add('end', function(name) {
            return new EndState(name, {
                text: $("Thanks for the report!"),
                next: 'states:start',
            });
        });

        // End

        self.states.add('states:end', function(name) {
            return new EndState(name, {
                text: $('Bye!'),
                next: 'states:start',
                events: {
                    'state:enter': function (state) {
                        return Q.all([
                            self.commcare.send_monthly_sms_1(
                                self.im.user, self.report_states),
                            self.commcare.send_monthly_sms_2(
                                self.im.user, self.report_states)
                        ]);
                    }
                }
            });
        });
    });

    return {
        GoApp: GoApp
    };
}();
<|endoftext|>


<commit_before>var firepad = firepad || { };

firepad.EntityManager = (function () {
  var utils = firepad.utils;

  function EntityManager() {
    this.entities_ = {};

    var attrs = ['src', 'alt', 'width', 'height', 'style', 'class'];
    this.register('img', {
      render: function(info) {
        utils.assert(info.src, "image entity should have 'src'!");
        var attrs = ['src', 'alt', 'width', 'height', 'style', 'class'];
        var html = '<img ';
        for(var i = 0; i < attrs.length; i++) {
          var attr = attrs[i];
          if (attr in info) {
            html += ' ' + attr + '="' + info[attr] + '"';
          }
        }
        html += ">";
        return html;
      },
      fromElement: function(element) {
        var info = {};
        for(var i = 0; i < attrs.length; i++) {
          var attr = attrs[i];
          if (element.hasAttribute(attr)) {
            info[attr] = element.getAttribute(attr);
          }
        }
        return info;
      }
    });
  }

  EntityManager.prototype.register = function(type, options) {
    firepad.utils.assert(options.render, "Entity options should include a 'render' function!");
    firepad.utils.assert(options.fromElement, "Entity options should include a 'fromElement' function!");
    this.entities_[type] = options;
  };

  EntityManager.prototype.renderToElement = function(entity, entityHandle) {
    return this.tryRenderToElement_(entity, 'render', entityHandle);
  };

  EntityManager.prototype.exportToElement = function(entity) {
    // Turns out 'export' is a reserved keyword, so 'getHtml' is preferable.
    var elt = this.tryRenderToElement_(entity, 'export') ||
              this.tryRenderToElement_(entity, 'getHtml') ||
              this.tryRenderToElement_(entity, 'render');
    elt.setAttribute('data-firepad-entity', entity.type);
    return elt;
  };

  /* Updates a DOM element to reflect the given entity.
     If the entity doesn't support the update method, it is fully
     re-rendered.
  */
  EntityManager.prototype.updateElement = function(entity, element) {
    var type = entity.type;
    var info = entity.info;
    if (this.entities_[type] && typeof(this.entities_[type].update) != 'undefined') {
      this.entities_[type].update(info, element);
    }
  };

  EntityManager.prototype.fromElement = function(element) {
    var type = element.getAttribute('data-firepad-entity');

    // HACK.  This should be configurable through entity registration.
    if (!type)
      type = element.nodeName.toLowerCase();

    if (type && this.entities_[type]) {
      var info = this.entities_[type].fromElement(element);
      return new firepad.Entity(type, info);
    }
  };

  EntityManager.prototype.tryRenderToElement_ = function(entity, renderFn, entityHandle) {
    var type = entity.type, info = entity.info;
    if (this.entities_[type] && this.entities_[type][renderFn]) {
      var res = this.entities_[type][renderFn](info, entityHandle);
      if (res) {
        if (typeof res === 'string') {
          var div = (firepad.document || document).createElement('div');
          div.innerHTML = res;
          return div.childNodes[0];
        } else if (typeof res === 'object') {
          firepad.utils.assert(typeof res.nodeType !== 'undefined', 'Error rendering ' + type + ' entity.  render() function' +
              ' must return an html string or a DOM element.');
          return res;
        }
      }
    }
  };

  EntityManager.prototype.entitySupportsUpdate = function(entityType) {
    return this.entities_[entityType] && this.entities_[entityType]['update'];
  };

  return EntityManager;
})();
<commit_msg>Added the window document to entity manager tryRenderToElement<commit_after>var firepad = firepad || { };

firepad.EntityManager = (function () {
  var utils = firepad.utils;

  function EntityManager() {
    this.entities_ = {};

    var attrs = ['src', 'alt', 'width', 'height', 'style', 'class'];
    this.register('img', {
      render: function(info) {
        utils.assert(info.src, "image entity should have 'src'!");
        var attrs = ['src', 'alt', 'width', 'height', 'style', 'class'];
        var html = '<img ';
        for(var i = 0; i < attrs.length; i++) {
          var attr = attrs[i];
          if (attr in info) {
            html += ' ' + attr + '="' + info[attr] + '"';
          }
        }
        html += ">";
        return html;
      },
      fromElement: function(element) {
        var info = {};
        for(var i = 0; i < attrs.length; i++) {
          var attr = attrs[i];
          if (element.hasAttribute(attr)) {
            info[attr] = element.getAttribute(attr);
          }
        }
        return info;
      }
    });
  }

  EntityManager.prototype.register = function(type, options) {
    firepad.utils.assert(options.render, "Entity options should include a 'render' function!");
    firepad.utils.assert(options.fromElement, "Entity options should include a 'fromElement' function!");
    this.entities_[type] = options;
  };

  EntityManager.prototype.renderToElement = function(entity, entityHandle) {
    return this.tryRenderToElement_(entity, 'render', entityHandle);
  };

  EntityManager.prototype.exportToElement = function(entity) {
    // Turns out 'export' is a reserved keyword, so 'getHtml' is preferable.
    var elt = this.tryRenderToElement_(entity, 'export') ||
              this.tryRenderToElement_(entity, 'getHtml') ||
              this.tryRenderToElement_(entity, 'render');
    elt.setAttribute('data-firepad-entity', entity.type);
    return elt;
  };

  /* Updates a DOM element to reflect the given entity.
     If the entity doesn't support the update method, it is fully
     re-rendered.
  */
  EntityManager.prototype.updateElement = function(entity, element) {
    var type = entity.type;
    var info = entity.info;
    if (this.entities_[type] && typeof(this.entities_[type].update) != 'undefined') {
      this.entities_[type].update(info, element);
    }
  };

  EntityManager.prototype.fromElement = function(element) {
    var type = element.getAttribute('data-firepad-entity');

    // HACK.  This should be configurable through entity registration.
    if (!type)
      type = element.nodeName.toLowerCase();

    if (type && this.entities_[type]) {
      var info = this.entities_[type].fromElement(element);
      return new firepad.Entity(type, info);
    }
  };

  EntityManager.prototype.tryRenderToElement_ = function(entity, renderFn, entityHandle) {
    var type = entity.type, info = entity.info;
    if (this.entities_[type] && this.entities_[type][renderFn]) {
      var windowDocument = firepad.document || (window && window.document);
      var res = this.entities_[type][renderFn](info, entityHandle, windowDocument);
      if (res) {
        if (typeof res === 'string') {
          var div = (firepad.document || document).createElement('div');
          div.innerHTML = res;
          return div.childNodes[0];
        } else if (typeof res === 'object') {
          firepad.utils.assert(typeof res.nodeType !== 'undefined', 'Error rendering ' + type + ' entity.  render() function' +
              ' must return an html string or a DOM element.');
          return res;
        }
      }
    }
  };

  EntityManager.prototype.entitySupportsUpdate = function(entityType) {
    return this.entities_[entityType] && this.entities_[entityType]['update'];
  };

  return EntityManager;
})();
<|endoftext|>


<commit_before>import { useState } from 'react';
import { t, jt } from 'ttag';
import Button from '@material-ui/core/Button';
import Popover from '@material-ui/core/Popover';
import RssFeedIcon from '@material-ui/icons/RssFeed';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(theme => ({
  leftIcon: { marginRight: theme.spacing(1) },
  paper: { padding: theme.spacing(2) },
}));

function FeedDisplay({ feedUrl }) {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = useState(null);

  const handleClick = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <>
      <Button onClick={handleClick}>
        <RssFeedIcon className={classes.leftIcon} />
        {t`Subscribe to this list`}
      </Button>
      <Popover
        anchorEl={anchorEl}
        open={!!anchorEl}
        onClose={handleClose}
        classes={{
          paper: classes.paper,
        }}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
      >
        {jt`You can follow this list using any RSS reader.`}
        <TextField
          label={t`RSS Feed URL`}
          defaultValue={feedUrl}
          margin="normal"
          variant="outlined"
          InputProps={{ readOnly: true }}
          onFocus={e => e.target.select()}
          fullWidth
        />
        {t`Add to`}{' '}
        <a
          href={`https://feedly.com/i/discover/sources/search/feed/${encodeURIComponent(
            feedUrl
          )}`}
          target="_blank"
          rel="noopener noreferrer"
        >
          {t`Feedly`}
        </a>
      </Popover>
    </>
  );
}

export default FeedDisplay;
<commit_msg>[FeedDisplay] add Feedrabbit, Blogtrottr and IFTTT<commit_after>import { useState } from 'react';
import { t } from 'ttag';
import Button from '@material-ui/core/Button';
import Popover from '@material-ui/core/Popover';
import RssFeedIcon from '@material-ui/icons/RssFeed';
import TextField from '@material-ui/core/TextField';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import ListSubheader from '@material-ui/core/ListSubheader';

import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(theme => ({
  leftIcon: { marginRight: theme.spacing(1) },
}));

function ListItemLink({ href, children }) {
  return (
    <ListItem
      button
      component="a"
      href={href}
      target="_blank"
      rel="noopener noreferrer"
    >
      <ListItemText>{children}</ListItemText>
    </ListItem>
  );
}

function FeedDisplay({ feedUrl }) {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = useState(null);

  const handleClick = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <>
      <Button onClick={handleClick}>
        <RssFeedIcon className={classes.leftIcon} />
        {t`Subscribe to this list`}
      </Button>
      <Popover
        anchorEl={anchorEl}
        open={!!anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
      >
        <List>
          <ListSubheader>{t`Get update using Email`}</ListSubheader>
          <ListItemLink href={`https://feedrabbit.com/?url=${feedUrl}`}>
            {t`Via Feedrabbit`}
          </ListItemLink>
          <ListItemLink href={`https://blogtrottr.com/?subscribe=${feedUrl}`}>
            {t`Via Blogtrottr`}
          </ListItemLink>
          <ListItemLink href="https://ifttt.com/feed">
            {t`Via IFTTT (also connects to LINE)`}
          </ListItemLink>

          <ListSubheader>{t`Get RSS updates`}</ListSubheader>
          <ListItemLink
            href={`https://feedly.com/i/discover/sources/search/feed/${encodeURIComponent(
              feedUrl
            )}`}
          >
            {t`Via Feedly`}
          </ListItemLink>
          <ListItem>
            <TextField
              label={t`RSS Feed URL for this list`}
              defaultValue={feedUrl}
              margin="normal"
              variant="outlined"
              InputProps={{ readOnly: true }}
              onFocus={e => e.target.select()}
              fullWidth
            />
          </ListItem>
        </List>
      </Popover>
    </>
  );
}

export default FeedDisplay;
<|endoftext|>


<commit_before>import Image from 'next/image';
import React from 'react';

function Article(props) {
	return (

				<Image
					src={props.article.image}
					width={360}
					height={200}
					alt={props.article.alt}
				/>

{props.article.headline}

	);
}

export default Article;
<commit_msg>Fixed stretched images (#500)<commit_after>import Image from 'next/image';
import React from 'react';

function Article(props) {
	return (

				<Image
					src={props.article.image}
					width={360}
					height={200}
					objectFit='cover'
					alt={props.article.alt}
				/>

{props.article.headline}

	);
}

export default Article;
<|endoftext|>


<commit_before>var Sequelize = require('sequelize');
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
//var jquery = require('jquery');

// connect to the database
var sequelize = new Sequelize('auctionate', process.env.POSTGRES_USER, process.env.POSTGRES_PASSWORD, {
	host: 'localhost',
	dialect: 'postgres',
	define: {
		timestamps: false
	}
});

// create table called items
var Item = sequelize.define('item', {
	lotnumber: Sequelize.INTEGER,
	name: Sequelize.STRING,
	category: Sequelize.STRING,
	description: Sequelize.TEXT,
	estimate: Sequelize.INTEGER,
	reserve: Sequelize.INTEGER,
	premium: Sequelize.INTEGER
});

// create table called consignors
var Consignor = sequelize.define('consignor', {
	lastname: Sequelize.STRING,
	address: Sequelize.STRING,
	zipcode: Sequelize.INTEGER,
	city: Sequelize.STRING,
	phone: Sequelize.STRING,
	email: Sequelize.STRING,
	bankaccount: Sequelize.INTEGER,
	commission: Sequelize.INTEGER,
	fee: Sequelize.INTEGER
});

// create table called bidders
var Bidder = sequelize.define('bidder', {
	firstname: Sequelize.STRING,
	lastname: Sequelize.STRING,
	phone: Sequelize.STRING,
	email: Sequelize.STRING,
	address: Sequelize.STRING,
	zipcode: Sequelize.INTEGER,
	city: Sequelize.STRING,
	payment: Sequelize.TEXT,
	shipping: Sequelize.TEXT
});

// assigns consignors to items
Consignor.hasMany(Item);
Item.belongsTo(Consignor);

// assigns items to bidder -- FIX THIS
// Bidder.hasMany(Item);
// Item.belongsTo(Bidder);

var app = express();

app.use(express.static('./src/'));
app.use(bodyParser.urlencoded({extended: true}));

app.use(session({
	secret: 'oh wow very secret much security',
	resave: true,
	saveUninitialized: false
}));

app.set('views', './src/views');
app.set('view engine', 'jade');

// HOME VIEW
app.get('/', function (req, res) {
	res.render('index');
});

// gets all the itmes in the database
app.get('/item', function (req, res) {
	Item.findAll().then(function (items) {
		items = items.map(function (itemRow) {
			var columns = itemRow.dataValues;
			return {
				lotnumber: columns.lotnumber,
				name: columns.name,
				category: columns.category,
				description: columns.description,
				estimate: columns.estimate,
				reserve: columns.reserve,
				premium: columns.premium
			}
		});
		res.render('item', {
			items: items
		});
	});
});

app.post('/item', function (req, res) {
	Item.create({
		lotnumber: req.body.lotnumber,
		name: req.body.name,
		category: req.body.catergory,
		description: req.body.description,
		estimate: req.body.estimate,
		reserve: req.body.reserve,
		premium: req.body.premium
	});
	res.redirect('back') // back says" stay on this page
});

// gets all the consignors from the database
app.get('/consignor', function (req, res) {
	Consignor.findAll().then(function (consignors) {
		consignors = consignors.map(function (consignorRow) {
			var columns = consignorRow.dataValues;
			return {
				lastname: columns.lastname,
				address: columns.address,
				zipcode: columns.zipcode,
				city: columns.city,
				phone: columns.phone,
				email: columns.email,
				bankaccount: columns.bankaccount,
				commission: columns.commission,
				fee: columns.fee
			}
		});
		res.render('consignor', {
			consignors: consignors
		});
	});
});

// add new consignor
app.post('/consignor', function (req, res) {
	Consignor.create({
		lastname: req.body.lastname,
		address: req.body.address,
		zipcode: req.body.zipcode,
		city: req.body.city,
		phone: req.body.phone,
		email: req.body.email,
		bankaccount: req.body.bankaccount,
		commission: req.body.commission,
		fee: req.body.fee
	});
	res.redirect('back') // back says: stay on this page
});

// form to add new bidder
app.get('/bidder', function (req, res) {
	res.render('bidder');
});

app.post('/bidder', function (req, res) {
	Bidder.create({
		firstname: req.body.firstname,
		lastname: req.body.lastname,
		phone: req.body.phone,
		email: req.body.email,
		address: req.body.address,
		zipcode: req.body.zipcode,
		city: req.body.city,
		payment: req.body.payment,
		shipping: req.body.shipping
	});
	res.redirect('back') // back says: stay on this page
});

sequelize.sync().then(function () {
	var server = app.listen(3000, function () {
		console.log('Auctionate app listening on port: ' + server.address().port);
	});
});
<commit_msg>added get route to pull bidder informations out of the database<commit_after>var Sequelize = require('sequelize');
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
//var jquery = require('jquery');

// connect to the database
var sequelize = new Sequelize('auctionate', process.env.POSTGRES_USER, process.env.POSTGRES_PASSWORD, {
	host: 'localhost',
	dialect: 'postgres',
	define: {
		timestamps: false
	}
});

// create table called items
var Item = sequelize.define('item', {
	lotnumber: Sequelize.INTEGER,
	name: Sequelize.STRING,
	category: Sequelize.STRING,
	description: Sequelize.TEXT,
	estimate: Sequelize.INTEGER,
	reserve: Sequelize.INTEGER,
	premium: Sequelize.INTEGER
});

// create table called consignors
var Consignor = sequelize.define('consignor', {
	lastname: Sequelize.STRING,
	address: Sequelize.STRING,
	zipcode: Sequelize.INTEGER,
	city: Sequelize.STRING,
	phone: Sequelize.STRING,
	email: Sequelize.STRING,
	bankaccount: Sequelize.INTEGER,
	commission: Sequelize.INTEGER,
	fee: Sequelize.INTEGER
});

// create table called bidders
var Bidder = sequelize.define('bidder', {
	firstname: Sequelize.STRING,
	lastname: Sequelize.STRING,
	phone: Sequelize.STRING,
	email: Sequelize.STRING,
	address: Sequelize.STRING,
	zipcode: Sequelize.INTEGER,
	city: Sequelize.STRING,
	payment: Sequelize.TEXT,
	shipping: Sequelize.TEXT
});

// assigns consignors to items
Consignor.hasMany(Item);
Item.belongsTo(Consignor);

// assigns items to bidder -- FIX THIS
// Bidder.hasMany(Item);
// Item.belongsTo(Bidder);

var app = express();

app.use(express.static('./src/'));
app.use(bodyParser.urlencoded({extended: true}));

app.use(session({
	secret: 'oh wow very secret much security',
	resave: true,
	saveUninitialized: false
}));

app.set('views', './src/views');
app.set('view engine', 'jade');

// HOME VIEW
app.get('/', function (req, res) {
	res.render('index');
});

// gets all the itmes in the database
app.get('/item', function (req, res) {
	Item.findAll().then(function (items) {
		items = items.map(function (itemRow) {
			var columns = itemRow.dataValues;
			return {
				lotnumber: columns.lotnumber,
				name: columns.name,
				category: columns.category,
				description: columns.description,
				estimate: columns.estimate,
				reserve: columns.reserve,
				premium: columns.premium
			}
		});
		res.render('item', {
			items: items
		});
	});
});

app.post('/item', function (req, res) {
	Item.create({
		lotnumber: req.body.lotnumber,
		name: req.body.name,
		category: req.body.catergory,
		description: req.body.description,
		estimate: req.body.estimate,
		reserve: req.body.reserve,
		premium: req.body.premium
	});
	res.redirect('back') // back says" stay on this page
});

// gets all the consignors from the database
app.get('/consignor', function (req, res) {
	Consignor.findAll().then(function (consignors) {
		consignors = consignors.map(function (consignorRow) {
			var columns = consignorRow.dataValues;
			return {
				lastname: columns.lastname,
				address: columns.address,
				zipcode: columns.zipcode,
				city: columns.city,
				phone: columns.phone,
				email: columns.email,
				bankaccount: columns.bankaccount,
				commission: columns.commission,
				fee: columns.fee
			}
		});
		res.render('consignor', {
			consignors: consignors
		});
	});
});

// add new consignor
app.post('/consignor', function (req, res) {
	Consignor.create({
		lastname: req.body.lastname,
		address: req.body.address,
		zipcode: req.body.zipcode,
		city: req.body.city,
		phone: req.body.phone,
		email: req.body.email,
		bankaccount: req.body.bankaccount,
		commission: req.body.commission,
		fee: req.body.fee
	});
	res.redirect('back') // back says: stay on this page
});

// get all bidders out of the database
app.get('/bidder', function (req, res) {
	Bidder.findAll().then(function (bidders) {
		bidders = bidders.map(function (bidderRow) {
			var columns = bidderRow.dataValues;
			return {
				firstname: columns.firstname,
				lastname: columns.lastname,
				phone: columns.phone,
				email: columns.email,
				address: columns.address,
				zipcode: columns.zipcode,
				city: columns.city,
				payment: columns.payment,
				shipping: columns.shipping
			}
		});
		res.render('bidder', {
			bidders: bidders
		});
	});
});

app.post('/bidder', function (req, res) {
	Bidder.create({
		firstname: req.body.firstname,
		lastname: req.body.lastname,
		phone: req.body.phone,
		email: req.body.email,
		address: req.body.address,
		zipcode: req.body.zipcode,
		city: req.body.city,
		payment: req.body.payment,
		shipping: req.body.shipping
	});
	res.redirect('back') // back says: stay on this page
});

sequelize.sync().then(function () {
	var server = app.listen(3000, function () {
		console.log('Auctionate app listening on port: ' + server.address().port);
	});
});
<|endoftext|>