<commit_before>"use strict";
var http = require('http');
var graphql = require('graphql');
require('babel-register');
var WebSocketServer = require('websocket').server;
var graphql_tools = require('graphql-tools');
var graphql_validator = require('graphql/validation');
var graphql_execution = require('graphql/execution');
import gql from 'graphql-tag';
var data = require('../data.json');

class Server {
  constructor(schema, httpServer) {
    this.schema = schema;
    //initialize http server

    //init and connect websocket server to http
    this.wsServer = new WebSocketServer({
      httpServer: httpServer,
      autoAcceptConnections: false
    });

    this.wsServer.on('request', (request) => {
      //accept connection
      var connection = request.accept('graphql-protocol', request.origin);
      connection.on('message', (message) => {
        let message_data = JSON.parse(message.utf8Data);
        if (! message_data.type) { //mutation message
          if (message_data.name && connection.triggers && connection.triggers[message_data.name]) {
            let triggered_subs = connection.triggers[message_data.name];
            triggered_subs.forEach((sub_id) => {
              let sub_data = connection.subscriptions[sub_id];
              graphql.graphql(
                this.schema,
                sub_data.query,
                sub_data.rootValue,
                sub_data.contextValue,
                sub_data.variables,
                sub_data.operationName
              ).then(function(response) {
                let message = response;
                message.type = 'subscription_data';
                message.id = sub_id;
                connection.sendUTF(JSON.stringify(message));
              }, function(err) {
                let message = response;
                message.type = 'subscription_data';
                message.id = sub_id;
                connection.sendUTF(JSON.stringify(message));
              });
            })
          }
        } else {
          if (message_data.type === 'subscription_start') {
            let syntax_errors = graphql_validator.validate(this.schema, graphql.parse(message_data.query));
            if (syntax_errors.length > 0) {
              let message = {
                type: 'subscription_fail',
                errors: syntax_errors,
                id: message_data.id,
              };
              connection.sendUTF(JSON.stringify(message));
            } else {
              const sub_id = message_data.id;
              if (!connection.subscriptions) {
                connection.subscriptions = {};
              }
              //set up trigger listeners
              if (message_data.triggers) {
                if (! connection.triggers) {
                  connection.triggers = {};
                }
                message_data.triggers.forEach(function(trigger) {
                  if (! connection.triggers[trigger]) {
                    connection.triggers[trigger] = [sub_id];
                  } else {
                    connection.triggers[trigger].push(sub_id);
                  }
                });
              }
              //set up polling message
              if (message_data.pollingInterval) {
                let pollingId = setInterval(
                  () => {
                    graphql.graphql(
                      this.schema,
                      message_data.query,
                      message_data.rootValue,
                      message_data.contextValue,
                      message_data.variables,
                      message_data.operationName
                    ).then(function(response){
                      let message = response;
                      message.type = 'subscription_data';
                      message.id = sub_id;
                      connection.sendUTF(JSON.stringify(message));
                    }, function(err) {
                      let message = response;
                      message.type = 'subscription_data';
                      message.id = sub_id;
                      connection.sendUTF(JSON.stringify(message));
                    });
                  },
                  message_data.pollingInterval
                );
                message_data.pollingId = pollingId;
              }

              connection.subscriptions[sub_id] = message_data;
            }

          } else if (message_data.type === 'subscription_end') {
            const sub_id = message.data.id;
            clearInterval(connection.subscriptions[sub_id][pollingId]);
            delete connection.subscriptions[sub_id];
          }
        }
      });

      connection.on('close', function(reasonCode, description) {
        console.log(" Peer " + connection.remoteAddress + ' disconnected.');
      });
    });
  }
}
module.exports = Server;
<commit_msg>Removed gql import<commit_after>"use strict";
var http = require('http');
var graphql = require('graphql');
require('babel-register');
var WebSocketServer = require('websocket').server;
var graphql_tools = require('graphql-tools');
var graphql_validator = require('graphql/validation');
var graphql_execution = require('graphql/execution');

class Server {
  constructor(schema, httpServer) {
    this.schema = schema;
    //initialize http server

    //init and connect websocket server to http
    this.wsServer = new WebSocketServer({
      httpServer: httpServer,
      autoAcceptConnections: false
    });

    this.wsServer.on('request', (request) => {
      //accept connection
      var connection = request.accept('graphql-protocol', request.origin);
      connection.on('message', (message) => {
        let message_data = JSON.parse(message.utf8Data);
        if (! message_data.type) { //mutation message
          if (message_data.name && connection.triggers && connection.triggers[message_data.name]) {
            let triggered_subs = connection.triggers[message_data.name];
            triggered_subs.forEach((sub_id) => {
              let sub_data = connection.subscriptions[sub_id];
              graphql.graphql(
                this.schema,
                sub_data.query,
                sub_data.rootValue,
                sub_data.contextValue,
                sub_data.variables,
                sub_data.operationName
              ).then(function(response) {
                let message = response;
                message.type = 'subscription_data';
                message.id = sub_id;
                connection.sendUTF(JSON.stringify(message));
              }, function(err) {
                let message = response;
                message.type = 'subscription_data';
                message.id = sub_id;
                connection.sendUTF(JSON.stringify(message));
              });
            })
          }
        } else {
          if (message_data.type === 'subscription_start') {
            let syntax_errors = graphql_validator.validate(this.schema, graphql.parse(message_data.query));
            if (syntax_errors.length > 0) {
              let message = {
                type: 'subscription_fail',
                errors: syntax_errors,
                id: message_data.id,
              };
              connection.sendUTF(JSON.stringify(message));
            } else {
              const sub_id = message_data.id;
              if (!connection.subscriptions) {
                connection.subscriptions = {};
              }
              //set up trigger listeners
              if (message_data.triggers) {
                if (! connection.triggers) {
                  connection.triggers = {};
                }
                message_data.triggers.forEach(function(trigger) {
                  if (! connection.triggers[trigger]) {
                    connection.triggers[trigger] = [sub_id];
                  } else {
                    connection.triggers[trigger].push(sub_id);
                  }
                });
              }
              //set up polling message
              if (message_data.pollingInterval) {
                let pollingId = setInterval(
                  () => {
                    graphql.graphql(
                      this.schema,
                      message_data.query,
                      message_data.rootValue,
                      message_data.contextValue,
                      message_data.variables,
                      message_data.operationName
                    ).then(function(response){
                      let message = response;
                      message.type = 'subscription_data';
                      message.id = sub_id;
                      connection.sendUTF(JSON.stringify(message));
                    }, function(err) {
                      let message = response;
                      message.type = 'subscription_data';
                      message.id = sub_id;
                      connection.sendUTF(JSON.stringify(message));
                    });
                  },
                  message_data.pollingInterval
                );
                message_data.pollingId = pollingId;
              }

              connection.subscriptions[sub_id] = message_data;
            }

          } else if (message_data.type === 'subscription_end') {
            const sub_id = message.data.id;
            clearInterval(connection.subscriptions[sub_id][pollingId]);
            delete connection.subscriptions[sub_id];
          }
        }
      });

      connection.on('close', function(reasonCode, description) {
        console.log(" Peer " + connection.remoteAddress + ' disconnected.');
      });
    });
  }
}
module.exports = Server;
<|endoftext|>


<commit_before>'use strict';

module.exports = jest.fn();
<commit_msg>Chore: Remove unused file<commit_after><|endoftext|>


<commit_before>const express = require("express");
const app = express();
const path = require("path");
const port = process.env.PORT || 8080;
const Views = require("./database/view-model");
const dbconnection = require("./database/dbconnect");
const Music = require("./database/music-model");
const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();
const Subs = require("./database/subscribers-model");
const Isemail = require("isemail");
const User = require("./database/user-model");
const passport = require("passport");
const Strategy = require("passport-local").Strategy;
const Events = require("./database/events-model");
const nodemailer = require("nodemailer");
const React = require("react");
const ReactDOM = require("react-dom");
const {match, RouterContext} = require("react-router");
const {renderToString} = require("react-dom/server");
require('babel-core/register')({
    presets: ['es2015', 'react', "stage-0"]
});
const routes = require("./routes");

dbconnection();
require("dotenv").config({path: "./src/paypal.env"});

