<commit_before>'use strict';

var fs                    = require('fs-extra');

var fileUtils             = rootRequire('utils/file-utils');
var authenticationUtils   = rootRequire('utils/authentication-utils');
var model                 = rootRequire('models/model');
var cloudstorage          = rootRequire('libs/cloudstorage/cloudstorage');
var beatport              = rootRequire('libs/beatport/beatport');

module.exports.controller = function(app) {

  /**
   * Ensures current user is the owner of the company
   * Company ID must be passed as req.body.companyId
   **/
  function ensureCompanyOwner(req, res, next) {
    var companyId = req.body.companyId;
    var userId = req.user;
    model.Company.find({ where: {id: companyId} }).then(function(company) {
      if (!company) {
        var err = new Error();
        err.status=404;
        err.message="Requested company does not exist";
        return next(err);
      }
      company.getUsers({ where: {id: userId}}).then(function(user) {
        if (!user){
          var err = new Error();
          err.status=401;
          err.message="You don't have access to the requested resource";
          return next(err);
        }
        return next();
      });
    });
  }

  /**
   * Ensure current user is an owner of the company who ows the label
   * Label ID must be passed as req.params.labelId
   **/
  function ensureCompanyOwnerFromLabel(req, res, next) {
    var labelId = req.params.labelId;
    var userId = req.user;
    model.Label.find({ where: {id: labelId} }).then(function(label) {
      if (!label) {
        var err = new Error();
        err.status=404;
        err.message="Requested label does not exist";
        return next(err);
      }
      label.getCompanies().then(function(companies) {
        if (!companies) {
          var err = new Error();
          err.status=401;
          err.message="You don't have access to the requested resource";
          return next(err);
        }
        companies.forEach(function(company) {
          company.getUsers({ where: {id: userId}}).then(function(user) {
            if (!user){
              var err = new Error();
              err.status=401;
              err.message="You don't have access to the requested resource";
              return next(err);
            }
            return next();
          });
        });
      });
    });
  }

  /**
   * Ensure current user is a manager of the selected label
   * Label ID must be passed as req.params.labelId
   **/
  function ensureLabelManager(req, res, next) {
    var labelId = req.params.labelId;
    model.Label.find({ where: {id: labelId} }).then(function(label) {
      if (!label) {
        var err = new Error();
        err.status=404;
        err.message="Requested label does not exist";
        return next(err);
      }
      label.getUsers({ where: {id: userId}}).then(function(users) {
        if (!users) {
          var err = new Error();
          err.status=401;
          err.message="You don't have access to the requested resource";
          return next(err);
        }
        return next();
      });
    });
  }

  /**
   * Ensure current user is either company owner or label manager
   * Label ID must be passed as req.params.labelId
   **/
  function ensureLabelManagerOrCompanyOwner(req, res, next) {
    var labelId = req.params.labelId;
    var userId = req.user;
    model.Label.find({ where: {id: labelId} }).then(function(label) {
      if (!label) {
        var err = new Error();
        err.status=404;
        err.message="Requested label does not exist";
        return next(err);
      }
      label.getUsers({ where: {id: userId}}).then(function(users) {
        if (!users) {
          // Current user is not label manager, check if he is company owner
          label.getCompanies().then(function(companies) {
            if (!companies) {
              var err = new Error();
              err.status=401;
              err.message="You don't have access to the requested resource";
              return next(err);
            }
            companies.forEach(function(company) {
              company.getUsers({ where: {id: userId}}).then(function(user) {
                if (!user){
                  var err = new Error();
                  err.status=401;
                  err.message="You don't have access to the requested resource";
                  return next(err);
                }
                return next();
              });
            });
          });
        }
        return next();
      });
    });
  }

  /**
   * GET /labels/search/:searchString
   * Return the list of labels whose displayName resambles the search string
   * TODO: paginate request
   */
  app.get('/labels/search/:searchString', function(req, res, next) {
    var searchString = req.params.searchString;
    model.Label.find({ where: ["displayName LIKE ?", "%"+searchString+"%"] }).then(function(labels) {
      res.send(labels);
    });
  });

  /**
   * GET /labels/search/:searchString
   * Return the list of labels whose displayName exactly matches the search string
   */
  app.get('/labels/searchExact/:searchString', function(req, res, next) {
    var searchString = req.params.searchString;
    model.Label.find({ where: {displayName: searchString} }).then(function(labels) {
      res.send(labels);
    });
  });

  /**
   * GET /labels/:id
   * Return the label corresponding to the passed id
   */
  app.get('/labels/:labelId', authenticationUtils.ensureAuthenticated, function(req, res, next) {
    var LabelId = req.params.labelId;
    model.Label.find({ where: {id: LabelId} }).then(function(label) {
      if(label){
        label.getUsers({attributes: ['displayName']}).success(function(associatedUsers) {
          label.dataValues.labelManagers = (associatedUsers);
          res.send(label);
        })
      } else {
        var err = new Error();
        err.status=404;
        err.message="Requested label does not exist";
        return next(err);
      }
    });
  });

  /**
   * POST /labels/
   * Add label in post payload to the label list of the company
   * TODO: permission controll, check current user is owner of the company and company owns the label
   **/
  app.post('/labels/', authenticationUtils.ensureAuthenticated, ensureCompanyOwner, function(req, res, next) {
    var companyId = req.body.companyId;
    var labelName = req.body.labelName;

    console.log("companyId"+companyId)
    console.log("labelName"+labelName)

    model.Label.find({ where: {displayName: labelName}}).success(function(label) {
      if(!label){
         model.Label.create({
              displayName: labelName
            }).success(function(label) {
                  model.Company.find({where: {id: companyId}}).then(function(company) {
                    company.addLabels([label]).success(function(labels) {
                      //model.User.find({where: {id: req.user}}).then(function(user) {
                        //label.addUsers([user]).success(function(user) {
                          res.send();
                        //});
                      //});
                  });
                })
            })
      } else {
        var err = new Error();
        err.status = 409;
        err.message = "Label name already in use";
        return next(err);
      }
    });
  });

  /**
   * POST /labels/:idLabel/profilePicture/:width/:height/
   * Upload label profile picture to the CDN, original size and resized
   **/
  app.post('/labels/:labelId/profilePicture/:width/:height/',
    authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner,
    fileUtils.uploadFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
    fileUtils.resizeFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
    function (req, res, next) {
      var idLabel = req.params.labelId;
      model.Label.find({ where: {id: idLabel} }).then(function(label) {
        var oldLogo = label.logo;
        var oldFullSizeLogo = label.fullSizeLogo;
        label.logo = fileUtils.remoteImagePath(req, req.uploadedFile[0].resizedFilename);
        label.fullSizeLogo = fileUtils.remoteImagePath(req, req.uploadedFile[0].filename);

        label.save().then(function (label) {
          // we remove old avatars from the CDN
          cloudstorage.remove(oldLogo);
          cloudstorage.remove(oldFullSizeLogo);
          // We remove temporarily stored files
          fs.unlink(fileUtils.localImagePath(req, req.uploadedFile[0].filename));
          fs.unlink(fileUtils.localImagePath(req, req.uploadedFile[0].resizedFilename));

          res.writeHead(200, {"content-type":"text/html"});   //http response header
          res.end(JSON.stringify(req.uploadedFile));
        });
      });
    });

  /**
   * POST /labels/:idLabel/dropZone
   * Upload a file to the dropZone for the label with id :idLabel
   **/
  app.post('/labels/:labelId/dropZone/',
    authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner,
    fileUtils.uploadFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
    function (req, res, next) {

        var idLabel = req.params.labelId;
        console.log("****************")
        console.log(req.uploadedFile)
        console.log("****************")

        model.DropZoneFile.find({ where: model.Sequelize.and({fileName: req.uploadedFile[0].originalfilename},{extension: req.uploadedFile[0].extension} ) }).then(function(file) {
          if(file){
            // file exists .. Update file?
            file.path = req.uploadedFile[0].filename;
            file.size = req.uploadedFile[0].filesize;
            file.save().success(function() {
              res.send();
            })
          }else{
            model.DropZoneFile.create({
              fileName: req.uploadedFile[0].originalfilename,
              extension: req.uploadedFile[0].extension,
              size: req.uploadedFile[0].filesize,
              path: req.uploadedFile[0].filename,
            }).success(function(dropZoneFile) {
              model.Label.find({ where: {id: idLabel}}).then(function(label){
                label.addDropZoneFiles(dropZoneFile).then(function(associationFile) {
                  res.send();
                })
              });

            })
          }

        });
       //res.send();
  });

  /**
   * GET /labels/:idLabel/processReleases/info
   * Validates the files in the dropZone to a beatport compliant playlist
   **/
  app.get('/labels/:labelId/processReleases/info', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
      var idLabel = req.params.labelId;
      model.Label.find({ where: {id: idLabel}}).then(function(label){
        console.log("The label found for release infos is " + label);
        if (!label) {
          var err = new Error();
          err.status = 404;
          err.message = "Requested label does not exist";
          return next(err);
        }
        label.getDropZoneFiles({where: {extension: "xml"}}).then(function(xmls){

            beatport.validate(xmls).then(function(results){
              res.send(results);
            })

          })

      })
  });

  /**
   * POST /labels/:idLabel/processReleases/
   * Asks the server to process files in the dropZone as a new release
   **/
  app.post('/labels/:labelId/processReleases/', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
      var idLabel = req.params.labelId;
      model.Label.find({ where: {id: idLabel}}).then(function(label){
        if (!label) {
          var err = new Error();
          err.status = 404;
          err.message = "Requested label does not exist";
          return next (err);
        }
        label.getDropZoneFiles({where: {extension: "xml"}}).then(function(xmls){
            beatport.process(xmls,idLabel).then(function(results){
              console.log("--server response")
              res.send(results);
            })
          })
      })
  });

  /**
   * POST /labels/:idLabel/labelManagers/   POST {the id of owner to add}
   * Adds a new manager for the label
   **/
  app.post('/labels/:labelId/labelManagers', authenticationUtils.ensureAuthenticated, ensureCompanyOwnerFromLabel, function(req, res, next) {
    var newLabelManagerId = req.body.newLabelManager;
    var labelId = req.params.labelId
    console.log(labelId);

    model.Label.find({where: {id: labelId}}).then(function(label) {
      if (!label) {
        var err = new Error();
        err.status = 404;
        err.message = "Requested label does not exist";
        return next (err);
      }

      label.getUsers({ where: {id: newLabelManagerId}}).then(function(users) {

        if(users.length == 0){
            model.User.find({where: {id: newLabelManagerId}}).then(function(user) {
              label.addUsers(user).then(function(label) {

                res.send();
              })
            })
        }else{

          console.log("This user was already associated to this label!")
          var err = new Error();
          err.status = 409;
          err.message = "The user is already a manager of the selected label";
          return next (err);
          // TODO, there were an error, need to fix
        }
      })
    });
  });

  /**
   * DELETE /labels/:idLabels/labelManagers/:idUser
   * Delete a manager from the label
   **/
  app.delete('/labels/:labelId/labelManagers/:userId', authenticationUtils.ensureAuthenticated, ensureCompanyOwnerFromLabel, function(req, res, next) {
    var userId = req.params.userId;
    var labelId = req.params.labelId

    model.Label.find({where: {id: labelId}}).then(function(label) {
        if (!label) {
        var err = new Error();
        err.status = 404;
        err.message = "Requested label does not exist";
        return next (err);
      }
      model.User.find({where: {id: userId}}).then(function(user) {
              if (!user) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested user does not exist";
                return next (err);
              }
              label.removeUser(user).success(function() {
                res.send();
              })
            })
    });
  });

  /**
   * GET /labels/:id/dropZoneFiles
   * Get the list of files in the dropZone
   **/
  app.get('/labels/:labelId/dropZoneFiles', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
    var LabelId = req.params.labelId;
    model.Label.find({ where: {id: LabelId} }).then(function(label) {
      if(label){
          label.getDropZoneFiles().success(function(dropZoneFiles) {
              res.send(dropZoneFiles);
          })
      } else {
        var err = new Error();
        err.status = 404;
        err.message = "Requested label does not exist";
        return next (err);
      }
    });
  });

  /**
   * GET /labels/id/catalog
   * Get all releases associated to the label
   **/
  app.get('/labels/:labelId/catalog', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
    var LabelId = req.params.labelId;
    model.Label.find({ where: {id: LabelId} }).then(function(label) {
      if(label){
          label.getReleases().success(function(releases) {
              res.send(releases);
          })
      } else {
        var err = new Error();
        err.status = 404;
        err.message = "Requested label does not exist";
        return next (err);
      }
    });
  });

} /* End of labels controller */<commit_msg>replace find with findAll in label/search/string api endpoint<commit_after>'use strict';

