<commit_before>import { Component, ApplicationRef } from '@angular/core';

import path from 'path';
import fs from 'fs';
import $ from 'jquery';
import { remote, app, shell } from 'electron'; // native electron module
import jetpack from 'fs-jetpack'; // module loaded from npm
import Docxtemplater from 'docxtemplater';
var Handsontable = require('./handsontablep/dist/handsontable.full.js');
import dataapi from '../stores/dataapi';
import schemas from '../schemas';
import { exportKeluarga } from '../helpers/exporter';
import { initializeTableSearch, initializeTableCount, initializeTableSelected } from '../helpers/table';
import expressions from 'angular-expressions';
import createPrintVars from '../helpers/printvars';
import diffProps from '../helpers/diff';

window.jQuery = $;
require('./node_modules/bootstrap/dist/js/bootstrap.js');

var app = remote.app;
var hot;
var sheetContainer;
var emptyContainer;
var resultBefore=[];

var init =  function () {
    sheetContainer = document.getElementById('sheet');
    emptyContainer = document.getElementById('empty');
    window.hot = hot = new Handsontable(sheetContainer, {
        data: [],
        topOverlay: 34,

        rowHeaders: true,
        colHeaders: schemas.getHeader(schemas.keluarga),
        columns: schemas.keluarga,

        colWidths: schemas.getColWidths(schemas.keluarga),
        rowHeights: 23,

        columnSorting: true,
        sortIndicator: true,
        hiddenColumns: {indicators: true},

        renderAllRows: false,
        outsideClickDeselects: false,
        autoColumnSize: false,

        search: true,
        filters: true,
        contextMenu: ['undo', 'redo', 'row_above', 'remove_row'],
        dropdownMenu: ['filter_by_condition', 'filter_action_bar']
    });

    var spanSelected = $("#span-selected")[0];
    initializeTableSelected(hot, 1, spanSelected);

    var spanCount = $("#span-count")[0];
    initializeTableCount(hot, spanCount);

    window.addEventListener('resize', function(e){
        hot.render();
    })
};

var showColumns = [
    [],
    ["no_kk","nama_kepala_keluarga","alamat","dusun","rt","rw"],
    ["no_kk","nama_kepala_keluarga","raskin","jamkesmas","pkh"]
]

var spliceArray = function(fields, showColumns){
    var result=[];
    for(var i=0;i!=fields.length;i++){
        var index = showColumns.indexOf(fields[i]);
        if (index == -1) result.push(i);
    }
    return result;
}

var allPenduduks = {};
var updateKeluarga = function(keluargas, penduduks){
    var existsKeluargas = {};
    var keluargaMap = {};
    for(var i = 0; i < keluargas.length; i++){
        var k = keluargas[i];
        existsKeluargas[k[0]] = true;
        keluargaMap[k[0]] = k;
    }

    for(var i = 0; i < penduduks.length; i++){
        var p = penduduks[i];
        var po = schemas.arrayToObj(p, schemas.penduduk);
        if(!po.no_kk)
            continue;

        if(!existsKeluargas[po.no_kk]){
            var ko = {no_kk: po.no_kk, dusun: po.dusun, rt: po.rt, rw: po.rw, alamat_jalan: po.alamat_jalan, raskin: null, bpjs: null, kip: null, pkh: null};
            var k = schemas.objToArray(ko, schemas.keluarga);
            keluargas.push(k);
            keluargaMap[po.no_kk] = k;
            existsKeluargas[po.no_kk] = true;
        }

        if(!allPenduduks[po.no_kk]){
            allPenduduks[po.no_kk] = [];
        }
        allPenduduks[po.no_kk].push(po)

        if(po.hubungan_keluarga == "Kepala Keluarga"){
            keluargaMap[po.no_kk][1] = po.nama_penduduk;
            keluargaMap[po.no_kk][2] = po.nik;
        }
    }

    for(var i = keluargas.length - 1; i >= 0; i--){
        var k = keluargas[i];
        var count = 0;
        if(allPenduduks[k[0]])
            count = allPenduduks[k[0]].length;
        k[3] = count;
        if(count == 0){
            keluargas.splice(i, 1);
        }
    }

}

var KeluargaComponent = Component({
    selector: 'keluarga',
    templateUrl: 'templates/keluarga.html'
})
.Class(Object.assign(diffProps, {
    constructor: function(appRef) {
        this.appRef = appRef;
    },
    ngOnInit: function(){
        $("title").html("Data Keluarga - " +dataapi.getActiveAuth().desa_name);
        init();

        var inputSearch = document.getElementById("input-search");
        this.tableSearcher = initializeTableSearch(hot, document, inputSearch);

        this.hot = window.hot;
        var ctrl = this;

        function keyup(e) {
            //ctrl+s
            if (e.ctrlKey && e.keyCode == 83){
                ctrl.openSaveDiffDialog();
                e.preventDefault();
                e.stopPropagation();
            }
            //ctrl+p
            if (e.ctrlKey && e.keyCode == 80){
                ctrl.printKK();
                e.preventDefault();
                e.stopPropagation();
            }
        }
        document.addEventListener('keyup', keyup, false);

        dataapi.getContent("keluarga", null, [], schemas.keluarga, function(keluargaContent){
            dataapi.getContent("penduduk", null, [], schemas.penduduk, function(pendudukContent){
                updateKeluarga(keluargaContent, pendudukContent);
                ctrl.initialData = JSON.parse(JSON.stringify(keluargaContent));
                hot.loadData(keluargaContent);
                setTimeout(function(){
                    $("#loader").addClass("hidden");
                    $(sheetContainer).removeClass("hidden");
                    hot.render();
                    ctrl.loaded = true;
                    ctrl.appRef.tick();
                },500);
            })
        })
        this.initDiffComponent();
    },
    exportExcel: function(){
        var data = hot.getSourceData();
        exportKeluarga(data, "Data Keluarga");
    },
    filterContent: function(){
        var plugin = hot.getPlugin('hiddenColumns');
        var value = $('input[name=btn-filter]:checked').val();
        var fields = schemas.keluarga.map(c => c.field);
        var result = spliceArray(fields,showColumns[value]);

        plugin.showColumns(resultBefore);
        if(value==0) plugin.showColumns(result);
        else plugin.hideColumns(result);
        hot.render();
        resultBefore = result;
    },
    saveContent: function(){
        $("#modal-save-diff").modal("hide");
        var timestamp = new Date().getTime();
        var content = hot.getSourceData();
        this.savingMessage = "Menyimpan...";
        var that = this;
        dataapi.saveContent("keluarga", null, content, schemas.keluarga, function(err, response, body){
            that.savingMessage = "Penyimpanan "+ (err ? "gagal" : "berhasil");
            setTimeout(function(){
                if(!err){
                    that.initialData = JSON.parse(JSON.stringify(content));
                    that.afterSave();
                }
                that.savingMessage = null;
            }, 2000);
        });
        return false;
    },
    printKK: function(){
        var selected = hot.getSelected();
        if(!selected)
            return;

        var fileName = remote.dialog.showSaveDialog({
            filters: [
                {name: 'Word document', extensions: ['docx']},
            ]
        });
        if(fileName){
            if(!fileName.endsWith(".docx"))
                fileName = fileName+".docx";
            var angularParser= function(tag){
                var expr=expressions.compile(tag);
                return {get:expr};
            }
            var nullGetter = function(tag, props) {
                return "";
            };
            var keluarga = schemas.arrayToObj(hot.getDataAtRow(selected[0]), schemas.keluarga);
            var rawPenduduks = allPenduduks[keluarga.no_kk];
            var idx = 1;
            var penduduks = rawPenduduks.map(function(o){
                var res = Object.assign({}, o);
                res.no = idx;
                idx++;
                return res;
            });
            dataapi.getDesa(function(desas){
                var auth = dataapi.getActiveAuth();
                var desa = desas.filter(d => d.blog_id == auth.desa_id)[0];
                var printvars = createPrintVars(desa);

                var content = fs.readFileSync(path.join(app.getAppPath(), "docx_templates","kk.docx"),"binary");
                var doc=new Docxtemplater(content);
                doc.setOptions({parser:angularParser, nullGetter: nullGetter});
                doc.setData({penduduks: penduduks, vars: printvars, keluarga: keluarga});
                doc.render();

                var buf = doc.getZip().generate({type:"nodebuffer"});
                fs.writeFileSync(fileName, buf);
                shell.openItem(fileName);
            });
        }
    }
}));

KeluargaComponent.parameters = [ApplicationRef];
export default KeluargaComponent;
<commit_msg>apbdes and indicator colors<commit_after>import { Component, ApplicationRef } from '@angular/core';

import path from 'path';
import fs from 'fs';
import $ from 'jquery';
import { remote, app, shell } from 'electron'; // native electron module
import jetpack from 'fs-jetpack'; // module loaded from npm
import Docxtemplater from 'docxtemplater';
var Handsontable = require('./handsontablep/dist/handsontable.full.js');
import dataapi from '../stores/dataapi';
import schemas from '../schemas';
import { exportKeluarga } from '../helpers/exporter';
import { initializeTableSearch, initializeTableCount, initializeTableSelected } from '../helpers/table';
import expressions from 'angular-expressions';
import createPrintVars from '../helpers/printvars';
import diffProps from '../helpers/diff';

window.jQuery = $;
require('./node_modules/bootstrap/dist/js/bootstrap.js');

var app = remote.app;
var hot;
var sheetContainer;
var emptyContainer;
var resultBefore=[];