app.set("view engine", "ejs")
app.use("/static", express.static(path.join(__dirname, "static")));
app.use(require('cookie-parser')());
app.use(jsonParser);

passport.use(new Strategy(
  function(username, password, done) {
      console.dir(done);
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));
let transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: process.env.GUSER,
        pass: process.env.GPASS
    }
});

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, cb) {
  cb(null, user.id);
});

passport.deserializeUser(function(id, cb) {
  User.findById(id, function (err, user) {
    if (err) { return cb(err); }
    cb(null, user);
  });
});

/*app.get("/", (req, res) => {
    res.sendFile(__dirname + "/static/index.html");
});*/

app.get("/views", (req, res) => {
    Views.findOne({}, (err, viewArr) => {
        if (!viewArr) {
            let view = new Views({
                views: 0,
                ip: []
            });
            view.save((err) => {
                if (err) {
                    throw err;
                }
            });
        }
        else {
            if (viewArr.ip.indexOf(req.ip) !== -1) {
                res.json({data: false});
            }
            else {
                viewArr.ip.push(req.ip);
                viewArr.views++;
                viewArr.markModified("ip");
                viewArr.save();
                res.json({data: viewArr.views});
            }
        }
    })
});

app.get("/render-music", (req, res) => {
    Music.find({}, (err, music) => {
        res.json({data: music});
    })
})

app.post("/video-views", jsonParser, (req, res) => {
    Music.findOne({title: req.body.data.name}, (err, obj) => {
        if (obj.views.ip.indexOf(req.ip) === -1) {
            obj.views.num++;
            obj.views.ip.push(req.ip);
            obj.markModified("views");
            obj.save();
            res.json({data: obj});
        }
        else {
            res.json({data: false})
        }
    });
});

app.post("/search", jsonParser, (req, res) => {
    let text = req.body.text;
    Music.find({}, (err, list) => {
        let newList;
        newList = list.filter((ele) => {
            return ele.title.toLowerCase().indexOf(text) !== -1 || ele.genre.toLowerCase().indexOf(text) !== -1 || ele.artName.toLowerCase().indexOf(text) !== -1;
        });
        res.json({data: newList});
    });
});

app.get("/get-id", (req, res) => {
    res.json({data: {prod: process.env.PAYPAL_ID, sandbox: process.env.PAYPAL_SANDBOX}});
});

app.post("/subscribe", jsonParser, (req, res) => {
    Subs.findOne({}, (err, subs) => {
        if (!subs) {
            let subsList = new Subs({
                subscribers: []
            });
            subsList.save();
        }
        else {
            if (subs.subscribers.indexOf(req.body.email) === -1) {
                if (Isemail.validate(req.body.email)) {
                    subs.subscribers.push(req.body.email);
                    subs.markModified("subscribers");
                    subs.save();
                    res.json({data: true});
                }
                else {
                    res.json({data: "invalid"});
                }
            }
            else {
                res.json({data: false})
           }
        }
    });
});

app.post("/login", passport.authenticate("local"), (req, res, next) => {
    console.log("success");
    res.json({data: "success"});
});

app.post("/update-music", (req, res) => {
    let thumbnail = `https://img.youtube.com/vi/${req.body.id}/hqdefault.jpg`
    let date = new Date();
    let current = date.toString().slice(0, 15);
    let MusicList = new Music({
        title: req.body.title,
        artName: req.body.artist,
        views: {
            num: 0,
            ip: []
        },
        genre: req.body.genre,
        date: current,
        price: req.body.price,
        thumbnail: thumbnail,
        videoId: req.body.id
    });
    MusicList.save((err) => {
        if (err) {
            throw err;
        }
        res.json({data: "success"});
    })
});

app.post("/events-update", (req, res) => {
    let eventsList = new Events({
        location: req.body.location,
        description: req.body.description
    });
    eventsList.save();
    Subs.findOne({}, (err, subs) => {
        if (err) {
            throw err;
        }
        subs.subscribers.forEach((email) => {
            let mailOptions = {
                from: "<" + process.env.GUSER + "@gmail.com>", // sender address
                to: email, // list of receivers
                subject: "RRProductions Events Update", // Subject line
                text: req.body.description, // plain text body
                html: "
" + req.body.description + "
" // html body
            };
            transporter.sendMail(mailOptions, (error, info) => {
                if (error) {
                    return console.log(error);
                }
            });
        })
        res.json({data: "success"});
    })
});

app.get("/logout", (req, res) => {
    req.logout();
    res.redirect("/");
});

app.post("/delete", (req, res) => {
    Music.find({}, (err, musicList) => {
        if (err) {
            throw err;
        }
        let list = musicList.slice(0);
        list.splice(req.body.id, 1);
        musicList[req.body.id].remove();
        res.json({data: list});
    })
})

app.get('*', (req, res) => {
  match(
    { routes, location: req.url },
    (err, redirectLocation, renderProps) => {
      if (err) {
        return res.status(500).send(err.message);
      }
      if (redirectLocation) {
        return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
      }
      let markup;
      if (renderProps) {
        markup = renderToString(React.createElement(RouterContext, renderProps));
      }
      else {
        //markup = renderToString(<NotFoundPage/>);
        res.status(404);
      }
      return res.render("index", {markup});
    }
  );
});

app.listen(port, () => {
    console.log(`Listening on port ${port}`);
});<commit_msg>added new logic for view count<commit_after>const express = require("express");
const app = express();
const path = require("path");
const port = process.env.PORT || 8080;
const Views = require("./database/view-model");
const dbconnection = require("./database/dbconnect");
const Music = require("./database/music-model");
const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();
const Subs = require("./database/subscribers-model");
const Isemail = require("isemail");
const User = require("./database/user-model");
const passport = require("passport");
const Strategy = require("passport-local").Strategy;
const Events = require("./database/events-model");
const nodemailer = require("nodemailer");
const React = require("react");
const ReactDOM = require("react-dom");
const {match, RouterContext} = require("react-router");
const {renderToString} = require("react-dom/server");
require('babel-core/register')({
    presets: ['es2015', 'react', "stage-0"]
});
const routes = require("./routes");

dbconnection();
require("dotenv").config({path: "./src/paypal.env"});

app.set("view engine", "ejs")
app.use("/static", express.static(path.join(__dirname, "static")));
app.use(require('cookie-parser')());
app.use(jsonParser);

passport.use(new Strategy(
  function(username, password, done) {
      console.dir(done);
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));
let transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: process.env.GUSER,
        pass: process.env.GPASS
    }
});

app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, cb) {
  cb(null, user.id);
});

passport.deserializeUser(function(id, cb) {
  User.findById(id, function (err, user) {
    if (err) { return cb(err); }
    cb(null, user);
  });
});

/*app.get("/", (req, res) => {
    res.sendFile(__dirname + "/static/index.html");
});*/

app.get("/views", (req, res) => {
    Views.findOne({}, (err, viewArr) => {
        if (!viewArr) {
            let view = new Views({
                views: 0
            });
            view.save((err) => {
                if (err) {
                    throw err;
                }
                res.json({data: 0});
            });
        }
        else {
            viewArr.views++;
            viewArr.save();
            res.json({data: viewArr.views});
        }
    })
});

app.get("/render-music", (req, res) => {
    Music.find({}, (err, music) => {
        res.json({data: music});
    })
})

app.post("/video-views", jsonParser, (req, res) => {
    Music.findOne({title: req.body.data.name}, (err, obj) => {
        if (obj.views.ip.indexOf(req.ip) === -1) {
            obj.views.num++;
            obj.views.ip.push(req.ip);
            obj.markModified("views");
            obj.save();
            res.json({data: obj});
        }
        else {
            res.json({data: false})
        }
    });
});

app.post("/search", jsonParser, (req, res) => {
    let text = req.body.text;
    Music.find({}, (err, list) => {
        let newList;
        newList = list.filter((ele) => {
            return ele.title.toLowerCase().indexOf(text) !== -1 || ele.genre.toLowerCase().indexOf(text) !== -1 || ele.artName.toLowerCase().indexOf(text) !== -1;
        });
        res.json({data: newList});
    });
});

app.get("/get-id", (req, res) => {
    res.json({data: {prod: process.env.PAYPAL_ID, sandbox: process.env.PAYPAL_SANDBOX}});
});