var fs = require('fs-extra');

var fileUtils = rootRequire('utils/file-utils');
var authenticationUtils = rootRequire('utils/authentication-utils');
var model = rootRequire('models/model');
var cloudstorage = rootRequire('libs/cloudstorage/cloudstorage');
var beatport = rootRequire('libs/beatport/beatport');

module.exports.controller = function(app) {

    /**
     * Ensures current user is the owner of the company
     * Company ID must be passed as req.body.companyId
     **/
    function ensureCompanyOwner(req, res, next) {
        var companyId = req.body.companyId;
        var userId = req.user;
        model.Company.find({
            where: {
                id: companyId
            }
        }).then(function(company) {
            if (!company) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested company does not exist";
                return next(err);
            }
            company.getUsers({
                where: {
                    id: userId
                }
            }).then(function(user) {
                if (!user) {
                    var err = new Error();
                    err.status = 401;
                    err.message = "You don't have access to the requested resource";
                    return next(err);
                }
                return next();
            });
        });
    }

    /**
     * Ensure current user is an owner of the company who ows the label
     * Label ID must be passed as req.params.labelId
     **/
    function ensureCompanyOwnerFromLabel(req, res, next) {
        var labelId = req.params.labelId;
        var userId = req.user;
        model.Label.find({
            where: {
                id: labelId
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            label.getCompanies().then(function(companies) {
                if (!companies) {
                    var err = new Error();
                    err.status = 401;
                    err.message = "You don't have access to the requested resource";
                    return next(err);
                }
                companies.forEach(function(company) {
                    company.getUsers({
                        where: {
                            id: userId
                        }
                    }).then(function(user) {
                        if (!user) {
                            var err = new Error();
                            err.status = 401;
                            err.message = "You don't have access to the requested resource";
                            return next(err);
                        }
                        return next();
                    });
                });
            });
        });
    }

    /**
     * Ensure current user is a manager of the selected label
     * Label ID must be passed as req.params.labelId
     **/
    function ensureLabelManager(req, res, next) {
        var labelId = req.params.labelId;
        model.Label.find({
            where: {
                id: labelId
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            label.getUsers({
                where: {
                    id: userId
                }
            }).then(function(users) {
                if (!users) {
                    var err = new Error();
                    err.status = 401;
                    err.message = "You don't have access to the requested resource";
                    return next(err);
                }
                return next();
            });
        });
    }

    /**
     * Ensure current user is either company owner or label manager
     * Label ID must be passed as req.params.labelId
     **/
    function ensureLabelManagerOrCompanyOwner(req, res, next) {
        var labelId = req.params.labelId;
        var userId = req.user;
        model.Label.find({
            where: {
                id: labelId
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            label.getUsers({
                where: {
                    id: userId
                }
            }).then(function(users) {
                if (!users) {
                    // Current user is not label manager, check if he is company owner
                    label.getCompanies().then(function(companies) {
                        if (!companies) {
                            var err = new Error();
                            err.status = 401;
                            err.message = "You don't have access to the requested resource";
                            return next(err);
                        }
                        companies.forEach(function(company) {
                            company.getUsers({
                                where: {
                                    id: userId
                                }
                            }).then(function(user) {
                                if (!user) {
                                    var err = new Error();
                                    err.status = 401;
                                    err.message = "You don't have access to the requested resource";
                                    return next(err);
                                }
                                return next();
                            });
                        });
                    });
                }
                return next();
            });
        });
    }

    /**
     * GET /labels/search/:searchString
     * Return the list of labels whose displayName resambles the search string
     * TODO: paginate request
     */
    app.get('/labels/search/:searchString', function(req, res, next) {
        var searchString = req.params.searchString;
        model.Label.findAll({
            where: ["displayName LIKE ?", "%" + searchString + "%"]
        }).then(function(labels) {
            res.send(labels);
        });
    });

    /**
     * GET /labels/search/:searchString
     * Return the list of labels whose displayName exactly matches the search string
     */
    app.get('/labels/searchExact/:searchString', function(req, res, next) {
        var searchString = req.params.searchString;
        model.Label.find({
            where: {
                displayName: searchString
            }
        }).then(function(labels) {
            res.send(labels);
        });
    });

    /**
     * GET /labels/:id
     * Return the label corresponding to the passed id
     */
    app.get('/labels/:labelId', authenticationUtils.ensureAuthenticated, function(req, res, next) {
        var LabelId = req.params.labelId;
        model.Label.find({
            where: {
                id: LabelId
            }
        }).then(function(label) {
            if (label) {
                label.getUsers({
                    attributes: ['displayName']
                }).success(function(associatedUsers) {
                    label.dataValues.labelManagers = (associatedUsers);
                    res.send(label);
                })
            } else {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
        });
    });

    /**
     * POST /labels/
     * Add label in post payload to the label list of the company
     * TODO: permission controll, check current user is owner of the company and company owns the label
     **/
    app.post('/labels/', authenticationUtils.ensureAuthenticated, ensureCompanyOwner, function(req, res, next) {
        var companyId = req.body.companyId;
        var labelName = req.body.labelName;

        console.log("companyId" + companyId)
        console.log("labelName" + labelName)

        model.Label.find({
            where: {
                displayName: labelName
            }
        }).success(function(label) {
            if (!label) {
                model.Label.create({
                    displayName: labelName
                }).success(function(label) {
                    model.Company.find({
                        where: {
                            id: companyId
                        }
                    }).then(function(company) {
                        company.addLabels([label]).success(function(labels) {
                            //model.User.find({where: {id: req.user}}).then(function(user) {
                            //label.addUsers([user]).success(function(user) {
                            res.send();
                            //});
                            //});
                        });
                    })
                })
            } else {
                var err = new Error();
                err.status = 409;
                err.message = "Label name already in use";
                return next(err);
            }
        });
    });

    /**
     * POST /labels/:idLabel/profilePicture/:width/:height/
     * Upload label profile picture to the CDN, original size and resized
     **/
    app.post('/labels/:labelId/profilePicture/:width/:height/',
        authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner,
        fileUtils.uploadFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
        fileUtils.resizeFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
        function(req, res, next) {
            var idLabel = req.params.labelId;
            model.Label.find({
                where: {
                    id: idLabel
                }
            }).then(function(label) {
                var oldLogo = label.logo;
                var oldFullSizeLogo = label.fullSizeLogo;
                label.logo = fileUtils.remoteImagePath(req, req.uploadedFile[0].resizedFilename);
                label.fullSizeLogo = fileUtils.remoteImagePath(req, req.uploadedFile[0].filename);

                label.save().then(function(label) {
                    // we remove old avatars from the CDN
                    cloudstorage.remove(oldLogo);
                    cloudstorage.remove(oldFullSizeLogo);
                    // We remove temporarily stored files
                    fs.unlink(fileUtils.localImagePath(req, req.uploadedFile[0].filename));
                    fs.unlink(fileUtils.localImagePath(req, req.uploadedFile[0].resizedFilename));

                    res.writeHead(200, {
                        "content-type": "text/html"
                    }); //http response header
                    res.end(JSON.stringify(req.uploadedFile));
                });
            });
        });

    /**
     * POST /labels/:idLabel/dropZone
     * Upload a file to the dropZone for the label with id :idLabel
     **/
    app.post('/labels/:labelId/dropZone/',
        authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner,
        fileUtils.uploadFunction(fileUtils.localImagePath, fileUtils.remoteImagePath),
        function(req, res, next) {

            var idLabel = req.params.labelId;
            console.log("****************")
            console.log(req.uploadedFile)
            console.log("****************")

            model.DropZoneFile.find
({
                where: model.Sequelize.and({
                    fileName: req.uploadedFile[0].originalfilename
                }, {
                    extension: req.uploadedFile[0].extension
                })
            }).then(function(file) {
                if (file) {
                    // file exists .. Update file?
                    file.path = req.uploadedFile[0].filename;
                    file.size = req.uploadedFile[0].filesize;
                    file.save().success(function() {
                        res.send();
                    })
                } else {
                    model.DropZoneFile.create({
                        fileName: req.uploadedFile[0].originalfilename,
                        extension: req.uploadedFile[0].extension,
                        size: req.uploadedFile[0].filesize,
                        path: req.uploadedFile[0].filename,
                    }).success(function(dropZoneFile) {
                        model.Label.find({
                            where: {
                                id: idLabel
                            }
                        }).then(function(label) {
                            label.addDropZoneFiles(dropZoneFile).then(function(associationFile) {
                                res.send();
                            })
                        });

                    })
                }

            });
            //res.send();
        });

    /**
     * GET /labels/:idLabel/processReleases/info
     * Validates the files in the dropZone to a beatport compliant playlist
     **/
    app.get('/labels/:labelId/processReleases/info', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
        var idLabel = req.params.labelId;
        model.Label.find({
            where: {
                id: idLabel
            }
        }).then(function(label) {
            console.log("The label found for release infos is " + label);
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            label.getDropZoneFiles({
                where: {
                    extension: "xml"
                }
            }).then(function(xmls) {

                beatport.validate(xmls).then(function(results) {
                    res.send(results);
                })

            })

        })
    });

    /**
     * POST /labels/:idLabel/processReleases/
     * Asks the server to process files in the dropZone as a new release
     **/
    app.post('/labels/:labelId/processReleases/', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
        var idLabel = req.params.labelId;
        model.Label.find({
            where: {
                id: idLabel
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            label.getDropZoneFiles({
                where: {
                    extension: "xml"
                }
            }).then(function(xmls) {
                beatport.process(xmls, idLabel).then(function(results) {
                    console.log("--server response")
                    res.send(results);
                })
            })
        })
    });

    /**
     * POST /labels/:idLabel/labelManagers/   POST {the id of owner to add}
     * Adds a new manager for the label
     **/
    app.post('/labels/:labelId/labelManagers', authenticationUtils.ensureAuthenticated, ensureCompanyOwnerFromLabel, function(req, res, next) {
        var newLabelManagerId = req.body.newLabelManager;
        var labelId = req.params.labelId
        console.log(labelId);

        model.Label.find({
            where: {
                id: labelId
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }

            label.getUsers({
                where: {
                    id: newLabelManagerId
                }
            }).then(function(users) {

                if (users.length == 0) {
                    model.User.find({
                        where: {
                            id: newLabelManagerId
                        }
                    }).then(function(user) {
                        label.addUsers(user).then(function(label) {

                            res.send();
                        })
                    })
                } else {

                    console.log("This user was already associated to this label!")
                    var err = new Error();
                    err.status = 409;
                    err.message = "The user is already a manager of the selected label";
                    return next(err);
                    // TODO, there were an error, need to fix
                }
            })
        });
    });

    /**
     * DELETE /labels/:idLabels/labelManagers/:idUser
     * Delete a manager from the label
     **/
    app.delete('/labels/:labelId/labelManagers/:userId', authenticationUtils.ensureAuthenticated, ensureCompanyOwnerFromLabel, function(req, res, next) {
        var userId = req.params.userId;
        var labelId = req.params.labelId

        model.Label.find({
            where: {
                id: labelId
            }
        }).then(function(label) {
            if (!label) {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
            model.User.find({
                where: {
                    id: userId
                }
            }).then(function(user) {
                if (!user) {
                    var err = new Error();
                    err.status = 404;
                    err.message = "Requested user does not exist";
                    return next(err);
                }
                label.removeUser(user).success(function() {
                    res.send();
                })
            })
        });
    });

    /**
     * GET /labels/:id/dropZoneFiles
     * Get the list of files in the dropZone
     **/
    app.get('/labels/:labelId/dropZoneFiles', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
        var LabelId = req.params.labelId;
        model.Label.find({
            where: {
                id: LabelId
            }
        }).then(function(label) {
            if (label) {
                label.getDropZoneFiles().success(function(dropZoneFiles) {
                    res.send(dropZoneFiles);
                })
            } else {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
        });
    });

    /**
     * GET /labels/id/catalog
     * Get all releases associated to the label
     **/
    app.get('/labels/:labelId/catalog', authenticationUtils.ensureAuthenticated, ensureLabelManagerOrCompanyOwner, function(req, res, next) {
        var LabelId = req.params.labelId;
        model.Label.find({
            where: {
                id: LabelId
            }
        }).then(function(label) {
            if (label) {
                label.getReleases().success(function(releases) {
                    res.send(releases);
                })
            } else {
                var err = new Error();
                err.status = 404;
                err.message = "Requested label does not exist";
                return next(err);
            }
        });
    });

} /* End of labels controller */
<|endoftext|>


<commit_before>'use strict'

const Q = require('q');
const companySearch = require('../services/company-api-gh.js');
const utilities = require('../services/utilities.js');

// Repeated function, different end function
function loadCompanyToObj(responseObj, company) {
  return utilities.queryPostsofCompany(company)
    .then(function (company){
        responseObj.payloads = preparePayloadsOfObj(company);
        return responseObj;
    });
}

// has incoming Company object, with Posts and OtherCompanies attached
// loads payloads as an array, each will trigger a response
// (sub-loading functions should go to separate functions for testability)
function preparePayloadsOfObj(company) {
    var payloads = [];

    var posts = company.posts;
    var otherCompanies = company.otherCompanies;
    var name = company.name;

    var contactInfo = utilities.extractContactInfo(company);

    if (posts && posts.length) {
    // if Posts exist, send Post info cards
      var postElements = [];
      for (let i = 0; i < posts.length; i++) {
        let text = posts[i].title || '';
        let urlId = posts[i].urlId || ''
        let singleElement = {
            "title": "Top issues for " + name + ", #" + (i+1) + " of " + posts.length + ":",
            "subtitle": text,
            "buttons": [{
                "type": "web_url",
                "url": "https://gethuman.com?company=" + encodeURIComponent(name) ,
                "title": "Solve this for Me - $20"
            },
            {
                "type": "web_url",
                "url": "https://answers.gethuman.co/_" + encodeURIComponent(urlId) ,
                "title": "More info ..."
            }],
        };
        postElements.push(singleElement);
      }
      console.log("Post Elements prepared: " + JSON.stringify(postElements));
      console.log(payloads);
      payloads.push(postElements);
    }

    // make Company Info Card
    var companyInfoElement = [{
        "title": "Best ways to contact " + name + ":",
        'buttons': utilities.formatContactButtonsMessenger(contactInfo)
    }];
    if (contactInfo.email) {
        companyInfoElement[0].subtitle = contactInfo.email;
    };
    // only push in if at least one button exists:
    if (companyInfoElement[0].subtitle || companyInfoElement[0].buttons.length) {
        console.log("Company Info Element prepared: " + JSON.stringify(companyInfoElement));
        payloads.push(companyInfoElement);
    };

    // make Other Companies Card
    // To-Do: Make buttons trigger a Postback to do another search/reply
    if (otherCompanies && otherCompanies.length) {
        var otherCompaniesElement = [{
            "title": "Were you trying to reach " + name + "?",
            "subtitle": "Perhaps you would like to ask me about these companies:",
            "buttons": [],
        }];
        // change these to a Postback to trigger a new search with altCompany as user input
        // cull down Other Options to 3 - could make more scrolling cards if wanted...
        var otherCompaniesSubSet = otherCompanies.slice(0,3);
        otherCompaniesSubSet.forEach(function(altCompany){
            otherCompaniesElement[0].buttons.push({
                "type": "postback",
                "title": altCompany,
                // does the payload need to be an object?
                "payload": {
                    "newSearch": altCompany
                }
            })
        })
        console.log("Other Companies Element prepared: " + JSON.stringify(otherCompaniesElement));
        payloads.push(otherCompaniesElement);
    }

    // check if nothing is in payload at this point - return NothingFound payload if so
    if (!payloads.length) {
        payloads.push([{
            "title": "Nothing found!",
            "subtitle": "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"Verizon Wireless\")",
            "buttons": [{
                "type": "web_url",
                "url": "https://gethuman.com",
                "title": "Solve this for Me - $20"
            }],
        }])
    }
    // console.log("All payload elements prepared: " + JSON.stringify(payloads));
    return payloads;
}

function nothingFound(responseObj) {
    var textInput = responseObj.context.textInput;

    let nothingFoundElement = [[{
        "title": "Nothing found!",
        "subtitle": "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"Verizon Wireless\")",
        "buttons": [{
            "type": "web_url",
            "url": "https://gethuman.com",
            "title": "Solve this for Me - $20"
        }],
    }]];
    responseObj.payloads = nothingFoundElement;
    console.log ("Loading a NOTHING FOUND payload into response object");
    return responseObj;
};

// needs checking - not yet tested
// Should button go elsewhere?
function error(error) {
    console.log("About to form up ERROR payload.")
    let elements = [{
        "title": "We ran into an error!",
        "subtitle": JSON.stringify(error),
        "buttons": [{
            "type": "web_url",
            "url": "https://gethuman.com",
            "title": "Go to GetHuman"
        }],
    }];
    console.log("Elements returned for ERROR payload: " + JSON.stringify(elements));
    return elements;
};

module.exports = {
  nothingFound: nothingFound,
  error: error,
  loadCompanyToObj: loadCompanyToObj
}<commit_msg>debug<commit_after>'use strict'

const Q = require('q');
const companySearch = require('../services/company-api-gh.js');
const utilities = require('../services/utilities.js');

// Repeated function, different end function
function loadCompanyToObj(responseObj, company) {
  return utilities.queryPostsofCompany(company)
    .then(function (company){
        responseObj.payloads = preparePayloadsOfObj(company);
        return responseObj;
    });
}

// has incoming Company object, with Posts and OtherCompanies attached
// loads payloads as an array, each will trigger a response
// (sub-loading functions should go to separate functions for testability)
function preparePayloadsOfObj(company) {
    var payloads = [];

    var posts = company.posts;
    var otherCompanies = company.otherCompanies;
    var name = company.name;

    var contactInfo = utilities.extractContactInfo(company);

    if (posts && posts.length) {
    // if Posts exist, send Post info cards
      var postElements = [];
      for (let i = 0; i < posts.length; i++) {
        let text = posts[i].title || '';
        let urlId = posts[i].urlId || ''
        let singleElement = {
            "title": "Top issues for " + name + ", #" + (i+1) + " of " + posts.length + ":",
            "subtitle": text,
            "buttons": [{
                "type": "web_url",
                "url": "https://gethuman.com?company=" + encodeURIComponent(name) ,
                "title": "Solve this for Me - $20"
            },
            {
                "type": "web_url",
                "url": "https://answers.gethuman.co/_" + encodeURIComponent(urlId) ,
                "title": "More info ..."
            }],
        };
        postElements.push(singleElement);
      }
      console.log("Post Elements prepared: " + JSON.stringify(postElements));
      console.log(payloads);
      payloads.push(postElements);
    }

    // make Company Info Card
    var companyInfoElement = [{
        "title": "Best ways to contact " + name + ":",
        'buttons': utilities.formatContactButtonsMessenger(contactInfo)
    }];
    if (contactInfo.email) {
        companyInfoElement[0].subtitle = contactInfo.email;
    };
    // only push in if at least one button exists:
    if (companyInfoElement[0].subtitle || companyInfoElement[0].buttons.length) {
        console.log("Company Info Element prepared: " + JSON.stringify(companyInfoElement));
        payloads.push(companyInfoElement);
    };

    // make Other Companies Card
    // To-Do: Make buttons trigger a Postback to do another search/reply
    if (otherCompanies && otherCompanies.length) {
        var otherCompaniesElement = [{
            "title": "Were you trying to reach " + name + "?",
            "subtitle": "Perhaps you would like to ask me about these companies:",
            "buttons": [],
        }];
        // change these to a Postback to trigger a new search with altCompany as user input
        // cull down Other Options to 3 - could make more scrolling cards if wanted...
        var otherCompaniesSubSet = otherCompanies.slice(0,3);
        otherCompaniesSubSet.forEach(function(altCompany){
            otherCompaniesElement[0].buttons.push({
                "type": "postback",
                "title": altCompany,
                // does the payload need to be an object?
                "payload": JSON.stringify({
                    "newSearch": altCompany
                })
            })
        })
        console.log("Other Companies Element prepared: " + JSON.stringify(otherCompaniesElement));
        payloads.push(otherCompaniesElement);
    }

    // check if nothing is in payload at this point - return NothingFound payload if so
    if (!payloads.length) {
        payloads.push([{
            "title": "Nothing found!",
            "subtitle": "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"Verizon Wireless\")",
            "buttons": [{
                "type": "web_url",
                "url": "https://gethuman.com",
                "title": "Solve this for Me - $20"
            }],
        }])
    }
    // console.log("All payload elements prepared: " + JSON.stringify(payloads));
    return payloads;
}

function nothingFound(responseObj) {
    var textInput = responseObj.context.textInput;

    let nothingFoundElement = [[{
        "title": "Nothing found!",
        "subtitle": "I couldn't tell what you meant by \"" + textInput + "\". Please tell me company you are looking for. (ex: \"Verizon Wireless\")",
        "buttons": [{
            "type": "web_url",
            "url": "https://gethuman.com",
            "title": "Solve this for Me - $20"
        }],
    }]];
    responseObj.payloads = nothingFoundElement;
    console.log ("Loading a NOTHING FOUND payload into response object");
    return responseObj;
};

// needs checking - not yet tested
// Should button go elsewhere?
function error(error) {
    console.log("About to form up ERROR payload.")
    let elements = [{
        "title": "We ran into an error!",
        "subtitle": JSON.stringify(error),
        "buttons": [{
            "type": "web_url",
            "url": "https://gethuman.com",
            "title": "Go to GetHuman"
        }],
    }];
    console.log("Elements returned for ERROR payload: " + JSON.stringify(elements));
    return elements;
};

module.exports = {
  nothingFound: nothingFound,
  error: error,
  loadCompanyToObj: loadCompanyToObj
}<|endoftext|>


<commit_before>/* eslint-env mocha */

const assert = require("assert");
const sinon = require("sinon");

// tested module
const Compiler = require("../../lib/Compiler");

describe("Compiler#createFileHandler", function() {
	before(() => {
		sinon.stub(console, "log");
	});
	after(() => {
		sinon.restore();
	});

	it("should propagate errors via callback function (TypeError)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: {},
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: undefined // This will cause a TypeError when calling path.join
		};
		const handleDataAndCallCallback = sinon.stub();
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 0);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].message,
			`The "path" argument must be of type string. Received undefined`
		);
	});
	it("should propagate errors via callback function (File not found)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: {
				readFile: sinon.stub().resolves(null)
			},
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: "someFolder"
		};
		const handleDataAndCallCallback = sinon.stub();
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 0);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].type, "File");
		assert.equal(callback.getCall(0).args[0].message,
			`Could not find file at path 'someFolder/someFile'`
		);
	});
	it("should propagate errors via callback function (error within handleDataAndCallCallback)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: {
				readFile: sinon.stub().resolves({
					path: "", content: ""
				})
			},
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: "someFolder"
		};
		const handleDataAndCallCallback = sinon.stub().throws(new Error("Error from handleDataAndCallCallback"));
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 1);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].message,
			`Error from handleDataAndCallCallback`
		);
	});
});
<commit_msg>[INTERNAL] Fix TypeError test on Node v10<commit_after>/* eslint-env mocha */