var init =  function () {
    sheetContainer = document.getElementById('sheet');
    emptyContainer = document.getElementById('empty');
    window.hot = hot = new Handsontable(sheetContainer, {
        data: [],
        topOverlay: 34,

        rowHeaders: true,
        colHeaders: schemas.getHeader(schemas.keluarga),
        columns: schemas.keluarga,

        colWidths: schemas.getColWidths(schemas.keluarga),
        rowHeights: 23,

        columnSorting: true,
        sortIndicator: true,
        hiddenColumns: {indicators: true},

        renderAllRows: false,
        outsideClickDeselects: false,
        autoColumnSize: false,

        search: true,
        filters: true,
        contextMenu: ['undo', 'redo', 'row_above', 'remove_row'],
        dropdownMenu: ['filter_by_condition', 'filter_action_bar']
    });

    var spanSelected = $("#span-selected")[0];
    initializeTableSelected(hot, 1, spanSelected);

    var spanCount = $("#span-count")[0];
    initializeTableCount(hot, spanCount);

    window.addEventListener('resize', function(e){
        hot.render();
    })
};

var showColumns = [
    [],
    ["no_kk","nama_kepala_keluarga","alamat","dusun","rt","rw"],
    ["no_kk","nama_kepala_keluarga","raskin","jamkesmas","pkh"]
]

var spliceArray = function(fields, showColumns){
    var result=[];
    for(var i=0;i!=fields.length;i++){
        var index = showColumns.indexOf(fields[i]);
        if (index == -1) result.push(i);
    }
    return result;
}

var allPenduduks = {};
var updateKeluarga = function(keluargas, penduduks){
    var existsKeluargas = {};
    var keluargaMap = {};
    for(var i = 0; i < keluargas.length; i++){
        var k = keluargas[i];
        existsKeluargas[k[0]] = true;
        keluargaMap[k[0]] = k;
    }

    for(var i = 0; i < penduduks.length; i++){
        var p = penduduks[i];
        var po = schemas.arrayToObj(p, schemas.penduduk);
        if(!po.no_kk)
            continue;

        if(!existsKeluargas[po.no_kk]){
            var ko = {no_kk: po.no_kk, dusun: po.dusun, rt: po.rt, rw: po.rw, alamat_jalan: po.alamat_jalan, raskin: null, bpjs: null, kip: null, pkh: null};
            var k = schemas.objToArray(ko, schemas.keluarga);
            keluargas.push(k);
            keluargaMap[po.no_kk] = k;
            existsKeluargas[po.no_kk] = true;
        }

        if(!allPenduduks[po.no_kk]){
            allPenduduks[po.no_kk] = [];
        }
        allPenduduks[po.no_kk].push(po)

        if(po.hubungan_keluarga == "Kepala Keluarga"){
            keluargaMap[po.no_kk][1] = po.nama_penduduk;
            keluargaMap[po.no_kk][2] = po.nik;
        }
    }

    for(var i = keluargas.length - 1; i >= 0; i--){
        var k = keluargas[i];
        var count = 0;
        if(allPenduduks[k[0]])
            count = allPenduduks[k[0]].length;
        k[3] = count;
        if(count == 0){
            keluargas.splice(i, 1);
        }
    }

}

var KeluargaComponent = Component({
    selector: 'keluarga',
    templateUrl: 'templates/keluarga.html'
})
.Class(Object.assign(diffProps, {
    constructor: function(appRef) {
        this.appRef = appRef;
    },
    ngOnInit: function(){
        $("title").html("Data Keluarga - " +dataapi.getActiveAuth().desa_name);
        init();

        var inputSearch = document.getElementById("input-search");
        this.tableSearcher = initializeTableSearch(hot, document, inputSearch);

        this.hot = window.hot;
        var ctrl = this;

        function keyup(e) {
            //ctrl+s
            if (e.ctrlKey && e.keyCode == 83){
                ctrl.openSaveDiffDialog();
                e.preventDefault();
                e.stopPropagation();
            }
            //ctrl+p
            if (e.ctrlKey && e.keyCode == 80){
                ctrl.printKK();
                e.preventDefault();
                e.stopPropagation();
            }
        }
        document.addEventListener('keyup', keyup, false);

        dataapi.getContent("keluarga", null, [], schemas.keluarga, function(keluargaContent){
            dataapi.getContent("penduduk", null, [], schemas.penduduk, function(pendudukContent){
                updateKeluarga(keluargaContent, pendudukContent);
                ctrl.initialData = JSON.parse(JSON.stringify(keluargaContent));
                hot.loadData(keluargaContent);
                $("#loader").addClass("hidden");
                setTimeout(function(){
                    $(sheetContainer).removeClass("hidden");
                    hot.render();
                    ctrl.loaded = true;
                    ctrl.appRef.tick();
                },500);
            })
        })
        this.initDiffComponent();
    },
    exportExcel: function(){
        var data = hot.getSourceData();
        exportKeluarga(data, "Data Keluarga");
    },
    filterContent: function(){
        var plugin = hot.getPlugin('hiddenColumns');
        var value = $('input[name=btn-filter]:checked').val();
        var fields = schemas.keluarga.map(c => c.field);
        var result = spliceArray(fields,showColumns[value]);

        plugin.showColumns(resultBefore);
        if(value==0) plugin.showColumns(result);
        else plugin.hideColumns(result);
        hot.render();
        resultBefore = result;
    },
    saveContent: function(){
        $("#modal-save-diff").modal("hide");
        var timestamp = new Date().getTime();
        var content = hot.getSourceData();
        this.savingMessage = "Menyimpan...";
        var that = this;
        dataapi.saveContent("keluarga", null, content, schemas.keluarga, function(err, response, body){
            that.savingMessage = "Penyimpanan "+ (err ? "gagal" : "berhasil");
            setTimeout(function(){
                if(!err){
                    that.initialData = JSON.parse(JSON.stringify(content));
                    that.afterSave();
                }
                that.savingMessage = null;
            }, 2000);
        });
        return false;
    },
    printKK: function(){
        var selected = hot.getSelected();
        if(!selected)
            return;

        var fileName = remote.dialog.showSaveDialog({
            filters: [
                {name: 'Word document', extensions: ['docx']},
            ]
        });
        if(fileName){
            if(!fileName.endsWith(".docx"))
                fileName = fileName+".docx";
            var angularParser= function(tag){
                var expr=expressions.compile(tag);
                return {get:expr};
            }
            var nullGetter = function(tag, props) {
                return "";
            };
            var keluarga = schemas.arrayToObj(hot.getDataAtRow(selected[0]), schemas.keluarga);
            var rawPenduduks = allPenduduks[keluarga.no_kk];
            var idx = 1;
            var penduduks = rawPenduduks.map(function(o){
                var res = Object.assign({}, o);
                res.no = idx;
                idx++;
                return res;
            });
            dataapi.getDesa(function(desas){
                var auth = dataapi.getActiveAuth();
                var desa = desas.filter(d => d.blog_id == auth.desa_id)[0];
                var printvars = createPrintVars(desa);

                var content = fs.readFileSync(path.join(app.getAppPath(), "docx_templates","kk.docx"),"binary");
                var doc=new Docxtemplater(content);
                doc.setOptions({parser:angularParser, nullGetter: nullGetter});
                doc.setData({penduduks: penduduks, vars: printvars, keluarga: keluarga});
                doc.render();

                var buf = doc.getZip().generate({type:"nodebuffer"});
                fs.writeFileSync(fileName, buf);
                shell.openItem(fileName);
            });
        }
    }
}));

KeluargaComponent.parameters = [ApplicationRef];
export default KeluargaComponent;
<|endoftext|>


<commit_before>import { addGraphQLResolvers, addGraphQLQuery } from 'meteor/vulcan:core';
import { Posts } from '../lib/collections/posts';
import { WeightedList } from './weightedList.js';
import { accessFilterMultiple } from '../lib/modules/utils/schemaUtils.js';

// The set of fields on Posts which are used for deciding which posts to
// recommend. Fields other than these will be projected out before downloading
// from the database.
const scoreRelevantFields = {baseScore:1, curatedDate:1, frontpageDate:1};

// Returns part of a mongodb aggregate pipeline, which will join against the
// LWEvents collection and filter out any posts which have a corresponding
// post-view event for the current user. Returns as an array, so you can spread
// this into a pipeline with ...pipelineFilterUnread(currentUser). If
// currentUser is null, returns an empty array (no aggregation pipeline stages),
// so all posts are included.
const pipelineFilterUnread = ({currentUser}) => {
  if (!currentUser)
    return [];

  return [
    { $lookup: {
      from: "lwevents",
      let: { documentId: "$_id", },
      pipeline: [
        { $match: {
          name: "post-view",
          userId: currentUser._id,
        } },
        { $match: { $expr: {
          $and: [
            {$eq: ["$documentId", "$$documentId"]},
          ]
        } } },
        { $limit: 1},
      ],
      as: "views",
    } },

    { $match: {
      "views": {$size:0}
    } },
  ];
}

// A filter (mongodb selector) for which posts should be considered at all as
// recommendations.
const recommendablePostFilter = {
  // Gets the selector from the default Posts view, which includes things like
  // excluding drafts and deleted posts
  ...Posts.getParameters({}).selector,

  // Only consider recommending posts if they have score>30. This has a big
  // effect on the size of the recommendable-post set, which needs to not be
  // too big for performance reasons.
  baseScore: {$gt: 30},

  // Don't recommend meta posts
  meta: false,

  // Enforce the disableRecommendation flag
  disableRecommendation: {$ne: true},
}

// Return the set of all posts that are eligible for being recommended, with
// scoreRelevantFields included (but other fields projected away). If
// onlyUnread is true and currentUser is nonnull, posts that the user has
// already read are filtered out.
const allRecommendablePosts = async ({currentUser, onlyUnread}) => {
  return await Posts.aggregate([
    // Filter to recommendable posts
    { $match: {
      ...recommendablePostFilter,
    } },

    // If onlyUnread, filter to just unread posts
    ...(onlyUnread ? pipelineFilterUnread({currentUser}) : []),

    // Project out fields other than _id and scoreRelevantFields
    { $project: {_id:1, ...scoreRelevantFields} },
  ]).toArray();
}

