<commit_before>/* Copyright 2015 IBM Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

var express = require('express');
var router = express.Router();
var config = require('../config/server');
var parseString = require('xml2js').parseString;
var request = require('request');
var Busboy = require('busboy');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.redirect('/');
});

//getfeed for home page content
router.get('/feed', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  //config.server.domain is the domain name of the server (without the https or the directoy i.e example.com)

  var url = 'https://' + config.server.domain + '/files/oauth/api/documents/feed?visibility=public&includeTags=true';

  //if query parameters exist, append them onto the url
  if(!isEmpty(req.query.q)){
    url = url + '?tag=' + req.query.q;
  }

  var headers = {};

  // we must attach the key we got through passportto the header as
  // Authorization: Bearer + key. Passport gives us access to the user profile
  // we saved through the request user object
  headers['Authorization'] = 'Bearer ' + req.user.accessToken;

  var options = {
    url: url,
    headers: headers
  };

  request.get(options, function(error, response, body){

    // if there is an error lets log it to the console and inform the angular
    // of our app so it can be handled
    if(error){
      console.log('Error occured while getting feed from Connections Cloud: ' + error);
      res.status(500).end();
    } else {

      // otherwise, the api returns an xml which can be easily converted to a
      // JSON to make parsing easier using the xml2js module for nodejs
      parseString(body, function(err, result){

        // initialize the array of photos we will be sending back
        var photos = [];

        // get the actual entries object in the response
        var entries = result.feed.entry;

        // iterate over the entries to send back each photo that was returned
        for(var i = 0; i < entries.length; i++){
          var photo = {};
          var entry = entries[i];

          // the photo id which is used to reference the photo internally for
          // ibm connection cloud, this will need to be stored to quickly
          // get the photo and information on the photo later
          photo.id = entry['td:uuid'][0];

          // iterate through the tags in the entry and build an object that has
          // all the tags, starting at 1 because the first category describes
          // the document and is not a true 'tag'
          var tags = [];
          for(var j = 1; j < entry.category.length; j ++){
            var category = entry.category[j];
            var tag = category.$.label;
            tags.push(tag);
          }
          photo.tags = tags;

          // the author of the file, and in our case the photographer
          photo.photographer = entry.author[0].name[0];

          // the title of the document
          photo.title = entry.title[0]['_'];

          // the upload date of the document
          photo.published = entry.published[0];

          // the link object contains many links related to the document,
          // however we want the link to the actual image, therefore we will
          // look for the object with the type of image
          for(var j = 0; j < entry.link.length; j++){
            var link = entry.link[j];
            var type = link.$.type;
            if(!(type === undefined) && (type.indexOf('image') > -1)){
              photo.link = link.$.href;
              break;
            }
          }

          // in addition we need to pass the library id of the entry, for later
          // calls in which we will have to pass the library id to the api
          photo.lid = entry['td:libraryId'][0];

          // push the photo to our photos array
          console.log('pushing :' + JSON.stringify(photo));
          photos.push(photo);
        }

        //return our photos array
        console.log('sending response');
        res.send(photos);
      });
    }
  });
});

//get photo for retrieving a photo by id
router.get('/photo', function(req, res, next){

  if(!req.user)
    res.status(403).end();

  //if no id was passed, return an error code
  if(isEmpty(req.query.id)){ //|| isEmpty(req.query.lid)){
    console.log('query not found');
    res.status(412).end();
  } else {
      var url = 'https://' + config.server.domain + '/files/oauth/api/library/' + req.query.lid + '/document/' + req.query.id + '/entry?includeTags=true';
      // we must attach the key we got through passportto the header as
      // Authorization: Bearer + key. Passport gives us access to the user profile
      // we saved through the request user object
      var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

      var options = {
        url: url,
        headers: headers
      };

      request.get(options, function(error, response, body){
        if(error){
          console.log('photo error: ' + error);
          res.status(500).end();
        } else {
          //see get feed for more details
          parseString(body, function(err, result){
            var photo = {};
            var entry = result.entry;
            photo.id = entry['td:uuid'][0];
            var tags = [];
            for(var j = 1; j < entry.category.length; j ++){
              var category = entry.category[j];
              var tag = category.$.label;
              tags.push(tag);
            }
            photo.tags = tags;
            for(var j = 0; j < entry.link.length; j++){
              var link = entry.link[j];
              var type = link.$.type;
              if(!(type === undefined) && (type.indexOf('image') > -1)){
                photo.link = link.$.href;
                break;
              }
            }
            photo.photographer = entry.author[0].name[0];
            photo.userid = entry.author[0]['snx:userid'][0];
            photo.title = entry.title[0]['_'];
            photo.published = entry.published[0];
            var socialx = entry['snx:rank'];
            for(var i = 0; i < socialx.length; i++){
              var x = socialx[i];
              if(x.$.scheme.indexOf('recommendations') > -1){
                photo.likes = parseInt(x['_']);
                break;
              }
            }
            photo.libraryid = entry['td:libraryId'][0];
            photo.userid = entry.author[0]['snx:userid'][0];
            console.log('Sending response');
            res.send(photo);
          });
        }
      });
  }
});

router.put('/like', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  if(isEmpty(req.query.id) || isEmpty(req.query.lid) || isEmpty(req.query.r)){
    console.log('Query not found');
    req.status(412).end();
  } else {
    var url = 'https://' + config.server.domain + '/files/oauth/api/library/' + req.query.lid + '/document/' + req.query.id + '/media?recommendation=' + req.query.r;

    var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

    var options = {
      url: url,
      headers: headers
    };

    request.put(options, function(error, response, body){
      if(error){
        console.log('error in putting like: ' + error);
        res.status(500).end();
      } else {
        parseString(body, function(err, result){
          fs.writeFile("Response.txt", JSON.stringify(result));
          res.send(200).end();
        });
      }
    });
  }
})

router.get('/comments', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  //if no id was passed
  if(isEmpty(req.query.id)){
    console.log("query not found");
    res.status(412).end();
  } else if(isEmpty(req.query.userid)){
    res.status(412).end();
  } else {
    var url = 'https://' + config.server.domain + '/files/oauth/api/userlibrary/' + req.query.userid + '/document/' + req.query.id + '/feed?category=comment';

    var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

    var options = {
      url: url,
      headers: headers
    };

    request.get(options, function(error, response, body){
      if(error){
        console.log('error in get comment: ' + error);
        res.status(500).end();
      } else {
        parseString(body, function(err, result){

          // create the comment array that we will return
          var comments = [];

          // get the main data from the json
          var entries = result.feed.entry;

          // iterate through the comments creating new objects and pushing them
          // to the array
          for(var i = 0; i < entries.length; i++){

            // grab the entry we are iterating on
            var entry = entries[i];

            // create the comment we will add to the array
            var comment = {};

            // grab the author name
            comment.author = entry.author[0].name[0];

            // grab the publish date of the comment
            comment.date = entry.published[0];

            // grab the content of the comment
            comment.content = entry.content[0]['_'];

            // push the comment to the array
            comments.push(comment);
          }

          //return the array of comments
          res.send(comments);
        });
      }
    });
  }
});

//upload a file
router.post('/upload', function(req, res, next){
  // if the user does not exist, send back forbidden
  if(!req.user)
    res.status(403).end()

  // before uploading, we must obtain a nonce, which is a handshake between
  // the api and our server to allow us to post to the server
  var url = 'https://' + config.server.domain + '/files/oauth/api/nonce';

  var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

  var options = {
    url: url,
    headers: headers
  };

  // making the nonce request
  request.get(options, function(error, response, body){

    // if there was an error log the error and send back an error
    if(error){
      console.log('nonce failed: ' + error);
      res.status(500).end()
    } else {

      // the nonce is returned in the body of the response
      var nonce = body;

      // to obtain the file from the client, we use a module called busboy
      // that allows us to obtain the file stream from the client
      var busboy = new Busboy({headers: req.headers});

      // when busboy encounters a file (which should be the only thing it
      // obtains from the page) it will then pip the file to a request to the
      // api server
      busboy.on('file', function(fieldname, file, filename, encoding, mimetype){
        var url = 'https://' + server.domain + '/files/oauth/api/myuserlibrary/feed';

        // the slug is used to tell the api what it should call the file
        var slug = filename;

        var headers = {
          'Authorization': 'Bearer ' + req.user.accessToken,
          'Slug': slug,
          //the nonce is the nonce we obtained before
          'X-Update-Nonce': nonce
        };

        var options = {
          url: url,
          headers: headers
        };

        // we then pipe the file to the request to the api server
        file.pipe(request.post(options, function(error, response, body){

          // if we recieve an error then log it and send and erro back to the
          // client
          if(error){
            console.log('upload failed: ' + error);
            res.status(500).end();
          }
        }));

      });

      // when the busboy finishes processing the file, send back an OK status
      // and close the connection
      busboy.on('finish', function(){
        res.status(200).end();
      });
    }
  });
});

router.get('/profile', function(req, res, next){
  if(!req.user){
    res.status(403).end();
  }

  if(isEmpty(req.query.userid)){
    console.log('query not found');
    req.status(412).end()
  } else {

    var url = 'https://' + config.server.domain + '/profiles/atom/profile.do?userid=' + req.query.userid;

    var headers = {'Authorization' : 'Bearer ' + req.user.accessToken};

    var options = {
      url : url,
      headers : headers
    };

    request.get(options, function(error, response, body){
      if(error){
        console.log('error: ' + error);
        res.status(500).end();
      }

      parseString(body, function(err, result){

        // grab the main data of the json
        var entry = result.feed.entry[0];

        // create the object we will send back
        var profile = {};

        // grabbing the name of the profile
        profile.name = entry.contributor[0].name[0];

        // grabbing the email of the profile
        profile.email = entry.contributor[0].email[0];

        // iterate through the links to find the image that represents the
        // profile picture
        for(var i = 0; i < entry.link.length; i++){
          if(entry.link[i].$.type.indexOf(image) > -1){
            profile.img = entry.link[i].$.href;
            break;
          }
        }

        //send back the profile
        res.send(profile);
      });
    });
  }
});

var hasOwnProperty = Object.prototype.hasOwnProperty;

function isEmpty(obj) {

    // null and undefined are "empty"
    if (obj == null) return true;

    // Assume if it has a length property with a non-zero value
    // that that property is correct.
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;

    // Otherwise, does it have any properties of its own?
    // Note that this doesn't handle
    // toString and valueOf enumeration bugs in IE < 9
    for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) return false;
    }

    return true;
}

module.exports = router;
<commit_msg>updated field names to reflect consistancy<commit_after>/* Copyright 2015 IBM Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

var express = require('express');
var router = express.Router();
var config = require('../config/server');
var parseString = require('xml2js').parseString;
var request = require('request');
var Busboy = require('busboy');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.redirect('/');
});

//getfeed for home page content
router.get('/feed', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  //config.server.domain is the domain name of the server (without the https or the directoy i.e example.com)

  var url = 'https://' + config.server.domain + '/files/oauth/api/documents/feed?visibility=public&includeTags=true';

  //if query parameters exist, append them onto the url
  if(!isEmpty(req.query.q)){
    url = url + '?tag=' + req.query.q;
  }

  var headers = {};

  // we must attach the key we got through passportto the header as
  // Authorization: Bearer + key. Passport gives us access to the user profile
  // we saved through the request user object
  headers['Authorization'] = 'Bearer ' + req.user.accessToken;

  var options = {
    url: url,
    headers: headers
  };

  request.get(options, function(error, response, body){

    // if there is an error lets log it to the console and inform the angular
    // of our app so it can be handled
    if(error){
      console.log('Error occured while getting feed from Connections Cloud: ' + error);
      res.status(500).end();
    } else {

      // otherwise, the api returns an xml which can be easily converted to a
      // JSON to make parsing easier using the xml2js module for nodejs
      parseString(body, function(err, result){

        // initialize the array of photos we will be sending back
        var photos = [];

        // get the actual entries object in the response
        var entries = result.feed.entry;

        // iterate over the entries to send back each photo that was returned
        for(var i = 0; i < entries.length; i++){
          var photo = {};
          var entry = entries[i];

          // the photo id which is used to reference the photo internally for
          // ibm connection cloud, this will need to be stored to quickly
          // get the photo and information on the photo later
          photo.id = entry['td:uuid'][0];

          // iterate through the tags in the entry and build an object that has
          // all the tags, starting at 1 because the first category describes
          // the document and is not a true 'tag'
          var tags = [];
          for(var j = 1; j < entry.category.length; j ++){
            var category = entry.category[j];
            var tag = category.$.label;
            tags.push(tag);
          }
          photo.tags = tags;

          // the author of the file, and in our case the photographer
          photo.photographer = entry.author[0].name[0];

          // the title of the document
          photo.title = entry.title[0]['_'];

          // the upload date of the document
          photo.published = entry.published[0];

          // the link object contains many links related to the document,
          // however we want the link to the actual image, therefore we will
          // look for the object with the type of image
          for(var j = 0; j < entry.link.length; j++){
            var link = entry.link[j];
            var type = link.$.type;
            if(!(type === undefined) && (type.indexOf('image') > -1)){
              photo.link = link.$.href;
              break;
            }
          }

          // in addition we need to pass the library id of the entry, for later
          // calls in which we will have to pass the library id to the api
          photo.lid = entry['td:libraryId'][0];

          // push the photo to our photos array
          console.log('pushing :' + JSON.stringify(photo));
          photos.push(photo);
        }

        //return our photos array
        console.log('sending response');
        res.send(photos);
      });
    }
  });
});

//get photo for retrieving a photo by id
router.get('/photo', function(req, res, next){

  if(!req.user)
    res.status(403).end();

  //if no id was passed, return an error code
  if(isEmpty(req.query.id) || isEmpty(req.query.lid)){
    console.log('query not found');
    res.status(412).end();
  } else {
      var url = 'https://' + config.server.domain + '/files/oauth/api/library/' + req.query.lid + '/document/' + req.query.id + '/entry?includeTags=true';
      // we must attach the key we got through passportto the header as
      // Authorization: Bearer + key. Passport gives us access to the user profile
      // we saved through the request user object
      var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

      var options = {
        url: url,
        headers: headers
      };

      request.get(options, function(error, response, body){
        if(error){
          console.log('photo error: ' + error);
          res.status(500).end();
        } else {
          //see get feed for more details
          parseString(body, function(err, result){
            var photo = {};
            var entry = result.entry;
            photo.id = entry['td:uuid'][0];
            var tags = [];
            for(var j = 1; j < entry.category.length; j ++){
              var category = entry.category[j];
              var tag = category.$.label;
              tags.push(tag);
            }
            photo.tags = tags;
            for(var j = 0; j < entry.link.length; j++){
              var link = entry.link[j];
              var type = link.$.type;
              if(!(type === undefined) && (type.indexOf('image') > -1)){
                photo.link = link.$.href;
                break;
              }
            }
            photo.photographer = entry.author[0].name[0];
            photo.uid = entry.author[0]['snx:userid'][0];
            photo.title = entry.title[0]['_'];
            photo.published = entry.published[0];
            var socialx = entry['snx:rank'];
            for(var i = 0; i < socialx.length; i++){
              var x = socialx[i];
              if(x.$.scheme.indexOf('recommendations') > -1){
                photo.likes = parseInt(x['_']);
                break;
              }
            }
            photo.lid = entry['td:libraryId'][0];
            console.log('Sending response');
            res.send(photo);
          });
        }
      });
  }
});

router.put('/like', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  if(isEmpty(req.query.id) || isEmpty(req.query.lid) || isEmpty(req.query.r)){
    console.log('Query not found');
    req.status(412).end();
  } else {
    var url = 'https://' + config.server.domain + '/files/oauth/api/library/' + req.query.lid + '/document/' + req.query.id + '/media?recommendation=' + req.query.r;

    var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

    var options = {
      url: url,
      headers: headers
    };

    request.put(options, function(error, response, body){
      if(error){
        console.log('error in putting like: ' + error);
        res.status(500).end();
      } else {
        parseString(body, function(err, result){
          fs.writeFile("Response.txt", JSON.stringify(result));
          res.send(200).end();
        });
      }
    });
  }
})

router.get('/comments', function(req, res, next){
  if(!req.user)
    res.status(403).end();

  //if no id was passed
  if(isEmpty(req.query.id)){
    console.log("query not found");
    res.status(412).end();
  } else if(isEmpty(req.query.uid)){
    res.status(412).end();
  } else {
    var url = 'https://' + config.server.domain + '/files/oauth/api/userlibrary/' + req.query.uid + '/document/' + req.query.id + '/feed?category=comment';

    var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

    var options = {
      url: url,
      headers: headers
    };

    request.get(options, function(error, response, body){
      if(error){
        console.log('error in get comment: ' + error);
        res.status(500).end();
      } else {
        parseString(body, function(err, result){

          // create the comment array that we will return
          var comments = [];

          // get the main data from the json
          var entries = result.feed.entry;

          // iterate through the comments creating new objects and pushing them
          // to the array
          for(var i = 0; i < entries.length; i++){

            // grab the entry we are iterating on
            var entry = entries[i];

            // create the comment we will add to the array
            var comment = {};

            // grab the author name
            comment.author = entry.author[0].name[0];

            // grab the publish date of the comment
            comment.date = entry.published[0];

            // grab the content of the comment
            comment.content = entry.content[0]['_'];

            // push the comment to the array
            comments.push(comment);
          }

          //return the array of comments
          res.send(comments);
        });
      }
    });
  }
});

//upload a file
router.post('/upload', function(req, res, next){
  // if the user does not exist, send back forbidden
  if(!req.user)
    res.status(403).end()

  // before uploading, we must obtain a nonce, which is a handshake between
  // the api and our server to allow us to post to the server
  var url = 'https://' + config.server.domain + '/files/oauth/api/nonce';

  var headers = {'Authorization': 'Bearer ' + req.user.accessToken};

  var options = {
    url: url,
    headers: headers
  };

  // making the nonce request
  request.get(options, function(error, response, body){

    // if there was an error log the error and send back an error
    if(error){
      console.log('nonce failed: ' + error);
      res.status(500).end()
    } else {

      // the nonce is returned in the body of the response
      var nonce = body;

      // to obtain the file from the client, we use a module called busboy
      // that allows us to obtain the file stream from the client
      var busboy = new Busboy({headers: req.headers});

      // when busboy encounters a file (which should be the only thing it
      // obtains from the page) it will then pip the file to a request to the
      // api server
      busboy.on('file', function(fieldname, file, filename, encoding, mimetype){
        var url = 'https://' + server.domain + '/files/oauth/api/myuserlibrary/feed';

        // the slug is used to tell the api what it should call the file
        var slug = filename;

        var headers = {
          'Authorization': 'Bearer ' + req.user.accessToken,
          'Slug': slug,
          //the nonce is the nonce we obtained before
          'X-Update-Nonce': nonce
        };

        var options = {
          url: url,
          headers: headers
        };

        // we then pipe the file to the request to the api server
        file.pipe(request.post(options, function(error, response, body){

          // if we recieve an error then log it and send and erro back to the
          // client
          if(error){
            console.log('upload failed: ' + error);
            res.status(500).end();
          }
        }));

      });

      // when the busboy finishes processing the file, send back an OK status
      // and close the connection
      busboy.on('finish', function(){
        res.status(200).end();
      });
    }
  });
});

router.get('/profile', function(req, res, next){
  if(!req.user){
    res.status(403).end();
  }

  if(isEmpty(req.query.uid)){
    console.log('query not found');
    req.status(412).end()
  } else {

    var url = 'https://' + config.server.domain + '/profiles/atom/profile.do?userid=' + req.query.uid;

    var headers = {'Authorization' : 'Bearer ' + req.user.accessToken};

    var options = {
      url : url,
      headers : headers
    };

    request.get(options, function(error, response, body){
      if(error){
        console.log('error: ' + error);
        res.status(500).end();
      }

      parseString(body, function(err, result){

        // grab the main data of the json
        var entry = result.feed.entry[0];

        // create the object we will send back
        var profile = {};

        // grabbing the name of the profile
        profile.name = entry.contributor[0].name[0];

        // grabbing the email of the profile
        profile.email = entry.contributor[0].email[0];

        // iterate through the links to find the image that represents the
        // profile picture
        for(var i = 0; i < entry.link.length; i++){
          if(entry.link[i].$.type.indexOf(image) > -1){
            profile.img = entry.link[i].$.href;
            break;
          }
        }

        //send back the profile
        res.send(profile);
      });
    });
  }
});

var hasOwnProperty = Object.prototype.hasOwnProperty;

function isEmpty(obj) {

    // null and undefined are "empty"
    if (obj == null) return true;

    // Assume if it has a length property with a non-zero value
    // that that property is correct.
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;

    // Otherwise, does it have any properties of its own?
    // Note that this doesn't handle
    // toString and valueOf enumeration bugs in IE < 9
    for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) return false;
    }

    return true;
}

module.exports = router;
<|endoftext|>


<commit_before>/* Module: DiscordTimeRoles -- A Time addon that sets Discord roles based on timezone offsets. */