const assert = require("assert");
const sinon = require("sinon");

// tested module
const Compiler = require("../../lib/Compiler");

describe("Compiler#createFileHandler", function() {
	before(() => {
		sinon.stub(console, "log");
	});
	after(() => {
		sinon.restore();
	});

	it("should propagate errors via callback function (TypeError)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: undefined // This will cause a TypeError when calling fileUtils.readFile
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: "someFolder"
		};
		const handleDataAndCallCallback = sinon.stub();
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 0);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].name, "TypeError");
		assert.equal(callback.getCall(0).args[0].message,
			`Cannot read property 'readFile' of undefined`
		);
	});
	it("should propagate errors via callback function (File not found)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: {
				readFile: sinon.stub().resolves(null)
			},
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: "someFolder"
		};
		const handleDataAndCallCallback = sinon.stub();
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 0);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].type, "File");
		assert.equal(callback.getCall(0).args[0].message,
			`Could not find file at path 'someFolder/someFile'`
		);
	});
	it("should propagate errors via callback function (error within handleDataAndCallCallback)", async function() {
		const compiler = new Compiler({
			options: {
				rootPaths: ["foo"]
			},
			fileUtils: {
				readFile: sinon.stub().resolves({
					path: "", content: ""
				})
			},
		});

		const file = "someFile";
		const currentFileInfo = {
			currentDirectory: "someFolder"
		};
		const handleDataAndCallCallback = sinon.stub().throws(new Error("Error from handleDataAndCallCallback"));
		const callback = sinon.stub();

		await compiler.fnFileHandler(file, currentFileInfo, handleDataAndCallCallback, callback);

		assert.equal(handleDataAndCallCallback.callCount, 1);
		assert.equal(callback.callCount, 1);
		assert.equal(callback.getCall(0).args.length, 1);
		assert.equal(callback.getCall(0).args[0].message,
			`Error from handleDataAndCallCallback`
		);
	});
});
<|endoftext|>