// Returns the top-rated posts (rated by scoreFn) to recommend to a user.
//   count: The maximum number of posts to return. May return fewer, if there
//     aren't enough recommendable unread posts in the database.
//   currentUser: The user who is requesting the recommendations, or null if
//     logged out.
//   onlyUnread: Whether to exclude posts which currentUser has already read.
//   scoreFn: Function which takes a post (with at least scoreRelevantFields
//     included), and returns a number. The posts with the highest scoreFn
//     return value will be the ones returned.
const topPosts = async ({count, currentUser, onlyUnread, scoreFn}) => {
  const unreadPostsMetadata  = await allRecommendablePosts({currentUser, onlyUnread});

  const unreadTopPosts = _.first(
    _.sortBy(unreadPostsMetadata, post => -scoreFn(post)),
    count);
  const unreadTopPostIds = _.map(unreadTopPosts, p=>p._id);

  return await Posts.find(
    { _id: {$in: unreadTopPostIds} },
    { sort: {baseScore: -1} }
  ).fetch();
}

// Returns a random weighted sampling of highly-rated posts (weighted by
// sampleWeightFn) to recommend to a user.
//   count: The maximum number of posts to return. May return fewer, if there
//     aren't enough recommendable unread posts in the database.
//   currentUser: The user who is requesting the recommendations, or null if
//     logged out.
//   onlyUnread: Whether to exclude posts which currentUser has already read.
//   sampleWeightFn: Function which takes a post (with at least
//     scoreRelevantFields included), and returns a number. Higher numbers are
//     more likely to be recommended.
const samplePosts = async ({count, currentUser, onlyUnread, sampleWeightFn}) => {
  const unreadPostsMetadata  = await allRecommendablePosts({currentUser, onlyUnread});

  const sampledPosts = new WeightedList(
    _.map(unreadPostsMetadata, post => [post._id, sampleWeightFn(post)])
  ).pop(count);

  return await Posts.find(
    { _id: {$in: sampledPosts} },
  ).fetch();
}

const getRecommendations = async ({count, algorithm, currentUser}) => {
  const scoreFn = post => {
    const sectionModifier = post.curatedDate
      ? algorithm.curatedModifier
      : (post.frontpageDate
        ? algorithm.frontpageModifier
        : algorithm.personalBlogpostModifier);
    const weight = sectionModifier + Math.pow(post.baseScore - algorithm.scoreOffset, algorithm.scoreExponent)
    return Math.max(0, weight);
  }

  // Cases here should match recommendationAlgorithms in RecommendationsAlgorithmPicker.jsx
  switch(algorithm.method) {
    case "top": {
      return await topPosts({
        count, currentUser,
        onlyUnread: algorithm.onlyUnread,
        scoreFn
      });
    }
    case "sample": {
      return await samplePosts({
        count, currentUser,
        onlyUnread: algorithm.onlyUnread,
        sampleWeightFn: scoreFn,
      });
    }
    default: {
      throw new Error(`Unrecognized recommendation algorithm: ${algorithm.method}`);
    }
  }
};

addGraphQLResolvers({
  Query: {
    async Recommendations(root, {count,algorithm}, {currentUser}) {
      const recommended = await getRecommendations({count, algorithm, currentUser})
      const accessFiltered = accessFilterMultiple(currentUser, Posts, recommended);
      if (recommended.length !== accessFiltered.length) {
        // eslint-disable-next-line no-console
        console.error("Recommendation engine returned a post which permissions filtered out as inaccessible");
      }
      return accessFiltered;
    }
  }
});

addGraphQLQuery("Recommendations(count: Int, algorithm: JSON): [Post!]");
<commit_msg>increase baseScore for recommendations<commit_after>import { addGraphQLResolvers, addGraphQLQuery } from 'meteor/vulcan:core';
import { Posts } from '../lib/collections/posts';
import { WeightedList } from './weightedList.js';
import { accessFilterMultiple } from '../lib/modules/utils/schemaUtils.js';

// The set of fields on Posts which are used for deciding which posts to
// recommend. Fields other than these will be projected out before downloading
// from the database.
const scoreRelevantFields = {baseScore:1, curatedDate:1, frontpageDate:1};

// Returns part of a mongodb aggregate pipeline, which will join against the
// LWEvents collection and filter out any posts which have a corresponding
// post-view event for the current user. Returns as an array, so you can spread
// this into a pipeline with ...pipelineFilterUnread(currentUser). If
// currentUser is null, returns an empty array (no aggregation pipeline stages),
// so all posts are included.
const pipelineFilterUnread = ({currentUser}) => {
  if (!currentUser)
    return [];

  return [
    { $lookup: {
      from: "lwevents",
      let: { documentId: "$_id", },
      pipeline: [
        { $match: {
          name: "post-view",
          userId: currentUser._id,
        } },
        { $match: { $expr: {
          $and: [
            {$eq: ["$documentId", "$$documentId"]},
          ]
        } } },
        { $limit: 1},
      ],
      as: "views",
    } },

    { $match: {
      "views": {$size:0}
    } },
  ];
}

// A filter (mongodb selector) for which posts should be considered at all as
// recommendations.
const recommendablePostFilter = {
  // Gets the selector from the default Posts view, which includes things like
  // excluding drafts and deleted posts
  ...Posts.getParameters({}).selector,

  // Only consider recommending posts if they have score>30. This has a big
  // effect on the size of the recommendable-post set, which needs to not be
  // too big for performance reasons.
  baseScore: {$gt: 60},

  // Don't recommend meta posts
  meta: false,

  // Enforce the disableRecommendation flag
  disableRecommendation: {$ne: true},
}

// Return the set of all posts that are eligible for being recommended, with
// scoreRelevantFields included (but other fields projected away). If
// onlyUnread is true and currentUser is nonnull, posts that the user has
// already read are filtered out.
const allRecommendablePosts = async ({currentUser, onlyUnread}) => {
  return await Posts.aggregate([
    // Filter to recommendable posts
    { $match: {
      ...recommendablePostFilter,
    } },

    // If onlyUnread, filter to just unread posts
    ...(onlyUnread ? pipelineFilterUnread({currentUser}) : []),

    // Project out fields other than _id and scoreRelevantFields
    { $project: {_id:1, ...scoreRelevantFields} },
  ]).toArray();
}

// Returns the top-rated posts (rated by scoreFn) to recommend to a user.
//   count: The maximum number of posts to return. May return fewer, if there
//     aren't enough recommendable unread posts in the database.
//   currentUser: The user who is requesting the recommendations, or null if
//     logged out.
//   onlyUnread: Whether to exclude posts which currentUser has already read.
//   scoreFn: Function which takes a post (with at least scoreRelevantFields
//     included), and returns a number. The posts with the highest scoreFn
//     return value will be the ones returned.
const topPosts = async ({count, currentUser, onlyUnread, scoreFn}) => {
  const unreadPostsMetadata  = await allRecommendablePosts({currentUser, onlyUnread});

  const unreadTopPosts = _.first(
    _.sortBy(unreadPostsMetadata, post => -scoreFn(post)),
    count);
  const unreadTopPostIds = _.map(unreadTopPosts, p=>p._id);

  return await Posts.find(
    { _id: {$in: unreadTopPostIds} },
    { sort: {baseScore: -1} }
  ).fetch();
}

// Returns a random weighted sampling of highly-rated posts (weighted by
// sampleWeightFn) to recommend to a user.
//   count: The maximum number of posts to return. May return fewer, if there
//     aren't enough recommendable unread posts in the database.
//   currentUser: The user who is requesting the recommendations, or null if
//     logged out.
//   onlyUnread: Whether to exclude posts which currentUser has already read.
//   sampleWeightFn: Function which takes a post (with at least
//     scoreRelevantFields included), and returns a number. Higher numbers are
//     more likely to be recommended.
const samplePosts = async ({count, currentUser, onlyUnread, sampleWeightFn}) => {
  const unreadPostsMetadata  = await allRecommendablePosts({currentUser, onlyUnread});

  const sampledPosts = new WeightedList(
    _.map(unreadPostsMetadata, post => [post._id, sampleWeightFn(post)])
  ).pop(count);

  return await Posts.find(
    { _id: {$in: sampledPosts} },
  ).fetch();
}

const getRecommendations = async ({count, algorithm, currentUser}) => {
  const scoreFn = post => {
    const sectionModifier = post.curatedDate
      ? algorithm.curatedModifier
      : (post.frontpageDate
        ? algorithm.frontpageModifier
        : algorithm.personalBlogpostModifier);
    const weight = sectionModifier + Math.pow(post.baseScore - algorithm.scoreOffset, algorithm.scoreExponent)
    return Math.max(0, weight);
  }

  // Cases here should match recommendationAlgorithms in RecommendationsAlgorithmPicker.jsx
  switch(algorithm.method) {
    case "top": {
      return await topPosts({
        count, currentUser,
        onlyUnread: algorithm.onlyUnread,
        scoreFn
      });
    }
    case "sample": {
      return await samplePosts({
        count, currentUser,
        onlyUnread: algorithm.onlyUnread,
        sampleWeightFn: scoreFn,
      });
    }
    default: {
      throw new Error(`Unrecognized recommendation algorithm: ${algorithm.method}`);
    }
  }
};