app.post("/subscribe", jsonParser, (req, res) => {
    Subs.findOne({}, (err, subs) => {
        if (!subs) {
            let subsList = new Subs({
                subscribers: []
            });
            subsList.save();
        }
        else {
            if (subs.subscribers.indexOf(req.body.email) === -1) {
                if (Isemail.validate(req.body.email)) {
                    subs.subscribers.push(req.body.email);
                    subs.markModified("subscribers");
                    subs.save();
                    res.json({data: true});
                }
                else {
                    res.json({data: "invalid"});
                }
            }
            else {
                res.json({data: false})
           }
        }
    });
});

app.post("/login", passport.authenticate("local"), (req, res, next) => {
    console.log("success");
    res.json({data: "success"});
});

app.post("/update-music", (req, res) => {
    let thumbnail = `https://img.youtube.com/vi/${req.body.id}/hqdefault.jpg`
    let date = new Date();
    let current = date.toString().slice(0, 15);
    let MusicList = new Music({
        title: req.body.title,
        artName: req.body.artist,
        views: {
            num: 0,
            ip: []
        },
        genre: req.body.genre,
        date: current,
        price: req.body.price,
        thumbnail: thumbnail,
        videoId: req.body.id
    });
    MusicList.save((err) => {
        if (err) {
            throw err;
        }
        res.json({data: "success"});
    })
});

app.post("/events-update", (req, res) => {
    let eventsList = new Events({
        location: req.body.location,
        description: req.body.description
    });
    eventsList.save();
    Subs.findOne({}, (err, subs) => {
        if (err) {
            throw err;
        }
        subs.subscribers.forEach((email) => {
            let mailOptions = {
                from: "<" + process.env.GUSER + "@gmail.com>", // sender address
                to: email, // list of receivers
                subject: "RRProductions Events Update", // Subject line
                text: req.body.description, // plain text body
                html: "
" + req.body.description + "
" // html body
            };
            transporter.sendMail(mailOptions, (error, info) => {
                if (error) {
                    return console.log(error);
                }
            });
        })
        res.json({data: "success"});
    })
});

app.get("/logout", (req, res) => {
    req.logout();
    res.redirect("/");
});

app.post("/delete", (req, res) => {
    Music.find({}, (err, musicList) => {
        if (err) {
            throw err;
        }
        let list = musicList.slice(0);
        list.splice(req.body.id, 1);
        musicList[req.body.id].remove();
        res.json({data: list});
    })
})

app.get('*', (req, res) => {
  match(
    { routes, location: req.url },
    (err, redirectLocation, renderProps) => {
      if (err) {
        return res.status(500).send(err.message);
      }
      if (redirectLocation) {
        return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
      }
      let markup;
      if (renderProps) {
        markup = renderToString(React.createElement(RouterContext, renderProps));
      }
      else {
        //markup = renderToString(<NotFoundPage/>);
        res.status(404);
      }
      return res.render("index", {markup});
    }
  );
});

app.listen(port, () => {
    console.log(`Listening on port ${port}`);
});<|endoftext|>


<commit_before>'use strict';

/**
 * Methods to aid landscape integration.
 *
 * @module views
 * @submodule views.landscape
 */

YUI.add('juju-landscape', function(Y) {
  var views = Y.namespace('juju.views');

  /**
   * Ensure a trailing slash on a string.
   * @method slash
   * @return {String} string with trailing slash.
   **/
  function slash(u) {
    if (u.lastIndexOf('/') !== u.length - 1) {
      u += '/';
    }
    return u;
  }

  /**
   * Collect annotation data about landscape integration
   * for easy consumption.
   *
   * For now this inspects the current database and
   * computes data.
   *
   * TODO: take set of [a/c] | [d] models and do
   * incremental updates.
   * @class Landscape
   **/
  function Landscape() {
    Landscape.superclass.constructor.apply(this, arguments);
  }

  views.Landscape = Y.extend(Landscape, Y.Base, {
    /**
     * This tells `Y.Base` that it should create ad-hoc attributes for config
     * properties passed to Model's constructor. This makes it possible to
     * instantiate a model and set a bunch of attributes without having to
     * subclass `Y.Model` and declare all those attributes first.
     *
     * @property _allowAdHocAttrs
     * @type {Boolean}
     * @default true
     * @protected
     * @since 3.5.0
     **/
    _allowAdHocAttrs: true,

    /**
     * Collect annotation information from units to services and from
     * services to environemnt.
     *
     * @method update
     * @chainable
     ***/
    update: function() {
      // Roll up information from the unit level
      // to the service level.
      var db = this.get('db');
      var env = db.environment;

      // Rollup each unit annotation name applying it
      // service and environment.
      //
      // Iterate each landscape annotation.
      Y.each([
              'landscape-security-upgrades',
              'landscape-needs-reboot'],
      function(annotationName) {
        // Iterate each service, we do this so we can rollup
        // when no unit in the services set has the annotation.
        // This is needed to be able to detect and clear annotations
        // at the service/environment level when the unit level flags
        // are cleared.
        // The inner loop uses Y.some allowing it to stop on the
        // first true value.
        var serviceFlagged = false;
        Y.each(db.services, function(service) {
          /*jslint bitwise: true*/
          // The above lint is needed to allow a |= expression
          // to pass the linter.
          serviceFlagged |= service[annotationName] = Y.some(
              db.units.get_units_for_service(service),
              function(unit) {
                var annotations = unit.annotations;
                return Boolean(
                    annotations && annotations[annotationName]);
              });
        });
        env[annotationName] = Boolean(serviceFlagged);
      });
      return this;
    },

    /**
     * Get the landscape url for a given service with respect to
     * the models in the db we've been passed. This depends on
     * the 'db' attribute of this object being set.
     *
     * @method getLandscapeURL
     * @param {Model} model to get URL for.
     * @param {String} intent (optional) can be 'security' or 'reboot'.
     * @return {String} URL to access model entity in landscape.
     **/
    getLandscapeURL: function(model, intent) {
      var env = this.get('db').environment.get('annotations');
      var url = env['landscape-url'];

      if (!url) {
        // If this environment annotation doesn't exist
        // we cannot generate URLs.
        return undefined;
      }

      url += env['landscape-computers'];
      if (model.name === 'service') {
        var computers = model.get('annotations')['landscape-computers'];
        if (!computers) {
          console.warn('Service missing the landscape-computers annotation!');
          return undefined;
        }
        url += slash(computers);
      } else if (model.name === 'serviceUnit') {
        var computer = model.annotations['landscape-computer'];
        if (!computer) {
          console.warn('Unit missing the landscape-computer annotation!');
          return undefined;
        }
        url += slash(computer);
      }

      if (!intent) {
        return slash(url);
      } else if (intent === 'reboot') {
        return url + env['landscape-reboot-alert-url'];
      } else if (intent === 'security') {
        return url + env['landscape-security-alert-url'];
      }
    },

    /**
     * Given a model and an intent return an object
     * with the properties of a badge. If the object
     * shouldn't have a badge undefined is returned.
     *
     * @method getLandscapeBadge
     * @param {Model} model to render badge for.
     * @param {String} intent 'security' || 'reboot'.
     * @param {String} hint image postfix to use ex _round.
     * @return {Object} {link: {String}, sprite:{String}}.
     **/
    getLandscapeBadge: function(model, intent, hint) {
      var badge = {};
      var props = model;
      var sprite = 'landscape_';

      if (model.name === 'serviceUnit' || !model.name) {
        props = model.annotations;
      }
      if (!props) {
        return undefined;
      }

      badge.link = this.getLandscapeURL(model, intent);
      if (intent === 'reboot') {
        if (!props['landscape-needs-reboot']) {
          return undefined;
        }
        sprite += 'restart';

      } else if (intent === 'security') {
        if (!props['landscape-security-upgrades']) {
          return undefined;
        }
        sprite += intent;
      }

      if (hint) {
        sprite += '_' + hint;
      }

      badge.sprite = sprite;
      return badge;
    }
  });

}, '0.1.0', {
  requires: [
    'juju-models',
    'base'
  ]
});
<commit_msg>Responding to review comments.<commit_after>'use strict';

/**
 * Methods to aid landscape integration.
 *
 * @module views
 * @submodule views.landscape
 */