<commit_before>var Utils = require('../lib/Logic/Utils.js');
var DiscordDJ = require('../lib/index.js');

var Special = require('./Special.js');

var Discordie = Utils.include('discordie');

if(Discordie == null) {
    console.log('DiscordDJ is not installed correctly.');
    console.log('Please, install it using "setup-bot.bat" or "setup-bot.sh"');
    console.log('http://guichaguri.github.io/DiscordDJ/');
    process.exit(0);
}

var config = Utils.include(process.cwd() + '/config.json');
var configModified = false;
var connected = false;

var bot = new Discordie();
var manager = null;

function install(shouldLogin, callback) {
    require('./Installer.js')(bot, config, shouldLogin, callback);
    configModified = true;
}

function connect() {
    var credentials = {}, hasCredentials = false;

    if(Utils.exists(config['token'])) {
        credentials['token'] = config['token'];
        hasCredentials = true;
    }
    if(Utils.exists(config['email']) && Utils.exists(config['password'])) {
        credentials['email'] = config['email'];
        credentials['password'] = config['password'];
        hasCredentials = true;
    }

    if(!hasCredentials) return install(true, finishInstallation);

    bot.Dispatcher.removeListener(Discordie.Events.GATEWAY_READY, handleConnection);
    bot.Dispatcher.removeListener(Discordie.Events.DISCONNECTED, handleDisconnection);
    bot.Dispatcher.once(Discordie.Events.GATEWAY_READY, handleConnection);
    bot.Dispatcher.once(Discordie.Events.DISCONNECTED, handleDisconnection);

    console.log('Trying to connect...');
    bot.connect(credentials);
}

