<commit_before>const Octokit = require("@octokit/core").Octokit.plugin(require("@octokit/plugin-paginate-rest").paginateRest)
,   async = require("async")
,   pg = require("password-generator")
,   crypto = require("crypto")
,   template = require("./template")
;

// helpers

function GH (user) {
    if (!user) throw new Error("The GH module requires a user.");
    this.user = user;
    this.octo = new Octokit({ auth: user.accessToken });
}

function makeNewRepo (gh, target, owner, repoShortName, report) {
    return gh.octo.request("POST " + target, {
      org: owner,
      data: { name: repoShortName }
    }).then(function ({data: repo}) {
      report.push("Repo '" + repoShortName + "' created.");
      return repo;
    });
}

function pickUserRepo (gh, target, owner, repoShortName, report) {
    report.push("Looking for repo " + owner + "/" + repoShortName + " to import.");
    return gh.octo.request("GET /repos/:owner/:repoShortName", {owner, repoShortName}).then(({data: repo}) => repo);
}

function newFile (gh, name, content, report) {
    return function () {
        return gh.octo.request("PUT /repos/:owner/:reponame/contents/:name", {
          owner: gh.currentRepo.owner.login,
          reponame: gh.currentRepo.name,
          name,
          data:{
            message:    "Adding baseline " + name
            ,   content:    new Buffer(content).toString("base64")
          }})
        .then(function () {
          report.push("Added file " + name);
        })
        .catch(function () {
          report.push("Skipped existing file " + name);
        })
      ;
    };
}

function andify (groups, field) {
    var len = groups.length;
    if (len === 1) return groups[0][field];
    else if (len === 2) return groups.map(function (g) { return g[field]; }).join(" and ");
    else {
        var copy = [].concat(groups)
        ,   last = copy.pop()
        ;
        return copy.map(function (g) { return g[field] + ", "; }) + "and " + last[field];
    }
}

GH.prototype = {
    userOrgs:       function(cb) {
        const self = this;
        self.octo.paginate("GET /user/orgs").then(data => {
            cb(null, [self.user.username].concat(data.map(function (org) { return org.login; })));
        }, cb);
    }
,   userOrgRepos:   function (cb) {
        const self = this;
        self.octo.paginate("GET /user/orgs").then(data => {
            Promise.all(
                [{login: self.user.username, type: 'user'}].concat(data.map(function (org) { return {login: org.login, type: 'org'}; }))
                .map(({type, login}) => {
                    const target = type === 'user' ? "users" : "orgs";
                    return self.octo.paginate("GET /:target/:login/repos", { login, target, per_page: 100}).then(repos => {return {login, repos: repos.map(r => r.name)};});
                })).then(results => {
                    cb(null, results.reduce(function(a,b) { a[b.login] = b.repos; return a;}, {}));
                }, cb);
        }, cb);
    }
,   commentOnPR: function({owner, shortName, num, comment}, cb) {
        this.octo.request("POST /repos/:owner/:shortName/issues/:num/comments", { owner, shortName, num, data: comment}).then(({data: comment}) => cb(null, comment), cb);
    }
,   createRepo: function (data, config, cb) {
        this.createOrImportRepo(data, makeNewRepo, newFile, config, cb);
    }
,   importRepo: function (data, config, cb) {
        this.createOrImportRepo(data, pickUserRepo, newFile, config, cb);
    }
    // data describes the repo to create
    // setupAction is a function returning a promise that is called to initiate the creation or
    // obtain a pointer to the repo, it must resolve with the octo repo object
    // action is a function returning a promise that creates or imports a file, and logs a message
   // config is a configuration object with data about the server setup
,   createOrImportRepo: function (data, setupAction, action, config, cb) {
                               // { org: ..., repo: ... }
        const self = this;
        if (!data.groups.some(g => g)) return cb({json: {message: "No group selected to associate with repository"}});
        var report = []
        ,   targetPath = (this.user.username === data.org) ?
           // we need to treat the current user and an org differently
                            "/user/repos": "/orgs/:org/repos"
        ,   license
        ,   licensePath
        ,   contributing
        ,   contributingPath
        ,   w3cJSON
        ,   index
        ,   simpleRepo
        ,   readme
        ,   codeOfConduct
        ,   hookURL = config.hookURL || (config.url + config.hookPath)
        ,   tmplData = {
                name:           andify(data.groups, "name")
            ,   usernames:      data.w3cJsonContacts ? JSON.stringify(data.w3cJsonContacts) : null
            ,   w3cid:          JSON.stringify(data.groups.map(function (g) { return parseInt(g.w3cid, 10); }))
            ,   repo:           data.repo
            ,   displayName:    this.user.displayName
            ,   repotype:    data.groups[0].groupType === "WG" ? "rec-track" : "cg-report"
            }
        ;
        // collaborations between groups of different types aren't really possible, they don't have
        // the same legal regimen, so we only look at the first one
        if (data.groups[0].groupType === "CG") {
            contributingPath = "CG-contributing.md";
            licensePath = "CG-license.md";
        }
        else if (data.groups[0].groupType === "WG") {
            if (data.wgLicense === 'doc') {
                contributingPath = "WG-CONTRIBUTING.md";
                licensePath = "WG-LICENSE.md";
            } else {
                contributingPath = "WG-CONTRIBUTING-SW.md";
                licensePath = "WG-LICENSE-SW.md";
            }
        }
        else {
            var msg = "We currently don't support creating repos for group type: " + data.groups[0].groupType;
            return cb({json: {message: msg}});
        }
        if (data.includeContributing && contributingPath) {
            contributing = template(contributingPath, tmplData);
        }
        if (data.includeLicense && licensePath) {
            license = template(licensePath, tmplData);
        }
        w3cJSON = data.includeW3cJson ? template("w3c.json", tmplData) : null;
        index = data.includeSpec ? template("index.html", tmplData) : null;
        readme = data.includeReadme ? template("README.md", tmplData) : null;
        codeOfConduct = data.includeCodeOfConduct ? template("CODE_OF_CONDUCT.md", tmplData) : null;
        setupAction(self, targetPath, data.org, data.repo, report)
            .then(function (repo) {
                self.currentRepo = repo;
                simpleRepo = {
                    name:       repo.name
                ,   fullName:   repo.owner.login + "/" + repo.name
                ,   owner:      repo.owner.login
                ,   groups:     data.groups.map(function (g) { return g.w3cid; })
                ,   secret:     pg(20)
                };
            })
            .then(license ? action(self, "LICENSE.md", license, report) : null)
            .then(contributing ? action(self, "CONTRIBUTING.md", contributing, report) : null)
            .then(readme ? action(self, "README.md", readme, report) : null)
            .then(codeOfConduct ? action(self, "CODE_OF_CONDUCT.md", codeOfConduct, report) : null)
            .then(index ? action(self, "index.html", index, report) : null)
            .then(w3cJSON ? action(self, "w3c.json", w3cJSON, report) : null)
            .then(function () {
                return self.octo.request("GET /repos/:owner/:name/hooks",
                                         {
                                           owner: self.currentRepo.owner.login, name: self.currentRepo.name
                                         })
                        .then(function ({data: hooks}) {
                            if (!hooks || !hooks.length || !hooks.some(function (h) { return h && h.config && h.config.url === hookURL; })) {
                                return self.octo.request("POST /repos/:owner/:name/hooks",
                                         {
                                           owner: self.currentRepo.owner.login, name: self.currentRepo.name, data: {
                                                            name:   "web"
                                                        ,   config: {
                                                                url:            config.hookURL || (config.url + "api/hook")
                                                            ,   content_type:   "json"
                                                            ,   secret:         simpleRepo.secret
                                                            }
                                                        ,   events: ["pull_request", "issue_comment"]
                                                        ,   active: true
                                           }})
                                                        .then(function () { report.push("Hook installed."); })
                                ;
                            }
                            else {
                                report.push("Hook already present.");
                            }
                        })
                ;
            })
            .then(function () {
                cb(null, { actions: report, repo: simpleRepo });
            })
            .catch(cb)
        ;
    }
,   getRepoContacts: function (repofullname, cb) {
       var self = this;
       const ret = self.octo
             .request("GET /repos/:owner/:name/contents/:file", {
               owner: repofullname.split('/')[0],
               name: repofullname.split('/')[1],
               file: 'w3c.json'
             })
           .then(function({data: w3cinfodesc}) {
               var w3cinfo = JSON.parse(new Buffer(w3cinfodesc.content, 'base64').toString('utf8'));
               return Promise.all(w3cinfo.contacts.map(function(username) {
                   return self.octo.request("GET /users/:username", {username})
                       .then(({data: user}) => user.email);
               }));
           });
       if (!cb) return ret;
       ret.then(emails => cb(null, emails), cb);
}
,   status: function ({owner, shortName, sha, payload}, cb) {
        this.octo
        .request("POST /repos/:owner/:shortName/statuses/:sha", {
          owner, shortName, sha, data: payload
        }).then(function () { cb(null); }, cb);
    }
,   getPrFiles: function(owner, name, prnum, cb) {
        const ret = this.octo
            .request("GET /repos/:owner/:name/pulls/:prnum/files", {owner, name, prnum}).then(({data: files}) => files);
        if (!cb) return ret;
        ret.then(files => cb(null, files), cb);
    }
,   isAdmin:    function (username, orgOrUser, cb) {
        if (username === orgOrUser) {
           return cb(null, true);
        }
        const ret = this.octo.request("GET /orgs/:orgOrUser/memberships/:username", {username, orgOrUser})
              .then(function ({data: role}) {
                return role && role.role === "admin";
              }, (res) => {
                if (res.status === 404) return false;
                throw(res);
              });
        if (!cb) return ret;
        return ret.then(u => cb(null, u), cb);
    }
,   getUser:    function (username, cb) {
        const ret = this.octo.request("GET /users/:username", {username})
            .then(function ({data: user}) {
                var u = {
                        accessToken:        null
                    ,   admin:              false
                    ,   affiliation:        null
                    ,   affiliationName:    null
                    ,   blanket:            false
                    ,   blog:               user.blog || ""
                    ,   displayName:        user.name
                    ,   ghID:               user.id
                    ,   groups:             {}
                    ,   emails:             []
                    ,   photos:             []
                    ,   profileUrl:         user.html_url
                    ,   provider:           "github"
                    ,   username:           username
                    ,   w3capi:             null
                    ,   w3cid:              null
                };
                if (user.email) u.emails.push({ value: user.email });
                if (user.avatar_url) u.photos.push({ value: user.avatar_url });
                return u;
            });
        if (!cb) return ret;
        return ret.then(u => cb(null, u), cb);
    }
};

GH.signPayload = function (algo, secret, buffer) {
    return algo + "=" + crypto.createHmac(algo, secret).update(buffer).digest("hex");
};