addGraphQLResolvers({
  Query: {
    async Recommendations(root, {count,algorithm}, {currentUser}) {
      const recommended = await getRecommendations({count, algorithm, currentUser})
      const accessFiltered = accessFilterMultiple(currentUser, Posts, recommended);
      if (recommended.length !== accessFiltered.length) {
        // eslint-disable-next-line no-console
        console.error("Recommendation engine returned a post which permissions filtered out as inaccessible");
      }
      return accessFiltered;
    }
  }
});

addGraphQLQuery("Recommendations(count: Int, algorithm: JSON): [Post!]");
<|endoftext|>


<commit_before>Vue.component('api-method', {
	props: ['method', 'index', 'maintags'],
	data: function() {
		return {
            visible: false,
            schemaEditor: undefined
        }
	},
    methods: {
        toggleBody : function() {
            this.visible = !this.visible;
            $(this.hashUid).collapse('toggle');
            if (this.visible) {
                Vue.nextTick(function(){
                    this.tagSetup();
                },this);
            }
        },
        duplicateOperation : function(method) {
            this.$parent.addOperation(method);
        },
		removeOperation : function(target) {
            this.$parent.removeOperation(target);
	    },
        addParameter : function() {
            var newParam = {};
            newParam.name = 'newParam';
            newParam.in = 'query';
            newParam.required = true;
            newParam.type = 'string';
            this.method.parameters.push(newParam);
        },
        removeParameter : function(index) {
            this.$root.save();
            this.method.parameters.splice(index,1);
        },
        addResponse : function() {
            var status = 200;
            while (this.method.responses[status]) {
                status++;
            }
            var response = {};
            response.description = 'Description';
            Vue.set(this.method.responses, status, response);
        },
        editResponse : function(status) {
            var response = this.method.responses[status];
            if (!response.schema) {
                Vue.set(response, 'schema', {});
            }
            var initial = deref(response.schema,this.$root.container.openapi);
            var editorOptions = {
                theme: 'bootstrap2',
                iconlib: 'fontawesome3',
                schema: jsonSchemaDraft4,
                refs: this.$root.container.openapi,
                startval: initial
            };
            var element = document.getElementById('schemaContainer');
            try {
                this.schemaEditor = new JSONEditor(element, editorOptions);
                schemaEditorClose = function() {
                    this.schemaEditor.destroy();
                    $('#schemaModal').modal('hide');
                }.bind(this);
                schemaEditorSave = function() {
                    this.response.schema = this.schemaEditor.getValue();
                    schemaEditorClose();
                }.bind(this);
                var modalOptions = {};
                $('#schemaModal').modal(modalOptions);
            }
            catch (ex) {
                bootbox.alert('The editor could not be instantiated. Circular schemas are not yet supported');
            }
        },
        removeResponse : function(status) {
            this.$root.save();
            Vue.delete(this.method.responses, status);
        },
        tagSetup : function() {
            var simpleTags = [];
            for (var t in this.maintags) {
                simpleTags.push(this.maintags[t].name);
            }
            $(this.hashTagId).tagsinput({
                typeahead: {
                    name: this.tagId,
                    source: function(query) {
                        return simpleTags;
                    }
                }
            });
            for (var t in this.method.tags) {
                $(this.hashTagId).tagsinput('add', this.method.tags[t]);
            }
            $(this.hashTagId).on('itemAdded', function(event) {
                // event.item: contains the item. Convert jQuery event to native event for vue.js
                var e = document.createEvent('HTMLEvents');
                e.initEvent('change', true, true);
                setTimeout(function(){
                    this.dispatchEvent(e);
                },0);
            });
            $(this.hashTagId).on('itemRemoved', function(event) {
                // event.item: contains the item. Convert jQuery event to native event for vue.js
                var e = document.createEvent('HTMLEvents');
                e.initEvent('change', true, true);
                setTimeout(function(){
                    this.dispatchEvent(e);
                },0);
            });
        }
    },
    computed: {
        httpMethod : {
            get : function() {
                return this.index.toUpperCase();
            },
            set : function(newVal) {
                this.$parent.renameOperation(this.index, newVal.toLowerCase());
            }
        },
        hashUid : function() {
            return '#'+this._uid;
        },
        tagId : function() {
            return 'tags-input'+this._uid;
        },
        hashTagId : function() {
            return '#'+this.tagId;
        },
        vtags : {
            get : function() {
				if (!this.method.tags) Vue.set(this.method, 'tags', []);
                return this.method.tags;
            },
            set : function(newVal) {
                this.method.tags = newVal;
            }
        }
    },
    beforeMount : function() {
        if (!this.method.externalDocs) {
            Vue.set(this.method, 'externalDocs', {});
        }
    },
	template: '#template-method'
});

Vue.component('api-response', {
	props: ["response", "status"],
	computed: {
		statusCode: {
			get : function() {
				return this.status;
			},
			set : function(newVal) {
				this.$parent.renameResponse(this.status, newVal);
			}
		}
	},
	data: function() {
		return {}
	}
});
<commit_msg>Default new parameters to required:false<commit_after>Vue.component('api-method', {
	props: ['method', 'index', 'maintags'],
	data: function() {
		return {
            visible: false,
            schemaEditor: undefined
        }
	},
    methods: {
        toggleBody : function() {
            this.visible = !this.visible;
            $(this.hashUid).collapse('toggle');
            if (this.visible) {
                Vue.nextTick(function(){
                    this.tagSetup();
                },this);
            }
        },
        duplicateOperation : function(method) {
            this.$parent.addOperation(method);
        },
		removeOperation : function(target) {
            this.$parent.removeOperation(target);
	    },
        addParameter : function() {
            var newParam = {};
            newParam.name = 'newParam';
            newParam.in = 'query';
            newParam.required = false;
            newParam.type = 'string';
            this.method.parameters.push(newParam);
        },
        removeParameter : function(index) {
            this.$root.save();
            this.method.parameters.splice(index,1);
        },
        addResponse : function() {
            var status = 200;
            while (this.method.responses[status]) {
                status++;
            }
            var response = {};
            response.description = 'Description';
            Vue.set(this.method.responses, status, response);
        },
        editResponse : function(status) {
            var response = this.method.responses[status];
            if (!response.schema) {
                Vue.set(response, 'schema', {});
            }
            var initial = deref(response.schema,this.$root.container.openapi);
            var editorOptions = {
                theme: 'bootstrap2',
                iconlib: 'fontawesome3',
                schema: jsonSchemaDraft4,
                refs: this.$root.container.openapi,
                startval: initial
            };
            var element = document.getElementById('schemaContainer');
            try {
                this.schemaEditor = new JSONEditor(element, editorOptions);
                schemaEditorClose = function() {
                    this.schemaEditor.destroy();
                    $('#schemaModal').modal('hide');
                }.bind(this);
                schemaEditorSave = function() {
                    this.response.schema = this.schemaEditor.getValue();
                    schemaEditorClose();
                }.bind(this);
                var modalOptions = {};
                $('#schemaModal').modal(modalOptions);
            }
            catch (ex) {
                bootbox.alert('The editor could not be instantiated. Circular schemas are not yet supported');
            }
        },
        removeResponse : function(status) {
            this.$root.save();
            Vue.delete(this.method.responses, status);
        },
        tagSetup : function() {
            var simpleTags = [];
            for (var t in this.maintags) {
                simpleTags.push(this.maintags[t].name);
            }
            $(this.hashTagId).tagsinput({
                typeahead: {
                    name: this.tagId,
                    source: function(query) {
                        return simpleTags;
                    }
                }
            });
            for (var t in this.method.tags) {
                $(this.hashTagId).tagsinput('add', this.method.tags[t]);
            }
            $(this.hashTagId).on('itemAdded', function(event) {
                // event.item: contains the item. Convert jQuery event to native event for vue.js
                var e = document.createEvent('HTMLEvents');
                e.initEvent('change', true, true);
                setTimeout(function(){
                    this.dispatchEvent(e);
                },0);
            });
            $(this.hashTagId).on('itemRemoved', function(event) {
                // event.item: contains the item. Convert jQuery event to native event for vue.js
                var e = document.createEvent('HTMLEvents');
                e.initEvent('change', true, true);
                setTimeout(function(){
                    this.dispatchEvent(e);
                },0);
            });
        }
    },
    computed: {
        httpMethod : {
            get : function() {
                return this.index.toUpperCase();
            },
            set : function(newVal) {
                this.$parent.renameOperation(this.index, newVal.toLowerCase());
            }
        },
        hashUid : function() {
            return '#'+this._uid;
        },
        tagId : function() {
            return 'tags-input'+this._uid;
        },
        hashTagId : function() {
            return '#'+this.tagId;
        },
        vtags : {
            get : function() {
				if (!this.method.tags) Vue.set(this.method, 'tags', []);
                return this.method.tags;
            },
            set : function(newVal) {
                this.method.tags = newVal;
            }
        }
    },
    beforeMount : function() {
        if (!this.method.externalDocs) {
            Vue.set(this.method, 'externalDocs', {});
        }
    },
	template: '#template-method'
});

Vue.component('api-response', {
	props: ["response", "status"],
	computed: {
		statusCode: {
			get : function() {
				return this.status;
			},
			set : function(newVal) {
				this.$parent.renameResponse(this.status, newVal);
			}
		}
	},
	data: function() {
		return {}
	}
});
<|endoftext|>


<commit_before>import React, { useEffect, useMemo } from 'react';
import { usePlugin } from '@wq/react';
import PropTypes from 'prop-types';
import MapboxGL from '@react-native-mapbox-gl/maps';
import { useMapState } from '@wq/map';