const Module = require('../Module.js');

const moment = require('moment');

class ModDiscordTimeRoles extends Module {

    get requiredParams() { return [
        'env',
        'roles'                 //A map of {ROLEID: {MIN, MAX}, ...} where MIN and MAX are timezone offsets in minutes.
    ]; }

    get optionalParams() { return [
        'strict'                //If true, removes incorrect roles on startup.
    ]; }

    get requiredEnvironments() { return [
        'Discord'
    ]; }

    get requiredModules() { return [
        'Time'
    ]; }

    get denv() {
        return this.env(this.param('env'));
    }

    constructor(name) {
        super('DiscordTimeRoles', name);

        this._params['strict'] = false;
    }

    initialize(opt) {
        if (!super.initialize(opt)) return false;

        if (this.denv.envName != "Discord") return false;

        //Register handlers

        this.denv.on("connected", async () => {

            for (let member of this.denv.server.members.cache.array()) {
                let utcOffset = this.mod("Time").getCurrentUtcOffsetByUserid(this.denv, member.id);
                if (utcOffset === null) continue;

                //Modify assignments on startup

                this.addAndRemoveRoles(member, utcOffset, this.param("strict"));

            }

        });

        //Modify assignments on timezone change

        this.mod("Time").registerTimezoneCallback((env, userid, handle, tzinfo) => {
            if (env.name != this.denv.name) return false;

            this.addAndRemoveRoles(env.server.members.cache.get(userid), moment().tz(tzinfo.name).utcOffset(), true);

        });

        return true;
    }