function createDJ(djCfg, manager) {
    if(!Utils.exists(djCfg['voice-channel'])) return install(false, finishInstallation);

    var voiceChannel = null;

    if(Utils.exists(djCfg['server'])) {
        var guild = bot.Guilds.get(djCfg['server']) || bot.Guilds.getBy('name', djCfg['server']);
        if(guild != null) {
            voiceChannel = guild.voiceChannels.filter(function(c) {
                return c.name == djCfg['voice-channel'] || c.id == djCfg['voice-channel'];
            });
            voiceChannel = voiceChannel.length == 0 ? null : voiceChannel[0];
        }
    }
    if(voiceChannel == null) {
        voiceChannel = bot.Channels.get(djCfg['voice-channel']) || bot.Channels.getBy('name', djCfg['voice-channel']);
    }

    if(voiceChannel == null) return install(false, finishInstallation);

    if(djCfg['server'] != voiceChannel.guild_id || djCfg['voice-channel'] != voiceChannel.id) {
        configModified = true;
    }
    djCfg['server'] = voiceChannel.guild_id;
    djCfg['voice-channel'] = voiceChannel.id;

    console.log('Initializing DJ in "' + voiceChannel.guild.name + '"');
    var dj = manager.create(voiceChannel, DiscordDJ.BotDJ);

    return djCfg;
}

function handleConnection() {
    console.log('Connected! Initializing the DJs...');
    connected = true;

    if(config['token'] != bot.token) configModified = true;
    config['token'] = bot.token;

    if(!Utils.exists(config['djs'])) return install(false, finishInstallation);

    var manager = new DiscordDJ.DJManager(bot);

    for(var i = 0; i < config['djs'].length; i++) {
        config['djs'][i] = createDJ(config['djs'][i], manager);
    }

    if(configModified) {
        console.log('SAVE CONFIG');
        require('fs').writeFile('config.json', JSON.stringify(config), function(error) {
            console.log(error == null ? 'Config saved!' : 'An error ocurred while saving the config: ' + error);
        });
    }

    Special.checkUpdate();
    //Special.registerCommands();//TODO HANDLER
}

function handleDisconnection() {
    var time;
    if(connected) {
        console.log('The bot has disconnected');
        console.log('Trying to reconnect in 10 seconds...');
        time = 10000;
    } else {
        console.log('Could not connect into the account');
        console.log('Discord is down or the credentials are wrong.');
        console.log('If you want to run the installer again, delete your config file');
        console.log('Trying to reconnect in 30 seconds...');
        time = 30000;
    }
    connected = false;
    setTimeout(connect, time);
}

function finishInstallation(cfg) {
    if(Utils.exists(cfg)) config = cfg;
    handleConnection();
}

if(config == null) {
    config = {};
    install(true, finishInstallation);
} else {
    connect();
}
<commit_msg>Revert "fix it so that the config loads"<commit_after>var Utils = require('../lib/Logic/Utils.js');
var DiscordDJ = require('../lib/index.js');

var Special = require('./Special.js');

var Discordie = Utils.include('discordie');

if(Discordie == null) {
    console.log('DiscordDJ is not installed correctly.');
    console.log('Please, install it using "setup-bot.bat" or "setup-bot.sh"');
    console.log('http://guichaguri.github.io/DiscordDJ/');
    process.exit(0);
}

var config = Utils.include('config.json');
var configModified = false;
var connected = false;

var bot = new Discordie();
var manager = null;

function install(shouldLogin, callback) {
    require('./Installer.js')(bot, config, shouldLogin, callback);
    configModified = true;
}

function connect() {
    var credentials = {}, hasCredentials = false;

    if(Utils.exists(config['token'])) {
        credentials['token'] = config['token'];
        hasCredentials = true;
    }
    if(Utils.exists(config['email']) && Utils.exists(config['password'])) {
        credentials['email'] = config['email'];
        credentials['password'] = config['password'];
        hasCredentials = true;
    }

    if(!hasCredentials) return install(true, finishInstallation);

    bot.Dispatcher.removeListener(Discordie.Events.GATEWAY_READY, handleConnection);
    bot.Dispatcher.removeListener(Discordie.Events.DISCONNECTED, handleDisconnection);
    bot.Dispatcher.once(Discordie.Events.GATEWAY_READY, handleConnection);
    bot.Dispatcher.once(Discordie.Events.DISCONNECTED, handleDisconnection);

    console.log('Trying to connect...');
    bot.connect(credentials);
}

function createDJ(djCfg, manager) {
    if(!Utils.exists(djCfg['voice-channel'])) return install(false, finishInstallation);

    var voiceChannel = null;

    if(Utils.exists(djCfg['server'])) {
        var guild = bot.Guilds.get(djCfg['server']) || bot.Guilds.getBy('name', djCfg['server']);
        if(guild != null) {
            voiceChannel = guild.voiceChannels.filter(function(c) {
                return c.name == djCfg['voice-channel'] || c.id == djCfg['voice-channel'];
            });
            voiceChannel = voiceChannel.length == 0 ? null : voiceChannel[0];
        }
    }
    if(voiceChannel == null) {
        voiceChannel = bot.Channels.get(djCfg['voice-channel']) || bot.Channels.getBy('name', djCfg['voice-channel']);
    }

    if(voiceChannel == null) return install(false, finishInstallation);

    if(djCfg['server'] != voiceChannel.guild_id || djCfg['voice-channel'] != voiceChannel.id) {
        configModified = true;
    }
    djCfg['server'] = voiceChannel.guild_id;
    djCfg['voice-channel'] = voiceChannel.id;

    console.log('Initializing DJ in "' + voiceChannel.guild.name + '"');
    var dj = manager.create(voiceChannel, DiscordDJ.BotDJ);

    return djCfg;
}

function handleConnection() {
    console.log('Connected! Initializing the DJs...');
    connected = true;

    if(config['token'] != bot.token) configModified = true;
    config['token'] = bot.token;

    if(!Utils.exists(config['djs'])) return install(false, finishInstallation);

    var manager = new DiscordDJ.DJManager(bot);

    for(var i = 0; i < config['djs'].length; i++) {
        config['djs'][i] = createDJ(config['djs'][i], manager);
    }

    if(configModified) {
        console.log('SAVE CONFIG');
        require('fs').writeFile('config.json', JSON.stringify(config), function(error) {
            console.log(error == null ? 'Config saved!' : 'An error ocurred while saving the config: ' + error);
        });
    }

    Special.checkUpdate();
    //Special.registerCommands();//TODO HANDLER
}

function handleDisconnection() {
    var time;
    if(connected) {
        console.log('The bot has disconnected');
        console.log('Trying to reconnect in 10 seconds...');
        time = 10000;
    } else {
        console.log('Could not connect into the account');
        console.log('Discord is down or the credentials are wrong.');
        console.log('If you want to run the installer again, delete your config file');
        console.log('Trying to reconnect in 30 seconds...');
        time = 30000;
    }
    connected = false;
    setTimeout(connect, time);
}

function finishInstallation(cfg) {
    if(Utils.exists(cfg)) config = cfg;
    handleConnection();
}

if(config == null) {
    config = {};
    install(true, finishInstallation);
} else {
    connect();
}<|endoftext|>


<commit_before>import m from 'mithril';
import h from '../h';

const I18nScope = _.partial(h.i18nScope, 'users.balance');

const userBalanceTrasactionRow = {
    controller(args) {
        const expanded = h.toggleProp(false, true);

        if (args.index == 0) {
            expanded.toggle();
        }

        return {
            expanded
        };
    },
    view(ctrl, args) {
        const item = args.item,
            createdAt = h.momentFromString(item.created_at, 'YYYY-MM-DD');

        return m(`div[class='balance-card ${(ctrl.expanded() ? 'card-detailed-open' : '')}']`,
                 m('.w-clearfix.card.card-clickable', [
                     m('.w-row', [
                         m('.w-col.w-col-2.w-col-tiny-2', [
                             m('.fontsize-small.lineheight-tightest', createdAt.format('D MMM')),
                             m('.fontsize-smallest.fontcolor-terciary', createdAt.format('YYYY'))
                         ]),
                         m('.w-col.w-col-10.w-col-tiny-10', [
                             m('.w-row', [
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('debit', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base.text-error', `R$ ${h.formatNumber(Math.abs(item.debit), 2, 3)}`)
                                     ])
                                 ]),
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('credit', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base.text-success', `R$ ${h.formatNumber(item.credit, 2, 3)}`)
                                     ])
                                 ]),
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('totals', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base', `R$ ${h.formatNumber(item.total_amount, 2, 3)}`)
                                     ])
                                 ])
                             ])
                         ])
                     ]),
                     m(`a.w-inline-block.arrow-admin.${(ctrl.expanded() ? 'arrow-admin-opened' : '')}.fa.fa-chevron-down.fontcolor-secondary[href="javascript:(void(0));"]`, { onclick: ctrl.expanded.toggle })
                 ]),
                 (ctrl.expanded() ? m('.card', _.map(item.source, (transaction) => {
                     const pos = transaction.amount >= 0;
                     const event_data = {
                         subscription_reward_label: transaction.origin_objects.subscription_reward_label || '',
                         subscriber_name: transaction.origin_objects.subscriber_name,
                         service_fee: transaction.origin_objects.service_fee ? (transaction.origin_objects.service_fee*100.0) : '',
                         project_name: transaction.origin_objects.project_name,
                         contributitor_name: transaction.origin_objects.contributor_name
                     };

                     return m('div', [
                         m('.w-row.fontsize-small.u-marginbottom-10', [
                             m('.w-col.w-col-2', [
                                 m(`.text-${(pos ? 'success' : 'error')}`, `${pos ? '+' : '-'} R$ ${h.formatNumber(Math.abs(transaction.amount), 2, 3)}`)
                             ]),
                             m('.w-col.w-col-10', [
                                 m('div', I18n.t(`event_names.${transaction.event_name}`, I18nScope(event_data)))
                             ])
                         ]),
                         m('.divider.u-marginbottom-10')
                     ]);
                 })) : '')
                );
    }
};

export default userBalanceTrasactionRow;
<commit_msg>when event is balance_expired should use m.trust to render link<commit_after>import m from 'mithril';
import h from '../h';