export default function Map({ bounds, children, mapProps, containerStyle }) {
    const {
        accessToken = null,
        dragRotate: rotateEnabled,
        pitchWithRotate: pitchEnabled = mapProps.dragRotate
    } = mapProps || {};
    useEffect(() => {
        MapboxGL.setAccessToken(accessToken);
    }, [accessToken]);

    const { ready } = usePlugin('map'),
        fitBounds = useMemo(() => {
            const [[ymin, xmin], [ymax, xmax]] = bounds;
            return { sw: [xmin, ymin], ne: [xmax, ymax] };
        }, [bounds]),
        state = useMapState(),
        basemap = state && state.basemaps.filter(basemap => basemap.active)[0];

    let style;
    if (basemap) {
        if (basemap.type === 'vector-tile') {
            style = basemap.url;
        } else if (basemap.type === 'tile') {
            const urls = [];
            if (basemap.url.match('{s}')) {
                (basemap.subdomains || ['a', 'b', 'c']).forEach(s =>
                    urls.push(basemap.url.replace('{s}', s))
                );
            } else {
                urls.push(basemap.url);
            }
            style = {
                version: 8,
                sources: {
                    [basemap.name]: {
                        type: 'raster',
                        tiles: urls,
                        tileSize: basemap.tileSize || 256
                    }
                },
                layers: [
                    {
                        id: basemap.name,
                        type: 'raster',
                        source: basemap.name
                    }
                ]
            };
        }
    } else {
        style = null;
    }

    const mapRef = React.useRef(),
        setRef = React.useCallback(ref => {
            mapRef.current = ref;
            ready(ref);
        }, []);

    containerStyle = {
        flex: 1,
        minHeight: 200,
        ...containerStyle
    };

    return (
        <MapboxGL.MapView
            styleURL={style}
            ref={setRef}
            rotateEnabled={rotateEnabled}
            pitchEnabled={pitchEnabled}
            attributionEnabled={!!accessToken}
            logoEnabled={!!accessToken}
            style={containerStyle}
        >
            <MapboxGL.Camera
                bounds={fitBounds}
                ref={ref => (mapRef.current.camera = ref)}
                animationDuration={0}
            />
            {children}
        </MapboxGL.MapView>
    );
}

Map.propTypes = {
    bounds: PropTypes.array,
    children: PropTypes.node,
    mapProps: PropTypes.object,
    containerStyle: PropTypes.object
};
<commit_msg>refs might load in different order<commit_after>import React, { useEffect, useMemo } from 'react';
import { usePlugin } from '@wq/react';
import PropTypes from 'prop-types';
import MapboxGL from '@react-native-mapbox-gl/maps';
import { useMapState } from '@wq/map';

export default function Map({ bounds, children, mapProps, containerStyle }) {
    const {
        accessToken = null,
        dragRotate: rotateEnabled,
        pitchWithRotate: pitchEnabled = mapProps.dragRotate
    } = mapProps || {};
    useEffect(() => {
        MapboxGL.setAccessToken(accessToken);
    }, [accessToken]);

    const { ready } = usePlugin('map'),
        fitBounds = useMemo(() => {
            const [[ymin, xmin], [ymax, xmax]] = bounds;
            return { sw: [xmin, ymin], ne: [xmax, ymax] };
        }, [bounds]),
        state = useMapState(),
        basemap = state && state.basemaps.filter(basemap => basemap.active)[0];

    let style;
    if (basemap) {
        if (basemap.type === 'vector-tile') {
            style = basemap.url;
        } else if (basemap.type === 'tile') {
            const urls = [];
            if (basemap.url.match('{s}')) {
                (basemap.subdomains || ['a', 'b', 'c']).forEach(s =>
                    urls.push(basemap.url.replace('{s}', s))
                );
            } else {
                urls.push(basemap.url);
            }
            style = {
                version: 8,
                sources: {
                    [basemap.name]: {
                        type: 'raster',
                        tiles: urls,
                        tileSize: basemap.tileSize || 256
                    }
                },
                layers: [
                    {
                        id: basemap.name,
                        type: 'raster',
                        source: basemap.name
                    }
                ]
            };
        }
    } else {
        style = null;
    }

    const mapRef = React.useRef(),
        setMapRef = React.useCallback(ref => {
            if (cameraRef.current) {
                ref.camera = cameraRef.current;
            }
            mapRef.current = ref;
            ready(ref);
        }, []),
        cameraRef = React.useRef(),
        setCameraRef = React.useCallback(ref => {
            cameraRef.current = ref;
            if (mapRef.current) {
                mapRef.current.camera = ref;
            }
        }, []);

    containerStyle = {
        flex: 1,
        minHeight: 200,
        ...containerStyle
    };

    return (
        <MapboxGL.MapView
            styleURL={style}
            ref={setMapRef}
            rotateEnabled={rotateEnabled}
            pitchEnabled={pitchEnabled}
            attributionEnabled={!!accessToken}
            logoEnabled={!!accessToken}
            style={containerStyle}
        >
            <MapboxGL.Camera
                bounds={fitBounds}
                ref={setCameraRef}
                animationDuration={0}
            />
            {children}
        </MapboxGL.MapView>
    );
}

Map.propTypes = {
    bounds: PropTypes.array,
    children: PropTypes.node,
    mapProps: PropTypes.object,
    containerStyle: PropTypes.object
};
<|endoftext|>


<commit_before>// Create bot and add dialogs
var restify = require('restify');
var builder = require('botbuilder');
var request = require('request');

var server = restify.createServer();
var model = 'https://api.projectoxford.ai/luis/v1/application?id=05e77449-7d73-446b-99a2-d3bf101ef87d&subscription-key='+ process.env.LUIS_KEY
var dialog = new builder.LuisDialog(model);
var bot = new builder.BotConnectorBot();
bot.add('/', dialog);

dialog.on('Greeting', [
    function(session, args, next){
        // prompt user to order pizza
        //console.log(session.message.text)
        session.send("Hi, can I take your order?");
    },
])

dialog.on('OrderPizza', [
    function(session, args, next){
        // initialize empty array that will be passed on until end that holds conversations
        var conversations = [];
        conversations.push();
        conversations.push({text:"Hi, can I take your order?", time: new Date().toLocaleString()})
        conversations.push(session.message.text);
        conversations.push({text:session.message.text, time: new Date().toLocaleString()});
        conversations.push({text:"Where would you like it delivered?", time: new Date().toLocaleString()});
        // get the size
        var size = builder.EntityRecognizer.findEntity(args.entities, 'Size');
        // get the toppings
        var toppings = builder.EntityRecognizer.findAllEntities(args.entities, 'Topping');
        // store conversations
        session.dialogData.conversations = conversations;
        // store size
        session.dialogData.size = size.entity;
        // store toppings
        session.dialogData.toppings = toppings.map(function(topping){return topping.entity});
        // store the pizza order
        var pizzas = [];
        session.dialogData.pizzas = pizzas;
        var orders = [];
        session.dialogData.orders = orders;
        // prompt user for address
        builder.Prompts.text(session, "Where would you like it delivered?");

    },
    function(session, results, next){
        // store the address
        session.dialogData.address = results.response;
        session.dialogData.conversations.push({text: session.dialogData.address, time: new Date().toLocaleString()});
        next();
    },
    function(session, results, next){
       var time = new Date().toLocaleString();
       session.dialogData.pizzas.push({size:session.dialogData.size, toppings:session.dialogData.toppings});
       session.dialogData.orders.push({time: time, pizzas:JSON.stringify(session.dialogData.pizzas), price:15, address:session.dialogData.address, status:'confirmed'});
       session.dalogData.orders.push({conversations: session.dialogData.coversations});
       next();
    },
    function(session, results, next){
      var options = {
        method: 'post',
        body: JSON.stringify({order: session.dialogData.orders}),
        json: true,
        url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
        headers: {
            'X-Parse-Application-Id': process.env.PARSE_ID,
        }
      }
      request (options, function (err, res, body) {
        if (err) {
        console.log('Error :', err)
        return
        }
      console.log(' Body :', body)

        });
      next();
    },
    function(session, results){
        console.log(session.dialogData.orders);
        session.endDialog("Thank you! Your order has been placed");
    }
]);

server.use(bot.verifyBotFramework({ appId: process.env.APP_ID, appSecret: process.env.APP_SECRET }));
server.post('/api/messages', bot.listen());

server.listen(8080, function () {
    console.log('%s listening to %s', server.name, server.url);
});<commit_msg>fixed bug<commit_after>// Create bot and add dialogs
var restify = require('restify');
var builder = require('botbuilder');
var request = require('request');

var server = restify.createServer();
var model = 'https://api.projectoxford.ai/luis/v1/application?id=05e77449-7d73-446b-99a2-d3bf101ef87d&subscription-key='+ process.env.LUIS_KEY
var dialog = new builder.LuisDialog(model);
var bot = new builder.BotConnectorBot();
bot.add('/', dialog);

dialog.on('Greeting', [
    function(session, args, next){
        // prompt user to order pizza
        //console.log(session.message.text)
        session.send("Hi, can I take your order?");
    },
])