GH.checkPayloadSignature = function (algo, secret, buffer, remotesig) {
    return crypto.timingSafeEqual(Buffer.from(GH.signPayload(algo, secret, buffer)), Buffer.from(remotesig));
};

module.exports = GH;
<commit_msg>Fix bug in submitting GH comment (#179)<commit_after>const Octokit = require("@octokit/core").Octokit.plugin(require("@octokit/plugin-paginate-rest").paginateRest)
,   async = require("async")
,   pg = require("password-generator")
,   crypto = require("crypto")
,   template = require("./template")
;

// helpers

function GH (user) {
    if (!user) throw new Error("The GH module requires a user.");
    this.user = user;
    this.octo = new Octokit({ auth: user.accessToken });
}

function makeNewRepo (gh, target, owner, repoShortName, report) {
    return gh.octo.request("POST " + target, {
      org: owner,
      data: { name: repoShortName }
    }).then(function ({data: repo}) {
      report.push("Repo '" + repoShortName + "' created.");
      return repo;
    });
}

function pickUserRepo (gh, target, owner, repoShortName, report) {
    report.push("Looking for repo " + owner + "/" + repoShortName + " to import.");
    return gh.octo.request("GET /repos/:owner/:repoShortName", {owner, repoShortName}).then(({data: repo}) => repo);
}

function newFile (gh, name, content, report) {
    return function () {
        return gh.octo.request("PUT /repos/:owner/:reponame/contents/:name", {
          owner: gh.currentRepo.owner.login,
          reponame: gh.currentRepo.name,
          name,
          data:{
            message:    "Adding baseline " + name
            ,   content:    new Buffer(content).toString("base64")
          }})
        .then(function () {
          report.push("Added file " + name);
        })
        .catch(function () {
          report.push("Skipped existing file " + name);
        })
      ;
    };
}

function andify (groups, field) {
    var len = groups.length;
    if (len === 1) return groups[0][field];
    else if (len === 2) return groups.map(function (g) { return g[field]; }).join(" and ");
    else {
        var copy = [].concat(groups)
        ,   last = copy.pop()
        ;
        return copy.map(function (g) { return g[field] + ", "; }) + "and " + last[field];
    }
}

GH.prototype = {
    userOrgs:       function(cb) {
        const self = this;
        self.octo.paginate("GET /user/orgs").then(data => {
            cb(null, [self.user.username].concat(data.map(function (org) { return org.login; })));
        }, cb);
    }
,   userOrgRepos:   function (cb) {
        const self = this;
        self.octo.paginate("GET /user/orgs").then(data => {
            Promise.all(
                [{login: self.user.username, type: 'user'}].concat(data.map(function (org) { return {login: org.login, type: 'org'}; }))
                .map(({type, login}) => {
                    const target = type === 'user' ? "users" : "orgs";
                    return self.octo.paginate("GET /:target/:login/repos", { login, target, per_page: 100}).then(repos => {return {login, repos: repos.map(r => r.name)};});
                })).then(results => {
                    cb(null, results.reduce(function(a,b) { a[b.login] = b.repos; return a;}, {}));
                }, cb);
        }, cb);
    }
,   commentOnPR: function({owner, shortName, num, comment}, cb) {
        this.octo.request("POST /repos/:owner/:shortName/issues/:num/comments", { owner, shortName, num, data: {body: comment}}).then(({data: comment}) => cb(null, comment), cb);
    }
,   createRepo: function (data, config, cb) {
        this.createOrImportRepo(data, makeNewRepo, newFile, config, cb);
    }
,   importRepo: function (data, config, cb) {
        this.createOrImportRepo(data, pickUserRepo, newFile, config, cb);
    }
    // data describes the repo to create
    // setupAction is a function returning a promise that is called to initiate the creation or
    // obtain a pointer to the repo, it must resolve with the octo repo object
    // action is a function returning a promise that creates or imports a file, and logs a message
   // config is a configuration object with data about the server setup
,   createOrImportRepo: function (data, setupAction, action, config, cb) {
                               // { org: ..., repo: ... }
        const self = this;
        if (!data.groups.some(g => g)) return cb({json: {message: "No group selected to associate with repository"}});
        var report = []
        ,   targetPath = (this.user.username === data.org) ?
           // we need to treat the current user and an org differently
                            "/user/repos": "/orgs/:org/repos"
        ,   license
        ,   licensePath
        ,   contributing
        ,   contributingPath
        ,   w3cJSON
        ,   index
        ,   simpleRepo
        ,   readme
        ,   codeOfConduct
        ,   hookURL = config.hookURL || (config.url + config.hookPath)
        ,   tmplData = {
                name:           andify(data.groups, "name")
            ,   usernames:      data.w3cJsonContacts ? JSON.stringify(data.w3cJsonContacts) : null
            ,   w3cid:          JSON.stringify(data.groups.map(function (g) { return parseInt(g.w3cid, 10); }))
            ,   repo:           data.repo
            ,   displayName:    this.user.displayName
            ,   repotype:    data.groups[0].groupType === "WG" ? "rec-track" : "cg-report"
            }
        ;
        // collaborations between groups of different types aren't really possible, they don't have
        // the same legal regimen, so we only look at the first one
        if (data.groups[0].groupType === "CG") {
            contributingPath = "CG-contributing.md";
            licensePath = "CG-license.md";
        }
        else if (data.groups[0].groupType === "WG") {
            if (data.wgLicense === 'doc') {
                contributingPath = "WG-CONTRIBUTING.md";
                licensePath = "WG-LICENSE.md";
            } else {
                contributingPath = "WG-CONTRIBUTING-SW.md";
                licensePath = "WG-LICENSE-SW.md";
            }
        }
        else {
            var msg = "We currently don't support creating repos for group type: " + data.groups[0].groupType;
            return cb({json: {message: msg}});
        }
        if (data.includeContributing && contributingPath) {
            contributing = template(contributingPath, tmplData);
        }
        if (data.includeLicense && licensePath) {
            license = template(licensePath, tmplData);
        }
        w3cJSON = data.includeW3cJson ? template("w3c.json", tmplData) : null;
        index = data.includeSpec ? template("index.html", tmplData) : null;
        readme = data.includeReadme ? template("README.md", tmplData) : null;
        codeOfConduct = data.includeCodeOfConduct ? template("CODE_OF_CONDUCT.md", tmplData) : null;
        setupAction(self, targetPath, data.org, data.repo, report)
            .then(function (repo) {
                self.currentRepo = repo;
                simpleRepo = {
                    name:       repo.name
                ,   fullName:   repo.owner.login + "/" + repo.name
                ,   owner:      repo.owner.login
                ,   groups:     data.groups.map(function (g) { return g.w3cid; })
                ,   secret:     pg(20)
                };
            })
            .then(license ? action(self, "LICENSE.md", license, report) : null)
            .then(contributing ? action(self, "CONTRIBUTING.md", contributing, report) : null)
            .then(readme ? action(self, "README.md", readme, report) : null)
            .then(codeOfConduct ? action(self, "CODE_OF_CONDUCT.md", codeOfConduct, report) : null)
            .then(index ? action(self, "index.html", index, report) : null)
            .then(w3cJSON ? action(self, "w3c.json", w3cJSON, report) : null)
            .then(function () {
                return self.octo.request("GET /repos/:owner/:name/hooks",
                                         {
                                           owner: self.currentRepo.owner.login, name: self.currentRepo.name
                                         })
                        .then(function ({data: hooks}) {
                            if (!hooks || !hooks.length || !hooks.some(function (h) { return h && h.config && h.config.url === hookURL; })) {
                                return self.octo.request("POST /repos/:owner/:name/hooks",
                                         {
                                           owner: self.currentRepo.owner.login, name: self.currentRepo.name, data: {
                                                            name:   "web"
                                                        ,   config: {
                                                                url:            config.hookURL || (config.url + "api/hook")
                                                            ,   content_type:   "json"
                                                            ,   secret:         simpleRepo.secret
                                                            }
                                                        ,   events: ["pull_request", "issue_comment"]
                                                        ,   active: true
                                           }})
                                                        .then(function () { report.push("Hook installed."); })
                                ;
                            }
                            else {
                                report.push("Hook already present.");
                            }
                        })
                ;
            })
            .then(function () {
                cb(null, { actions: report, repo: simpleRepo });
            })
            .catch(cb)
        ;
    }
,   getRepoContacts: function (repofullname, cb) {
       var self = this;
       const ret = self.octo
             .request("GET /repos/:owner/:name/contents/:file", {
               owner: repofullname.split('/')[0],
               name: repofullname.split('/')[1],
               file: 'w3c.json'
             })
           .then(function({data: w3cinfodesc}) {
               var w3cinfo = JSON.parse(new Buffer(w3cinfodesc.content, 'base64').toString('utf8'));
               return Promise.all(w3cinfo.contacts.map(function(username) {
                   return self.octo.request("GET /users/:username", {username})
                       .then(({data: user}) => user.email);
               }));
           });
       if (!cb) return ret;
       ret.then(emails => cb(null, emails), cb);
}
,   status: function ({owner, shortName, sha, payload}, cb) {
        this.octo
        .request("POST /repos/:owner/:shortName/statuses/:sha", {
          owner, shortName, sha, data: payload
        }).then(function () { cb(null); }, cb);
    }
,   getPrFiles: function(owner, name, prnum, cb) {
        const ret = this.octo
            .request("GET /repos/:owner/:name/pulls/:prnum/files", {owner, name, prnum}).then(({data: files}) => files);
        if (!cb) return ret;
        ret.then(files => cb(null, files), cb);
    }
,   isAdmin:    function (username, orgOrUser, cb) {
        if (username === orgOrUser) {
           return cb(null, true);
        }
        const ret = this.octo.request("GET /orgs/:orgOrUser/memberships/:username", {username, orgOrUser})
              .then(function ({data: role}) {
                return role && role.role === "admin";
              }, (res) => {
                if (res.status === 404) return false;
                throw(res);
              });
        if (!cb) return ret;
        return ret.then(u => cb(null, u), cb);
    }
,   getUser:    function (username, cb) {
        const ret = this.octo.request("GET /users/:username", {username})
            .then(function ({data: user}) {
                var u = {
                        accessToken:        null
                    ,   admin:              false
                    ,   affiliation:        null
                    ,   affiliationName:    null
                    ,   blanket:            false
                    ,   blog:               user.blog || ""
                    ,   displayName:        user.name
                    ,   ghID:               user.id
                    ,   groups:             {}
                    ,   emails:             []
                    ,   photos:             []
                    ,   profileUrl:         user.html_url
                    ,   provider:           "github"
                    ,   username:           username
                    ,   w3capi:             null
                    ,   w3cid:              null
                };
                if (user.email) u.emails.push({ value: user.email });
                if (user.avatar_url) u.photos.push({ value: user.avatar_url });
                return u;
            });
        if (!cb) return ret;
        return ret.then(u => cb(null, u), cb);
    }
};

GH.signPayload = function (algo, secret, buffer) {
    return algo + "=" + crypto.createHmac(algo, secret).update(buffer).digest("hex");
};

GH.checkPayloadSignature = function (algo, secret, buffer, remotesig) {
    return crypto.timingSafeEqual(Buffer.from(GH.signPayload(algo, secret, buffer)), Buffer.from(remotesig));
};

module.exports = GH;
<|endoftext|>


<commit_before>(function (is) {
    is.array = function (val) {
        return Object.prototype.toString.call(val) === '[object Array]';
    };

    is.function = function (val) {
        return Object.prototype.toString.call(val) === '[object Function]';
    };

    is.number = function (val) {
        return !is.object(val) && Object.prototype.toString.call(val) === '[object Number]';
    };

    is.string = function (val) {
        return !is.object(val) && Object.prototype.toString.call(val) === '[object String]';
    };

    is.arrayOf = function (typeFn) {
        return function (val) {
            var ok = is.array(val);

            if (val) { // a truthy check will suffice, instead if is.defined(val)
                for (var i = 0; i < val.length && ok; i++) {
                    ok = typeFn(val[i]);
                }
            }

            return !!ok;
        };
    };

    is.nan = function (val) {
       return val !== val;
    };

    is.boolean = function (val) {
        return !!val === val;
    };

    is.defined = function (val) {
        return val !== null &&
            !is.undefined(val) &&
            val !== Infinity &&
            val !== -Infinity &&
            !is.nan(val);
    }

    is.realNumber = function (val) {
        return is.number(val) &&
            val !== Infinity &&
            val !== -Infinity &&
            !is.nan(val);
    };

    is.integer = function (val) {
        return is.number(val) && val % 1 === 0;
    }

    is.object = function (val) {
        return !!val && val instanceof Object;
    };

    is.undefined = function (val) {
        return (typeof val === 'undefined');
    };

    is.instanceOf = function (constructor) {
        return function (val) {
            return is.function(constructor) && (val instanceof constructor);
        };
    };

// this cryptic expression is fairly common with npm modules
// it exports the library via exports for node.js,
// and attaches to window in the browser
}(typeof exports === 'undefined' ? this.is = {} : exports, this));

<commit_msg>3 bytes smaller<commit_after>(function (is) {

    is.number = function (val) {
        return !is.object(val) && Object.prototype.toString.call(val) === '[object Number]';
    };

    is.string = function (val) {
        return !is.object(val) && Object.prototype.toString.call(val) === '[object String]';
    };

    is.function = function (val) {
        return val instanceof Function;
    };

    is.array = function (val) {
        return val instanceof Array;
    };

    is.arrayOf = function (typeFn) {
        return function (val) {
            var ok = is.array(val);

            if (val) { // a truthy check will suffice, instead if is.defined(val)
                for (var i = 0; i < val.length && ok; i++) {
                    ok = typeFn(val[i]);
                }
            }

            return !!ok;
        };
    };

    is.nan = function (val) {
       return val !== val;
    };

    is.boolean = function (val) {
        return !!val === val;
    };

    is.defined = function (val) {
        return val !== null &&
            !is.undefined(val) &&
            val !== Infinity &&
            val !== -Infinity &&
            !is.nan(val);
    }

    is.realNumber = function (val) {
        return is.number(val) &&
            val !== Infinity &&
            val !== -Infinity &&
            !is.nan(val);
    };

    is.integer = function (val) {
        return is.number(val) && val % 1 === 0;
    }

    is.object = function (val) {
        return !!val && val instanceof Object;
    };

    is.undefined = function (val) {
        return (typeof val === 'undefined');
    };

    is.instanceOf = function (constructor) {
        return function (val) {
            return is.function(constructor) && (val instanceof constructor);
        };
    };

// this cryptic expression is fairly common with npm modules
// it exports the library via exports for node.js,
// and attaches to window in the browser
}(typeof exports === 'undefined' ? this.is = {} : exports, this));

<|endoftext|>


<commit_before>function add_text(str,ids){
  var tweet = document.getElementsByName("tweet")[0];
  var id = document.getElementsByName("id")[0];
  tweet.value += str;
  id.value += ids;
}

function checkCount(){
  var x = document.post.tweet.value.length;
  if (x > 140) {
    x = (x - 140) + '\u6587\u5b57\u30aa\u30fc\u30d0\u30fc\u3057\u3066\u3044\u307e\u3059\u305e\uff01';
  } else {
    x = x + '\u6587\u5b57';
  }
  document.getElementById("log").innerHTML = x;
  return false;
}

String.prototype.replaceAll = function (org, dest){
  return this.split(org).join(dest);
}

var request = null;
function makeRequest(id, count, sendtype) {
  if(typeof window.XMLHttpRequest != 'undefined') {
    try {
      request = new XMLHttpRequest();
    } catch(err) {
      request = null;
    }
  }
  request.onreadystatechange = function() {
    if (request.responseText != 'undefined') {
      document.getElementById(count).innerHTML=(request.responseText);
      document.getElementById('link'+count).innerHTML=('');
    } else {
      document.getElementById(count).innerHTML=('\u614c\u3066\u306a\u3044\u3067\uff01');
    }
  }
  request.open(POST, 'http://npsptter.dip.jp/sendlojax.php', true);
  request.setRequestHeader('Content-type', 'text/plain;charset=utf-8');
  request.send(type + '=' + id);
}
<commit_msg>modified:   js.js<commit_after>function add_text(str,ids){
  var tweet = document.getElementsByName("tweet")[0];
  var id = document.getElementsByName("id")[0];
  tweet.value += str;
  id.value += ids;
}

function checkCount(){
  var x = document.post.tweet.value.length;
  if (x > 140) {
    x = (x - 140) + '\u6587\u5b57\u30aa\u30fc\u30d0\u30fc\u3057\u3066\u3044\u307e\u3059\u305e\uff01';
  } else {
    x = x + '\u6587\u5b57';
  }
  document.getElementById("log").innerHTML = x;
  return false;
}

String.prototype.replaceAll = function (org, dest){
  return this.split(org).join(dest);
}

var request = null;
function makeRequest(id, count, sendtype) {
  if(typeof window.XMLHttpRequest != 'undefined') {
    try {
      request = new XMLHttpRequest();
    } catch(err) {
      request = null;
    }
  }
  request.onreadystatechange = function() {
    if (request.responseText != 'undefined') {
      document.getElementById(count).innerHTML=(request.responseText);
      document.getElementById('link'+count).innerHTML=('');
    } else {
      document.getElementById(count).innerHTML=('\u614c\u3066\u306a\u3044\u3067\uff01');
    }
  }
  request.open(POST, 'http://npsptter.dip.jp/sendlojax.php', true);
  request.setRequestHeader('Content-type', 'text/plain;charset=utf-8');
  request.send(sendtype + '=' + id);
}
<|endoftext|>


<commit_before>
/**
* @license jspm-git
* Copyright (c) 2014 Tauren Mills, contributors
* jspm endpoint for Git Repositories
* License: MIT
*/

'use strict';

var exec = require('child_process').exec;
var path = require('path');
var Promise = require('rsvp').Promise;
var rimraf = require('rimraf');
var ncp = require('ncp').ncp;
var fs = require('fs');
var temp = require('temp');
var semver = require('semver');
var urljoin = require('url-join');

var logging = false;
var vPrefixVersions = [];

var logMsg = function(msg) {
  if (logging) {
    console.log(new Date() + ': ' + msg);
  }
};

var createGitUrl = function(basepath, repo, reposuffix) {
  return urljoin(basepath, repo + reposuffix);
};

var getGitVersion = function() {
  return new Promise(function(resolve, reject) {
    exec('git --version', null, function(err, stdout, stderr) {
      var versionArr;
      if (err) {
        logMsg('Error while reading our the Git version: ' + stderr);
        reject(stderr);
      } else {
        versionArr = stdout.match(/\d.\d.\d/);
        if (versionArr.length === 1) {
          resolve(versionArr[0]);
        } else {
          logMsg('Error while parsing the Git version');
          reject();
        }
      }
    });
  });
};

var cloneGitRepo = function(repoDir, branch, url, execOpt) {
  return getGitVersion().
  then(function(gitVersion) {
    return new Promise(function(resolve, reject) {
      var command;
      // Parameter --single-branch is only supported from Git version 1.7.10 upwards
      if (semver.lt(gitVersion, '1.7.10')) {
        command = 'git clone -b ' + branch + ' --depth 1 ' + url + ' ' + repoDir;
      } else {
        command = 'git clone -b ' + branch + ' --depth 1 --single-branch ' + url + ' ' + repoDir;
      }
      exec(command, execOpt, function(err, stdout, stderr) {
        if (err) {
          logMsg('Error while cloning the git branch: ' + stderr);
          rimraf(repoDir, function() {
            reject(stderr);
          });
        } else {
          resolve();
        }
      });
    });
  });
};

var exportGitRepo = function(repoDir, branch, url, execOpt) {
  return cloneGitRepo(repoDir, branch, url, execOpt).
  then(function() {
    return new Promise(function(resolve, reject) {
      // Remove the .git folder
      rimraf(path.join(repoDir, '.git'), function(err) {
        if (err) {
          logMsg('Error while removing the .git folder: ' + err);
          reject(err);
        } else {
          resolve();
        }
      });
    });
  });
};

var readPackageJSON = function(repoDir) {

  return new Promise(function(resolve, reject) {
    fs.readFile(path.join(repoDir, 'package.json'), 'utf8', function (err, data) {
      if (err) {
        logMsg('Warn: No package.json found');
        resolve({});
      } else {
        try {
          resolve(JSON.parse(data));
        } catch (err) {
          logMsg('Error while parsing package.json: ' + err);
          reject(err);
        }
      }
    });
  });
};

var moveRepoToOutDir = function(repoDir, outDir) {

  return new Promise(function(resolve, reject) {
    ncp(repoDir, outDir, {'stopOnErr': true}, function(err) {
      if (err) {
        logMsg('Error while moving repo to outDir: ' + err);
        // Make sure the the outDir gets removed
        rimraf(outDir, function() {
          reject(err);
        });
      } else {
        rimraf(repoDir, function() {
          resolve();
        });
      }
    });
  });
};

var createTempDir = function() {

  return new Promise(function(resolve, reject) {
    temp.mkdir('jspm-git-', function(err, tempDirPath) {
      if (err) {
        reject();
      } else {
        resolve(tempDirPath);
      }
    });
  });
};

var GitLocation = function(options) {

  logging = options.log === false ? false : true;

  this.execOpt = {
    cwd: options.tmpDir,
    timeout: options.timeout * 1000,
    killSignal: 'SIGKILL'
  };

  if (typeof options.reposuffix !== 'string') {
    options.reposuffix = '.git';
  }

  this.options = options;
};

// static configuration function
GitLocation.configure = function(config, ui) {

  return Promise.resolve(ui.input('Enter the base URL of your git server e.g. https://code.mycompany.com/git/', null))
  .then(function(baseurl) {
    if (!baseurl || baseurl === '') {
      ui.log('warn', 'Invalid base URL was entered');
      return Promise.reject();
    }
    config.baseurl = baseurl;
  })
  .then(function() {
    return Promise.resolve(ui.confirm('Would you like to use the default git repository suffix (.git)?', true))
    .then(function(usedefaultsuffix) {
      if(usedefaultsuffix) {
        // Leave the reposuffix config empty in order to use the default configuration of the endpoint
        return;
      }
      return Promise.resolve(ui.confirm('Would you like to set an empty git repository suffix?', false))
      .then(function(setemptysuffix) {
        if (setemptysuffix) {
          // Set an empty repository suffix
          config.reposuffix = '';
          return;
        }
        return Promise.resolve(ui.input('Enter the git repository suffix', '.git'))
        .then(function(reposuffix) {
          // Use the entered suffix for the endpoint
          config.reposuffix = reposuffix;
        });
      });
    });
  })
  .then(function() {
    return config;
  });
};

GitLocation.prototype = {

  parse: function(name) {
    var parts = name.split('/');
    var packageName = parts.splice(0, 2).join('/');
    return {
      package: packageName,
      path: parts.join('/')
    };
  },

  // return values
  // { versions: { versionhash } }
  // { redirect: 'newrepo' }
  // { notfound: true }
  lookup: function(repo) {
    var self = this;
    return new Promise(function(resolve, reject) {

      var versions, cancel,
          url = createGitUrl(self.options.baseurl, repo, self.options.reposuffix);

      exec('git ls-remote ' + url + ' refs/tags/* refs/heads/*', self.execOpt, function(err, stdout, stderr) {
        if (cancel)
          return;

        if (err) {
          if ((err + '').indexOf('Repository not found') == -1) {
            cancel = true;
            reject(stderr);
          }
          return;
        }

        versions = {};
        var refs = stdout.split('\n');
        for (var i = 0; i < refs.length; i++) {
          if (!refs[i])
            continue;

          var hash = refs[i].substr(0, refs[i].indexOf('\t'));
          var refName = refs[i].substr(hash.length + 1);
          var version;

          if (refName.substr(0, 11) == 'refs/heads/')
            version = '#' + refName.substr(11);

          else if (refName.substr(0, 10) == 'refs/tags/') {
            if (refName.substr(refName.length - 3, 3) == '^{}')
              version = refName.substr(10, refName.length - 13);
            else
              version = refName.substr(10);

            if (version.substr(0, 1) == 'v' && semver.valid(version.substr(1))) {
              version = version.substr(1);
              // note when we remove a "v" which versions we need to add it back to
              // to work out the tag version again
              vPrefixVersions.push(repo + '@' + version);
            }
          }

          versions[version] = hash;
        }

        resolve({ versions: versions });
      });
    });
  },

  // always an exact version
  // assumed that this is run after getVersions so the repo exists
  download: function(repo, version, hash, outDir) {

    var url, tempRepoDir, packageJSONData, self = this;

    if (vPrefixVersions.indexOf(repo + '@' + version) != -1) {
      version = 'v' + version;
    }

    // Automatically track and cleanup files at exit
    temp.track();

    url = createGitUrl(this.options.baseurl, repo, this.options.reposuffix);

    return createTempDir().then(function(tempDir) {
      tempRepoDir = tempDir;
      return exportGitRepo(tempRepoDir, version, url, self.execOpt);
    }).then(function() {
      return readPackageJSON(tempRepoDir);
    }).then(function(data) {
      packageJSONData = data;
      return moveRepoToOutDir(tempRepoDir, outDir);
    }).then(function() {
      return packageJSONData;
    });
  },

  // sync function to clean up any tmp files / store save caches etc
  dispose: function() {

    // temp folder that has been created during download will be automaically
    // removed at exit due the call of temp.track();
  }
};

module.exports = GitLocation;
<commit_msg>BREAKING CHANGE: Make jspm-git compatible to jspm 0.9.0 endpoint API<commit_after>
/**
* @license jspm-git
* Copyright (c) 2014 Tauren Mills, contributors
* jspm endpoint for Git Repositories
* (based on Guy Bedford's github endpoint for jspm https://github.com/jspm/github)
* License: MIT
*/

'use strict';

var exec = require('child_process').exec;
var path = require('path');
var Promise = require('rsvp').Promise;
var rimraf = require('rimraf');
var ncp = require('ncp').ncp;
var fs = require('fs');
var temp = require('temp');
var semver = require('semver');
var urljoin = require('url-join');

var logging = false;

var logMsg = function(msg) {
  if (logging) {
    console.log(new Date() + ': ' + msg);
  }
};

var createGitUrl = function(basepath, repo, reposuffix) {
  return urljoin(basepath, repo + reposuffix);
};

var getGitVersion = function() {
  return new Promise(function(resolve, reject) {
    exec('git --version', null, function(err, stdout, stderr) {
      var versionArr;
      if (err) {
        logMsg('Error while reading our the Git version: ' + stderr);
        reject(stderr);
      } else {
        versionArr = stdout.match(/\d.\d.\d/);
        if (versionArr.length === 1) {
          resolve(versionArr[0]);
        } else {
          logMsg('Error while parsing the Git version');
          reject();
        }
      }
    });
  });
};

var cloneGitRepo = function(repoDir, branch, url, execOpt) {
  return getGitVersion().
  then(function(gitVersion) {
    return new Promise(function(resolve, reject) {
      var command;
      // Parameter --single-branch is only supported from Git version 1.7.10 upwards
      if (semver.lt(gitVersion, '1.7.10')) {
        command = 'git clone -b ' + branch + ' --depth 1 ' + url + ' ' + repoDir;
      } else {
        command = 'git clone -b ' + branch + ' --depth 1 --single-branch ' + url + ' ' + repoDir;
      }
      exec(command, execOpt, function(err, stdout, stderr) {
        if (err) {
          logMsg('Error while cloning the git branch: ' + stderr);
          rimraf(repoDir, function() {
            reject(stderr);
          });
        } else {
          resolve();
        }
      });
    });
  });
};

var exportGitRepo = function(repoDir, branch, url, execOpt) {
  return cloneGitRepo(repoDir, branch, url, execOpt).
  then(function() {
    return new Promise(function(resolve, reject) {
      // Remove the .git folder
      rimraf(path.join(repoDir, '.git'), function(err) {
        if (err) {
          logMsg('Error while removing the .git folder: ' + err);
          reject(err);
        } else {
          resolve();
        }
      });
    });
  });
};

var readPackageJSON = function(repoDir) {

  return new Promise(function(resolve, reject) {
    fs.readFile(path.join(repoDir, 'package.json'), 'utf8', function (err, data) {
      if (err) {
        logMsg('Warn: No package.json found');
        resolve({});
      } else {
        try {
          resolve(JSON.parse(data));
        } catch (err) {
          logMsg('Error while parsing package.json: ' + err);
          reject(err);
        }
      }
    });
  });
};

var moveRepoToOutDir = function(repoDir, outDir) {

  return new Promise(function(resolve, reject) {
    ncp(repoDir, outDir, {'stopOnErr': true}, function(err) {
      if (err) {
        logMsg('Error while moving repo to outDir: ' + err);
        // Make sure the the outDir gets removed
        rimraf(outDir, function() {
          reject(err);
        });
      } else {
        rimraf(repoDir, function() {
          resolve();
        });
      }
    });
  });
};

var createTempDir = function() {

  return new Promise(function(resolve, reject) {
    temp.mkdir('jspm-git-', function(err, tempDirPath) {
      if (err) {
        reject();
      } else {
        resolve(tempDirPath);
      }
    });
  });
};

var GitLocation = function(options) {

  logging = options.log === false ? false : true;

  this.execOpt = {
    cwd: options.tmpDir,
    timeout: options.timeout * 1000,
    killSignal: 'SIGKILL'
  };

  if (typeof options.reposuffix !== 'string') {
    options.reposuffix = '.git';
  }

  this.options = options;
};

// static configuration function
GitLocation.configure = function(config, ui) {

  return Promise.resolve(ui.input('Enter the base URL of your git server e.g. https://code.mycompany.com/git/', null))
  .then(function(baseurl) {
    if (!baseurl || baseurl === '') {
      ui.log('warn', 'Invalid base URL was entered');
      return Promise.reject();
    }
    config.baseurl = baseurl;
  })
  .then(function() {
    return Promise.resolve(ui.confirm('Would you like to use the default git repository suffix (.git)?', true))
    .then(function(usedefaultsuffix) {
      if(usedefaultsuffix) {
        // Leave the reposuffix config empty in order to use the default configuration of the endpoint
        return;
      }
      return Promise.resolve(ui.confirm('Would you like to set an empty git repository suffix?', false))
      .then(function(setemptysuffix) {
        if (setemptysuffix) {
          // Set an empty repository suffix
          config.reposuffix = '';
          return;
        }
        return Promise.resolve(ui.input('Enter the git repository suffix', '.git'))
        .then(function(reposuffix) {
          // Use the entered suffix for the endpoint
          config.reposuffix = reposuffix;
        });
      });
    });
  })
  .then(function() {
    return config;
  });
};

GitLocation.prototype = {

  parse: function(name) {
    var parts = name.split('/');
    var packageName = parts.splice(0, 2).join('/');
    return {
      package: packageName,
      path: parts.join('/')
    };
  },

  // return values
  // { versions: { versionhash } }
  // { notfound: true }
  lookup: function(repo) {
    var self = this;
    return new Promise(function(resolve, reject) {

      var versions,
          url = createGitUrl(self.options.baseurl, repo, self.options.reposuffix);

      exec('git ls-remote ' + url + ' refs/tags/* refs/heads/*', self.execOpt, function(err, stdout, stderr) {
        if (err) {
          if ((err + '').indexOf('Repository not found') == -1)
            reject(stderr);
          else
            resolve({ notfound: true });
        }

        versions = {};
        var refs = stdout.split('\n');
        for (var i = 0; i < refs.length; i++) {
          if (!refs[i])
            continue;

          var hash = refs[i].substr(0, refs[i].indexOf('\t'));
          var refName = refs[i].substr(hash.length + 1);
          var version;
          var versionObj = { hash: hash, meta: {} };

          if (refName.substr(0, 11) == 'refs/heads/') {
            version = refName.substr(11);
            versionObj.exactOnly = true;
          }

          else if (refName.substr(0, 10) == 'refs/tags/') {
            if (refName.substr(refName.length - 3, 3) == '^{}')
              version = refName.substr(10, refName.length - 13);
            else
              version = refName.substr(10);

            if (version.substr(0, 1) == 'v' && semver.valid(version.substr(1))) {
              version = version.substr(1);
              // note when we remove a "v" which versions we need to add it back to
              // to work out the tag version again
              versionObj.meta.vPrefix = true;
            }
          }

          versions[version] = versionObj;
        }

        resolve({ versions: versions });
      });
    });
  },

  // always an exact version
  // assumed that this is run after getVersions so the repo exists
  download: function(repo, version, hash, meta, outDir) {

    var url, tempRepoDir, packageJSONData, self = this;

    if (meta.vPrefix)
      version = 'v' + version;

    // Automatically track and cleanup files at exit
    temp.track();

    url = createGitUrl(this.options.baseurl, repo, this.options.reposuffix);

    return createTempDir().then(function(tempDir) {
      tempRepoDir = tempDir;
      return exportGitRepo(tempRepoDir, version, url, self.execOpt);
    }).then(function() {
      return readPackageJSON(tempRepoDir);
    }).then(function(data) {
      packageJSONData = data;
      return moveRepoToOutDir(tempRepoDir, outDir);
    }).then(function() {
      return packageJSONData;
    });
  },

  // sync function to clean up any tmp files / store save caches etc
  dispose: function() {

    // temp folder that has been created during download will be automaically
    // removed at exit due the call of temp.track();
  }
};

module.exports = GitLocation;
<|endoftext|>


<commit_before>var Discord = require('discord.js');
var Request = require('request');
var parseIrc = require('irc-message').parse;
var config = require('./config.js');
var request = Request.defaults({
    headers: {
        'User-Agent': 'riotlv v' + require('./package.json').version
    }
});

const invitelink = 'https://discordapp.com/oauth2/authorize?client_id='
    + config.client_id + '&scope=bot&permissions=19456';

var client = new Discord.Client({
    autoReconnect: true
});

client.on('ready', function () {
    console.log("Ready");
    client.setStatus('online', 'with butts');
});

client.on('message', function (message) {
    // Make sure we're on allowed server
    if (message.channel.server.id === config.server_id) {
        let words = message.cleanContent.match(/(?:[^\s"]+|"[^"]*")+/g);
        if (words[0].startsWith(config.prefix)) {
            let cmd = words[0].substring(config.prefix.length);
            if (commands[cmd]) {
                words.shift();
                commands[cmd](message, words);
            }
        }
    }
});

client.on('warn', function (warn) {
    console.error('WARN', warn);
});

client.on('error', function (error) {
    console.error('ERROR', error);
});

client.loginWithToken(config.token, function (error) {
    if (error) {
        console.error("Couldn't login: ", error);
        process.exit(15);
    }
});

var commands = {
    help: function (message, words) {
        sendReply(message, "command prefix: " + config.prefix + " - commands: " + Object.keys(commands).join(', '));
    },
    lv: function (message, words) {
        let limit = words[2] || 10;
        let channel = words[1] || "riotgames";
        let user = words[0] || null;

        try {
            limit = Math.min(parseInt(limit), 50);
        } catch (e) {
            sendReply(message, "limit must be a number");
            return;
        }

        console.log("Log request for: `" + JSON.stringify({ user: words[0], channel: channel, limit: limit }) + "`");

        if (user === null) {
            sendReply(message, "usage: " + config.prefix + "lv <user> [channel] [limit]");
            return;
        }

        request('http://' + config.lvdomain + '/api/logs/'
                + encodeURIComponent(channel) + "/?token=" + config.lvtoken
                + "&nick=" + encodeURIComponent(user) + "&before=" + limit,
        function (error, response, body) {
            let reply;
            let data;
            if (error) {
                reply = "an error occurred with the API request";
                console.error('RERROR', error);
            }
            else {
                try {
                    data = JSON.parse(body);
                } catch (e) {
                    data = null;
                    reply = "an error occurred parsing the API response";
                    console.error('PERROR', e);
                }

                if (data !== null && data.before) {
                    reply = "here are logs for **" + user + "** from **" + channel + "**\n\n```";
                    for (let i = data.before.length - 1; i >= 0; --i) {
                        let index = data.before.length - 1 - i;
                        let ircmsg = parseIrc(data.before[index].text);
                        let line = "\n" + (new Date(data.before[index].time * 1000)).toISOString().replace('T', ' ').replace('Z', ' UTC')
                            + " | " + ircmsg.params[1];
                        if (reply.length + line.length > 1900) {
                            reply += "\n```";
                            sendReply(message, reply);
                            reply = "\n```";
                        }
                        reply += line;
                    }
                    reply += "\n```";
                }
                else {
                    reply = "no data found.";
                }
				reply += '\nSee http://' + config.lvdomain + '/' + encodeURIComponent(channel) + "/?user=" + encodeURIComponent(user);
            }
            sendReply(message, reply);
        });
    },
    game: function (message, words) {
        let game = words.join(' ') || "with butts";
        client.setStatus('online', game);
    }
};

function sendReply(message, reply) {
    client.reply(message, reply, { tts: false }, function (error) {
        if (error) {
            console.error('WERROR', error);
        }
    });
}

process.on('SIGINT', function () {
    console.log("Logging out");
    client.logout(function () { process.exit(); });
});
<commit_msg>check words exists<commit_after>var Discord = require('discord.js');
var Request = require('request');
var parseIrc = require('irc-message').parse;
var config = require('./config.js');
var request = Request.defaults({
    headers: {
        'User-Agent': 'riotlv v' + require('./package.json').version
    }
});

const invitelink = 'https://discordapp.com/oauth2/authorize?client_id='
    + config.client_id + '&scope=bot&permissions=19456';

var client = new Discord.Client({
    autoReconnect: true
});

client.on('ready', function () {
    console.log("Ready");
    client.setStatus('online', 'with butts');
});

client.on('message', function (message) {
    // Make sure we're on allowed server
    if (message.channel.server.id === config.server_id) {
        let words = message.cleanContent.match(/(?:[^\s"]+|"[^"]*")+/g);
        if (words && words[0].startsWith(config.prefix)) {
            let cmd = words[0].substring(config.prefix.length);
            if (commands[cmd]) {
                words.shift();
                commands[cmd](message, words);
            }
        }
    }
});

client.on('warn', function (warn) {
    console.error('WARN', warn);
});

client.on('error', function (error) {
    console.error('ERROR', error);
});

client.loginWithToken(config.token, function (error) {
    if (error) {
        console.error("Couldn't login: ", error);
        process.exit(15);
    }
});

var commands = {
    help: function (message, words) {
        sendReply(message, "command prefix: " + config.prefix + " - commands: " + Object.keys(commands).join(', '));
    },
    lv: function (message, words) {
        let limit = words[2] || 10;
        let channel = words[1] || "riotgames";
        let user = words[0] || null;

        try {
            limit = Math.min(parseInt(limit), 50);
        } catch (e) {
            sendReply(message, "limit must be a number");
            return;
        }

        console.log("Log request for: `" + JSON.stringify({ user: words[0], channel: channel, limit: limit }) + "`");

        if (user === null) {
            sendReply(message, "usage: " + config.prefix + "lv <user> [channel] [limit]");
            return;
        }

        request('http://' + config.lvdomain + '/api/logs/'
                + encodeURIComponent(channel) + "/?token=" + config.lvtoken
                + "&nick=" + encodeURIComponent(user) + "&before=" + limit,
        function (error, response, body) {
            let reply;
            let data;
            if (error) {
                reply = "an error occurred with the API request";
                console.error('RERROR', error);
            }
            else {
                try {
                    data = JSON.parse(body);
                } catch (e) {
                    data = null;
                    reply = "an error occurred parsing the API response";
                    console.error('PERROR', e);
                }

                if (data !== null && data.before) {
                    reply = "here are logs for **" + user + "** from **" + channel + "**\n\n```";
                    for (let i = data.before.length - 1; i >= 0; --i) {
                        let index = data.before.length - 1 - i;
                        let ircmsg = parseIrc(data.before[index].text);
                        let line = "\n" + (new Date(data.before[index].time * 1000)).toISOString().replace('T', ' ').replace('Z', ' UTC')
                            + " | " + ircmsg.params[1];
                        if (reply.length + line.length > 1900) {
                            reply += "\n```";
                            sendReply(message, reply);
                            reply = "\n```";
                        }
                        reply += line;
                    }
                    reply += "\n```";
                }
                else {
                    reply = "no data found.";
                }
				reply += '\nSee http://' + config.lvdomain + '/' + encodeURIComponent(channel) + "/?user=" + encodeURIComponent(user);
            }
            sendReply(message, reply);
        });
    },
    game: function (message, words) {
        let game = words.join(' ') || "with butts";
        client.setStatus('online', game);
    }
};

function sendReply(message, reply) {
    client.reply(message, reply, { tts: false }, function (error) {
        if (error) {
            console.error('WERROR', error);
        }
    });
}

process.on('SIGINT', function () {
    console.log("Logging out");
    client.logout(function () { process.exit(); });
});
<|endoftext|>


<commit_before>$( ".closeX" ).click(function() {
    var id = $( this ).parent().attr("id");
    var markup = [
        '
',
        '
',
        '
Are you sure you want to remove this user?
',
        '

Yes

',
        '

No

',
        '

'].join('');

    $( markup ).hide().appendTo('body');
    $( "#" + id ).clone().appendTo(".confirmBox").children('.closeX').hide();
    $( ".gray-out" ).fadeIn();

    $( "#yes.button" ).click(function(){
        $.ajax({
            url: 'remover.php',
            type: 'POST',
            data: 'id=' + id});
        $( this ).parent().fadeOut(400, function() {
            $( this ).parent().remove();
            $( "#" + id).fadeOut(400);
        })
    });

    $( "#no.button" ).click(function(){
        $( this ).parent().fadeOut(400, function() {
            $( this ).parent().remove();
        })
    });
});
<commit_msg>smoothed out fading<commit_after>$( ".closeX" ).click(function() {
    var id = $( this ).parent().attr("id");
    var markup = [
        '
',
        '
',
        '
Are you sure you want to remove this user?
',
        '

Yes

',
        '

No

',
        '

'].join('');

    $( markup ).hide().appendTo('body');
    $( "#" + id ).clone().appendTo(".confirmBox").children('.closeX').hide();
    $( ".gray-out" ).fadeIn();

    $( "#yes.button" ).click(function(){
        $.ajax({
            url: 'remover.php',
            type: 'POST',
            data: 'id=' + id});
        $( ".gray-out" ).fadeOut(400, function() {
            $( this ).remove();
            $( "#" + id).fadeOut(400);
        })
    });

    $( "#no.button" ).click(function(){
        $( ".gray-out" ).fadeOut(400, function() {
            $( this ).remove();
        })
    });
});
<|endoftext|>


<commit_before>/**
 * Written by Nathan Fritz and Lance Stout. Copyright © 2011 by &yet, LLC.
 * Released under the terms of the MIT License
 */

var thoonkmodule = require('./thoonk'),
    // Queue = require("./queue.js").Queue,
    uuid = require("node-uuid"),
    redis = require('redis'),
    fs = require('fs');

/**
 * A Thoonk Job is a queue which does not completely remove items
 * from the queue until a task completion notice is received.
 *
 * Job Item Lifecycle:
 *     - A job is created using put() with the data for the job.
 *     - The job is moved to a claimed state when a worker retrieves
 *       the job data from the queue.
 *     - The worker performs any processing required, and calls
 *       finish() with the job's result data.
 *     - The job is marked as finished and removed from the queue.
 *
 * Alternative: Job Cancellation
 *     - After a worker has claimed a job, it calls cancel() with
 *       the job's ID, possibly because of an error or lack of required
 *       resources.
 *     - The job is moved from a claimed state back to the queue.
 *
 * Alternative: Job Stalling
 *     - A call to stall() with the job ID is made.
 *     - The job is moved out of the queue and into a stalled state. While
 *       stalled, the job will not be dispatched.
 *     - A call to retry() with the job ID is made.
 *     - The job is moved out of the stalled state and back into the queue.
 *
 * Alternative: Job Deletion
 *     - A call to retract() with the job ID is made.
 *     - The job item is completely removed from the queue and any
 *       other job states.
 *
 * Redis Keys Used:
 *     feed.published:[feed] -- A time sorted set of queued jobs.
 *     feed.cancelled:[feed] -- A hash table of cancelled jobs.
 *     feed.claimed:[feed]   -- A hash table of claimed jobs.
 *     feed.stalled:[feed]   -- A hash table of stalled jobs.
 *     feeed.funning:[feed]  -- A hash table of running jobs.
 *     feed.finished:[feed]\x00[id] -- Temporary queue for receiving job
 *                                     result data.
 *
 * Thoonk Standard API:
 *     cancel    -- Move a job from a claimed state back into the queue.
 *     finish    -- Mark a job as completed and store the results.
 *     get       -- Retrieve the next job from the queue.
 *     getIds    -- Return IDs of all jobs in the queue.
 *     getResult -- Retrieve the result of a job.
 *     put       -- Add a new job to the queue.
 *     retract   -- Completely remove a job from use.
 *     retry     -- Resume execution of a stalled job.
 *     stall     -- Pause execution of a queued job.
 */

/**
 * Create a new Job queue object for a given Thoonk feed.
 *
 * Note: More than one Job queue objects may be create for
 *       the same Thoonk feed, and creating a Job queue object
 *       does not automatically generate the Thoonk feed itself.
 *
 * Arguments:
 *     thoonk -- The main Thoonk object.
 *     feed   -- The name of the feed.
 *     config -- Optional dictionary of configuration values.
 */
function Job(name, thoonk, config) {

    thoonkmodule.ThoonkBaseObject.call(this, name, thoonk);
    this.bredis = this.thoonk._get_blocking_redis(name);
    this.lredis = this.thoonk.lredis;

    this.subscribables = ['publish', 'edit', 'retract', 'finish', 'retry', 'stall'];

    this.thoonk.on('job.finish:' + this.name, function(feed, id, result) {
        this.emit('job.id.finish:' + id, null, feed, id, result);
    }.bind(this));

    this.thoonk.on('quit', function() {
        this.lredis.unsubscribe('job.finish:' + this.name);
        this.bredis.quit();
    }.bind(this));
}

/**
 * Add a new job to the queue.
 *
 * Arguments:
 *     item            -- The contents of the job request.
 *     callback        -- Executed on successful submission of the job.
 *     high_priority   -- Optional bool indicating that the job
 *                      should be inserted to the beginning of the
 *                      queue. Defaults to false.
 *     id              -- Optionally set the id of the job.
 *     finish_callback -- Optional callback (feed, id, result) for published job
 *
 * Callback Arguments:
 *     error
 *     item  -- The contents of the job.
 *     id    -- The ID of the submitted job.
 */
function jobPublish(item, callback, high_priority, id, finish_callback) {
    if(id === undefined || id === null) {
        var id = uuid();
    }
    var args = [id, JSON.stringify(item), ''+Date.now(), high_priority];
    if(finish_callback) {
        this.once('job.id.finish:' + id, finish_callback);
    }
    this.runscript('publish', args, callback);
}

/**
 * Retrieve the next job from the queue.
 *
 * Arguments:
 *     timeout  -- Optional time in seconds to wait before exiting.
 *     callback --
 *
 * Callback Arguments:
 *     error
 *     result  -- The content of the job request.
 *     id      -- The ID of the job.
 *     timeout -- Flag indicating that the request timed out.
 */
function jobGet(timeout, callback) {
    console.log('job.get called');
    if(!timeout) timeout = 0;
    this.bredis.brpop(this.name, timeout, function (err, item, id) {
        console.log('job brpop cb args: ', arguments);
    });
}

/**
 * Mark a job as completed, and optionally store any results.
 *
 * Arguments:
 *     id        -- The ID of the job to finish.
 *     callback  -- Executes
 *     setresult -- Optional result data from the job.
 *
 * Callback Arguments:
 *     error -- Boolean indicating that an error occurred.
 *     id    -- The ID of the finished job.
 */
function jobFinish(id, callback, setresult) {
    // this.runscript
}

/**
 * Move a claimed job back to the queue.
 *
 * Arguments:
 *     id       -- The ID of the job to cancel.
 *     callback -- Executed if an error occurs.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the cancelled job.
 */
function jobCancel(id, callback) {

}

/**
 * Move a job out of the queue in order to pause processing.
 *
 * While stalled, a job will not be dispatched to requesting workers.
 *
 * Arguments:
 *     id       -- The ID of the job to pause.
 *     callback -- Executed if an error occurs.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the stalled job.
 */
function jobStall(id, callback) {

}

/**
 * Move a job from a stalled state back into the job queue.
 *
 * Arguments:
 *     id       -- The ID of the job to resume.
 *     callback -- Executed if an error occurred.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the resumed job.
 */
function jobRetry(id, callback) {

}

/**
 * Get the number of times the job has been cancelled.
 *
 * Arguments:
 *     id       -- The ID of the job to check.
 *     callback -- Called with result.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     num   -- The number of times the job has been cancelled.
 */
function jobGetNumOfFailures(id, callback) {
    this.redis.hget("feed.cancelled:" + this.name, id, callback);
}

/**
 * Delete a job from anywhere in the process.
 *
 * Arguments:
 *     id       -- The ID of the job to delete.
 *     callback -- Executed if an error occurred.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the deleted job.
 */
function jobRetract(id, callback) {

}

Job.prototype = thoonkmodule.ThoonkBaseObject.prototype;
Job.prototype.constructor = Job;
Job.prototype.objtype = 'job';
Job.prototype.scriptdir = __dirname + '/scripts/job';

Job.prototype.put = jobPublish;
Job.prototype.publish = jobPublish;
Job.prototype.get = jobGet;
Job.prototype.finish = jobFinish;
Job.prototype.cancel = jobCancel;
Job.prototype.stall = jobStall;
Job.prototype.retry = jobRetry;
Job.prototype.retract = jobRetract;
Job.prototype.getNumOfFailures = jobGetNumOfFailures;
// Job.prototype.ready = jobReady;

exports.Job = Job;
<commit_msg>flesh out most of the functionality needed in the Job JS wrapper<commit_after>/**
 * Written by Nathan Fritz and Lance Stout. Copyright © 2011 by &yet, LLC.
 * Released under the terms of the MIT License
 */

var thoonkmodule = require('./thoonk'),
    uuid = require("node-uuid"),
    redis = require('redis'),
    fs = require('fs');

/**
 * A Thoonk Job is a queue which does not completely remove items
 * from the queue until a task completion notice is received.
 *
 * Job Item Lifecycle:
 *     - A job is created using put() with the data for the job.
 *     - The job is moved to a claimed state when a worker retrieves
 *       the job data from the queue.
 *     - The worker performs any processing required, and calls
 *       finish() with the job's result data.
 *     - The job is marked as finished and removed from the queue.
 *
 * Alternative: Job Cancellation
 *     - After a worker has claimed a job, it calls cancel() with
 *       the job's ID, possibly because of an error or lack of required
 *       resources.
 *     - The job is moved from a claimed state back to the queue.
 *
 * Alternative: Job Stalling
 *     - A call to stall() with the job ID is made.
 *     - The job is moved out of the queue and into a stalled state. While
 *       stalled, the job will not be dispatched.
 *     - A call to retry() with the job ID is made.
 *     - The job is moved out of the stalled state and back into the queue.
 *
 * Alternative: Job Deletion
 *     - A call to retract() with the job ID is made.
 *     - The job item is completely removed from the queue and any
 *       other job states.
 *
 * Redis Keys Used:
 *     feed.published:[feed] -- A time sorted set of queued jobs.
 *     feed.cancelled:[feed] -- A hash table of cancelled jobs.
 *     feed.claimed:[feed]   -- A hash table of claimed jobs.
 *     feed.stalled:[feed]   -- A hash table of stalled jobs.
 *     feeed.funning:[feed]  -- A hash table of running jobs.
 *     feed.finished:[feed]\x00[id] -- Temporary queue for receiving job
 *                                     result data.
 *
 * Thoonk Standard API:
 *     cancel    -- Move a job from a claimed state back into the queue.
 *     finish    -- Mark a job as completed and store the results.
 *     get       -- Retrieve the next job from the queue.
 *     getIds    -- Return IDs of all jobs in the queue.
 *     getResult -- Retrieve the result of a job.
 *     put       -- Add a new job to the queue.
 *     retract   -- Completely remove a job from use.
 *     retry     -- Resume execution of a stalled job.
 *     stall     -- Pause execution of a queued job.
 */

/**
 * Create a new Job queue object for a given Thoonk feed.
 *
 * Note: More than one Job queue objects may be create for
 *       the same Thoonk feed, and creating a Job queue object
 *       does not automatically generate the Thoonk feed itself.
 *
 * Arguments:
 *     thoonk -- The main Thoonk object.
 *     feed   -- The name of the feed.
 *     config -- Optional dictionary of configuration values.
 */
function Job(name, thoonk, config) {

    thoonkmodule.ThoonkBaseObject.call(this, name, thoonk);
    this.bredis = this.thoonk._get_blocking_redis(name);
    this.lredis = this.thoonk.lredis;

    this.subscribables = ['publish', 'edit', 'retract', 'finish', 'retry', 'stall'];

    this.thoonk.on('job.finish:' + this.name, function(feed, id, result) {
        this.emit('job.id.finish:' + id, null, feed, id, result);
    }.bind(this));

    this.thoonk.on('quit', function() {
        this.lredis.unsubscribe('job.finish:' + this.name);
        this.bredis.quit();
    }.bind(this));
}

/**
 * Add a new job to the queue.
 *
 * Arguments:
 *     item            -- The contents of the job request.
 *     callback        -- Executed on successful submission of the job.
 *     high_priority   -- Optional bool indicating that the job
 *                      should be inserted to the beginning of the
 *                      queue. Defaults to false.
 *     id              -- Optionally set the id of the job.
 *     finish_callback -- Optional callback (feed, id, result) for published job
 *
 * Callback Arguments:
 *     error
 *     item  -- The contents of the job.
 *     id    -- The ID of the submitted job.
 */
function jobPublish(item, callback, high_priority, id, finish_callback) {
    if(id === undefined || id === null) {
        var id = uuid();
    }
    var args = [id, JSON.stringify(item), ''+Date.now()];
    if (high_priority) args.push(high_priority);
    if(finish_callback) {
        this.once('job.id.finish:' + id, finish_callback);
    }
    this.runscript('publish', args, callback);
}

/**
 * Retrieve the next job from the queue.
 *
 * Arguments:
 *     timeout  -- Optional time in seconds to wait before exiting.
 *     callback --
 *
 * Callback Arguments:
 *     error
 *     result  -- The content of the job request.
 *     id      -- The ID of the job.
 *     timeout -- Flag indicating that the request timed out.
 */
function jobGet(timeout, callback) {
    this.bredis.brpop("job.ids:"+this.name, timeout||0, function (err, args) {
        // console.log('job.get brpop cb: ', arguments);
        if (args && args[1]) {
            // console.log('id is', args[1]);
            this.runscript('get', [args[1], ''+Date.now()], callback);
        } else {
            callback(null, null, null, true);
        }
    }.bind(this));
}

/**
 * Mark a job as completed, and optionally store any results.
 *
 * Arguments:
 *     id        -- The ID of the job to finish.
 *     callback  -- Executes
 *     setresult -- Optional result data from the job.
 *
 * Callback Arguments:
 *     error -- Boolean indicating that an error occurred.
 *     id    -- The ID of the finished job.
 */
function jobFinish(id, callback, setresult) {
    var args = [id];
    if (setresult) args.push(setresult);
    console.log('jobFinish args', args);
    this.runscript('finish', args, callback);
}

/**
 * Move a claimed job back to the queue.
 *
 * Arguments:
 *     id       -- The ID of the job to cancel.
 *     callback -- Executed if an error occurs.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the cancelled job.
 */
function jobCancel(id, callback) {
    this.runscript('cancel', [id], callback);
}

/**
 * Move a job out of the queue in order to pause processing.
 *
 * While stalled, a job will not be dispatched to requesting workers.
 *
 * Arguments:
 *     id       -- The ID of the job to pause.
 *     callback -- Executed if an error occurs.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the stalled job.
 */
function jobStall(id, callback) {
    this.runscript('stall', [id], callback);
}

/**
 * Move a job from a stalled state back into the job queue.
 *
 * Arguments:
 *     id       -- The ID of the job to resume.
 *     callback -- Executed if an error occurred.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the resumed job.
 */
function jobRetry(id, callback) {
    this.runscript('retry', [id], callback);
}

/**
 * Get the number of times the job has been cancelled.
 *
 * Arguments:
 *     id       -- The ID of the job to check.
 *     callback -- Called with result.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     num   -- The number of times the job has been cancelled.
 */
function jobGetNumOfFailures(id, callback) {
    this.redis.hget("feed.cancelled:" + this.name, id, callback);
}

/**
 * Delete a job from anywhere in the process.
 *
 * Arguments:
 *     id       -- The ID of the job to delete.
 *     callback -- Executed if an error occurred.
 *
 * Callback Arguments:
 *     error -- A string description of the error.
 *     id    -- The ID of the deleted job.
 */
function jobRetract(id, callback) {

}

Job.prototype = thoonkmodule.ThoonkBaseObject.prototype;
Job.prototype.constructor = Job;
Job.prototype.objtype = 'job';
Job.prototype.scriptdir = __dirname + '/scripts/job';

Job.prototype.put = jobPublish;
Job.prototype.publish = jobPublish;
Job.prototype.get = jobGet;
Job.prototype.finish = jobFinish;
Job.prototype.cancel = jobCancel;
Job.prototype.stall = jobStall;
Job.prototype.retry = jobRetry;
Job.prototype.retract = jobRetract;
Job.prototype.getNumOfFailures = jobGetNumOfFailures;
// Job.prototype.ready = jobReady;

exports.Job = Job;
<|endoftext|>


<commit_before>#!/usr/bin/env node

const crypto = require("crypto");
const _sss = require("./build/Release/shamirsecretsharing");

exports.createShares = function createShares(data, n, k) {
  return new Promise((resolve) => {
    // Use node.js native random source for a key
    crypto.randomBytes(32, (err, random) => {
      if (err) throw err;
      _sss.createShares(data, n, k, random, resolve);
    });
  });
};

exports.combineShares = function combineShares(shares) {
  return new Promise((resolve) => {
    _sss.combineShares(shares, resolve);
  }).then((x) => {
    if (x === null) {
      throw "invalid or too few shares provided";
    } else {
      return x;
    }
  });
};
<commit_msg>Add error ident for easier catching<commit_after>#!/usr/bin/env node

const crypto = require("crypto");
const _sss = require("./build/Release/shamirsecretsharing");

exports.createShares = function createShares(data, n, k) {
  return new Promise((resolve) => {
    // Use node.js native random source for a key
    crypto.randomBytes(32, (err, random) => {
      if (err) throw err;
      _sss.createShares(data, n, k, random, resolve);
    });
  });
};

exports.combineShares = function combineShares(shares) {
  return new Promise((resolve) => {
    _sss.combineShares(shares, resolve);
  }).then((x) => {
    if (x === null) {
      throw "InvalidAccessError: nvalid or too few shares provided";
    } else {
      return x;
    }
  });
};
<|endoftext|>


<commit_before>"use strict";

var async = require('async');
var childProcess = require('child_process');
var storage = require('azure-storage');
var console = require('console');
var fs = require('fs');
var fsextra = require('fs-extra');
var path = require('path');
var process = require('process');

//////////////
//Shared functionality

function loadRemoteAccessInfo() {
    var res = undefined;
    try {
        res = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'azureconfig.json')));
    }
    catch (ex) {
        ;
    }

    return res;
}

function dirLooksLikeTrace(trgtDir) {
    try {
        if (fs.existsSync(trgtDir)) {
            var contents = fs.readdirSync(trgtDir);
            if (contents.length !== 0 && contents.indexOf('ttdlog.log') === -1) {
                //This doesn't look like an old trace directory!
                //We don't want to accidentally blow away user data.
                return false;
            }
        }
    } catch (ex) {
        return false;
    }

    return true;
}

function uploadFileToAzure(localFile, remoteFile, callback) {
    console.log('Uploading data to ' + remoteFile + ' from ' + localFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.createFileFromLocalFile('cloud-traces', '', remoteFile, localFile, function (err, res) {
            if (err) {
                console.error('Failed to upload trace to Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function downloadFileFromAzure(remoteFile, localFile, callback) {
    console.log('Downloading data from ' + remoteFile + ' to ' + localFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.getFileToLocalFile('cloud-traces', '', remoteFile, localFile, function (err, res) {
            if (err) {
                console.error('Failed to download trace from Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function removeFileFromAzure(remoteFile, callback) {
    console.log('Removing file from ' + remoteFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.deleteFileIfExists('cloud-traces', '', remoteFile, function (err) {
            if (err) {
                console.error('Failed to remove trace from Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function buildZipCmd(targetFile) {
    var zipcmd = undefined;
    if (process.platform === 'win32') {
        zipcmd = `"c:\\Program Files\\7-Zip\\7z.exe" a -bd -tzip ${targetFile} *`;
    }
    else {
        zipcmd = `zip -q ${targetFile} *`;
    }

    return zipcmd;
}

//Run compression of trace dir into temp file
function logCompress(targetFile, traceDirName, callback) {
    console.log('Compressing ' + traceDirName + ' into: ' + targetFile);

    var zipcmd = buildZipCmd(targetFile);
    if (!zipcmd) {
        callback("Failed to zip trace", null);
    }
    else {
        var startTime = new Date();
        var err = null;
        try {
            childProcess.execSync(zipcmd, { cwd: traceDirName });
            console.log(`Compress complete in ${(new Date() - startTime) / 1000}s.`);
        }
        catch (ex) {
            err = ex;
        }

        callback(err);
    }
}

function buildUnZipCmd(traceFile, traceDirName) {
    var zipcmd = undefined;
    if (process.platform === 'win32') {
        zipcmd = `"c:\\Program Files\\7-Zip\\7z.exe" e ${traceFile} -o${traceDirName}`;
    }
    else {
        zipcmd = `unzip -q ${targetFile} -d ${traceDirName}`;
    }

    return zipcmd;
}

function logDecompress(traceFile, traceDirName, callback) {
    console.log('Decompressing ' + traceFile + ' into: ' + traceDirName);

    var unzipcmd = buildUnZipCmd(traceFile, traceDirName);
    if (!unzipcmd) {
        callback("Failed to zip trace", null);
    }
    else {
        var startTime = new Date();
        var err = null;
        try {
            childProcess.execSync(unzipcmd);
            console.log(`Decompress complete in ${(new Date() - startTime) / 1000}s.`);
        }
        catch (ex) {
            err = ex;
        }

        callback(err);
    }
}

//////////////
//Upload functionality

//Ensure the trace dir looks like a TTD log dir.
function ensureTraceDir(traceDirName) {
    var dname = path.resolve(traceDirName);
    var lname = path.resolve(dname, 'ttdlog.log');
    if (fs.existsSync(dname) && fs.existsSync(lname)) {
        return dname;
    }
    else {
        if (!fs.existsSync(dname)) {
            console.error('Directory does not exist: ' + traceDirName);
        }
        else {
            console.error('Directory does not contain a diagnostics trace log: ' + traceDirName);
        }

        process.exit(1);
    }
}
exports.ensureTraceDir = ensureTraceDir;

//Do the processing for the trace upload
function processTraceUpload(traceDirName, remoteName) {
    var tempfile = path.resolve(path.dirname(traceDirName), path.basename(traceDirName) + '_' + 'templog.trc');
    var remoteFile = remoteName || path.basename(traceDirName) + '.trc';

    var actionPipeline = [
        function (callback) {
            logCompress(tempfile, traceDirName, callback);
        },
        function (callback) {
            uploadFileToAzure(tempfile, remoteFile, callback);
        },
        function (callback) {
            console.log('Deleting temp file: ' + tempfile);
            fs.unlink(tempfile, function (err) {
                //if it doesn't exist or something goes wrong that is fine just eat the error
                callback(null);
            });
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Upload failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Upload succeeded.');
        }
    });
}
exports.processTraceUpload = processTraceUpload;

//////////////
//Download functionality

//Create the target dir name we want to expand into and make sure it is ready to extract data into
function ensureTraceTargetDir(optTargetDirName) {
    var trgtDir = path.resolve(process.cwd(), '_tracelog' + path.sep);
    if (optTargetDirName) {
        trgtDir = path.resolve(optTargetDirName);
    }

    if (!dirLooksLikeTrace(trgtDir)) {
        return undefined;
    }

    fsextra.emptyDirSync(trgtDir);
    return trgtDir;
}
exports.ensureTraceTargetDir = ensureTraceTargetDir;

//copy the contents of the resources folder into the target dir
function copyReplayDebugResources(targetDir, callback) {
    var resourcespath = path.resolve(__dirname, 'resources');
    var resourcestarget = path.resolve(targetDir);

    console.log(`Copying resources from ${resourcespath} to ${resourcestarget}`);
    fsextra.copy(resourcespath, resourcestarget, function (err) {
        if (err) {
            console.error(`Failed to copy resources from ${resourcespath} to ${resourcestarget}`);
        }

        callback(err);
    });
}

function processTraceDownload(remoteFileName, targetDir) {
    var tempfile = path.resolve(__dirname, "templog.trc");

    var actionPipeline = [
        function (callback) {
            downloadFileFromAzure(path.basename(remoteFileName), tempfile, callback);
        },
        function (callback) {
            logDecompress(tempfile, targetDir, callback);
        },
        function (callback) {
            copyReplayDebugResources(targetDir, callback);
        },
        function (callback) {
            console.log('Deleting temp file: ' + tempfile);
            fs.unlink(tempfile, function (err) {
                //if it doesn't exist or something goes wrong that is fine just eat the error
                callback(null);
            });
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Download and process failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Download and process succeeded.');
        }
    });
}
exports.processTraceDownload = processTraceDownload;

//////////////
//Remove and Setup folder functionality

function processTraceRemove(traceName) {
    removeFileFromAzure(traceName, function (err) {
        if (!err) {
            console.log('Remove succeeded.');
        }
    });
}
exports.processTraceRemove = processTraceRemove;

function processTraceInitializeForVSCode(traceName) {
    if (!dirLooksLikeTrace(traceName)) {
        return false;
    }

    var actionPipeline = [
        function (callback) {
            copyReplayDebugResources(traceName, callback);
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Initialize trace directory for VSCode launch failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Initialize trace directory for VSCode launch succeeded.');
        }
    });

    return true;
}
exports.processTraceInitializeForVSCode = processTraceInitializeForVSCode;<commit_msg>We aren't x-plat yet.<commit_after>"use strict";

var async = require('async');
var childProcess = require('child_process');
var storage = require('azure-storage');
var console = require('console');
var fs = require('fs');
var fsextra = require('fs-extra');
var path = require('path');
var process = require('process');

//////////////
//Shared functionality

function loadRemoteAccessInfo() {
    var res = undefined;
    try {
        res = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'azureconfig.json')));
    }
    catch (ex) {
        ;
    }

    return res;
}

function dirLooksLikeTrace(trgtDir) {
    try {
        if (fs.existsSync(trgtDir)) {
            var contents = fs.readdirSync(trgtDir);
            if (contents.length !== 0 && contents.indexOf('ttdlog.log') === -1) {
                //This doesn't look like an old trace directory!
                //We don't want to accidentally blow away user data.
                return false;
            }
        }
    } catch (ex) {
        return false;
    }

    return true;
}

function uploadFileToAzure(localFile, remoteFile, callback) {
    console.log('Uploading data to ' + remoteFile + ' from ' + localFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.createFileFromLocalFile('cloud-traces', '', remoteFile, localFile, function (err, res) {
            if (err) {
                console.error('Failed to upload trace to Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function downloadFileFromAzure(remoteFile, localFile, callback) {
    console.log('Downloading data from ' + remoteFile + ' to ' + localFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.getFileToLocalFile('cloud-traces', '', remoteFile, localFile, function (err, res) {
            if (err) {
                console.error('Failed to download trace from Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function removeFileFromAzure(remoteFile, callback) {
    console.log('Removing file from ' + remoteFile);

    var accessInfo = loadRemoteAccessInfo();
    if (!accessInfo) {
        callback('Failed to load Azure config.');
    }
    else {
        var azureService = storage.createFileService(accessInfo.remoteUser, accessInfo.storageKey);
        azureService.deleteFileIfExists('cloud-traces', '', remoteFile, function (err) {
            if (err) {
                console.error('Failed to remove trace from Azure storage: ' + err);
            }

            callback(err);
        });
    }
}

function buildZipCmd(targetFile) {
    return `"c:\\Program Files\\7-Zip\\7z.exe" a -bd -tzip ${targetFile} *`;
}

//Run compression of trace dir into temp file
function logCompress(targetFile, traceDirName, callback) {
    console.log('Compressing ' + traceDirName + ' into: ' + targetFile);

    var zipcmd = buildZipCmd(targetFile);
    if (!zipcmd) {
        callback("Failed to zip trace", null);
    }
    else {
        var startTime = new Date();
        var err = null;
        try {
            childProcess.execSync(zipcmd, { cwd: traceDirName });
            console.log(`Compress complete in ${(new Date() - startTime) / 1000}s.`);
        }
        catch (ex) {
            err = ex;
        }

        callback(err);
    }
}

function buildUnZipCmd(traceFile, traceDirName) {
    return `"c:\\Program Files\\7-Zip\\7z.exe" e ${traceFile} -o${traceDirName}`;
}

function logDecompress(traceFile, traceDirName, callback) {
    console.log('Decompressing ' + traceFile + ' into: ' + traceDirName);

    var unzipcmd = buildUnZipCmd(traceFile, traceDirName);
    if (!unzipcmd) {
        callback("Failed to zip trace", null);
    }
    else {
        var startTime = new Date();
        var err = null;
        try {
            childProcess.execSync(unzipcmd);
            console.log(`Decompress complete in ${(new Date() - startTime) / 1000}s.`);
        }
        catch (ex) {
            err = ex;
        }

        callback(err);
    }
}

//////////////
//Upload functionality

//Ensure the trace dir looks like a TTD log dir.
function ensureTraceDir(traceDirName) {
    var dname = path.resolve(traceDirName);
    var lname = path.resolve(dname, 'ttdlog.log');
    if (fs.existsSync(dname) && fs.existsSync(lname)) {
        return dname;
    }
    else {
        if (!fs.existsSync(dname)) {
            console.error('Directory does not exist: ' + traceDirName);
        }
        else {
            console.error('Directory does not contain a diagnostics trace log: ' + traceDirName);
        }

        process.exit(1);
    }
}
exports.ensureTraceDir = ensureTraceDir;

//Do the processing for the trace upload
function processTraceUpload(traceDirName, remoteName) {
    var tempfile = path.resolve(path.dirname(traceDirName), path.basename(traceDirName) + '_' + 'templog.trc');
    var remoteFile = remoteName || path.basename(traceDirName) + '.trc';

    var actionPipeline = [
        function (callback) {
            logCompress(tempfile, traceDirName, callback);
        },
        function (callback) {
            uploadFileToAzure(tempfile, remoteFile, callback);
        },
        function (callback) {
            console.log('Deleting temp file: ' + tempfile);
            fs.unlink(tempfile, function (err) {
                //if it doesn't exist or something goes wrong that is fine just eat the error
                callback(null);
            });
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Upload failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Upload succeeded.');
        }
    });
}
exports.processTraceUpload = processTraceUpload;

//////////////
//Download functionality

//Create the target dir name we want to expand into and make sure it is ready to extract data into
function ensureTraceTargetDir(optTargetDirName) {
    var trgtDir = path.resolve(process.cwd(), '_tracelog' + path.sep);
    if (optTargetDirName) {
        trgtDir = path.resolve(optTargetDirName);
    }

    if (!dirLooksLikeTrace(trgtDir)) {
        return undefined;
    }

    fsextra.emptyDirSync(trgtDir);
    return trgtDir;
}
exports.ensureTraceTargetDir = ensureTraceTargetDir;

//copy the contents of the resources folder into the target dir
function copyReplayDebugResources(targetDir, callback) {
    var resourcespath = path.resolve(__dirname, 'resources');
    var resourcestarget = path.resolve(targetDir);

    console.log(`Copying resources from ${resourcespath} to ${resourcestarget}`);
    fsextra.copy(resourcespath, resourcestarget, function (err) {
        if (err) {
            console.error(`Failed to copy resources from ${resourcespath} to ${resourcestarget}`);
        }

        callback(err);
    });
}

function processTraceDownload(remoteFileName, targetDir) {
    var tempfile = path.resolve(__dirname, "templog.trc");

    var actionPipeline = [
        function (callback) {
            downloadFileFromAzure(path.basename(remoteFileName), tempfile, callback);
        },
        function (callback) {
            logDecompress(tempfile, targetDir, callback);
        },
        function (callback) {
            copyReplayDebugResources(targetDir, callback);
        },
        function (callback) {
            console.log('Deleting temp file: ' + tempfile);
            fs.unlink(tempfile, function (err) {
                //if it doesn't exist or something goes wrong that is fine just eat the error
                callback(null);
            });
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Download and process failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Download and process succeeded.');
        }
    });
}
exports.processTraceDownload = processTraceDownload;

//////////////
//Remove and Setup folder functionality

function processTraceRemove(traceName) {
    removeFileFromAzure(traceName, function (err) {
        if (!err) {
            console.log('Remove succeeded.');
        }
    });
}
exports.processTraceRemove = processTraceRemove;

function processTraceInitializeForVSCode(traceName) {
    if (!dirLooksLikeTrace(traceName)) {
        return false;
    }

    var actionPipeline = [
        function (callback) {
            copyReplayDebugResources(traceName, callback);
        }
    ];

    async.series(actionPipeline, function (err, results) {
        if (err) {
            console.error('Initialize trace directory for VSCode launch failed with: ' + err);
            process.exit(1);
        }
        else {
            console.log('Initialize trace directory for VSCode launch succeeded.');
        }
    });

    return true;
}
exports.processTraceInitializeForVSCode = processTraceInitializeForVSCode;<|endoftext|>