const I18nScope = _.partial(h.i18nScope, 'users.balance');

const userBalanceTrasactionRow = {
    controller(args) {
        const expanded = h.toggleProp(false, true);

        if (args.index == 0) {
            expanded.toggle();
        }

        return {
            expanded
        };
    },
    view(ctrl, args) {
        const item = args.item,
            createdAt = h.momentFromString(item.created_at, 'YYYY-MM-DD');

        return m(`div[class='balance-card ${(ctrl.expanded() ? 'card-detailed-open' : '')}']`,
                 m('.w-clearfix.card.card-clickable', [
                     m('.w-row', [
                         m('.w-col.w-col-2.w-col-tiny-2', [
                             m('.fontsize-small.lineheight-tightest', createdAt.format('D MMM')),
                             m('.fontsize-smallest.fontcolor-terciary', createdAt.format('YYYY'))
                         ]),
                         m('.w-col.w-col-10.w-col-tiny-10', [
                             m('.w-row', [
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('debit', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base.text-error', `R$ ${h.formatNumber(Math.abs(item.debit), 2, 3)}`)
                                     ])
                                 ]),
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('credit', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base.text-success', `R$ ${h.formatNumber(item.credit, 2, 3)}`)
                                     ])
                                 ]),
                                 m('.w-col.w-col-4', [
                                     m('div', [
                                         m('span.fontsize-smaller.fontcolor-secondary', I18n.t('totals', I18nScope())),
                                         m.trust(' '),
                                         m('span.fontsize-base', `R$ ${h.formatNumber(item.total_amount, 2, 3)}`)
                                     ])
                                 ])
                             ])
                         ])
                     ]),
                     m(`a.w-inline-block.arrow-admin.${(ctrl.expanded() ? 'arrow-admin-opened' : '')}.fa.fa-chevron-down.fontcolor-secondary[href="javascript:(void(0));"]`, { onclick: ctrl.expanded.toggle })
                 ]),
                 (ctrl.expanded() ? m('.card', _.map(item.source, (transaction) => {
                     const pos = transaction.amount >= 0;
                     const event_data = {
                         subscription_reward_label: transaction.origin_objects.subscription_reward_label || '',
                         subscriber_name: transaction.origin_objects.subscriber_name,
                         service_fee: transaction.origin_objects.service_fee ? (transaction.origin_objects.service_fee*100.0) : '',
                         project_name: transaction.origin_objects.project_name,
                         contributitor_name: transaction.origin_objects.contributor_name,
                     };

                     return m('div', [
                         m('.w-row.fontsize-small.u-marginbottom-10', [
                             m('.w-col.w-col-2', [
                                 m(`.text-${(pos ? 'success' : 'error')}`, `${pos ? '+' : '-'} R$ ${h.formatNumber(Math.abs(transaction.amount), 2, 3)}`)
                             ]),
                             m('.w-col.w-col-10', [
                                 (transaction.event_name === 'balance_expired'
                                     ? m('div', m.trust(I18n.t(`event_names.${transaction.event_name}`, I18nScope(event_data))))
                                     : m('div', I18n.t(`event_names.${transaction.event_name}`, I18nScope(event_data)))
                                 )
                             ])
                         ]),
                         m('.divider.u-marginbottom-10')
                     ]);
                 })) : '')
                );
    }
};

export default userBalanceTrasactionRow;
<|endoftext|>


<commit_before>var args = arguments[0] || {};
_.defaults(args, {
	askBeforeSubmit: false,
	submitTitle: L('form_submit', 'Submit')
});

var LCAT = "Ti.FormBuilder";

/////////////////////////
// Requirements checks //
/////////////////////////

if (Alloy.Globals.Trimethyl == null) {
	throw new Error(LCAT + ": you need to install Trimethyl to use this widget.");
}

var UIFactory = require('T/uifactory');
if (UIFactory == null) throw new Error(LCAT + ": you need the UIFactory module to use this widget");

var UIFactoryTextField = require('T/uifactory/textfield');
if (UIFactoryTextField == null) throw new Error(LCAT + ": you need the UIFactory.TextField module to use this widget");

var UIFactoryLabel = require('T/uifactory/label');
if (UIFactoryLabel == null) throw new Error(LCAT + ": you need the UIFactory.Label module to use this widget");

var UIFactorySelect = require('T/uifactory/select');
if (UIFactorySelect == null) throw new Error(LCAT + ": you need the UIFactory.Select module to use this widget");

var Dialog = require('T/dialog');
if (Dialog == null) throw new Error(LCAT + ": you need the Dialog module to use this widget");

////////////////
// Properties //
////////////////

var fields = args.fields;
var fields_map = [];

var submitting = false;

/////////////
// Methods //
/////////////

function addValidationError(f, msg) {
	f.uiValidation.text = msg;
	f.uiValidation.animate({
		opacity: 1,
	});

	if (_.isFunction(f.addError)) f.addError();
}

function removeValidationError(f) {
	f.uiValidation.text = "";
	f.uiValidation.animate({
		opacity: 1,
	});

	if (_.isFunction(f.removeError)) f.removeError();
}

function submit() {
	var obj = {};
	fields_map.forEach(function(f) {
		if (f.name) {
			obj[f.name] = _.isFunction(f.getValue) ? f.getValue() : f.ui.getValue();
		}
	});

	submitting = true;
	$.formMainView.touchEnabled = false;

	$.trigger('submit', {
		data: obj
	});
}

////////////////////
// Public methods //
////////////////////

$.endSubmit = function() {
	submitting = false;
	$.formMainView.touchEnabled = true;
};

$.submit = function() {
	if (args.askBeforeSubmit) {
		Dialog.option(L("form_submit_prompt", "Do you want to submit the form?"), [
		{
			title: L("form_submit", "Submit"),
			callback: function() {
				if ($.validate()) submit();
			}
		},
		{
			title: L("form_cancel", "Cancel"),
			cancel: true
		}
		]);
	} else {
		if ($.validate()) submit();
	}
};

$.validate = function() {
	var can_submit = true;
	var field_to_focus = null;

	_.each(fields_map, function(f, k) {
		var def = fields[k];
		var current_value = _.isFunction(f.getValue) ? f.getValue() : f.ui.getValue();

		// Required validation
		if (def.required) {
			var requiredValue = false;
			if (_.isBoolean(current_value)) {
				requiredValue = !!current_value;
			} else {
				requiredValue = !_.isEmpty(current_value);
			}

			if (requiredValue !== true) {
				addValidationError(f, L("form_required_field", "Required field"));
				can_submit = false;
				field_to_focus = field_to_focus || f;
				return false;
			}
		}

		// Validation custom
		if (_.isFunction(def.validator)) {
			var validMessage = def.validator(f.ui.value || '');
			if (validMessage !== true) {
				addValidationError(f, validMessage);
				can_submit = false;
				field_to_focus = field_to_focus || f;
				return false;
			}
		}

		removeValidationError(f);
	});

	if (field_to_focus != null) {
		if (_.isFunction(field_to_focus.focus)) {
			field_to_focus.focus();
		} else if (_.isFunction(field_to_focus.ui.focus)) {
			field_to_focus.ui.focus();
		}
	}

	return can_submit;
};

////////////////
// UI Builder //
////////////////

exports.UIBuilder = {};

exports.UIBuilder.text = function(e,f) {
	f.ui = UIFactoryTextField(_.extend({}, $.createStyle({ classes: ['formInput'], apiName: 'TextField' }), {
		textType: e.type,
		hintText: e.placeholder,
		value: e.value,
		returnKeyType: Titanium.UI.RETURNKEY_NEXT
	}));

	f.addError = function() { $.addClass(f.ui, "formInputError"); };
	f.removeError = function() { $.removeClass(f.ui, "formInputError"); };

	f.ui.addEventListener('return', $.validate);
};

exports.UIBuilder.boolean = function(e,f) {
	var switcher = Ti.UI.createSwitch({
		value: e.value,
		left: 0
	});
	var label = UIFactoryLabel(_.extend({}, $.createStyle({ classes: ['formBooleanLabel'], 'apiName':'Label' }), {
		left: 60,
		right: 0,
		html: e.placeholder
	}));

	f.ui = Ti.UI.createView();
	f.ui.add(switcher);
	f.ui.add(label);

	f.getValue = function() { return switcher.getValue(); };
};

exports.UIBuilder.select = function(e,f) {
	f.ui = UIFactorySelect(_.extend({}, $.createStyle({ classes: ['formInput'], apiName: 'Select' }), {
		values: e.values,
		value: e.value,
		hintText: e.placeholder
	}));

	f.addError = function() { $.addClass(f.ui, "formInputError"); };
	f.removeError = function() { $.removeClass(f.ui, "formInputError"); };

	f.ui.addEventListener('change', $.validate);
};

//////////////////
// Parse fields //
//////////////////

var index = 0;

_.each(_.groupBy(fields, 'group'), function(subFields, k) {
	if (k !== "undefined") {
		$.formMainView.add($.UI.create('Label', {
			classes: ['formGroupLabel'],
			text: k
		}));
		$.formMainView.add($.UI.create('View', {
			classes: ['formGroupSeparator']
		}));
	}

	$.formMainView.add(Ti.UI.createView({ height: 8 }));

	subFields.forEach(function(e) {
		var $wrap = $.UI.create('View', {
			classes: ['formWrap']
		});
		$wrap.add($.UI.create('Label', {
			classes: ['formLabel'],
			text: e.label
		}));

		var f = {
			name: e.name,
			index: (index++)
		};

		var factory = exports.UIBuilder[ e.type ] || exports.UIBuilder.text;
		factory(e,f);

		f.uiValidation = $.UI.create('Label', {
			text: '',
			opacity: 0,
			classes: ['formValidatorMessage']
		});

		$wrap.add(f.ui);
		$wrap.add(f.uiValidation);
		$.formMainView.add($wrap);

		fields_map.push(f);
	});
});