dialog.on('OrderPizza', [
    function(session, args, next){
        // initialize empty array that will be passed on until end that holds conversations
        var conversations = [];
        conversations.push();
        conversations.push({text:"Hi, can I take your order?", time: new Date().toLocaleString()})
        conversations.push(session.message.text);
        conversations.push({text:session.message.text, time: new Date().toLocaleString()});
        conversations.push({text:"Where would you like it delivered?", time: new Date().toLocaleString()});
        // get the size
        var size = builder.EntityRecognizer.findEntity(args.entities, 'Size');
        // get the toppings
        var toppings = builder.EntityRecognizer.findAllEntities(args.entities, 'Topping');
        // store conversations
        session.dialogData.conversations = conversations;
        // store size
        session.dialogData.size = size.entity;
        // store toppings
        session.dialogData.toppings = toppings.map(function(topping){return topping.entity});
        // store the pizza order
        var pizzas = [];
        session.dialogData.pizzas = pizzas;
        var orders = [];
        session.dialogData.orders = orders;
        // prompt user for address
        builder.Prompts.text(session, "Where would you like it delivered?");

    },
    function(session, results, next){
        // store the address
        session.dialogData.address = results.response;
        session.dialogData.conversations.push({text: session.dialogData.address, time: new Date().toLocaleString()});
        next();
    },
    function(session, results, next){
       var time = new Date().toLocaleString();
       session.dialogData.pizzas.push({size:session.dialogData.size, toppings:session.dialogData.toppings});
       session.dialogData.orders.push({time: time, pizzas:JSON.stringify(session.dialogData.pizzas), price:15, address:session.dialogData.address, status:'confirmed'});
       session.dialogData.orders.push({conversations: session.dialogData.conversations});
       next();
    },
    // function(session, results, next){
    //   var options = {
    //     method: 'post',
    //     body: JSON.stringify({order: session.dialogData.orders}),
    //     json: true,
    //     url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
    //     headers: {
    //         'X-Parse-Application-Id': process.env.PARSE_ID,
    //     }
    //   }
    //   request (options, function (err, res, body) {
    //     if (err) {
    //     console.log('Error :', err)
    //     return
    //     }
    //   console.log(' Body :', body)
    //      next();

    //     });
    // },
    function(session, results){
    //   var options = {
    //     method: 'post',
    //     body: JSON.stringify({order: session.dialogData.orders}),
    //     json: true,
    //     url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
    //     headers: {
    //         'X-Parse-Application-Id': process.env.PARSE_ID,
    //     }
    //   }
    //   request (options, function (err, res, body) {
    //     if (err) {
    //     console.log('Error :', err)
    //     return
    //     }
    //   console.log(' Body :', body)
      session.endDialog("Thank you! Your order has been placed");

    //     });

    }
]);

server.use(bot.verifyBotFramework({ appId: process.env.APP_ID, appSecret: process.env.APP_SECRET }));
server.post('/api/messages', bot.listen());

server.listen(8080, function () {
    console.log('%s listening to %s', server.name, server.url);
});<|endoftext|>


<commit_before>import {
  acyclicEqualsU,
  assocPartialU,
  curry2,
  curry3,
  curry4,
  dissocPartialU,
  id,
  isArray,
  isObject,
  mapPartialU,
  values,
  zipObjPartialU
} from "infestines"

//

const apply = (x2y, x) => x2y(x)
const always = x => _ => x
const snd = (_, c) => c

//

const Ident = {
  map: apply,
  of: id,
  ap: apply
}

const Const = {
  map: snd,
  of: id
}

const ConstOf = Monoid => ({
  map: snd,
  of: always(Monoid.empty()),
  ap: (x2yA, xA) => Monoid.concat(xA, x2yA)
})

const PartialList = {
  of: x => x !== undefined ? [x, null] : null,
  empty: () => null,
  cons: (h, t) => h !== undefined ? [h, t] : t,
  revConcat(xs, ys) {
    while (xs) {
      ys = [xs[0], ys]
      xs = xs[1]
    }
    return ys
  },
  reverse: xs => PartialList.revConcat(xs, null),
  concat: (xs, ys) => PartialList.revConcat(PartialList.reverse(xs), ys),
  toArray(xs) {
    const ys = []
    while (xs) {
      ys.push(xs[0])
      xs = xs[1]
    }
    return ys
  }
}

const Collect = ConstOf(PartialList)

const csnoc = t => h => PartialList.cons(h, t)

const PartialArray = {
  traverse(A, x2yA, xs) {
    let s = A.of(PartialList.empty())
    let i = xs.length
    while (i)
      s = A.ap(A.map(csnoc, s), x2yA(xs[--i]))
    return A.map(PartialList.toArray, s)
  }
}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const unArray = x => isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : emptyArray

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const emptyArrayToUndefined = xs => xs.length ? xs : undefined

//

const emptyArray = []
const emptyObject = {}

//

const toPartial = transform => x => x !== undefined ? transform(x) : x

//

const seemsLens = x => typeof x === "function" && x.length === 3

const lifted = assert("a lens", seemsLens)

const close = (l, A, i) => x => l(A, i, x)

function composed(ls) {
  switch (ls.length) {
    case 0:  return identity
    case 1:  return lift(ls[0])
    default: return (F, i, t) => {
      let n = ls.length
      i = close(lift(ls[--n]), F, i)
      while (1 < n)
        i = close(lift(ls[--n]), F, i)
      return lift(ls[0])(F, i, t)
    }
  }
}

function lift(l) {
  switch (typeof l) {
    case "string":   return liftProp(l)
    case "number":   return liftIndex(l)
    case "function": return lifted(l)
    default:         return composed(l)
  }
}

export function compose(...lenses) {
  switch (lenses.length) {
    case 0:  return identity
    case 1:  return lenses[0]
    default: return lenses
  }
}

function setI(l, x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x, s)
    case "number":   return setIndex(l, x, s)
    case "function": return lifted(l)(Ident, () => x, s)
    default:         return modifyComposedI(l, () => x, s)
  }
}

function getComposedI(ls, s0)  {
  let s = s0
  for (let i=0, n=ls.length; i<n; ++i)
    s = getI(ls[i], s)
  return s
}

function getI(l, s) {
  switch (typeof l) {
    case "string":   return getProp(l, s)
    case "number":   return getIndex(l, s)
    case "function": return lifted(l)(Const, Const.of, s)
    default:         return getComposedI(l, s)
  }
}

const getInverseI = (l, x) => setI(l, x, undefined)

function modifyComposedI(ls, x2x, s0) {
  let n = ls.length

  let r = s0
  const ss = []

  for (let i=0; i<n; ++i) {
    ss.push(r)
    const l = ls[i]
    switch (typeof l) {
      case "string":
        r = getProp(l, r)
        break
      case "number":
        r = getIndex(l, r)
        break
      default:
        r = composed(ls.slice(i))(Ident, x2x, r)
        n = i
        break
    }
  }

  if (n === ls.length)
    r = x2x(r)

  while (0 <= --n) {
    const l = ls[n]
    switch (typeof l) {
      case "string": r = setProp(l, r, ss[n]); break
      case "number": r = setIndex(l, r, ss[n]); break
    }
  }

  return r
}

function modifyI(l, x2x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x2x(getProp(l, s)), s)
    case "number":   return setIndex(l, x2x(getIndex(l, s)), s)
    case "function": return lifted(l)(Ident, x2x, s)
    default:         return modifyComposedI(l, x2x, s)
  }
}

const lensI = (getter, setter) => (F, inner, target) =>
  F.map(focus => setter(focus, target), inner(getter(target)))
const collectI = (l, s) =>
  PartialList.toArray(lift(l)(Collect, PartialList.of, s))

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const getInverse = curry2(getInverseI)
export const collect = curry2(collectI)

export const foldMapOf = curry4((m, l, to, s) => {
  const Const = ConstOf(m)
  return lift(l)(Const, to, s)
})

export const inverse = iso => (F, inner, x) =>
  F.map(x => getI(iso, x), inner(getInverseI(iso, x)))

export const chain = curry2((x2yL, xL) =>
  [xL, choose(xO => xO !== undefined ? x2yL(xO) : nothing)])

export const just = x => lensI(always(x), snd)

export const choose = x2yL => (F, inner, target) =>
  lift(x2yL(target))(F, inner, target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => acyclicEqualsU(x, inn) ? out : x
const normalizer = fn => (F, inner, x) => F.map(fn, inner(fn(x)))

export const replace = curry2((inn, out) => (F, inner, x) =>
  F.map(replacer(out, inn), inner(replacer(inn, out)(x))))

export const defaults = out => (F, inner, x) =>
  F.map(replacer(out, undefined), inner(x !== undefined ? x : out))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x !== undefined ? x : v)

export const valueOr = v => (_F, inner, x) =>
  inner(x !== undefined && x !== null ? x : v)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) =>
  v !== undefined ? assocPartialU(k, v, o) : dissocPartialU(k, o)