YUI.add('juju-landscape', function(Y) {
  var views = Y.namespace('juju.views');

  /**
   * Ensure a trailing slash on a string.
   * @method slash
   * @return {String} string with trailing slash.
   **/
  function slash(u) {
    if (u.lastIndexOf('/') !== u.length - 1) {
      u += '/';
    }
    return u;
  }

  /**
   * Collect annotation data about landscape integration
   * for easy consumption.
   *
   * For now this inspects the current database and
   * computes data.
   *
   * TODO: take set of [a/c] | [d] models and do
   * incremental updates.
   * @class Landscape
   **/
  function Landscape() {
    Landscape.superclass.constructor.apply(this, arguments);
  }

  views.Landscape = Y.extend(Landscape, Y.Base, {
    /**
     * This tells `Y.Base` that it should create ad-hoc attributes for config
     * properties passed to Model's constructor. This makes it possible to
     * instantiate a model and set a bunch of attributes without having to
     * subclass `Y.Model` and declare all those attributes first.
     *
     * @property _allowAdHocAttrs
     * @type {Boolean}
     * @default true
     * @protected
     * @since 3.5.0
     **/
    _allowAdHocAttrs: true,

    /**
     * Collect annotation information from units to services and from
     * services to environemnt.
     *
     * @method update
     * @chainable
     ***/
    update: function() {
      // Roll up information from the unit level
      // to the service level.
      var db = this.get('db');
      var env = db.environment;

      // Rollup each unit annotation name applying it
      // service and environment.
      //
      // Iterate each landscape annotation.
      Y.each([
              'landscape-security-upgrades',
              'landscape-needs-reboot'],
      function(annotationName) {
        // Iterate each service, we do this so we can rollup
        // when no unit in the services set has the annotation.
        // This is needed to be able to detect and clear annotations
        // at the service/environment level when the unit level flags
        // are cleared.
        // The inner loop uses Y.some allowing it to stop on the
        // first true value.
        var serviceFlagged = false;
        Y.each(db.services, function(service) {
          /*jslint bitwise: true*/
          // The above lint is needed to allow a |= expression
          // to pass the linter.
          serviceFlagged |= service[annotationName] = Y.some(
              db.units.get_units_for_service(service),
              function(unit) {
                var annotations = unit.annotations;
                return Boolean(
                    annotations && annotations[annotationName]);
              });
        });
        env[annotationName] = Boolean(serviceFlagged);
      });
      return this;
    },

    /**
     * Get the landscape url for a given service with respect to
     * the models in the db we've been passed. This depends on
     * the 'db' attribute of this object being set.
     *
     * @method getLandscapeURL
     * @param {Model} model to get URL for.
     * @param {String} intent (optional) can be 'security' or 'reboot'.
     * @return {String} URL to access model entity in landscape.
     **/
    getLandscapeURL: function(model, intent) {
      var env = this.get('db').environment.get('annotations');
      var url = env['landscape-url'];
      var modelAnnotation;

      if (!url) {
        // If this environment annotation doesn't exist
        // we cannot generate URLs.
        return undefined;
      }

      url += env['landscape-computers'];
      if (model.name === 'service') {
        modelAnnotation = model.get('annotations')['landscape-computers'];
        if (!modelAnnotation) {
          console.warn('Service missing the landscape-computers annotation!');
          return undefined;
        }
        url += slash(modelAnnotation);
      } else if (model.name === 'serviceUnit') {
        modelAnnotation = model.annotations['landscape-computer'];
        if (!modelAnnotation) {
          console.warn('Unit missing the landscape-computer annotation!');
          return undefined;
        }
        url += slash(modelAnnotation);
      }

      if (!intent) {
        return slash(url);
      } else if (intent === 'reboot') {
        return url + env['landscape-reboot-alert-url'];
      } else if (intent === 'security') {
        return url + env['landscape-security-alert-url'];
      }
    },

    /**
     * Given a model and an intent return an object
     * with the properties of a badge. If the object
     * shouldn't have a badge undefined is returned.
     *
     * @method getLandscapeBadge
     * @param {Model} model to render badge for.
     * @param {String} intent 'security' || 'reboot'.
     * @param {String} hint image postfix to use ex _round.
     * @return {Object} {link: {String}, sprite:{String}}.
     **/
    getLandscapeBadge: function(model, intent, hint) {
      var badge = {};
      var props = model;
      var sprite = 'landscape_';

      if (model.name === 'serviceUnit' || !model.name) {
        props = model.annotations;
      }
      if (!props) {
        return undefined;
      }

      badge.link = this.getLandscapeURL(model, intent);
      if (intent === 'reboot') {
        if (!props['landscape-needs-reboot']) {
          return undefined;
        }
        sprite += 'restart';

      } else if (intent === 'security') {
        if (!props['landscape-security-upgrades']) {
          return undefined;
        }
        sprite += intent;
      }

      if (hint) {
        sprite += '_' + hint;
      }

      badge.sprite = sprite;
      return badge;
    }
  });

}, '0.1.0', {
  requires: [
    'juju-models',
    'base'
  ]
});
<|endoftext|>


<commit_before>import {
    negate, isNil, isString, mapValues, extend, forIn, isFunction, pick, isBoolean,
} from 'lodash';
import moment from 'moment'
import isEmail from 'validator/lib/isEmail';
import Formous from 'formous';

import { isBlank } from './util';

function buildTest(defaultOptions, defaultMessage, test) {
    const { test: defaultTest, critical, message, name: _, ...otherOptions } = defaultOptions;
    return extend({
        tests: [{
            test: test || defaultTest,
            critical: isNil(critical) ? true : critical,
            failProps: {
                errorText: message || defaultMessage || 'is invalid',
            },
        }],
    }, otherOptions);
}

export function hasLength(len) {
    return options =>
        buildTest(options, `must be of length ${len}`, s => s.length >= len);
}

const NUMBER = /^[+-]?(\d*\.)?\d+$/;

export function numberValue(options = {}) {
    return buildTest(options, 'must be a number', v => NUMBER.test(v));
}

export function stringValue(options = {}) {
    return buildTest(options, 'must be a string', isString);
}

export function validEmail(options = {}) {
    return buildTest(options, 'must be a valid email', email => isEmail(email || ''));
}

export function booleanValue(options = {}) {
    return buildTest(options, 'must be true or false', isBoolean);
}

export function nonBlank(options = {}) {
    return buildTest(options, 'is required', negate(isBlank));
}

export function dateValue(options = {}) {
    return buildTest(options, 'must be valid date', v => moment(v, options.format).isValid());
}

export function validation(options = {}) {
    return buildTest(options, 'is required', options.test);
}

export function buildValidations(options = {}) {
    return mapValues(options, (v, name) => (isFunction(v) ? v({ name }) : v));
}

export function testWith(fn, msg='is invalid') {
    return buildTest({}, msg, fn);
}

const passEverything = () => true;

export function anyValue() {
    return buildTest({}, '', passEverything);
}

export function setFieldValue(field, value) {
    if (!field.events) { return; }
    extend(field, { cid: Math.random(), value });
    field.events.onChange({ target: { value: isNil(value) ? '' : value } });
}

export function setFieldValues(fields, values) {
    forIn(fields, (field, name) => {
        setFieldValue(field, values[name]);
    });
}

export function persistFieldValues(fields, model) {
    forIn(fields, (field, name) => (model[name] = field.value)); // eslint-disable-line
    return Promise.resolve(model);
}

export function addFormFieldValidations(component, ...staticProps) {
    const options = { fields: buildValidations(component.formFields) };
    return extend(Formous(options)(component), pick(component, staticProps));
}
<commit_msg>set after model is saved<commit_after>import {
    negate, isNil, isString, mapValues, extend, forIn, isFunction, pick, isBoolean, get, keys,
} from 'lodash';
import moment from 'moment'
import isEmail from 'validator/lib/isEmail';
import Formous from 'formous';
import { when } from 'mobx';
import { isBlank } from './util';

function buildTest(defaultOptions, defaultMessage, test) {
    const { test: defaultTest, critical, message, name: _, ...otherOptions } = defaultOptions;
    return extend({
        tests: [{
            test: test || defaultTest,
            critical: isNil(critical) ? true : critical,
            failProps: {
                errorText: message || defaultMessage || 'is invalid',
            },
        }],
    }, otherOptions);
}