var $submit_btn = $.UI.create('Button', {
	classes: ['formSubmitButton'],
	title: args.submitTitle
});

$submit_btn.addEventListener('click', function(e) {
	if (submitting) return;
	$.submit();
});

$.formMainView.add($submit_btn);
<commit_msg>Added showSubmitButton property. Added UI component for "time" type.<commit_after>var args = arguments[0] || {};
_.defaults(args, {
	showSubmitButton: true,
	askBeforeSubmit: false,
	submitTitle: L('form_submit', 'Submit')
});

var LCAT = "Ti.FormBuilder";

/////////////////////////
// Requirements checks //
/////////////////////////

if (Alloy.Globals.Trimethyl == null) {
	throw new Error(LCAT + ": you need to install Trimethyl to use this widget.");
}

var UIFactory = require('T/uifactory');
if (UIFactory == null) throw new Error(LCAT + ": you need the UIFactory module to use this widget");

var UIFactoryTextField = require('T/uifactory/textfield');
if (UIFactoryTextField == null) throw new Error(LCAT + ": you need the UIFactory.TextField module to use this widget");

var UIFactoryLabel = require('T/uifactory/label');
if (UIFactoryLabel == null) throw new Error(LCAT + ": you need the UIFactory.Label module to use this widget");

var UIFactorySelect = require('T/uifactory/select');
if (UIFactorySelect == null) throw new Error(LCAT + ": you need the UIFactory.Select module to use this widget");

var UIFactoryTimeSelect = require('T/uifactory/timeselect');
if (UIFactoryTimeSelect == null) throw new Error(LCAT + ": you need the UIFactory.TimeSelect module to use this widget");

var Dialog = require('T/dialog');
if (Dialog == null) throw new Error(LCAT + ": you need the Dialog module to use this widget");

////////////////
// Properties //
////////////////

var fields = args.fields;
var fields_map = [];

var submitting = false;

/////////////
// Methods //
/////////////

function addValidationError(f, msg) {
	f.uiValidation.text = msg;
	f.uiValidation.animate({
		opacity: 1,
	});

	if (_.isFunction(f.addError)) f.addError();
}

function removeValidationError(f) {
	f.uiValidation.text = "";
	f.uiValidation.animate({
		opacity: 1,
	});

	if (_.isFunction(f.removeError)) f.removeError();
}

function submit() {
	var obj = {};
	fields_map.forEach(function(f) {
		if (f.name) {
			obj[f.name] = _.isFunction(f.getValue) ? f.getValue() : f.ui.getValue();
		}
	});

	submitting = true;
	$.formMainView.touchEnabled = false;

	$.trigger('submit', {
		data: obj
	});
}

////////////////////
// Public methods //
////////////////////

$.endSubmit = function() {
	submitting = false;
	$.formMainView.touchEnabled = true;
};

$.submit = function() {
	if (args.askBeforeSubmit) {
		Dialog.option(L("form_submit_prompt", "Do you want to submit the form?"), [
		{
			title: L("form_submit", "Submit"),
			callback: function() {
				if ($.validate()) submit();
			}
		},
		{
			title: L("form_cancel", "Cancel"),
			cancel: true
		}
		]);
	} else {
		if ($.validate()) submit();
	}
};

$.validate = function() {
	var can_submit = true;
	var field_to_focus = null;

	_.each(fields_map, function(f, k) {
		var def = fields[k];
		var current_value = _.isFunction(f.getValue) ? f.getValue() : f.ui.getValue();

		// Required validation
		if (def.required) {
			var requiredValue = false;
			if (_.isBoolean(current_value)) {
				requiredValue = !!current_value;
			} else {
				requiredValue = !_.isEmpty(current_value);
			}

			if (requiredValue !== true) {
				addValidationError(f, L("form_required_field", "Required field"));
				can_submit = false;
				field_to_focus = field_to_focus || f;
				return false;
			}
		}

		// Validation custom
		if (_.isFunction(def.validator)) {
			var validMessage = def.validator(f.ui.value || '');
			if (validMessage !== true) {
				addValidationError(f, validMessage);
				can_submit = false;
				field_to_focus = field_to_focus || f;
				return false;
			}
		}

		removeValidationError(f);
	});

	if (field_to_focus != null) {
		if (_.isFunction(field_to_focus.focus)) {
			field_to_focus.focus();
		} else if (_.isFunction(field_to_focus.ui.focus)) {
			field_to_focus.ui.focus();
		}
	}

	return can_submit;
};

////////////////
// UI Builder //
////////////////

exports.UIBuilder = {};

exports.UIBuilder.text = function(e,f) {
	f.ui = UIFactoryTextField(_.extend({}, $.createStyle({ classes: ['formInput'], apiName: 'TextField' }), {
		textType: e.type,
		hintText: e.placeholder,
		value: e.value,
		returnKeyType: Titanium.UI.RETURNKEY_NEXT
	}));

	f.addError = function() { $.addClass(f.ui, "formInputError"); };
	f.removeError = function() { $.removeClass(f.ui, "formInputError"); };

	f.ui.addEventListener('return', $.validate);
};

exports.UIBuilder.boolean = function(e,f) {
	var switcher = Ti.UI.createSwitch({
		value: e.value,
		left: 0
	});
	var label = UIFactoryLabel(_.extend({}, $.createStyle({ classes: ['formBooleanLabel'], 'apiName':'Label' }), {
		left: 60,
		right: 0,
		html: e.placeholder
	}));

	f.ui = Ti.UI.createView();
	f.ui.add(switcher);
	f.ui.add(label);

	f.getValue = function() { return switcher.getValue(); };
};

exports.UIBuilder.select = function(e,f) {
	f.ui = UIFactorySelect(_.extend({}, $.createStyle({ classes: ['formInput'], apiName: 'Select' }), {
		values: e.values,
		value: e.value,
		hintText: e.placeholder
	}));

	f.addError = function() { $.addClass(f.ui, "formInputError"); };
	f.removeError = function() { $.removeClass(f.ui, "formInputError"); };

	f.ui.addEventListener('change', $.validate);
};

exports.UIBuilder.time = function(e,f) {
	f.ui = UIFactoryTimeSelect(_.extend({}, $.createStyle({ classes: ['formInput'], apiName: 'TimeSelect' }), {
		value: e.value,
		hintText: e.placeholder
	}));

	f.addError = function() { $.addClass(f.ui, "formInputError"); };
	f.removeError = function() { $.removeClass(f.ui, "formInputError"); };

	f.ui.addEventListener('change', $.validate);
};

//////////////////
// Parse fields //
//////////////////

var index = 0;

_.each(_.groupBy(fields, 'group'), function(subFields, k) {
	if (k !== "undefined") {
		$.formMainView.add($.UI.create('Label', {
			classes: ['formGroupLabel'],
			text: k
		}));
		$.formMainView.add($.UI.create('View', {
			classes: ['formGroupSeparator']
		}));
	}

	$.formMainView.add(Ti.UI.createView({ height: 8 }));

	subFields.forEach(function(e) {
		var $wrap = $.UI.create('View', {
			classes: ['formWrap']
		});
		$wrap.add($.UI.create('Label', {
			classes: ['formLabel'],
			text: e.label
		}));

		var f = {
			name: e.name,
			index: (index++)
		};

		var factory = exports.UIBuilder[ e.type ] || exports.UIBuilder.text;
		factory(e,f);

		f.uiValidation = $.UI.create('Label', {
			text: '',
			opacity: 0,
			classes: ['formValidatorMessage']
		});

		$wrap.add(f.ui);
		$wrap.add(f.uiValidation);
		$.formMainView.add($wrap);

		fields_map.push(f);
	});
});