const liftProp = k => (F, inner, o) =>
  F.map(v => setProp(k, v, o), inner(getProp(k, o)))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export function findWith(...ls) {
  const lls = compose(...ls)
  return [find(x => getI(lls, x) !== undefined), lls]
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const nulls = n => Array(n).fill(null)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
function setIndex(i, x, xs) {
  if (x !== undefined) {
    if (!isArray(xs))
      return i < 0 ? undefined : nulls(i).concat([x])
    const n = xs.length
    if (n <= i)
      return xs.concat(nulls(i - n), [x])
    if (i < 0)
      return !n ? undefined : xs
    const ys = Array(n)
    for (let j=0; j<n; ++j)
      ys[j] = xs[j]
    ys[i] = x
    return ys
  } else {
    if (!isArray(xs))
      return undefined
    const n = xs.length
    if (!n)
      return undefined
    if (i < 0 || n <= i)
      return xs
    if (n === 1)
      return undefined
    const ys = Array(n-1)
    for (let j=0; j<i; ++j)
      ys[j] = xs[j]
    for (let j=i+1; j<n; ++j)
      ys[j-1] = xs[j]
    return ys
  }
}
const liftIndex = i => (F, inner, xs) =>
  F.map(x => setIndex(i, x, xs), inner(getIndex(i, xs)))

export const append = lensI(snd, (x, xs) =>
  x !== undefined ? isArray(xs) ? xs.concat([x]) : [x] : unArray(xs))

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  emptyArrayToUndefined(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : emptyObject
      let z
      const set = (k, v) => {
        if (!z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

function getPick(template, target) {
  let r
  for (const k in template) {
    const v = getI(template[k], target)
    if (v !== undefined) {
      if (!r)
        r = {}
      r[k] = v
    }
  }
  return r
}
const setPick = (template, target) => value => {
  const o = value || emptyObject
  let c = target
  for (const k in template)
    c = setI(template[k], o[k], c)
  return c
}
export const pick = template => (F, inner, target) =>
  F.map(setPick(template, target), inner(getPick(template, target)))

export const identity = (_F, inner, t) => inner(t)

export const props = (...ks) => pick(zipObjPartialU(ks, ks))

const show = (labels, dir) => x => console.log(...labels, dir, x) || x

export const log = (...labels) =>
  lensI(show(labels, "get"), show(labels, "set"))

export const sequence = (A, inner, target) =>
  A === Ident
  ? emptyArrayToUndefined(mapPartialU(inner, mkArray(target)))
  : A.map(emptyArrayToUndefined, PartialArray.traverse(A, inner, mkArray(target)))

export const optional = (A, inner, target) =>
  target !== undefined ? inner(target) : A.of(undefined)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}, n=xs.length
      for (let i=0; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? values(o) : undefined)

export default compose
<commit_msg>Move before use<commit_after>import {
  acyclicEqualsU,
  assocPartialU,
  curry2,
  curry3,
  curry4,
  dissocPartialU,
  id,
  isArray,
  isObject,
  mapPartialU,
  values,
  zipObjPartialU
} from "infestines"

//

const apply = (x2y, x) => x2y(x)
const always = x => _ => x
const snd = (_, c) => c

//

const Ident = {
  map: apply,
  of: id,
  ap: apply
}

const Const = {
  map: snd,
  of: id
}

const ConstOf = Monoid => ({
  map: snd,
  of: always(Monoid.empty()),
  ap: (x2yA, xA) => Monoid.concat(xA, x2yA)
})

const PartialList = {
  of: x => x !== undefined ? [x, null] : null,
  empty: () => null,
  cons: (h, t) => h !== undefined ? [h, t] : t,
  revConcat(xs, ys) {
    while (xs) {
      ys = [xs[0], ys]
      xs = xs[1]
    }
    return ys
  },
  reverse: xs => PartialList.revConcat(xs, null),
  concat: (xs, ys) => PartialList.revConcat(PartialList.reverse(xs), ys),
  toArray(xs) {
    const ys = []
    while (xs) {
      ys.push(xs[0])
      xs = xs[1]
    }
    return ys
  }
}

const Collect = ConstOf(PartialList)

const csnoc = t => h => PartialList.cons(h, t)

const PartialArray = {
  traverse(A, x2yA, xs) {
    let s = A.of(PartialList.empty())
    let i = xs.length
    while (i)
      s = A.ap(A.map(csnoc, s), x2yA(xs[--i]))
    return A.map(PartialList.toArray, s)
  }
}

//

const warn = process.env.NODE_ENV === "production" ? () => {} : (() => {
  const warned = {}

  return message => {
    if (!(message in warned)) {
      warned[message] = message
      console.warn("partial.lenses:", message)
    }
  }
})()

//

const emptyArray = []
const emptyObject = {}

//

const unArray = x => isArray(x) ? x : undefined

const mkArray = x => isArray(x) ? x : emptyArray

//

const check = (expected, predicate) => x => {
  if (predicate(x))
    return x
  else
    throw new Error(`Expected ${expected}, but got ${x}.`)
}

const assert = process.env.NODE_ENV === "production" ? () => id : check

//

const emptyArrayToUndefined = xs => xs.length ? xs : undefined

//

const toPartial = transform => x => x !== undefined ? transform(x) : x

//

const seemsLens = x => typeof x === "function" && x.length === 3

const lifted = assert("a lens", seemsLens)

const close = (l, A, i) => x => l(A, i, x)

function composed(ls) {
  switch (ls.length) {
    case 0:  return identity
    case 1:  return lift(ls[0])
    default: return (F, i, t) => {
      let n = ls.length
      i = close(lift(ls[--n]), F, i)
      while (1 < n)
        i = close(lift(ls[--n]), F, i)
      return lift(ls[0])(F, i, t)
    }
  }
}

function lift(l) {
  switch (typeof l) {
    case "string":   return liftProp(l)
    case "number":   return liftIndex(l)
    case "function": return lifted(l)
    default:         return composed(l)
  }
}

export function compose(...lenses) {
  switch (lenses.length) {
    case 0:  return identity
    case 1:  return lenses[0]
    default: return lenses
  }
}

function setI(l, x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x, s)
    case "number":   return setIndex(l, x, s)
    case "function": return lifted(l)(Ident, () => x, s)
    default:         return modifyComposedI(l, () => x, s)
  }
}

function getComposedI(ls, s0)  {
  let s = s0
  for (let i=0, n=ls.length; i<n; ++i)
    s = getI(ls[i], s)
  return s
}

function getI(l, s) {
  switch (typeof l) {
    case "string":   return getProp(l, s)
    case "number":   return getIndex(l, s)
    case "function": return lifted(l)(Const, Const.of, s)
    default:         return getComposedI(l, s)
  }
}

const getInverseI = (l, x) => setI(l, x, undefined)

function modifyComposedI(ls, x2x, s0) {
  let n = ls.length

  let r = s0
  const ss = []

  for (let i=0; i<n; ++i) {
    ss.push(r)
    const l = ls[i]
    switch (typeof l) {
      case "string":
        r = getProp(l, r)
        break
      case "number":
        r = getIndex(l, r)
        break
      default:
        r = composed(ls.slice(i))(Ident, x2x, r)
        n = i
        break
    }
  }

  if (n === ls.length)
    r = x2x(r)

  while (0 <= --n) {
    const l = ls[n]
    switch (typeof l) {
      case "string": r = setProp(l, r, ss[n]); break
      case "number": r = setIndex(l, r, ss[n]); break
    }
  }

  return r
}

function modifyI(l, x2x, s) {
  switch (typeof l) {
    case "string":   return setProp(l, x2x(getProp(l, s)), s)
    case "number":   return setIndex(l, x2x(getIndex(l, s)), s)
    case "function": return lifted(l)(Ident, x2x, s)
    default:         return modifyComposedI(l, x2x, s)
  }
}

const lensI = (getter, setter) => (F, inner, target) =>
  F.map(focus => setter(focus, target), inner(getter(target)))
const collectI = (l, s) =>
  PartialList.toArray(lift(l)(Collect, PartialList.of, s))

export const remove = curry2((l, s) => setI(l, undefined, s))
export const lens = curry2(lensI)
export const modify = curry3(modifyI)
export const set = curry3(setI)
export const get = curry2(getI)
export const getInverse = curry2(getInverseI)
export const collect = curry2(collectI)

export const foldMapOf = curry4((m, l, to, s) => {
  const Const = ConstOf(m)
  return lift(l)(Const, to, s)
})

export const inverse = iso => (F, inner, x) =>
  F.map(x => getI(iso, x), inner(getInverseI(iso, x)))

export const chain = curry2((x2yL, xL) =>
  [xL, choose(xO => xO !== undefined ? x2yL(xO) : nothing)])

export const just = x => lensI(always(x), snd)

export const choose = x2yL => (F, inner, target) =>
  lift(x2yL(target))(F, inner, target)

export const nothing = lensI(snd, snd)

export const orElse =
  curry2((d, l) => choose(x => getI(l, x) !== undefined ? l : d))

export const choice = (...ls) => choose(x => {
  const i = ls.findIndex(l => getI(l, x) !== undefined)
  return 0 <= i ? ls[i] : nothing
})

const replacer = (inn, out) => x => acyclicEqualsU(x, inn) ? out : x
const normalizer = fn => (F, inner, x) => F.map(fn, inner(fn(x)))

export const replace = curry2((inn, out) => (F, inner, x) =>
  F.map(replacer(out, inn), inner(replacer(inn, out)(x))))

export const defaults = out => (F, inner, x) =>
  F.map(replacer(out, undefined), inner(x !== undefined ? x : out))
export const required = inn => replace(inn, undefined)
export const define = v => normalizer(x => x !== undefined ? x : v)

export const valueOr = v => (_F, inner, x) =>
  inner(x !== undefined && x !== null ? x : v)

export const normalize = transform => normalizer(toPartial(transform))

const isProp = x => typeof x === "string"

export const prop = assert("a string", isProp)

const getProp = (k, o) => isObject(o) ? o[k] : undefined
const setProp = (k, v, o) =>
  v !== undefined ? assocPartialU(k, v, o) : dissocPartialU(k, o)

const liftProp = k => (F, inner, o) =>
  F.map(v => setProp(k, v, o), inner(getProp(k, o)))

export const find = predicate => choose(xs => {
  if (isArray(xs)) {
    const i = xs.findIndex(predicate)
    return i < 0 ? append : i
  } else {
    return append
  }
})

export function findWith(...ls) {
  const lls = compose(...ls)
  return [find(x => getI(lls, x) !== undefined), lls]
}

const isIndex = x => Number.isInteger(x) && 0 <= x

export const index = assert("a non-negative integer", isIndex)

const nulls = n => Array(n).fill(null)

const getIndex = (i, xs) => isArray(xs) ? xs[i] : undefined
function setIndex(i, x, xs) {
  if (x !== undefined) {
    if (!isArray(xs))
      return i < 0 ? undefined : nulls(i).concat([x])
    const n = xs.length
    if (n <= i)
      return xs.concat(nulls(i - n), [x])
    if (i < 0)
      return !n ? undefined : xs
    const ys = Array(n)
    for (let j=0; j<n; ++j)
      ys[j] = xs[j]
    ys[i] = x
    return ys
  } else {
    if (!isArray(xs))
      return undefined
    const n = xs.length
    if (!n)
      return undefined
    if (i < 0 || n <= i)
      return xs
    if (n === 1)
      return undefined
    const ys = Array(n-1)
    for (let j=0; j<i; ++j)
      ys[j] = xs[j]
    for (let j=i+1; j<n; ++j)
      ys[j-1] = xs[j]
    return ys
  }
}
const liftIndex = i => (F, inner, xs) =>
  F.map(x => setIndex(i, x, xs), inner(getIndex(i, xs)))

export const append = lensI(snd, (x, xs) =>
  x !== undefined ? isArray(xs) ? xs.concat([x]) : [x] : unArray(xs))

export const filter = p => lensI(xs => unArray(xs) && xs.filter(p), (ys, xs) =>
  emptyArrayToUndefined(mkArray(ys).concat(mkArray(xs).filter(x => !p(x)))))

export const augment = template => lensI(
  x => {
    if (isObject(x)) {
      const z = {...x}
      for (const k in template)
        z[k] = template[k](z)
      return z
    } else {
      return undefined
    }
  },
  (y, cIn) => {
    if (isObject(y)) {
      const c = isObject(cIn) ? cIn : emptyObject
      let z
      const set = (k, v) => {
        if (!z)
          z = {}
        z[k] = v
      }
      for (const k in y) {
        if (!(k in template))
          set(k, y[k])
        else
          if (k in c)
            set(k, c[k])
      }
      return z
    } else {
      return undefined
    }
  })

function getPick(template, target) {
  let r
  for (const k in template) {
    const v = getI(template[k], target)
    if (v !== undefined) {
      if (!r)
        r = {}
      r[k] = v
    }
  }
  return r
}
const setPick = (template, target) => value => {
  const o = value || emptyObject
  let c = target
  for (const k in template)
    c = setI(template[k], o[k], c)
  return c
}
export const pick = template => (F, inner, target) =>
  F.map(setPick(template, target), inner(getPick(template, target)))

export const identity = (_F, inner, t) => inner(t)

export const props = (...ks) => pick(zipObjPartialU(ks, ks))

const show = (labels, dir) => x => console.log(...labels, dir, x) || x

export const log = (...labels) =>
  lensI(show(labels, "get"), show(labels, "set"))

export const sequence = (A, inner, target) =>
  A === Ident
  ? emptyArrayToUndefined(mapPartialU(inner, mkArray(target)))
  : A.map(emptyArrayToUndefined, PartialArray.traverse(A, inner, mkArray(target)))

export const optional = (A, inner, target) =>
  target !== undefined ? inner(target) : A.of(undefined)

export const fromArrayBy = id =>
  warn("`fromArrayBy` is experimental and might be removed, renamed or changed semantically before next major release") ||
  lensI(xs => {
    if (isArray(xs)) {
      const o = {}, n=xs.length
      for (let i=0; i<n; ++i) {
        const x = xs[i]
        o[x[id]] = x
      }
      return o
    }
  },
  o => isObject(o) ? values(o) : undefined)

export default compose
<|endoftext|>


<commit_before>// Create bot and add dialogs
var restify = require('restify');
var builder = require('botbuilder');
var request = require('request');

var server = restify.createServer();
var model = 'https://api.projectoxford.ai/luis/v1/application?id=05e77449-7d73-446b-99a2-d3bf101ef87d&subscription-key='+ process.env.LUIS_KEY
var dialog = new builder.LuisDialog(model);
var bot = new builder.BotConnectorBot();
bot.add('/', dialog);

dialog.on('Greeting', [
    function(session, args, next){
        // prompt user to order pizza
        //console.log(session.message.text)
        session.send("Hi, can I take your order?");
    },
])

dialog.on('OrderPizza', [
    function(session, args, next){
        // initialize empty array that will be passed on until end that holds conversations
        var conversations = [];
        conversations.push();
        conversations.push({text:"Hi, can I take your order?", time: new Date().toLocaleString()})
        conversations.push(session.message.text);
        conversations.push({text:session.message.text, time: new Date().toLocaleString()});
        conversations.push({text:"Where would you like it delivered?", time: new Date().toLocaleString()});
        // get the size
        var size = builder.EntityRecognizer.findEntity(args.entities, 'Size');
        // get the toppings
        var toppings = builder.EntityRecognizer.findAllEntities(args.entities, 'Topping');
        // store conversations
        session.dialogData.conversations = conversations;
        // store size
        session.dialogData.size = size.entity;
        // store toppings
        session.dialogData.toppings = toppings.map(function(topping){return topping.entity});
        // store the pizza order
        var pizzas = [];
        session.dialogData.pizzas = pizzas;
        var orders = [];
        session.dialogData.orders = orders;
        // prompt user for address
        builder.Prompts.text(session, "Where would you like it delivered?");

    },
    function(session, results, next){
        // store the address
        session.dialogData.address = results.response;
        session.dialogData.conversations.push({text: session.dialogData.address, time: new Date().toLocaleString()});
        next();
    },
    function(session, results, next){
       var time = new Date().toLocaleString();
       session.dialogData.pizzas.push({size:session.dialogData.size, toppings:session.dialogData.toppings});
       session.dialogData.orders.push({time: time, pizzas:JSON.stringify(session.dialogData.pizzas), price:15, address:session.dialogData.address, status:'confirmed'});
       session.dialogData.orders.push({conversations: session.dialogData.conversations});
       next();
    },
    // function(session, results, next){
    //   var options = {
    //     method: 'post',
    //     body: JSON.stringify({order: session.dialogData.orders}),
    //     json: true,
    //     url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
    //     headers: {
    //         'X-Parse-Application-Id': process.env.PARSE_ID,
    //     }
    //   }
    //   request (options, function (err, res, body) {
    //     if (err) {
    //     console.log('Error :', err)
    //     return
    //     }
    //   console.log(' Body :', body)
    //      next();

    //     });
    // },
    function(session, results){
    //   var options = {
    //     method: 'post',
    //     body: JSON.stringify({order: session.dialogData.orders}),
    //     json: true,
    //     url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
    //     headers: {
    //         'X-Parse-Application-Id': process.env.PARSE_ID,
    //     }
    //   }
    //   request (options, function (err, res, body) {
    //     if (err) {
    //     console.log('Error :', err)
    //     return
    //     }
    //   console.log(' Body :', body)
      session.endDialog("Thank you! Your order has been placed");

    //     });

    }
]);

server.use(bot.verifyBotFramework({ appId: process.env.APP_ID, appSecret: process.env.APP_SECRET }));
server.post('/api/messages', bot.listen());

server.listen(8080, function () {
    console.log('%s listening to %s', server.name, server.url);
});<commit_msg>pizza orders sent to parse server<commit_after>// Create bot and add dialogs
var restify = require('restify');
var builder = require('botbuilder');
var request = require('request');

var server = restify.createServer();
var model = 'https://api.projectoxford.ai/luis/v1/application?id=05e77449-7d73-446b-99a2-d3bf101ef87d&subscription-key='+ process.env.LUIS_KEY
var dialog = new builder.LuisDialog(model);
var bot = new builder.BotConnectorBot();
bot.add('/', dialog);

dialog.on('Greeting', [
    function(session, args, next){
        // prompt user to order pizza
        session.send("Hi, can I take your order?");
    },
])

dialog.on('OrderPizza', [
    function(session, args, next){
        // initialize empty array that will be passed on until end that holds conversations
        var conversations = [];
        conversations.push();
        conversations.push({text:"Hi, can I take your order?", time: new Date().toLocaleString()})
        conversations.push(session.message.text);
        conversations.push({text:session.message.text, time: new Date().toLocaleString()});
        conversations.push({text:"Where would you like it delivered?", time: new Date().toLocaleString()});
        // get the size
        var size = builder.EntityRecognizer.findEntity(args.entities, 'Size');
        // get the toppings
        var toppings = builder.EntityRecognizer.findAllEntities(args.entities, 'Topping');
        // store conversations
        session.dialogData.conversations = conversations;
        // store size
        session.dialogData.size = size.entity;
        // store toppings
        session.dialogData.toppings = toppings.map(function(topping){return topping.entity});
        // store the pizza order
        var pizzas = [];
        session.dialogData.pizzas = pizzas;
        var orders = {};
        session.dialogData.orders = orders;
        // prompt user for address
        builder.Prompts.text(session, "Where would you like it delivered?");

    },
    function(session, results, next){
        // store the address
        session.dialogData.address = results.response;
        session.dialogData.conversations.push({text: session.dialogData.address, time: new Date().toLocaleString()});
        next();
    },
    function(session, results, next){
       var time = new Date().toLocaleString();
       session.dialogData.pizzas.push({size:session.dialogData.size, toppings:session.dialogData.toppings});
       session.dialogData.orders.conversations = session.dialogData.conversations;
       session.dialogData.orders.time = time;
       session.dialogData.orders.pizzas = session.dialogData.pizzas;
       session.dialogData.orders.price = 15;
       session.dialogData.orders.address = session.dialogData.address;
       session.dialogData.orders.status = 'confirmed';
       next();
    },
    function(session, results, next){
      var options = {
        method: 'post',
        body: {'order': session.dialogData.orders},
        json: true,
        url: 'https://pizzaordersdb.azurewebsites.net/parse/classes/PizzaOrders',
        headers: {
            'X-Parse-Application-Id': process.env.PARSE_ID,
        }
      }
      request (options, function (err, res, body) {
        if (err) {
        console.log('Error :', err)
        return
        }
        console.log(' Body :', body);
        session.endDialog('Thank you for your order');
        });
    },
]);

server.use(bot.verifyBotFramework({ appId: process.env.APP_ID, appSecret: process.env.APP_SECRET }));
server.post('/api/messages', bot.listen());

server.listen(8080, function () {
    console.log('%s listening to %s', server.name, server.url);
});<|endoftext|>