export function hasLength(len) {
    return options =>
        buildTest(options, `must be of length ${len}`, s => s.length >= len);
}

const NUMBER = /^[+-]?(\d*\.)?\d+$/;

export function numberValue(options = {}) {
    return buildTest(options, 'must be a number', v => NUMBER.test(v));
}

export function stringValue(options = {}) {
    return buildTest(options, 'must be a string', isString);
}

export function validEmail(options = {}) {
    return buildTest(options, 'must be a valid email', email => isEmail(email || ''));
}

export function booleanValue(options = {}) {
    return buildTest(options, 'must be true or false', isBoolean);
}

export function nonBlank(options = {}) {
    return buildTest(options, 'is required', negate(isBlank));
}

export function dateValue(options = {}) {
    return buildTest(options, 'must be valid date', v => moment(v, options.format).isValid());
}

export function validation(options = {}) {
    return buildTest(options, 'is required', options.test);
}

export function buildValidations(options = {}) {
    return mapValues(options, (v, name) => (isFunction(v) ? v({ name }) : v));
}

export function testWith(fn, msg='is invalid') {
    return buildTest({}, msg, fn);
}

const passEverything = () => true;

export function anyValue() {
    return buildTest({}, '', passEverything);
}

export function setFieldValue(field, value) {
    if (!field.events) { return; }

    field.events.onChange({ target: { value: isNil(value) ? '' : value } });
}

export function setFieldValues(props, values) {
    props.setFieldValues(pick(values, keys(props.fields)));
}

export function setFieldsFromModel(props, model) {
    if (get(model, 'syncInProgress.isFetch')) {
        when(
            () => !get(model, 'syncInProgress.isFetch'),
            () => setFieldValues(props, model),
        );
    } else {
        setFieldValues(props, model);
    }
}

export function persistFieldValues(fields, model) {
    forIn(fields, (field, name) => (model[name] = field.value)); // eslint-disable-line
    return Promise.resolve(model);
}

export function addFormFieldValidations(component, ...staticProps) {
    const options = { fields: buildValidations(component.formFields) };
    return extend(Formous(options)(component), pick(component, staticProps));
}
<|endoftext|>


<commit_before>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import 'babel-polyfill';
import path from 'path';
import express from 'express';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import expressJwt from 'express-jwt';
import expressGraphQL from 'express-graphql';
import jwt from 'jsonwebtoken';
import ReactDOM from 'react-dom/server';
import PrettyError from 'pretty-error';
import passport from './core/passport';
import session from 'express-session';
import schema from './data/schema';
import Router from './routes';
import assets from './assets';
import { port, auth, analytics } from './config';

import PocketStrategy from 'passport-pocket';
import dotenv from 'dotenv';

import pocketClient from './core/pocketClient';

const server = global.server = express();

// Env setup
var envPath = path.join(__dirname, '..', ".env");
dotenv.config({ path:envPath });

const pocketConsumerKey = process.env.POCKET_CONSUMER_KEY;

//
// Tell any CSS tooling (such as Material UI) to use all vendor prefixes if the
// user agent is not known.
// -----------------------------------------------------------------------------
global.navigator = global.navigator || {};
global.navigator.userAgent = global.navigator.userAgent || 'all';

//
// Register Node.js middleware
// -----------------------------------------------------------------------------
server.use(express.static(path.join(__dirname, 'public')));
server.use(cookieParser());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(bodyParser.json());

// required for passport
server.use(session({ secret: 'SECRET' })); // session secret
server.use(passport.initialize());
server.use(passport.session()); // persistent login sessions

// Passport Set up
// Passport Set serializers
passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

var pocketStrategy = new PocketStrategy({
  consumerKey: pocketConsumerKey,
  callbackURL: "http://localhost:3001/auth/pocket/callback"
}, function (username, accessToken, done) {
  process.nextTick(function () {
    return done(null, {
      username: username,
      accessToken: accessToken,
    });
  });
}
);

passport.use(pocketStrategy);

// Passport routes for express
server.get('/auth/pocket', passport.authenticate('pocket'),
  function (req, res) {
    // The request will be redirected to Pocket for authentication, so this
    // function will not be called.
  });

server.get('/auth/pocket/callback', passport.authenticate('pocket', { failureRedirect: '/login' }),
  function (req, res) {
    res.redirect('/');
  });

//
// Authentication
// -----------------------------------------------------------------------------
server.use(expressJwt({
  secret: auth.jwt.secret,
  credentialsRequired: false,
  /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
  getToken: req => req.cookies.id_token,
  /* jscs:enable requireCamelCaseOrUpperCaseIdentifiers */
}));

server.get('/login/facebook',
  passport.authenticate('facebook', { scope: ['email', 'user_location'], session: false })
);
server.get('/login/facebook/return',
  passport.authenticate('facebook', { failureRedirect: '/login', session: false }),
  (req, res) => {
    const expiresIn = 60 * 60 * 24 * 180; // 180 days
    const token = jwt.sign(req.user, auth.jwt.secret, { expiresIn });
    res.cookie('id_token', token, { maxAge: 1000 * expiresIn, httpOnly: true });
    res.redirect('/');
  }
);

//
// Register API middleware
// -----------------------------------------------------------------------------
server.use('/graphql', expressGraphQL(req => ({
  schema,
  graphiql: true,
  rootValue: { request: req },
  pretty: process.env.NODE_ENV !== 'production',
})));

//
// Register server-side rendering middleware
// -----------------------------------------------------------------------------
server.get('*', async (req, res, next) => {
  try {
    let statusCode = 200;
    const template = require('./views/index.jade');
    const data = { title: '', description: '', css: '', body: '', entry: assets.main.js };

    if (process.env.NODE_ENV === 'production') {
      data.trackingId = analytics.google.trackingId;
    }

    const css = [];
    const context = {
      insertCss: styles => css.push(styles._getCss()),
      onSetTitle: value => (data.title = value),
      onSetMeta: (key, value) => (data[key] = value),
      onPageNotFound: () => (statusCode = 404),
    };

    await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
      data.body = ReactDOM.renderToString(component);
      data.css = css.join('');
    });

    var user = res.req.user;
    pocketClient.getArchive(pocketConsumerKey, user.accessToken);

    res.status(statusCode);
    res.send(template(data));
  } catch (err) {
    next(err);
  }
});

//
// Error handling
// -----------------------------------------------------------------------------
const pe = new PrettyError();
pe.skipNodeFiles();
pe.skipPackage('express');

server.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  console.log(pe.render(err)); // eslint-disable-line no-console
  const template = require('./views/error.jade');
  const statusCode = err.status || 500;
  res.status(statusCode);
  res.send(template({
    message: err.message,
    stack: process.env.NODE_ENV === 'production' ? '' : err.stack,
  }));
});

//
// Launch the server
// -----------------------------------------------------------------------------
server.listen(port, () => {
  /* eslint-disable no-console */
  console.log(`The server is running at http://localhost:${port}/`);
});
<commit_msg>Fixing unauthorized bug.<commit_after>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import 'babel-polyfill';
import path from 'path';
import express from 'express';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import expressJwt from 'express-jwt';
import expressGraphQL from 'express-graphql';
import jwt from 'jsonwebtoken';
import ReactDOM from 'react-dom/server';
import PrettyError from 'pretty-error';
import passport from './core/passport';
import session from 'express-session';
import schema from './data/schema';
import Router from './routes';
import assets from './assets';
import { port, auth, analytics } from './config';

import PocketStrategy from 'passport-pocket';
import dotenv from 'dotenv';

import pocketClient from './core/pocketClient';

const server = global.server = express();

// Env setup
var envPath = path.join(__dirname, '..', ".env");
dotenv.config({ path:envPath });

const pocketConsumerKey = process.env.POCKET_CONSUMER_KEY;

//
// Tell any CSS tooling (such as Material UI) to use all vendor prefixes if the
// user agent is not known.
// -----------------------------------------------------------------------------
global.navigator = global.navigator || {};
global.navigator.userAgent = global.navigator.userAgent || 'all';

//
// Register Node.js middleware
// -----------------------------------------------------------------------------
server.use(express.static(path.join(__dirname, 'public')));
server.use(cookieParser());
server.use(bodyParser.urlencoded({ extended: true }));
server.use(bodyParser.json());