if (args.showSubmitButton == true) {
	var $submit_btn = $.UI.create('Button', {
		classes: ['formSubmitButton'],
		title: args.submitTitle
	});

	$submit_btn.addEventListener('click', function(e) {
		if (submitting) return;
		$.submit();
	});

	$.formMainView.add($submit_btn);
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2017 Google Inc. All rights reserved.
 * This code may only be used under the BSD style license found at
 * http://polymer.github.io/LICENSE.txt
 * Code distributed by Google as part of this project is also
 * subject to an additional IP rights grant found at
 * http://polymer.github.io/PATENTS.txt
 */
'use strict';

import PEC from './particle-execution-context.js';
import assert from '../platform/assert-web.js';
import {PECOuterPort} from './api-channel.js';
import Manifest from './manifest.js';

// TODO: fix
import Loader from './loader.js';

class OuterPEC extends PEC {
  constructor(port, slotComposer, arc) {
    super();
    this._particles = [];
    this._apiPort = new PECOuterPort(port);
    this._arc = arc;
    this._nextIdentifier = 0;
    this.slotComposer = slotComposer;

    this._apiPort.onRender = ({particle, slotName, content}) => {
      if (this.slotComposer) {
        this.slotComposer.renderSlot(particle, slotName, content);
      }
    };

    this._apiPort.onSynchronize = async ({handle, target, callback, modelCallback, type}) => {
      if (handle.toList == undefined) {
        var model = await handle.get();
      } else {
        var model = await handle.toList();
      }
      this._apiPort.SimpleCallback({callback: modelCallback, data: model}, target);
      handle.on(type, data => this._apiPort.SimpleCallback({callback, data}), target);
    };

    this._apiPort.onHandleGet = async ({handle, callback}) => {
      this._apiPort.SimpleCallback({callback, data: await handle.get()});
    };

    this._apiPort.onHandleToList = async ({handle, callback}) => {
      this._apiPort.SimpleCallback({callback, data: await handle.toList()});
    };

    this._apiPort.onHandleSet = ({handle, data}) => {handle.set(data);};
    this._apiPort.onHandleStore = ({handle, data}) => handle.store(data);
    this._apiPort.onHandleClear = ({handle}) => handle.clear();
    this._apiPort.onHandleRemove = ({handle, data}) => handle.remove(data);

    this._apiPort.onIdle = ({version, relevance}) => {
      if (version == this._idleVersion) {
        this._idlePromise = undefined;
        this._idleResolve(relevance);
      }
    };

    this._apiPort.onConstructInnerArc = ({callback, particle}) => {
      var arc = {particle};
      this._apiPort.ConstructArcCallback({callback, arc});
    };

    this._apiPort.onArcCreateHandle = async ({callback, arc, type, name}) => {
      let handle = await this._arc.createHandle(type, name);
      this._apiPort.CreateHandleCallback(handle, {type, name, callback, id: handle.id});
    };

    this._apiPort.onArcMapHandle = async ({callback, arc, handle}) => {
      assert(this._arc.findHandleById(handle.id), `Cannot map nonexistent handle ${handle.id}`);
      // TODO: create hosted handles map with specially generated ids instead of returning the real ones?
      this._apiPort.MapHandleCallback({}, {callback, id: handle.id});
    };

    this._apiPort.onArcCreateSlot = ({callback, arc, transformationParticle, transformationSlotName, hostedParticleName, hostedSlotName}) => {
      if (this.slotComposer) {
        var hostedSlotId = this.slotComposer.createHostedSlot(transformationParticle, transformationSlotName, hostedParticleName, hostedSlotName);
      }
      this._apiPort.CreateSlotCallback({}, {callback, hostedSlotId});
    };

    this._apiPort.onArcLoadRecipe = async ({arc, recipe, callback}) => {
      let manifest = await Manifest.parse(recipe, {loader: this._arc._loader, fileName: ''});
      let error = undefined;
      var recipe = manifest.recipes[0];
      if (recipe) {
        for (let handle of recipe.views) {
          handle.mapToView(this._arc.findHandleById(handle.id));
        }
        if (recipe.normalize()) {
          if (recipe.isResolved()) {
            this._arc.instantiate(recipe, arc);
          } else {
            error = `Recipe is not resolvable ${recipe.toString({showUnresolved: true})}`;
          }
        } else {
          error = 'Recipe could not be normalized';
        }
      } else {
        error = 'No recipe defined';
      }
      this._apiPort.SimpleCallback({callback, data: error});
    };
  }

  stop() {
    this._apiPort.Stop();
  }

  get idle() {
    if (this._idlePromise == undefined) {
      this._idlePromise = new Promise((resolve, reject) => {
        this._idleResolve = resolve;
      });
    }
    this._idleVersion = this._nextIdentifier;
    this._apiPort.AwaitIdle({version: this._nextIdentifier++});
    return this._idlePromise;
  }

  get messageCount() {
    return this._apiPort.messageCount;
  }

  sendEvent(particle, slotName, event) {
    this._apiPort.UIEvent({particle, slotName, event});
  }

  instantiate(particleSpec, id, spec, handles, lastSeenVersion) {
    handles.forEach(handle => {
      var version = lastSeenVersion.get(handle.id) || 0;
      this._apiPort.DefineHandle(handle, {type: handle.type, name: handle.name,
                                       version});
    });

    // TODO: Can we just always define the particle and map a handle for use in later
    //       calls to InstantiateParticle?
    if (spec._model._isInline) {
      this._apiPort.DefineParticle({
        particleDefinition: spec._model._inlineDefinition,
        particleFunction: spec._model._inlineUpdateFunction
      });
    }

    // TODO: rename this concept to something like instantiatedParticle, handle or registration.
    this._apiPort.InstantiateParticle(particleSpec, {id, spec, handles});
    return particleSpec;
  }
  startRender({particle, slotName, contentTypes}) {
    this._apiPort.StartRender({particle, slotName, contentTypes});
  }
  stopRender({particle, slotName}) {
    this._apiPort.StopRender({particle, slotName});
  }
  innerArcRender(transformationParticle, transformationSlotName, hostedSlotId, content) {
    this._apiPort.InnerArcRender({transformationParticle, transformationSlotName, hostedSlotId, content});
  }
  initDebug() {
    this._apiPort.initDebug(this._arc.id);
  }
}

export default OuterPEC;
<commit_msg>fix name collision (tricky use of `var`)<commit_after>/**
 * @license
 * Copyright (c) 2017 Google Inc. All rights reserved.
 * This code may only be used under the BSD style license found at
 * http://polymer.github.io/LICENSE.txt
 * Code distributed by Google as part of this project is also
 * subject to an additional IP rights grant found at
 * http://polymer.github.io/PATENTS.txt
 */
'use strict';

import PEC from './particle-execution-context.js';
import assert from '../platform/assert-web.js';
import {PECOuterPort} from './api-channel.js';
import Manifest from './manifest.js';

// TODO: fix
import Loader from './loader.js';

class OuterPEC extends PEC {
  constructor(port, slotComposer, arc) {
    super();
    this._particles = [];
    this._apiPort = new PECOuterPort(port);
    this._arc = arc;
    this._nextIdentifier = 0;
    this.slotComposer = slotComposer;

    this._apiPort.onRender = ({particle, slotName, content}) => {
      if (this.slotComposer) {
        this.slotComposer.renderSlot(particle, slotName, content);
      }
    };

    this._apiPort.onSynchronize = async ({handle, target, callback, modelCallback, type}) => {
      if (handle.toList == undefined) {
        var model = await handle.get();
      } else {
        var model = await handle.toList();
      }
      this._apiPort.SimpleCallback({callback: modelCallback, data: model}, target);
      handle.on(type, data => this._apiPort.SimpleCallback({callback, data}), target);
    };

    this._apiPort.onHandleGet = async ({handle, callback}) => {
      this._apiPort.SimpleCallback({callback, data: await handle.get()});
    };

    this._apiPort.onHandleToList = async ({handle, callback}) => {
      this._apiPort.SimpleCallback({callback, data: await handle.toList()});
    };

    this._apiPort.onHandleSet = ({handle, data}) => {handle.set(data);};
    this._apiPort.onHandleStore = ({handle, data}) => handle.store(data);
    this._apiPort.onHandleClear = ({handle}) => handle.clear();
    this._apiPort.onHandleRemove = ({handle, data}) => handle.remove(data);

    this._apiPort.onIdle = ({version, relevance}) => {
      if (version == this._idleVersion) {
        this._idlePromise = undefined;
        this._idleResolve(relevance);
      }
    };

    this._apiPort.onConstructInnerArc = ({callback, particle}) => {
      var arc = {particle};
      this._apiPort.ConstructArcCallback({callback, arc});
    };

    this._apiPort.onArcCreateHandle = async ({callback, arc, type, name}) => {
      let handle = await this._arc.createHandle(type, name);
      this._apiPort.CreateHandleCallback(handle, {type, name, callback, id: handle.id});
    };

    this._apiPort.onArcMapHandle = async ({callback, arc, handle}) => {
      assert(this._arc.findHandleById(handle.id), `Cannot map nonexistent handle ${handle.id}`);
      // TODO: create hosted handles map with specially generated ids instead of returning the real ones?
      this._apiPort.MapHandleCallback({}, {callback, id: handle.id});
    };

    this._apiPort.onArcCreateSlot = ({callback, arc, transformationParticle, transformationSlotName, hostedParticleName, hostedSlotName}) => {
      if (this.slotComposer) {
        var hostedSlotId = this.slotComposer.createHostedSlot(transformationParticle, transformationSlotName, hostedParticleName, hostedSlotName);
      }
      this._apiPort.CreateSlotCallback({}, {callback, hostedSlotId});
    };

    this._apiPort.onArcLoadRecipe = async ({arc, recipe, callback}) => {
      let manifest = await Manifest.parse(recipe, {loader: this._arc._loader, fileName: ''});
      let error = undefined;
      let recipe0 = manifest.recipes[0];
      if (recipe0) {
        for (let handle of recipe0.views) {
          handle.mapToView(this._arc.findHandleById(handle.id));
        }
        if (recipe0.normalize()) {
          if (recipe0.isResolved()) {
            this._arc.instantiate(recipe0, arc);
          } else {
            error = `Recipe is not resolvable ${recipe0.toString({showUnresolved: true})}`;
          }
        } else {
          error = 'Recipe could not be normalized';
        }
      } else {
        error = 'No recipe defined';
      }
      this._apiPort.SimpleCallback({callback, data: error});
    };
  }

  stop() {
    this._apiPort.Stop();
  }

  get idle() {
    if (this._idlePromise == undefined) {
      this._idlePromise = new Promise((resolve, reject) => {
        this._idleResolve = resolve;
      });
    }
    this._idleVersion = this._nextIdentifier;
    this._apiPort.AwaitIdle({version: this._nextIdentifier++});
    return this._idlePromise;
  }

  get messageCount() {
    return this._apiPort.messageCount;
  }

  sendEvent(particle, slotName, event) {
    this._apiPort.UIEvent({particle, slotName, event});
  }

  instantiate(particleSpec, id, spec, handles, lastSeenVersion) {
    handles.forEach(handle => {
      var version = lastSeenVersion.get(handle.id) || 0;
      this._apiPort.DefineHandle(handle, {type: handle.type, name: handle.name,
                                       version});
    });

    // TODO: Can we just always define the particle and map a handle for use in later
    //       calls to InstantiateParticle?
    if (spec._model._isInline) {
      this._apiPort.DefineParticle({
        particleDefinition: spec._model._inlineDefinition,
        particleFunction: spec._model._inlineUpdateFunction
      });
    }

    // TODO: rename this concept to something like instantiatedParticle, handle or registration.
    this._apiPort.InstantiateParticle(particleSpec, {id, spec, handles});
    return particleSpec;
  }
  startRender({particle, slotName, contentTypes}) {
    this._apiPort.StartRender({particle, slotName, contentTypes});
  }
  stopRender({particle, slotName}) {
    this._apiPort.StopRender({particle, slotName});
  }
  innerArcRender(transformationParticle, transformationSlotName, hostedSlotId, content) {
    this._apiPort.InnerArcRender({transformationParticle, transformationSlotName, hostedSlotId, content});
  }
  initDebug() {
    this._apiPort.initDebug(this._arc.id);
  }
}

export default OuterPEC;
<|endoftext|>