    // # Module code below this line #

    addAndRemoveRoles(member, utcOffset, strict) {
        let addroles = [], removeroles = [];
        for (let roleid in this.param("roles")) {
            let roleconf = this.param("roles")[roleid];
            if (roleconf.max && utcOffset > roleconf.max || roleconf.min && utcOffset < roleconf.min) {
                if (member.roles.cache.get(roleid)) {
                    removeroles.push(roleid);
                }
            } else {
                if (!member.roles.cache.get(roleid)) {
                    addroles.push(roleid);
                }
            }
        }

        let doaddroles = Promise.resolve();
        if (addroles.length) {
            doaddroles = member.roles.add(addroles, "Adding role" + (addroles.length != 1 ? "s" : "") + " based on timezone rules.");
        }

        if (strict && removeroles.length) {
            //Circumventing discord.js bug
            doaddroles.then(() => member.roles.remove(removeroles, "Removing role" + (removeroles.length != 1 ? "s" : "") + " based on timezone rules."));
        }
    }

}

module.exports = ModDiscordTimeRoles;
<commit_msg>DiscordTimeRoles: Remove all roles if the timezone is missing and strict mode is on.<commit_after>/* Module: DiscordTimeRoles -- A Time addon that sets Discord roles based on timezone offsets. */

const Module = require('../Module.js');

const moment = require('moment');

class ModDiscordTimeRoles extends Module {

    get requiredParams() { return [
        'env',
        'roles'                 //A map of {ROLEID: {MIN, MAX}, ...} where MIN and MAX are timezone offsets in minutes.
    ]; }

    get optionalParams() { return [
        'strict'                //If true, removes incorrect roles on startup.
    ]; }

    get requiredEnvironments() { return [
        'Discord'
    ]; }

    get requiredModules() { return [
        'Time'
    ]; }

    get denv() {
        return this.env(this.param('env'));
    }

    constructor(name) {
        super('DiscordTimeRoles', name);

        this._params['strict'] = false;
    }

    initialize(opt) {
        if (!super.initialize(opt)) return false;

        if (this.denv.envName != "Discord") return false;

        //Register handlers

        this.denv.on("connected", async () => {

            for (let member of this.denv.server.members.cache.array()) {
                let utcOffset = this.mod("Time").getCurrentUtcOffsetByUserid(this.denv, member.id);
                if (!utcOffset && !this.param("strict")) continue;

                //Modify assignments on startup

                this.addAndRemoveRoles(member, utcOffset, this.param("strict"));

            }

        });

        //Modify assignments on timezone change

        this.mod("Time").registerTimezoneCallback((env, userid, handle, tzinfo) => {
            if (env.name != this.denv.name) return false;

            this.addAndRemoveRoles(env.server.members.cache.get(userid), moment().tz(tzinfo.name).utcOffset(), true);

        });

        return true;
    }

    // # Module code below this line #

    addAndRemoveRoles(member, utcOffset, strict) {
        let addroles = [], removeroles = [];
        for (let roleid in this.param("roles")) {
            let roleconf = this.param("roles")[roleid];
            if (!utcOffset || roleconf.max && utcOffset > roleconf.max || roleconf.min && utcOffset < roleconf.min) {
                if (member.roles.cache.get(roleid)) {
                    removeroles.push(roleid);
                }
            } else {
                if (!member.roles.cache.get(roleid)) {
                    addroles.push(roleid);
                }
            }
        }

        let doaddroles = Promise.resolve();
        if (addroles.length) {
            doaddroles = member.roles.add(addroles, "Adding role" + (addroles.length != 1 ? "s" : "") + " based on timezone rules.");
        }

        if (strict && removeroles.length) {
            //Circumventing discord.js bug
            doaddroles.then(() => member.roles.remove(removeroles, "Removing role" + (removeroles.length != 1 ? "s" : "") + " based on timezone rules."));
        }
    }

}