// required for passport
server.use(session({ secret: 'SECRET' })); // session secret
server.use(passport.initialize());
server.use(passport.session()); // persistent login sessions

// Passport Set up
// Passport Set serializers
passport.serializeUser(function (user, done) {
  done(null, user);
});

passport.deserializeUser(function (obj, done) {
  done(null, obj);
});

var pocketStrategy = new PocketStrategy({
  consumerKey: pocketConsumerKey,
  callbackURL: "http://localhost:3001/auth/pocket/callback"
}, function (username, accessToken, done) {
  process.nextTick(function () {
    return done(null, {
      username: username,
      accessToken: accessToken,
    });
  });
}
);

passport.use(pocketStrategy);

// Passport routes for express
server.get('/auth/pocket', passport.authenticate('pocket'),
  function (req, res) {
    // The request will be redirected to Pocket for authentication, so this
    // function will not be called.
  });

server.get('/auth/pocket/callback', passport.authenticate('pocket', { failureRedirect: '/login' }),
  function (req, res) {
    res.redirect('/');
  });

//
// Authentication
// -----------------------------------------------------------------------------
server.use(expressJwt({
  secret: auth.jwt.secret,
  credentialsRequired: false,
  /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
  getToken: req => req.cookies.id_token,
  /* jscs:enable requireCamelCaseOrUpperCaseIdentifiers */
}));

server.get('/login/facebook',
  passport.authenticate('facebook', { scope: ['email', 'user_location'], session: false })
);
server.get('/login/facebook/return',
  passport.authenticate('facebook', { failureRedirect: '/login', session: false }),
  (req, res) => {
    const expiresIn = 60 * 60 * 24 * 180; // 180 days
    const token = jwt.sign(req.user, auth.jwt.secret, { expiresIn });
    res.cookie('id_token', token, { maxAge: 1000 * expiresIn, httpOnly: true });
    res.redirect('/');
  }
);

//
// Register API middleware
// -----------------------------------------------------------------------------
server.use('/graphql', expressGraphQL(req => ({
  schema,
  graphiql: true,
  rootValue: { request: req },
  pretty: process.env.NODE_ENV !== 'production',
})));

//
// Register server-side rendering middleware
// -----------------------------------------------------------------------------
server.get('*', async (req, res, next) => {
  try {
    let statusCode = 200;
    const template = require('./views/index.jade');
    const data = { title: '', description: '', css: '', body: '', entry: assets.main.js };

    if (process.env.NODE_ENV === 'production') {
      data.trackingId = analytics.google.trackingId;
    }

    const css = [];
    const context = {
      insertCss: styles => css.push(styles._getCss()),
      onSetTitle: value => (data.title = value),
      onSetMeta: (key, value) => (data[key] = value),
      onPageNotFound: () => (statusCode = 404),
    };

    await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
      data.body = ReactDOM.renderToString(component);
      data.css = css.join('');
    });

    var user = res.req.user;

    if (user == null) {
      res.status(401);
      res.send(template({body:"Unauthorized"}));
      return;
    }

    pocketClient.getArchive(pocketConsumerKey, user.accessToken);

    res.status(statusCode);
    res.send(template(data));
  } catch (err) {
    next(err);
  }
});

//
// Error handling
// -----------------------------------------------------------------------------
const pe = new PrettyError();
pe.skipNodeFiles();
pe.skipPackage('express');

server.use((err, req, res, next) => { // eslint-disable-line no-unused-vars
  console.log(pe.render(err)); // eslint-disable-line no-console
  const template = require('./views/error.jade');
  const statusCode = err.status || 500;
  res.status(statusCode);
  res.send(template({
    message: err.message,
    stack: process.env.NODE_ENV === 'production' ? '' : err.stack,
  }));
});

//
// Launch the server
// -----------------------------------------------------------------------------
server.listen(port, () => {
  /* eslint-disable no-console */
  console.log(`The server is running at http://localhost:${port}/`);
});
<|endoftext|>


<commit_before>/**
 * websocket server that recieves match data as it arrives and checks if
 * any connected clients are subscribed to match properties.
 **/
const config = require('../config');
const redis = require('redis');
const WebSocket = require('ws');
const uuidV1 = require('uuid/v4');

const subTypes = ['player', 'team', 'league'];

const wss = new WebSocket.Server({
  port: config.WEBSOCKET_PORT,
});
const subclients = new Map();

// create a different redis client to subscribe to matches with
console.log('[SOCKET] connecting %s', config.REDIS_URL);
const redisClient = redis.createClient(config.REDIS_URL, {
  detect_buffers: true,
});
redisClient.on('error', (err) => {
  console.error(err);
  process.exit(1);
});

class Subclient {
  constructor(ws, uuid) {
    this._ws = ws;
    this._uuid = uuid;
    this._subscriptions = {
      player: [],
      team: [],
      league: [],
    };
  }

  get ws() { return this._ws; }
  get uuid() { return this._uuid; }
  get player() { return this._subscriptions.player; }
  get team() { return this._subscriptions.team; }
  get league() { return this._subscriptions.league; }
  get subscriptions() { return this._subscriptions; }

  // send data to this websocket
  send(data, nonce) {
    data.nonce = nonce || null;
    this._ws.send(JSON.stringify(data), (err) => {
      if (err) {
        console.error(`[SOCKET] err sending to ws ${this._uuid}`);
        console.error(err);
      }
    });
  }

  // given a match or partial match,
  // check if this websocket is subscribed to any of the paramaters.
  checkMatch(match, origin) {
    const found = {
      matches: 0,
      player: [],
      team: [],
      league: [],
    };
    match.players.forEach((player) => {
      if (this._subscriptions.player.indexOf(player.account_id) !== -1) {
        found.matches += 1;
        found.player.push(player.account_id);
      }
    });
    if (this._subscriptions.team.indexOf(match.radiant_team_id) !== -1) {
      found.matches += 1;
      found.team.push(match.radiant_team_id);
    }
    if (this._subscriptions.team.indexOf(match.dire_team_id) !== -1) {
      found.matches += 1;
      found.team.push(match.dire_team_id);
    }
    if (this._subscriptions.league.indexOf(match.leagueid) !== -1) {
      found.matches += 1;
      found.league.push(match.leagueid);
    }
    if (found.matches) {
      this.send({
        type: 'MATCH',
        message: {
          found,
          origin,
          match,
        },
      });
    }
  }
}

const handlers = {
  PING(ctx, data) {
    return ctx.send({
      type: 'PONG',
      message: { date: Date.now() },
    }, data.nonce);
  },
  SUBSCRIBE(ctx, data) {
    // check if we can subscribe to this type of id
    if (subTypes.indexOf(data.message.type) === -1) {
      return ctx.send({
        type: 'SUBSCRIBE_NAK',
        message: { err: `Incorrect subscribe type provided. No IDs subscribed to. Available types: ${subTypes.join(', ')}` },
      }, data.nonce);
    }
    // check if there are ids
    if (data.message.ids === undefined) {
      return ctx.send({
        type: 'SUBSCRIBE_NAK',
        message: { err: 'No IDs provided. Nothing to subscribe to.' },
      }, data.nonce);
    }
    // check if the ids are an array, otherwise create one
    if (!Array.isArray(data.message.ids)) {
      if (typeof data.message.ids === 'string' || typeof data.message.ids === 'number') {
        data.message.ids = [data.message.ids];
      }
    }
    ctx._subscriptions[data.message.type].push(...data.message.ids);
    ctx._subscriptions[data.message.type] = ctx._subscriptions[data.message.type]
      .filter((ele, index, array) => array.indexOf(ele) === index);
    return ctx.send({
      type: 'SUBSCRIBE_ACK',
      message: {
        type: data.message.type,
        ids: ctx._subscriptions[data.message.type],
      },
    }, data.nonce);
  },
  UNSUBSCRIBE(ctx, data) {
    // check if we can unsubcribe from this type of id
    if (subTypes.indexOf(data.message.type) === -1) {
      return ctx.send({
        type: 'UNSUBSCRIBE_NAK',
        message: { err: `Incorrect subscribe type provided. No IDs unsubscribed from. Available types: ${subTypes.join(', ')}` },
      }, data.nonce);
    }
    // check if there are ids to unsubscribe from
    if (data.message.ids === undefined) {
      return ctx.send({
        type: 'UNSUBSCRIBE_NAK',
        message: { err: 'No IDs provided. Nothing to unsubscribe from.' },
      }, data.nonce);
    }
    // check if the ids are an array, otherwise create one
    if (!Array.isArray(data.message.ids)) {
      if (typeof data.message.ids === 'string' || typeof data.message.ids === 'number') {
        data.message.ids = [data.message.ids];
      }
    }
    // unsubscribe from each id
    const removed = [];
    data.message.ids.forEach((id) => {
      removed.push(...ctx._subscriptions[data.message.type]
        .splice(ctx._subscriptions[data.message.type].indexOf(id), 1));
    });
    return ctx.send({
      type: 'UNSUBSCRIBE_ACK',
      message: {
        type: data.message.type,
        ids: removed,
      },
    }, data.nonce);
  },
  GET_SUBS(ctx, data) {
    // just return every sub we have
    return ctx.send({
      type: 'GET_SUBS_ACK',
      message: ctx._subscriptions,
    }, data.nonce);
  },
};

wss.on('connection', (ws) => {
  ws.on('close', (code, reason) => {
    console.log('[SOCKET] connection closed');
    console.log(`[SOCKET] code: ${code}, reason: ${reason}`);

    if (subclients.get(ws.uuid)) {
      subclients.delete(ws.uuid);
      console.log(`[SOCKET] deleted ${ws.uuid}`);
    }
  });
  ws.on('message', (data) => {
    if (typeof data === 'string') {
      try {
        data = JSON.parse(data);
      } catch (err) {
        console.error('[SOCKET] error parsing something');
        console.error(data);
        return;
      }
    }

    if (!data.type) {
      ws.send(JSON.stringify({
        type: 'NAK',
        message: {
          err: 'BAD REQUEST: No message type provided',
        },
        nonce: data.nonce || null,
      }), (err) => {
        if (err) {
          console.error('[SOCKET] error sending to ws');
          console.error(err);
        }
      });
      return;
    }

    if (data.type === 'IDENTIFY') {
      const uuid = uuidV1();
      ws.uuid = uuid;
      subclients.set(uuid, new Subclient(ws, uuid));
      const subc = subclients.get(uuid);
      subc.send({
        type: 'IDENTIFY',
        message: {
          uuid,
        },
        nonce: data.nonce || null,
      });
      setTimeout(() => {
        let subscribed = false;

        if (subc.player.length) subscribed = true;
        if (subc.team.length) subscribed = true;
        if (subc.league.length) subscribed = true;

        if (!subscribed) subc.ws.close(1013, 'Not enough feeds subscribed to in the alotted time.');
      }, 15000);
    } else {
      if (!data.uuid) {
        ws.send(JSON.stringify({
          type: 'NAK',
          message: {
            err: 'No UUID provided.',
          },
          nonce: data.nonce || null,
        }), (err) => {
          if (err) {
            console.error('[SOCKET] error sending to ws');
            console.error(err);
          }
        });
        return;
      }
      if (data.type in handlers) {
        const subc = subclients.get(data.uuid);
        if (subc) {
          handlers[data.type](subc, data);
        } else if (data.type === 'PING') {
          ws.send(JSON.stringify({
            type: 'PONG',
            message: {
              date: Date.now(),
              err: 'Invalid UUID provided.',
            },
            nonce: data.nonce || null,
          }), (err) => {
            if (err) {
              console.error('[SOCKET] error sending to ws');
              console.error(err);
            }
          });
        } else {
          ws.send(JSON.stringify({
            type: 'NAK',
            message: {
              err: 'Invalid UUID provided.',
            },
            nonce: data.nonce || null,
          }), (err) => {
            if (err) {
              console.error('[SOCKET] error sending to ws');
              console.error(err);
            }
          });
        }
      } else {
        ws.send(JSON.stringify({
          type: 'NAK',
          message: {
            err: 'Invalid request type specified.',
          },
          nonce: data.nonce || null,
        }), (err) => {
          if (err) {
            console.error('[SOCKET] error sending to ws');
            console.error(err);
          }
        });
        return;
      }
    }
  });
});

redisClient.on('message', (channel, message) => {
  message = JSON.parse(message);
  subclients.forEach((subc) => {
    subc.checkMatch(message, channel.split(':')[2]);
  });
});

wss.on('listening', () => {
  console.log('[SOCKET] server listening');
  redisClient.subscribe('socket:matches:scanner');
  redisClient.subscribe('socket:matches:parser');
});
<commit_msg>correctly send nonce on identify<commit_after>/**
 * websocket server that recieves match data as it arrives and checks if
 * any connected clients are subscribed to match properties.
 **/
const config = require('../config');
const redis = require('redis');
const WebSocket = require('ws');
const uuidV1 = require('uuid/v4');

const subTypes = ['player', 'team', 'league'];

const wss = new WebSocket.Server({
  port: config.WEBSOCKET_PORT,
});
const subclients = new Map();

// create a different redis client to subscribe to matches with
console.log('[SOCKET] connecting %s', config.REDIS_URL);
const redisClient = redis.createClient(config.REDIS_URL, {
  detect_buffers: true,
});
redisClient.on('error', (err) => {
  console.error(err);
  process.exit(1);
});

class Subclient {
  constructor(ws, uuid) {
    this._ws = ws;
    this._uuid = uuid;
    this._subscriptions = {
      player: [],
      team: [],
      league: [],
    };
  }

  get ws() { return this._ws; }
  get uuid() { return this._uuid; }
  get player() { return this._subscriptions.player; }
  get team() { return this._subscriptions.team; }
  get league() { return this._subscriptions.league; }
  get subscriptions() { return this._subscriptions; }

  // send data to this websocket
  send(data, nonce) {
    data.nonce = nonce || null;
    this._ws.send(JSON.stringify(data), (err) => {
      if (err) {
        console.error(`[SOCKET] err sending to ws ${this._uuid}`);
        console.error(err);
      }
    });
  }

  // given a match or partial match,
  // check if this websocket is subscribed to any of the paramaters.
  checkMatch(match, origin) {
    const found = {
      matches: 0,
      player: [],
      team: [],
      league: [],
    };
    match.players.forEach((player) => {
      if (this._subscriptions.player.indexOf(player.account_id) !== -1) {
        found.matches += 1;
        found.player.push(player.account_id);
      }
    });
    if (this._subscriptions.team.indexOf(match.radiant_team_id) !== -1) {
      found.matches += 1;
      found.team.push(match.radiant_team_id);
    }
    if (this._subscriptions.team.indexOf(match.dire_team_id) !== -1) {
      found.matches += 1;
      found.team.push(match.dire_team_id);
    }
    if (this._subscriptions.league.indexOf(match.leagueid) !== -1) {
      found.matches += 1;
      found.league.push(match.leagueid);
    }
    if (found.matches) {
      this.send({
        type: 'MATCH',
        message: {
          found,
          origin,
          match,
        },
      });
    }
  }
}