module.exports = ModDiscordTimeRoles;
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2017 Hsiang Leekwok
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var imgs = ["lehehe.jpg", "potu.jpg", "loading_img_1.gif", "loading_img_2.gif", "loading_img_3.gif", "loading_img_4.gif", "loading_img_5.gif"];
$(document).ready(function () {
    $("img").bind("error", function () {
        var obj = $(this);
        $(obj).attr("cache-src", $(obj).attr("src"));
        var index = Math.ceil(Math.random() * 100) % imgs.length;
        $(obj).attr("src", imgs[index]);
        setTimeout(function () {
            var src = $(obj).attr("cache-src");
            $(obj).attr("src", src);
        }, 10000);
    }).bind("load", function(){
        if($(this).attr("src").indexOf("http") == 0) {
            $(this).removeAttr("cache-src");
        }
    });
});<commit_msg>img加载失败后自动尝试重新加载（10s延迟）<commit_after>/**
 * Copyright (C) 2017 Hsiang Leekwok
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// var imgs = ["lehehe.jpg", "potu.jpg", "loading_img_1.gif", "loading_img_2.gif", "loading_img_3.gif", "loading_img_4.gif", "loading_img_5.gif"];

var cache_attr = "cached-src";

$(document).ready(function () {

    $("img").bind("error", function () {

        var obj = $(this);

        // 缓存真正的 src 属性
        $(obj).attr(cache_attr, $(obj).attr("src"));

        // 显示加载失败
        // var index = Math.ceil(Math.random() * 100) % imgs.length;
        // $(obj).attr("src", imgs[index]);
        $(obj).attr("src", "potu.jpg");

        // 10s 尝试再次显示一下真正的 src 里的图片内容
        setTimeout(function () {
            var src = $(obj).attr(cache_attr);
            $(obj).attr("src", src);
        }, 10000);

    }).bind("load", function () {
        // 去掉多余的没用属性
        if ($(this).attr("src").indexOf("http") == 0) {
            $(this).removeAttr(cache_attr);
        }
    });

});<|endoftext|>


<commit_before>define(function (require, exports, module) {
var $ = require('jquery');
var _ = require('underscore');
var Engine = require('famous/core/Engine');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var View = require('rich/view').FamousView;

function initializeRichContext(options){

    var $el;
    var context;
    var contentView;
    var constraints = options.constraints || null;

    if(typeof options.el == 'string'){
        $el = $(options.el);
    } else if (options.el instanceof $){
        $el = options.el;
    }

    context = Engine.createContext($el[0]);
    contentView = new View({
        context: context,
        constraints: constraints,
        size: context.getSize()
    });

    contentView.name = 'contentView';
    contentView._isRoot = true;
    contentView.superview = {_isRoot: true, _autolayout: {}};

    context.add(contentView);

    var resizeHandler = function(){
        var size = context.getSize();

        var variables = [
            contentView._autolayout.width,
            contentView._autolayout.height
        ];

        contentView.updateVariables(variables, size);
        contentView.invalidateLayout();
    };

    context.on('resize', resizeHandler);

    return contentView;
}

function disposeRichContext(view){
    var context = view.context;
    Engine.deregisterContext(context);
}

function getViewSize(view){
    var className = _.result(view, 'className');
    var fragment = document.createDocumentFragment();
    var div = document.createElement('div');

    if(className){
        div.setAttribute('class', className);
    }

    div.setAttribute('style', 'visibility:hidden; position:absolute;');

    div.innerHTML = view.renderHTML();

    fragment.appendChild(div);

    document.body.appendChild(fragment);
    var rect = div.getBoundingClientRect();
    document.body.removeChild(div);

    return [rect.width, rect.height];
}

function postrenderOnce(callback){
    var postrender = function(){
        Engine.removeListener('postrender', postrender);
        callback();
    };

    Engine.on('postrender', postrender);
}

function modifierWithTransform(config, modifier){
    modifier = modifier || new Modifier();

    if (config.transform){
        var transform;
        var candidate = config.transform;

        if(_.isArray(candidate)){
            var x = 0;
            var y = 0;
            var z = 0;

            x = config.transform[0] || x;
            y = config.transform[1] || y;
            z = config.transform[2] || z;

            transform = Transform.translate.apply(Transform, [x, y, z]);
        } else if(_.isFunction(candidate)){
            transform = candidate;
        }

        if(transform){
            modifier.transformFrom(transform);
        }
    }

    return modifier;
}

function modifierWithSize(config, modifier){
    modifier = modifier || new Modifier();

    if (config.size){
        modifier.sizeFrom(config.size);
    }

    return modifier;
}

function modifierWithOpacity(config, modifier){
    modifier = modifier || new Modifier();

    if (config.opacity){
        modifier.opacityFrom(config.opacity);
    }

    return modifier;
}

function modifierWithOrigin(config, modifier){
    modifier = modifier || new Modifier();

    if (config.origin){
        modifier.originFrom(config.origin);
    }

    return modifier;
}

function modifierWithAlign(config, modifier){
    modifier = modifier || new Modifier();

    if (config.align){
        modifier.alignFrom(config.align);
    }

    return modifier;
}

function modifierWithConfig(config){
    // config is:
    // {
    //    transform: ...
    //    origin: ...
    //    align: ...
    //    size: ...
    //    opacity: ...
    // }
    modifier = modifier || new Modifier();

    modifierWithOpacity(config, modifier);
    modifierWithOrigin(config, modifier);
    modifierWithSize(config, modifier);
    modifierWithTransform(config, modifier);

    return modifier;
}

exports.getViewSize = getViewSize;
exports.postrenderOnce = postrenderOnce;
exports.initializeRichContext = initializeRichContext;
exports.disposeRichContext = disposeRichContext;
exports.modifierWithTransform = modifierWithTransform;
exports.modifierWithSize = modifierWithSize;
exports.modifierWithOpacity = modifierWithOpacity;
exports.modifierWithOrigin = modifierWithOrigin;
exports.modifierWithAlign = modifierWithAlign;
exports.modifierWithConfig = modifierWithConfig;

});
<commit_msg>fixes postrenderonce<commit_after>define(function (require, exports, module) {
var $ = require('jquery');
var _ = require('underscore');
var Engine = require('famous/core/Engine');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var View = require('rich/view').FamousView;

function initializeRichContext(options){

    var $el;
    var context;
    var contentView;
    var constraints = options.constraints || null;

    if(typeof options.el == 'string'){
        $el = $(options.el);
    } else if (options.el instanceof $){
        $el = options.el;
    }

    context = Engine.createContext($el[0]);
    contentView = new View({
        context: context,
        constraints: constraints,
        size: context.getSize()
    });

    contentView.name = 'contentView';
    contentView._isRoot = true;
    contentView.superview = {_isRoot: true, _autolayout: {}};

    context.add(contentView);

    var resizeHandler = function(){
        var size = context.getSize();

        var variables = [
            contentView._autolayout.width,
            contentView._autolayout.height
        ];

        contentView.updateVariables(variables, size);
        contentView.invalidateLayout();
    };

    context.on('resize', resizeHandler);

    return contentView;
}

function disposeRichContext(view){
    var context = view.context;
    Engine.deregisterContext(context);
}

function getViewSize(view){
    var className = _.result(view, 'className');
    var fragment = document.createDocumentFragment();
    var div = document.createElement('div');

    if(className){
        div.setAttribute('class', className);
    }

    div.setAttribute('style', 'visibility:hidden; position:absolute;');

    div.innerHTML = view.renderHTML();

    fragment.appendChild(div);

    document.body.appendChild(fragment);
    var rect = div.getBoundingClientRect();
    document.body.removeChild(div);

    return [rect.width, rect.height];
}

function postrenderOnce(callback){
    var postrender = function(){
        Engine.removeListener('postrender', postrender);
        callback();
    };

    _.defer(function(){
        Engine.on('postrender', postrender);
    });

}

function modifierWithTransform(config, modifier){
    modifier = modifier || new Modifier();

    if (config.transform){
        var transform;
        var candidate = config.transform;

        if(_.isArray(candidate)){
            var x = 0;
            var y = 0;
            var z = 0;

            x = config.transform[0] || x;
            y = config.transform[1] || y;
            z = config.transform[2] || z;

            transform = Transform.translate.apply(Transform, [x, y, z]);
        } else if(_.isFunction(candidate)){
            transform = candidate;
        }

        if(transform){
            modifier.transformFrom(transform);
        }
    }

    return modifier;
}

function modifierWithSize(config, modifier){
    modifier = modifier || new Modifier();

    if (config.size){
        modifier.sizeFrom(config.size);
    }

    return modifier;
}

function modifierWithOpacity(config, modifier){
    modifier = modifier || new Modifier();

    if (config.opacity){
        modifier.opacityFrom(config.opacity);
    }

    return modifier;
}

function modifierWithOrigin(config, modifier){
    modifier = modifier || new Modifier();

    if (config.origin){
        modifier.originFrom(config.origin);
    }

    return modifier;
}

function modifierWithAlign(config, modifier){
    modifier = modifier || new Modifier();

    if (config.align){
        modifier.alignFrom(config.align);
    }

    return modifier;
}

function modifierWithConfig(config){
    // config is:
    // {
    //    transform: ...
    //    origin: ...
    //    align: ...
    //    size: ...
    //    opacity: ...
    // }
    modifier = modifier || new Modifier();

    modifierWithOpacity(config, modifier);
    modifierWithOrigin(config, modifier);
    modifierWithSize(config, modifier);
    modifierWithTransform(config, modifier);

    return modifier;
}

exports.getViewSize = getViewSize;
exports.postrenderOnce = postrenderOnce;
exports.initializeRichContext = initializeRichContext;
exports.disposeRichContext = disposeRichContext;
exports.modifierWithTransform = modifierWithTransform;
exports.modifierWithSize = modifierWithSize;
exports.modifierWithOpacity = modifierWithOpacity;
exports.modifierWithOrigin = modifierWithOrigin;
exports.modifierWithAlign = modifierWithAlign;
exports.modifierWithConfig = modifierWithConfig;

});
<|endoftext|>


<commit_before>

function PpGen(columns) {

    var PLUS = " + ";
    var COMMA = ", ";

    /* ####################################################################
    ##  JAVA
    #################################################################### */

    function javaDecl(pfx, decimation) {
        var sep = "";
        for (var i=0 ; i<decimation+2 ; i++) {
            p(sep + pfx + i + "=0.0");
            sep = COMMA;
        }
        p(";"); nl();
    }

    function javaDecShift(pfx, decimation) {
        for (i=0 ; i<decimation+1 ; i++) {
            p(pfx + i + "=" + pfx + (i+1) + "; ");
        }
        p(pfx + (decimation+1) + "=v;"); nl();
    }

    function javaOutput(decimation, size, table) {
       //showTable(table); return;
        var coeffs = decimationCoefficients(table);
        p("/**"); nl();
        p(" * ### decimation : " + decimation); nl();
        p(" */"); nl();
        p("class Resampler" + decimation + "() {"); nl();
        p("    private double ");
        javaDecl("r", decimation);
        p("    private double ");
        javaDecl("i", decimation);
        p("    private int idx = 0;"); nl();
        p("    private double value = 0.0;"); nl();
        p("    private double valuei = 0.0;"); nl();
        p("    public double getValue(){ return value; }"); nl();
        p("    public double getValueI(){ return valuei; }"); nl();
        nl();

        /**
         * REAL DECIMATION
         */
        p("    public boolean decimate(double v) {"); nl();
        p("        ");
        javaDecShift("r", decimation);
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            value = ");
        jsDecCalc(coeffs, "");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    }"); nl();
        nl();

        /**
         * COMPLEX DECIMATION
         */
        p("    public boolean decimate(double r, double i) {"); nl();
        p("        ");
        javaDecShift("r", decimation);
        p("        ");
        javaDecShift("i", decimation);
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            value = ");
        jsDecCalc(coeffs, ".r");
        p(";"); nl();
        p("            valuei = ");
        jsDecCalc(coeffs, ".i");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * REAL INTERPOLATION
         */
        p("    this.interpolate = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (var row = 0 ; row < decimation ; row++) {
            var rowarr = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr)) < 0.0001) {
                p("0");
            } else {
                jsIntCalc(rowarr, "");
            }
            p(";"); nl();
        }
        p("    };"); nl();
        nl();

       /**
         * COMPLEX INTERPOLATION
         */
        p("    this.interpolatex = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (row = 0 ; row < decimation ; row++) {
            var rowarr2 = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr2)) < 0.0001) {
                p("{r:0,i:0};"); nl();
            } else {
                p("{"); nl();
                p("            r: ");
                jsIntCalc(rowarr2, ".r");
                p(","); nl();
                p("            i: ");
                jsIntCalc(rowarr2, ".r");
                nl();
                p("        };"); nl();
            }
        }
        p("    };"); nl();
        nl();

        //# END
        p("}"); nl();
        nl();

        p("}"); nl();
    }

    /* ####################################################################
    ##  JAVASCRIPT
    #################################################################### */
    function jsDecCalc(coeffs, suffix) {
        var sep = "";
        var len = coeffs.length;
        for (var i=0 ; i<len ; i++) {
            var c = coeffs[i];
            //p("c:" + c + ""); nl();
            if (Math.abs(c) > 0.000001) {
                p(sep);
                p("d" + i + suffix + "*" + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function jsIntCalc(row, suffix) {
        var sep = "";
        var len = row.length;
        for (var col=0 ; col<len ; col++) {
            var c = row[col];
            if (Math.abs(c) > 0.00001) {
                p(sep);
                p("d" + col + suffix + " * " + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function jsOutput(decimation, size, table) {
        //showTable(table); return;
        var coeffs = decimationCoefficients(table);
        p("/**"); nl();
        p(" * ### decimation : " + decimation); nl();
        p(" */"); nl();
        p("function Resampler" + decimation + "() {"); nl();
        p("    ");
        for (var i=0 ; i<decimation+2 ; i++) {
            p("var d" + i + "=0; ");
        }
        nl();
        p("    var idx = 0;"); nl();
        p("    this.value = 0;"); nl();
        nl();

        /**
         * REAL DECIMATION
         */
        p("    this.decimate = function(v) {"); nl();
        p("        ");
        for (i=0 ; i<decimation+1 ; i++) {
            p("d" + i + "=d" + (i+1) + "; ");
        }
        p("d" + (decimation+1) + "=v;"); nl();
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            this.value = ");
        jsDecCalc(coeffs, "");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * COMPLEX DECIMATION
         */
        p("    this.decimatex = function(v) {"); nl();
        p("        ");
        for (i=0 ; i<decimation+1 ; i++) {
            p("d" + i + "=d" + (i+1) + "; ");
        }
        p("d" + (decimation+1) + "=v;"); nl();
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            var r = ");
        jsDecCalc(coeffs, ".r");
        p(";"); nl();
        p("            var i = ");
        jsDecCalc(coeffs, ".i");
        p(";"); nl();
        p("            this.value = { r:r, i:i };"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * REAL INTERPOLATION
         */
        p("    this.interpolate = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (var row = 0 ; row < decimation ; row++) {
            var rowarr = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr)) < 0.0001) {
                p("0");
            } else {
                jsIntCalc(rowarr, "");
            }
            p(";"); nl();
        }
        p("    };"); nl();
        nl();

       /**
         * COMPLEX INTERPOLATION
         */
        p("    this.interpolatex = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (row = 0 ; row < decimation ; row++) {
            var rowarr2 = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr2)) < 0.0001) {
                p("{r:0,i:0};"); nl();
            } else {
                p("{"); nl();
                p("            r: ");
                jsIntCalc(rowarr2, ".r");
                p(","); nl();
                p("            i: ");
                jsIntCalc(rowarr2, ".r");
                nl();
                p("        };"); nl();
            }
        }
        p("    };"); nl();
        nl();

        //# END
        p("}"); nl();
        nl();

    }

    var output = jsOutput;

    /* ####################################################################
    ##  M A I N
    #################################################################### */

    function makeWindow(size) {
        var w = new Array(size);
        for (var i=0 ; i<size ; i++) {
            w[i] = 0.5 - 0.5 * Math.cos(2.0 * Math.PI * i / (size - 1));  //Hann window
	    }
        return w;
    }

    var col = 0;
    function p(s) {
        process.stdout.write(s);
        col += s.length;
        if ((col > 65 && s=== " + ") || col>78) {
            nl();
            process.stdout.write("                ");
            col = 12;
        }
    }
    function nl() {
        process.stdout.write("\n");
        col = 0;
    }

    function showTable(table) {
        var len = table.length;
        p("=== decimation: " + len + "\n");
        for (var row=0 ; row<len ; row++) {
            for (var col=0 ; col< columns ; col++) {
                var v = table[row][col];
                var s = v.toFixed(5);
                var strlen = s.length;
                var fs = "                ".substring(0, 10-strlen) + s;
                p(fs);

            }
        p("\n");
        }

    }

    function decimationCoefficients(table) {
        var size = columns + table.length;
        var coeffs = new Array(size);
        for (var i=0 ; i<size ; i++) {
            coeffs[i] = 0.0;
        }
        for (var row = 0 ; row < table.length ; row++) {
            for (var col = 0 ; col < columns ; col++) {
                var idx = row + col;
                var v = table[row][col];
                //p("v:" + v.toFixed(5) + "\n");
                coeffs[idx] += v;
            }
         }
        return coeffs;
   }

    function arrsum(arr) {
        var sum = 0;
        for (var i=0 ; i<arr.length ; i++) {
            sum += arr[i];
        }
        return sum;
    }
    function generate(decimation) {

        // generate the normal FIR coefficients for the decimation
        var omega = Math.PI * 2.0 / decimation;
        var size = columns * decimation;
        var half = size>>1;
        var w = makeWindow(size);
        var sum = 0;
        var coeffs = new Array(size);
        for (var idx=0 ; idx < size ; idx++) {
            var i = idx - half;
            var coeff = (i === 0) ? omega / Math.PI : Math.sin(omega * i) / (Math.PI * i);
            sum += coeff;
            coeffs[idx] = coeff * w[idx];
        }

        //Normalize gain
        for (var ii=0 ; ii<size ; ii++) {
            coeffs[ii] /= sum;
        }

        /**
         * Now arrange into rows&columns for polyphase.
         * 0  4  8
         * 1  5  9
         * 2  6 10
         * 3  7 11
        */
        var table = new Array(decimation);
        for (var ij=0 ; ij<decimation ; ij++) {
            table[ij] = new Array(columns);
        }

        var cptr = 0;
        for (var col=0 ; col<columns ; col++) {
            for (var row=0 ; row<decimation ; row++) {
                table[row][col] = coeffs[cptr++];
            }
        }
        output(decimation, size, table);
    }

    function doIt() {

        for (var decim=2 ; decim<=7 ; decim++) {
            generate(decim);
        }
        generate(11);
        generate(13);
        generate(17);
        generate(19);
    }

    this.doIt = doIt;

}

var ppg = new PpGen(3);
ppg.doIt();
<commit_msg>Source-generating script<commit_after>

function PpGen(columns) {

    var PLUS = " + ";
    var COMMA = ", ";

    /* ####################################################################
    ##  JAVA
    #################################################################### */

    function javaDecl(pfx, decimation) {
        var sep = "";
        for (var i=0 ; i<decimation+2 ; i++) {
            p(sep + pfx + i + "=0.0");
            sep = COMMA;
        }
        p(";"); nl();
    }

    function javaDecShift(pfx, decimation, rhs) {
        for (i=0 ; i<decimation+1 ; i++) {
            p(pfx + i + "=" + pfx + (i+1) + "; ");
        }
        p(pfx + (decimation+1) + "=" + rhs + ";"); nl();
    }

    function javaDecCalc(pfx, coeffs, suffix) {
        var sep = "";
        var len = coeffs.length;
        for (var i=0 ; i<len ; i++) {
            var c = coeffs[i];
            //p("c:" + c + ""); nl();
            if (Math.abs(c) > 0.000001) {
                p(sep);
                p(pfx + i + suffix + "*" + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function javaIntCalc(pfx, row, suffix) {
        var sep = "";
        var len = row.length;
        for (var col=0 ; col<len ; col++) {
            var c = row[col];
            if (Math.abs(c) > 0.00001) {
                p(sep);
                p(pfx + col + suffix + " * " + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function javaOutput(decimation, size, table) {
       //showTable(table); return;
        var coeffs = decimationCoefficients(table);
        p("/**"); nl();
        p(" * ### decimation : " + decimation); nl();
        p(" */"); nl();
        p("public static class RS" + decimation + " implements RS {"); nl();
        p("    private double ");
        javaDecl("r", decimation);
        p("    private double ");
        javaDecl("i", decimation);
        p("    private int idx = 0;"); nl();
        p("    private double r = 0.0;"); nl();
        p("    private double i = 0.0;"); nl();
        p("    public double getR(){ return r; }"); nl();
        p("    public double getI(){ return i; }"); nl();
        nl();

        /**
         * REAL DECIMATION
         */
        p("    public boolean decimate(double v) {"); nl();
        p("        ");
        javaDecShift("r", decimation, "v");
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            r = ");
        javaDecCalc("r", coeffs, "");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    }"); nl();
        nl();

        /**
         * COMPLEX DECIMATION
         */
        p("    public boolean decimate(double r, double i) {"); nl();
        p("        ");
        javaDecShift("r", decimation, "r");
        p("        ");
        javaDecShift("i", decimation, "i");
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            r = ");
        javaDecCalc("r", coeffs, "");
        p(";"); nl();
        p("            i = ");
        javaDecCalc("i", coeffs, "");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * REAL INTERPOLATION
         */
        p("    public void interpolate(double v, double buf[]) {"); nl();
        p("        r0 = r1; r1 = r2; r2 = v;"); nl();
        for (var row = 0 ; row < decimation ; row++) {
            var rowarr = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr)) < 0.0001) {
                p("0");
            } else {
                javaIntCalc("r", rowarr, "");
            }
            p(";"); nl();
        }
        p("    };"); nl();
        nl();

       /**
         * COMPLEX INTERPOLATION
         */
        p("    public void interpolate(double r, double i, double rbuf[], double ibuf[]) {"); nl();
        p("        r0 = r1; r1 = r2; r2 = r;"); nl();
        p("        i0 = i1; i1 = i2; i2 = i;"); nl();
        for (row = 0 ; row < decimation ; row++) {
            var rowarr2 = table[row];
            p("        rbuf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr2)) < 0.0001) {
                p("0.0;"); nl();
            } else {
                javaIntCalc("r", rowarr2, "");
                p(";"); nl();
            }
            p("        ibuf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr2)) < 0.0001) {
                p("0.0;"); nl();
            } else {
                javaIntCalc("i", rowarr2, "");
                p(";"); nl();
            }
        }
        p("    };"); nl();
        nl();

        //# END
        p("}"); nl();
        nl();
    }

    function javaHeader() {
        p("public class Resampler {"); nl();
        p("    public interface RS {"); nl();
        p("        public boolean decimate(double v);"); nl();
        p("        public boolean decimate(double r, double i);"); nl();
        p("        public void interpolate(double v, double buf[]);"); nl();
        p("        public void interpolate(double r, double i, double rbuf[], double ibuf[]);"); nl();
        p("        public double getR();"); nl();
        p("        public double getI();"); nl();
        p("    }"); nl();
        nl();
        p("    public static class RS1 implements RS {"); nl();
        p("        private double r; double i;"); nl();
        p("        public boolean decimate(double v) { r = v ; return true; }"); nl();
        p("        public boolean decimate(double r, double i) { this.r=r; this.i=i; return true; }"); nl();
        p("        public void interpolate(double v, double buf[]) { buf[0] = v; }"); nl();
        p("        public void interpolate(double r, double i, double rbuf[], double ibuf[]) "); nl();
        p("            { rbuf[0]=r; ibuf[0] = i; }"); nl();
        p("        public double getR() { return r; }"); nl();
        p("        public double getI() { return i; }"); nl();
        p("    }"); nl();
        nl();
    }

    function javaFooter() {
        p("    public static RS create(int decimation) {"); nl();
        p("        switch (decimation) {"); nl();
        p("            case 2 : return new RS2();"); nl();
        p("            case 3 : return new RS3();"); nl();
        p("            case 4 : return new RS4();"); nl();
        p("            case 5 : return new RS5();"); nl();
        p("            case 6 : return new RS6();"); nl();
        p("            case 7 : return new RS7();"); nl();
        p("            default :"); nl();
        p("                throw new IllegalArgumentException(\"Decimation \" + decimation + \" is not supported\");"); nl();
        p("        }"); nl();
        p("    }"); nl();
        p("}"); nl();
    }

    /* ####################################################################
    ##  JAVASCRIPT
    #################################################################### */
    function jsDecCalc(coeffs, suffix) {
        var sep = "";
        var len = coeffs.length;
        for (var i=0 ; i<len ; i++) {
            var c = coeffs[i];
            //p("c:" + c + ""); nl();
            if (Math.abs(c) > 0.000001) {
                p(sep);
                p("d" + i + suffix + "*" + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function jsIntCalc(row, suffix) {
        var sep = "";
        var len = row.length;
        for (var col=0 ; col<len ; col++) {
            var c = row[col];
            if (Math.abs(c) > 0.00001) {
                p(sep);
                p("d" + col + suffix + " * " + c.toFixed(5));
                sep = PLUS;
            }
        }
    }

    function jsOutput(decimation, size, table) {
        //showTable(table); return;
        var coeffs = decimationCoefficients(table);
        p("/**"); nl();
        p(" * ### decimation : " + decimation); nl();
        p(" */"); nl();
        p("function Resampler" + decimation + "() {"); nl();
        p("    ");
        for (var i=0 ; i<decimation+2 ; i++) {
            p("var d" + i + "=0; ");
        }
        nl();
        p("    var idx = 0;"); nl();
        p("    this.value = 0;"); nl();
        nl();

        /**
         * REAL DECIMATION
         */
        p("    this.decimate = function(v) {"); nl();
        p("        ");
        for (i=0 ; i<decimation+1 ; i++) {
            p("d" + i + "=d" + (i+1) + "; ");
        }
        p("d" + (decimation+1) + "=v;"); nl();
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            this.value = ");
        jsDecCalc(coeffs, "");
        p(";"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * COMPLEX DECIMATION
         */
        p("    this.decimatex = function(v) {"); nl();
        p("        ");
        for (i=0 ; i<decimation+1 ; i++) {
            p("d" + i + "=d" + (i+1) + "; ");
        }
        p("d" + (decimation+1) + "=v;"); nl();
        p("        if (++idx >= " + decimation + ") {"); nl();
        p("            idx = 0;"); nl();
        p("            var r = ");
        jsDecCalc(coeffs, ".r");
        p(";"); nl();
        p("            var i = ");
        jsDecCalc(coeffs, ".i");
        p(";"); nl();
        p("            this.value = { r:r, i:i };"); nl();
        p("            return true;"); nl();
        p("        } else {"); nl();
        p("            return false;"); nl();
        p("        }"); nl();
        p("    };"); nl();
        nl();

        /**
         * REAL INTERPOLATION
         */
        p("    this.interpolate = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (var row = 0 ; row < decimation ; row++) {
            var rowarr = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr)) < 0.0001) {
                p("0");
            } else {
                jsIntCalc(rowarr, "");
            }
            p(";"); nl();
        }
        p("    };"); nl();
        nl();

       /**
         * COMPLEX INTERPOLATION
         */
        p("    this.interpolatex = function(v, buf) {"); nl();
        p("        d0 = d1; d1 = d2; d2 = v;"); nl();
        for (row = 0 ; row < decimation ; row++) {
            var rowarr2 = table[row];
            p("        buf[" + row + "] = ");
            if (Math.abs(arrsum(rowarr2)) < 0.0001) {
                p("{r:0,i:0};"); nl();
            } else {
                p("{"); nl();
                p("            r: ");
                jsIntCalc(rowarr2, ".r");
                p(","); nl();
                p("            i: ");
                jsIntCalc(rowarr2, ".r");
                nl();
                p("        };"); nl();
            }
        }
        p("    };"); nl();
        nl();

        //# END
        p("}"); nl();
        nl();

    }

    var header = javaHeader;
    var output = javaOutput;
    var footer = javaFooter;

    /* ####################################################################
    ##  M A I N
    #################################################################### */

    function makeWindow(size) {
        var w = new Array(size);
        for (var i=0 ; i<size ; i++) {
            w[i] = 0.5 - 0.5 * Math.cos(2.0 * Math.PI * i / (size - 1));  //Hann window
	    }
        return w;
    }

    var col = 0;
    function p(s) {
        process.stdout.write(s);
        col += s.length;
        if ((col > 65 && s=== " + ") || col>78) {
            nl();
            process.stdout.write("                ");
            col = 12;
        }
    }
    function nl() {
        process.stdout.write("\n");
        col = 0;
    }

    function showTable(table) {
        var len = table.length;
        p("=== decimation: " + len + "\n");
        for (var row=0 ; row<len ; row++) {
            for (var col=0 ; col< columns ; col++) {
                var v = table[row][col];
                var s = v.toFixed(5);
                var strlen = s.length;
                var fs = "                ".substring(0, 10-strlen) + s;
                p(fs);

            }
        p("\n");
        }

    }

    function decimationCoefficients(table) {
        var size = columns + table.length;
        var coeffs = new Array(size);
        for (var i=0 ; i<size ; i++) {
            coeffs[i] = 0.0;
        }
        for (var row = 0 ; row < table.length ; row++) {
            for (var col = 0 ; col < columns ; col++) {
                var idx = row + col;
                var v = table[row][col];
                //p("v:" + v.toFixed(5) + "\n");
                coeffs[idx] += v;
            }
         }
        return coeffs;
   }

    function arrsum(arr) {
        var sum = 0;
        for (var i=0 ; i<arr.length ; i++) {
            sum += arr[i];
        }
        return sum;
    }
    function generate(decimation) {

        // generate the normal FIR coefficients for the decimation
        var omega = Math.PI * 2.0 / decimation;
        var size = columns * decimation;
        var half = size>>1;
        var w = makeWindow(size);
        var sum = 0;
        var coeffs = new Array(size);
        for (var idx=0 ; idx < size ; idx++) {
            var i = idx - half;
            var coeff = (i === 0) ? omega / Math.PI : Math.sin(omega * i) / (Math.PI * i);
            sum += coeff;
            coeffs[idx] = coeff * w[idx];
        }

        //Normalize gain
        for (var ii=0 ; ii<size ; ii++) {
            coeffs[ii] /= sum;
        }

        /**
         * Now arrange into rows&columns for polyphase.
         * 0  4  8
         * 1  5  9
         * 2  6 10
         * 3  7 11
        */
        var table = new Array(decimation);
        for (var ij=0 ; ij<decimation ; ij++) {
            table[ij] = new Array(columns);
        }

        var cptr = 0;
        for (var col=0 ; col<columns ; col++) {
            for (var row=0 ; row<decimation ; row++) {
                table[row][col] = coeffs[cptr++];
            }
        }
        output(decimation, size, table);
    }

    function doIt() {

        header();

        for (var decim=2 ; decim<=7 ; decim++) {
            generate(decim);
        }
        generate(11);

        footer();
    }

    this.doIt = doIt;

}

var ppg = new PpGen(3);
ppg.doIt();
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name dreFrontendApp.controller:ProfileCtrl
 * @description
 * # ProfileCtrl
 * Controller of the dreFrontendApp
 */
angular.module('dreFrontendApp')
    .controller('ProfileCtrl', function ($scope, _, dreFrontEndPatientInfoService, dreFrontendGlobals, fhirEnv,
                                         dreFrontendFhirService, fhirValueSet) {

        $scope.init = function () {
            $scope.model = {
                patient: null,
                patientId: null,
                firstName: "",
                middleName: "",
                lastName: "",
                dateOfBirth: "",
                gender: "",
                primaryEmail: "",
                race: "",
                ethnicity: "",
                maritalStatus: "",
                addresses: [],
                phones: []
            };
        };
        $scope.init();

        $scope.view = {
            edit: false,
            addressEdit: false,
            phoneEdit: false,
            monthNames: dreFrontendGlobals.monthNames,
            maritalStatuses: [],
            genders: [],
            ethnicityCodes: fhirEnv.ethnicityCodes,
            raceCodes: fhirEnv.raceCodes,
            addressTypes: [],
            contactUse: []
        };

//todo refactor controller

        fhirValueSet.get("AddressType")
            .then(function (data) {
                $scope.view.addressTypes = data;
            });

        fhirValueSet.get("ContactPointUse")
            .then(function (data) {
                $scope.view.contactUse = data;
            });

        fhirValueSet.get("AdministrativeGender")
            .then(function (data) {
                $scope.view.genders = data;
            });

        fhirValueSet.get("v3 Code System MaritalStatus")
            .then(function (data) {
                $scope.view.maritalStatuses = data;
            });

        var _initTelecom = function (patient) {
            if (!patient.telecom || patient.telecom.length === 0) {
                patient.telecom = [
                    {system: fhirEnv.contactSystemCodes.email, value: ''},
                    {system: fhirEnv.contactSystemCodes.phone, value: ''}
                ];
            } else {
                var qty = {};
                angular.forEach(fhirEnv.contactSystemCodes, function (v) {
                    qty[v] = 0;
                });
                angular.forEach(patient.telecom, function (v) {
                    qty[v.system]++;
                });
                angular.forEach(qty, function (v, k) {
                    if (v < 1) {
                        patient.telecom.push({system: k, value: null});
                    }
                });
            }

        };

        $scope.contactSystemCodes = fhirEnv.contactSystemCodes;

        $scope.initPatientModel = function (force) {
            $scope.init();
            dreFrontEndPatientInfoService
                .getPatientData(force)
                .then(function (patient) {
                    var model = $scope.model;
                    model.patient = patient;
                    $scope.model.patientId = patient.id;

                    if (patient.name !== undefined && patient.name.length !== 0) {
                        var names = patient.name[0];
                        if (names.family !== undefined && names.family.length !== 0) {
                            model.lastName = names.family[0];
                        }
                        if (names.given !== undefined && names.given.length !== 0) {
                            model.firstName = names.given[0];
                            if (names.given.length > 1) {
                                model.middleName = names.given[1];
                            }
                        }
                    }
                    _initTelecom(patient);

                    if (patient.telecom && patient.telecom.length > 0) {
                        _.forEach(patient.telecom, function (entry) {
                            if (entry.system === $scope.contactSystemCodes.email) {
                                model.primaryEmail = entry.value;
                            }
                            if (entry.system === $scope.contactSystemCodes.phone) {
                                model.phones.push(entry);
                            }
                        });
                    }

                    if (patient.maritalStatus && patient.maritalStatus.coding.length > 0) {
                        model.maritalStatus = patient.maritalStatus.coding[0];
                    }

                    var extensionInfo;
                    if (patient.extension && patient.extension.length > 0) {
                        extensionInfo = patient.extension;
                    }

                    if (patient.birthDate) {
                        model.dateOfBirth = new Date(patient.birthDate);
                    }

                    if (patient.gender) {
                        model.gender = patient.gender;
                    }

                    if (patient.address && patient.address.length !== 0) {
                        model.addresses = patient.address;
                    } else {
                        patient.address = [];
                        model.addresses = patient.address;
                    }

                    _.forEach(model.addresses, function (entry) {
                        $scope.setContactType(entry);
                    });

                    _.forEach(model.phones, function (entry) {
                        $scope.setContactType(entry);
                    });

                    _.forEach(extensionInfo, function (entry) {
                        if (entry.url) {
                            var _url_type = null;
                            if (entry.url === fhirEnv.raceExtensionUrl) {
                                _url_type = 'race';
                            }
                            if (entry.url === fhirEnv.ethnicityExtensionUrl) {
                                _url_type = 'ethnicity';
                            }
                            if (_url_type && entry.valueCodeableConcept && entry.valueCodeableConcept.coding && entry.valueCodeableConcept.coding.length > 0) {
                                model[_url_type] = entry.valueCodeableConcept.coding[0];
                            }

                        }
                    });
                });
        };
        $scope.initPatientModel(true);

        $scope.changeEditProfileSection = function (force) {
            $scope.view.edit = !$scope.view.edit;
            $scope.initPatientModel(force);
        };

        $scope.changeEditAddressSection = function (force) {
            $scope.view.addressEdit = !$scope.view.addressEdit;
            $scope.initPatientModel(force);
        };

        $scope.changeEditPhoneSection = function (force) {
            $scope.view.phoneEdit = !$scope.view.phoneEdit;
            $scope.initPatientModel(force);
        };

        $scope.setContactType = function (address) {
            _.forEach($scope.view.addressCodes, function (entry) {
                if (address.use === entry.code) {
                    address.contactType = entry;
                }
            });
        };

        //TODO Check for bad response, SHOW IT in the GUI

        var _updatePatient = function(_patient) {
            _patient = _patient || $scope.model.patient;
            _patient.update()
                .then(function(){
                    $scope.changeEditProfileSection(true);
                });
        };

        $scope.updateProfile = function () {
            var model = $scope.model;
            var patient = model.patient;
            patient.name = [{given: [model.firstName, model.middleName], family: [model.lastName]}];
            patient.telecom = [];
            patient.telecom = patient.telecom.concat(model.phones);
            patient.telecom.push({system: $scope.contactSystemCodes.email, value: model.primaryEmail});
            patient.maritalStatus = {coding: [model.maritalStatus]};
            patient.birthDate = model.dateOfBirth.toISOString();
            patient.gender = model.gender;

            var extensionInfo;
            if (patient.extension && patient.extension.length > 0) {
                extensionInfo = patient.extension;
            } else {
                patient.extension = [];
                extensionInfo = patient.extension;
            }

            var raceFound = false;
            var ethnicityFound = false;
            _.forEach(extensionInfo, function (entry) {
                if (entry.url) {
                    if (entry.url === fhirEnv.raceExtensionUrl) {
                        entry.valueCodeableConcept = {};
                        entry.valueCodeableConcept.coding = [model.race];
                        raceFound = true;
                    }
                    if (entry.url === fhirEnv.ethnicityExtensionUrl) {
                        entry.valueCodeableConcept = {};
                        entry.valueCodeableConcept.coding = [model.ethnicity];
                        ethnicityFound = true;
                    }

                }
            });

            if (!raceFound) {
                var raceObj = {};
                raceObj.url = fhirEnv.raceExtensionUrl;
                raceObj.valueCodeableConcept = {};
                raceObj.valueCodeableConcept.coding = [model.race];
                patient.extension.push(raceObj);
            }

            if (!ethnicityFound) {
                var ethnicityObj = {};
                ethnicityObj.url = fhirEnv.ethnicityExtensionUrl;
                ethnicityObj.valueCodeableConcept = {};
                ethnicityObj.valueCodeableConcept.coding = [model.ethnicity];
                patient.extension.push(ethnicityObj);
            }

            _updatePatient(patient);
        };

        $scope.updateAddress = _updatePatient;
        $scope.updatePhone = _updatePatient;
    })
;
<commit_msg>small fix in profile controller<commit_after>'use strict';

/**
 * @ngdoc function
 * @name dreFrontendApp.controller:ProfileCtrl
 * @description
 * # ProfileCtrl
 * Controller of the dreFrontendApp
 */
angular.module('dreFrontendApp')
    .controller('ProfileCtrl', function ($scope, _, dreFrontEndPatientInfoService, dreFrontendGlobals, fhirEnv,
                                         dreFrontendFhirService, fhirValueSet) {

        $scope.init = function () {
            $scope.model = {
                patient: null,
                patientId: null,
                firstName: "",
                middleName: "",
                lastName: "",
                dateOfBirth: "",
                gender: "",
                primaryEmail: "",
                race: "",
                ethnicity: "",
                maritalStatus: "",
                addresses: [],
                phones: []
            };
        };
        $scope.init();

        $scope.view = {
            edit: false,
            addressEdit: false,
            phoneEdit: false,
            monthNames: dreFrontendGlobals.monthNames,
            maritalStatuses: [],
            genders: [],
            ethnicityCodes: fhirEnv.ethnicityCodes,
            raceCodes: fhirEnv.raceCodes,
            addressTypes: [],
            contactUse: []
        };

//todo refactor controller

        fhirValueSet.get("AddressType")
            .then(function (data) {
                $scope.view.addressTypes = data;
            });

        fhirValueSet.get("ContactPointUse")
            .then(function (data) {
                $scope.view.contactUse = data;
            });

        fhirValueSet.get("AdministrativeGender")
            .then(function (data) {
                $scope.view.genders = data;
            });

        fhirValueSet.get("v3 Code System MaritalStatus")
            .then(function (data) {
                $scope.view.maritalStatuses = data;
            });

        var _initTelecom = function (patient) {
            if (!patient.telecom || patient.telecom.length === 0) {
                patient.telecom = [
                    {system: fhirEnv.contactSystemCodes.email, value: ''},
                    {system: fhirEnv.contactSystemCodes.phone, value: ''}
                ];
            } else {
                var qty = {};
                angular.forEach(fhirEnv.contactSystemCodes, function (v) {
                    qty[v] = 0;
                });
                angular.forEach(patient.telecom, function (v) {
                    qty[v.system]++;
                });
                angular.forEach(qty, function (v, k) {
                    if (v < 1) {
                        patient.telecom.push({system: k, value: null});
                    }
                });
            }

        };

        $scope.contactSystemCodes = fhirEnv.contactSystemCodes;

        $scope.initPatientModel = function (force) {
            $scope.init();
            dreFrontEndPatientInfoService
                .getPatientData(force)
                .then(function (patient) {
                    var model = $scope.model;
                    model.patient = patient;
                    $scope.model.patientId = patient.id;

                    if (patient.name !== undefined && patient.name.length !== 0) {
                        var names = patient.name[0];
                        if (names.family !== undefined && names.family.length !== 0) {
                            model.lastName = names.family[0];
                        }
                        if (names.given !== undefined && names.given.length !== 0) {
                            model.firstName = names.given[0];
                            if (names.given.length > 1) {
                                model.middleName = names.given[1];
                            }
                        }
                    }
                    _initTelecom(patient);

                    if (patient.telecom && patient.telecom.length > 0) {
                        _.forEach(patient.telecom, function (entry) {
                            if (entry.system === $scope.contactSystemCodes.email) {
                                model.primaryEmail = entry.value;
                            }
                            if (entry.system === $scope.contactSystemCodes.phone) {
                                model.phones.push(entry);
                            }
                        });
                    }

                    if (patient.maritalStatus && patient.maritalStatus.coding.length > 0) {
                        model.maritalStatus = patient.maritalStatus.coding[0];
                    }

                    var extensionInfo;
                    if (patient.extension && patient.extension.length > 0) {
                        extensionInfo = patient.extension;
                    }

                    if (patient.birthDate) {
                        model.dateOfBirth = new Date(patient.birthDate);
                    }

                    if (patient.gender) {
                        model.gender = patient.gender;
                    }

                    if (patient.address && patient.address.length !== 0) {
                        model.addresses = patient.address;
                    } else {
                        patient.address = [];
                        model.addresses = patient.address;
                    }

                    _.forEach(model.addresses, function (entry) {
                        $scope.setContactType(entry);
                    });

                    _.forEach(model.phones, function (entry) {
                        $scope.setContactType(entry);
                    });

                    _.forEach(extensionInfo, function (entry) {
                        if (entry.url) {
                            var _url_type = null;
                            if (entry.url === fhirEnv.raceExtensionUrl) {
                                _url_type = 'race';
                            }
                            if (entry.url === fhirEnv.ethnicityExtensionUrl) {
                                _url_type = 'ethnicity';
                            }
                            if (_url_type && entry.valueCodeableConcept && entry.valueCodeableConcept.coding && entry.valueCodeableConcept.coding.length > 0) {
                                model[_url_type] = entry.valueCodeableConcept.coding[0];
                            }

                        }
                    });
                });
        };
        $scope.initPatientModel(true);

        $scope.changeEditProfileSection = function (force) {
            $scope.view.edit = !$scope.view.edit;
            $scope.initPatientModel(force);
        };

        $scope.changeEditAddressSection = function (force) {
            $scope.view.addressEdit = !$scope.view.addressEdit;
            $scope.initPatientModel(force);
        };

        $scope.changeEditPhoneSection = function (force) {
            $scope.view.phoneEdit = !$scope.view.phoneEdit;
            $scope.initPatientModel(force);
        };

        $scope.setContactType = function (address) {
            _.forEach($scope.view.addressCodes, function (entry) {
                if (address.use === entry.code) {
                    address.contactType = entry;
                }
            });
        };

        //TODO Check for bad response, SHOW IT in the GUI

        var _updatePatient = function (_patient, _editSection) {
            _patient.update()
                .then(function () {
                    $scope.view[_editSection]= false;
                    $scope.initPatientModel(true);
                });
        };

        $scope.updateProfile = function () {
            var model = $scope.model;
            var patient = model.patient;
            patient.name = [{given: [model.firstName, model.middleName], family: [model.lastName]}];
            patient.telecom = [];
            patient.telecom = patient.telecom.concat(model.phones);
            patient.telecom.push({system: $scope.contactSystemCodes.email, value: model.primaryEmail});
            patient.maritalStatus = {coding: [model.maritalStatus]};
            patient.birthDate = model.dateOfBirth.toISOString();
            patient.gender = model.gender;

            var extensionInfo;
            if (patient.extension && patient.extension.length > 0) {
                extensionInfo = patient.extension;
            } else {
                patient.extension = [];
                extensionInfo = patient.extension;
            }

            var raceFound = false;
            var ethnicityFound = false;
            _.forEach(extensionInfo, function (entry) {
                if (entry.url) {
                    if (entry.url === fhirEnv.raceExtensionUrl) {
                        entry.valueCodeableConcept = {};
                        entry.valueCodeableConcept.coding = [model.race];
                        raceFound = true;
                    }
                    if (entry.url === fhirEnv.ethnicityExtensionUrl) {
                        entry.valueCodeableConcept = {};
                        entry.valueCodeableConcept.coding = [model.ethnicity];
                        ethnicityFound = true;
                    }

                }
            });

            if (!raceFound) {
                var raceObj = {};
                raceObj.url = fhirEnv.raceExtensionUrl;
                raceObj.valueCodeableConcept = {};
                raceObj.valueCodeableConcept.coding = [model.race];
                patient.extension.push(raceObj);
            }

            if (!ethnicityFound) {
                var ethnicityObj = {};
                ethnicityObj.url = fhirEnv.ethnicityExtensionUrl;
                ethnicityObj.valueCodeableConcept = {};
                ethnicityObj.valueCodeableConcept.coding = [model.ethnicity];
                patient.extension.push(ethnicityObj);
            }

            _updatePatient($scope.model.patient, 'edit');
        };

        $scope.updateAddress = function () {
            _updatePatient($scope.model.patient, 'addressEdit');
        };

        $scope.updatePhone = function () {
            _updatePatient($scope.model.patient, 'phoneEdit');
        };
    });
<|endoftext|>