const handlers = {
  PING(ctx, data) {
    return ctx.send({
      type: 'PONG',
      message: { date: Date.now() },
    }, data.nonce);
  },
  SUBSCRIBE(ctx, data) {
    // check if we can subscribe to this type of id
    if (subTypes.indexOf(data.message.type) === -1) {
      return ctx.send({
        type: 'SUBSCRIBE_NAK',
        message: { err: `Incorrect subscribe type provided. No IDs subscribed to. Available types: ${subTypes.join(', ')}` },
      }, data.nonce);
    }
    // check if there are ids
    if (data.message.ids === undefined) {
      return ctx.send({
        type: 'SUBSCRIBE_NAK',
        message: { err: 'No IDs provided. Nothing to subscribe to.' },
      }, data.nonce);
    }
    // check if the ids are an array, otherwise create one
    if (!Array.isArray(data.message.ids)) {
      if (typeof data.message.ids === 'string' || typeof data.message.ids === 'number') {
        data.message.ids = [data.message.ids];
      }
    }
    ctx._subscriptions[data.message.type].push(...data.message.ids);
    ctx._subscriptions[data.message.type] = ctx._subscriptions[data.message.type]
      .filter((ele, index, array) => array.indexOf(ele) === index);
    return ctx.send({
      type: 'SUBSCRIBE_ACK',
      message: {
        type: data.message.type,
        ids: ctx._subscriptions[data.message.type],
      },
    }, data.nonce);
  },
  UNSUBSCRIBE(ctx, data) {
    // check if we can unsubcribe from this type of id
    if (subTypes.indexOf(data.message.type) === -1) {
      return ctx.send({
        type: 'UNSUBSCRIBE_NAK',
        message: { err: `Incorrect subscribe type provided. No IDs unsubscribed from. Available types: ${subTypes.join(', ')}` },
      }, data.nonce);
    }
    // check if there are ids to unsubscribe from
    if (data.message.ids === undefined) {
      return ctx.send({
        type: 'UNSUBSCRIBE_NAK',
        message: { err: 'No IDs provided. Nothing to unsubscribe from.' },
      }, data.nonce);
    }
    // check if the ids are an array, otherwise create one
    if (!Array.isArray(data.message.ids)) {
      if (typeof data.message.ids === 'string' || typeof data.message.ids === 'number') {
        data.message.ids = [data.message.ids];
      }
    }
    // unsubscribe from each id
    const removed = [];
    data.message.ids.forEach((id) => {
      removed.push(...ctx._subscriptions[data.message.type]
        .splice(ctx._subscriptions[data.message.type].indexOf(id), 1));
    });
    return ctx.send({
      type: 'UNSUBSCRIBE_ACK',
      message: {
        type: data.message.type,
        ids: removed,
      },
    }, data.nonce);
  },
  GET_SUBS(ctx, data) {
    // just return every sub we have
    return ctx.send({
      type: 'GET_SUBS_ACK',
      message: ctx._subscriptions,
    }, data.nonce);
  },
};

wss.on('connection', (ws) => {
  ws.on('close', (code, reason) => {
    console.log('[SOCKET] connection closed');
    console.log(`[SOCKET] code: ${code}, reason: ${reason}`);

    if (subclients.get(ws.uuid)) {
      subclients.delete(ws.uuid);
      console.log(`[SOCKET] deleted ${ws.uuid}`);
    }
  });
  ws.on('message', (data) => {
    if (typeof data === 'string') {
      try {
        data = JSON.parse(data);
      } catch (err) {
        console.error('[SOCKET] error parsing something');
        console.error(data);
        return;
      }
    }

    if (!data.type) {
      ws.send(JSON.stringify({
        type: 'NAK',
        message: {
          err: 'BAD REQUEST: No message type provided',
        },
        nonce: data.nonce || null,
      }), (err) => {
        if (err) {
          console.error('[SOCKET] error sending to ws');
          console.error(err);
        }
      });
      return;
    }

    if (data.type === 'IDENTIFY') {
      const uuid = uuidV1();
      ws.uuid = uuid;
      subclients.set(uuid, new Subclient(ws, uuid));
      const subc = subclients.get(uuid);
      subc.send({
        type: 'IDENTIFY',
        message: {
          uuid,
        },
      }, data.nonce);
      setTimeout(() => {
        let subscribed = false;

        if (subc.player.length) subscribed = true;
        if (subc.team.length) subscribed = true;
        if (subc.league.length) subscribed = true;

        if (!subscribed) subc.ws.close(1013, 'Not enough feeds subscribed to in the alotted time.');
      }, 15000);
    } else {
      if (!data.uuid) {
        ws.send(JSON.stringify({
          type: 'NAK',
          message: {
            err: 'No UUID provided.',
          },
          nonce: data.nonce || null,
        }), (err) => {
          if (err) {
            console.error('[SOCKET] error sending to ws');
            console.error(err);
          }
        });
        return;
      }
      if (data.type in handlers) {
        const subc = subclients.get(data.uuid);
        if (subc) {
          handlers[data.type](subc, data);
        } else if (data.type === 'PING') {
          ws.send(JSON.stringify({
            type: 'PONG',
            message: {
              date: Date.now(),
              err: 'Invalid UUID provided.',
            },
            nonce: data.nonce || null,
          }), (err) => {
            if (err) {
              console.error('[SOCKET] error sending to ws');
              console.error(err);
            }
          });
        } else {
          ws.send(JSON.stringify({
            type: 'NAK',
            message: {
              err: 'Invalid UUID provided.',
            },
            nonce: data.nonce || null,
          }), (err) => {
            if (err) {
              console.error('[SOCKET] error sending to ws');
              console.error(err);
            }
          });
        }
      } else {
        ws.send(JSON.stringify({
          type: 'NAK',
          message: {
            err: 'Invalid request type specified.',
          },
          nonce: data.nonce || null,
        }), (err) => {
          if (err) {
            console.error('[SOCKET] error sending to ws');
            console.error(err);
          }
        });
        return;
      }
    }
  });
});

redisClient.on('message', (channel, message) => {
  message = JSON.parse(message);
  subclients.forEach((subc) => {
    subc.checkMatch(message, channel.split(':')[2]);
  });
});

wss.on('listening', () => {
  console.log('[SOCKET] server listening');
  redisClient.subscribe('socket:matches:scanner');
  redisClient.subscribe('socket:matches:parser');
});
<|endoftext|>


<commit_before>Template.lastlog.onCreated(function() {
    this.subscribe("logRecent");
});
Template.lastlog.helpers({
    logentries: function() {
        return EventLog.find({}, {
            sort: {
                timestamp: -1
            },
            limit: 50
        }).fetch();
    },
    logEntryTemplate: function() {
        switch (this.activity) {
            case "food":
                return 'logFood';
            case "sleep":
                if (this.label == "night") return 'logSleep';
                return "logNap";
        }
        return "logDefault";
    },
    logicons: function() {
        var logicons = [];
        var eventlabelwords = this.label.split(" ");
        eventlabelwords.forEach(function(word, wordindex, wordarray) {
            var iconentry = LogIconTable[word];
            if (iconentry != undefined) logicons.push({
                iconclass: iconentry
            });
        });
        return logicons;
    }
});
/*Template.lastlog.created = function() {
    var logentries = this.logentries = new ReactiveVar();
    var querystring = 'https://docs.google.com/spreadsheets/d/1Hwu_DVFvcNDnuiSPryRuCO4rgmD9k91tn7XuVZ0Zk6E/edit#gid=0&range=A:J';
    var query = new google.visualization.Query(querystring);
    query.setRefreshInterval(120);
    var qstr = "select * order by F desc limit 20";
    query.setQuery(qstr);
    query.send(function(response) {
        if (response.isError()) {
            console.log("Error: " + response.getMessage());
        }
        var dataJson = response.getDataTable().toJSON();
        logentries.set(JSON.parse(dataJson));
    });
};

function parseGoogleDataTable(dataTable) {
    var formattedDataTable = [];
    dataTable.rows.forEach(function(rowitem, rowindex, rowarray) {
        var r = rowitem.c;
        var row = {
            activity: r[0] ? r[0].v : undefined,
            label: r[1] ? r[1].v : undefined,
            time: r[2] ? r[2].f : undefined,
            end: r[3] ? r[3].f : undefined,
            duration: r[6] ? moment(r[6].f).subtract(moment(r[5].f)).format("HH:mm"): undefined,
            timestamp: moment(r[5]),
            timestampformatted: r[5] ? moment(r[4].f).format("ddd, MMM D") : undefined,
            endtimestamp: r[6] ? moment(r[6].f) : undefined,
        };
        formattedDataTable.push(row);
    });
    return formattedDataTable;
}
*/
<commit_msg>commented-out code cleanup<commit_after>Template.lastlog.onCreated(function() {
    this.subscribe("logRecent");
});
Template.lastlog.helpers({
    logentries: function() {
        return EventLog.find({}, {
            sort: {
                timestamp: -1
            },
            limit: 50
        }).fetch();
    },
    logEntryTemplate: function() {
        switch (this.activity) {
            case "food":
                return 'logFood';
            case "sleep":
                if (this.label == "night") return 'logSleep';
                return "logNap";
        }
        return "logDefault";
    },
    logicons: function() {
        var logicons = [];
        var eventlabelwords = this.label.split(" ");
        eventlabelwords.forEach(function(word, wordindex, wordarray) {
            var iconentry = LogIconTable[word];
            if (iconentry != undefined) logicons.push({
                iconclass: iconentry
            });
        });
        return logicons;
    }
});
<|endoftext|>