<commit_before>var clone = (function() {
'use strict';

function _instanceof(obj, type) {
  return type != null && obj instanceof type;
}

var nativeMap;
try {
  nativeMap = Map;
} catch(_) {
  // maybe a reference error because no `Map`. Give it a dummy value that no
  // value will ever be an instanceof.
  nativeMap = function() {};
}

var nativeSet;
try {
  nativeSet = Set;
} catch(_) {
  nativeSet = function() {};
}

var nativePromise;
try {
  nativePromise = Promise;
} catch(_) {
  nativePromise = function() {};
}

/**
 * Clones (copies) an Object using deep copying.
 *
 * This function supports circular references by default, but if you are certain
 * there are no circular references in your object, you can save some CPU time
 * by calling clone(obj, false).
 *
 * Caution: if `circular` is false and `parent` contains circular references,
 * your program may enter an infinite loop and crash.
 *
 * @param `parent` - the object to be cloned
 * @param `circular` - set to true if the object to be cloned may contain
 *    circular references. (optional - true by default)
 * @param `depth` - set to a number if the object is only to be cloned to
 *    a particular depth. (optional - defaults to Infinity)
 * @param `prototype` - sets the prototype to be used when cloning an object.
 *    (optional - defaults to parent prototype).
 * @param `includeNonEnumerable` - set to true if the non-enumerable properties
 *    should be cloned as well. Non-enumerable properties on the prototype
 *    chain will be ignored. (optional - false by default)
*/
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
  if (typeof circular === 'object') {
    depth = circular.depth;
    prototype = circular.prototype;
    includeNonEnumerable = circular.includeNonEnumerable;
    circular = circular.circular;
  }
  // maintain two arrays for circular references, where corresponding parents
  // and children have the same index
  var allParents = [];
  var allChildren = [];

  var useBuffer = typeof Buffer != 'undefined';

  if (typeof circular == 'undefined')
    circular = true;

  if (typeof depth == 'undefined')
    depth = Infinity;

  // recurse this function so we don't reset allParents and allChildren
  function _clone(parent, depth) {
    // cloning null always returns null
    if (parent === null)
      return null;

    if (depth === 0)
      return parent;

    var child;
    var proto;
    if (typeof parent != 'object') {
      return parent;
    }

    if (_instanceof(parent, nativeMap)) {
      child = new nativeMap();
    } else if (_instanceof(parent, nativeSet)) {
      child = new nativeSet();
    } else if (_instanceof(parent, nativePromise)) {
      child = new nativePromise(function (resolve, reject) {
        parent.then(function(value) {
          resolve(_clone(value, depth - 1));
        }, function(err) {
          reject(_clone(err, depth - 1));
        });
      });
    } else if (clone.__isArray(parent)) {
      child = [];
    } else if (clone.__isRegExp(parent)) {
      child = new RegExp(parent.source, __getRegExpFlags(parent));
      if (parent.lastIndex) child.lastIndex = parent.lastIndex;
    } else if (clone.__isDate(parent)) {
      child = new Date(parent.getTime());
    } else if (useBuffer && Buffer.isBuffer(parent)) {
      if (Buffer.from) {
        // Node.js >= 5.10.0
        child = Buffer.from(parent);
      } else {
        // Older Node.js versions
        child = new Buffer(parent.length);
        parent.copy(child);
      }
      return child;
    } else if (_instanceof(parent, Error)) {
      child = Object.create(parent);
    } else {
      if (typeof prototype == 'undefined') {
        proto = Object.getPrototypeOf(parent);
        child = Object.create(proto);
      }
      else {
        child = Object.create(prototype);
        proto = prototype;
      }
    }

    if (circular) {
      var index = allParents.indexOf(parent);

      if (index != -1) {
        return allChildren[index];
      }
      allParents.push(parent);
      allChildren.push(child);
    }

    if (_instanceof(parent, nativeMap)) {
      parent.forEach(function(value, key) {
        var keyChild = _clone(key, depth - 1);
        var valueChild = _clone(value, depth - 1);
        child.set(keyChild, valueChild);
      });
    }
    if (_instanceof(parent, nativeSet)) {
      parent.forEach(function(value) {
        var entryChild = _clone(value, depth - 1);
        child.add(entryChild);
      });
    }

    for (var i in parent) {
      var attrs;
      if (proto) {
        attrs = Object.getOwnPropertyDescriptor(proto, i);
      }

      if (attrs && attrs.set == null) {
        continue;
      }
      child[i] = _clone(parent[i], depth - 1);
    }

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(parent);
      for (var i = 0; i < symbols.length; i++) {
        // Don't need to worry about cloning a symbol because it is a primitive,
        // like a number or string.
        var symbol = symbols[i];
        var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
        if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
          continue;
        }
        child[symbol] = _clone(parent[symbol], depth - 1);
        if (!descriptor.enumerable) {
          Object.defineProperty(child, symbol, {
            enumerable: false
          });
        }
      }
    }

    if (includeNonEnumerable) {
      var allPropertyNames = Object.getOwnPropertyNames(parent);
      for (var i = 0; i < allPropertyNames.length; i++) {
        var propertyName = allPropertyNames[i];
        var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
        if (descriptor && descriptor.enumerable) {
          continue;
        }
        child[propertyName] = _clone(parent[propertyName], depth - 1);
        Object.defineProperty(child, propertyName, {
          enumerable: false
        });
      }
    }

    return child;
  }

  return _clone(parent, depth);
}

/**
 * Simple flat clone using prototype, accepts only objects, usefull for property
 * override on FLAT configuration object (no nested props).
 *
 * USE WITH CAUTION! This may not behave as you wish if you do not know how this
 * works.
 */
clone.clonePrototype = function clonePrototype(parent) {
  if (parent === null)
    return null;

  var c = function () {};
  c.prototype = parent;
  return new c();
};

// private utility functions

function __objToStr(o) {
  return Object.prototype.toString.call(o);
}
clone.__objToStr = __objToStr;

function __isDate(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Date]';
}
clone.__isDate = __isDate;

function __isArray(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Array]';
}
clone.__isArray = __isArray;

function __isRegExp(o) {
  return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
}
clone.__isRegExp = __isRegExp;

function __getRegExpFlags(re) {
  var flags = '';
  if (re.global) flags += 'g';
  if (re.ignoreCase) flags += 'i';
  if (re.multiline) flags += 'm';
  return flags;
}
clone.__getRegExpFlags = __getRegExpFlags;

return clone;
})();

if (typeof module === 'object' && module.exports) {
  module.exports = clone;
}
<commit_msg>Simplify descriptor handling<commit_after>var clone = (function() {
'use strict';

function _instanceof(obj, type) {
  return type != null && obj instanceof type;
}

var nativeMap;
try {
  nativeMap = Map;
} catch(_) {
  // maybe a reference error because no `Map`. Give it a dummy value that no
  // value will ever be an instanceof.
  nativeMap = function() {};
}

var nativeSet;
try {
  nativeSet = Set;
} catch(_) {
  nativeSet = function() {};
}

var nativePromise;
try {
  nativePromise = Promise;
} catch(_) {
  nativePromise = function() {};
}

/**
 * Clones (copies) an Object using deep copying.
 *
 * This function supports circular references by default, but if you are certain
 * there are no circular references in your object, you can save some CPU time
 * by calling clone(obj, false).
 *
 * Caution: if `circular` is false and `parent` contains circular references,
 * your program may enter an infinite loop and crash.
 *
 * @param `parent` - the object to be cloned
 * @param `circular` - set to true if the object to be cloned may contain
 *    circular references. (optional - true by default)
 * @param `depth` - set to a number if the object is only to be cloned to
 *    a particular depth. (optional - defaults to Infinity)
 * @param `prototype` - sets the prototype to be used when cloning an object.
 *    (optional - defaults to parent prototype).
 * @param `includeNonEnumerable` - set to true if the non-enumerable properties
 *    should be cloned as well. Non-enumerable properties on the prototype
 *    chain will be ignored. (optional - false by default)
*/
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
  if (typeof circular === 'object') {
    depth = circular.depth;
    prototype = circular.prototype;
    includeNonEnumerable = circular.includeNonEnumerable;
    circular = circular.circular;
  }
  // maintain two arrays for circular references, where corresponding parents
  // and children have the same index
  var allParents = [];
  var allChildren = [];

  var useBuffer = typeof Buffer != 'undefined';

  if (typeof circular == 'undefined')
    circular = true;

  if (typeof depth == 'undefined')
    depth = Infinity;

  // recurse this function so we don't reset allParents and allChildren
  function _clone(parent, depth) {
    // cloning null always returns null
    if (parent === null)
      return null;

    if (depth === 0)
      return parent;

    var child;
    var proto;
    if (typeof parent != 'object') {
      return parent;
    }

    if (_instanceof(parent, nativeMap)) {
      child = new nativeMap();
    } else if (_instanceof(parent, nativeSet)) {
      child = new nativeSet();
    } else if (_instanceof(parent, nativePromise)) {
      child = new nativePromise(function (resolve, reject) {
        parent.then(function(value) {
          resolve(_clone(value, depth - 1));
        }, function(err) {
          reject(_clone(err, depth - 1));
        });
      });
    } else if (clone.__isArray(parent)) {
      child = [];
    } else if (clone.__isRegExp(parent)) {
      child = new RegExp(parent.source, __getRegExpFlags(parent));
      if (parent.lastIndex) child.lastIndex = parent.lastIndex;
    } else if (clone.__isDate(parent)) {
      child = new Date(parent.getTime());
    } else if (useBuffer && Buffer.isBuffer(parent)) {
      if (Buffer.from) {
        // Node.js >= 5.10.0
        child = Buffer.from(parent);
      } else {
        // Older Node.js versions
        child = new Buffer(parent.length);
        parent.copy(child);
      }
      return child;
    } else if (_instanceof(parent, Error)) {
      child = Object.create(parent);
    } else {
      if (typeof prototype == 'undefined') {
        proto = Object.getPrototypeOf(parent);
        child = Object.create(proto);
      }
      else {
        child = Object.create(prototype);
        proto = prototype;
      }
    }

    if (circular) {
      var index = allParents.indexOf(parent);

      if (index != -1) {
        return allChildren[index];
      }
      allParents.push(parent);
      allChildren.push(child);
    }

    if (_instanceof(parent, nativeMap)) {
      parent.forEach(function(value, key) {
        var keyChild = _clone(key, depth - 1);
        var valueChild = _clone(value, depth - 1);
        child.set(keyChild, valueChild);
      });
    }
    if (_instanceof(parent, nativeSet)) {
      parent.forEach(function(value) {
        var entryChild = _clone(value, depth - 1);
        child.add(entryChild);
      });
    }

    for (var i in parent) {
      var attrs = Object.getOwnPropertyDescriptor(parent, i);
      if (attrs) {
        child[i] = _clone(parent[i], depth - 1);
      }
    }

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(parent);
      for (var i = 0; i < symbols.length; i++) {
        // Don't need to worry about cloning a symbol because it is a primitive,
        // like a number or string.
        var symbol = symbols[i];
        var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
        if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
          continue;
        }
        child[symbol] = _clone(parent[symbol], depth - 1);
        Object.defineProperty(child, symbol, descriptor);
      }
    }

    if (includeNonEnumerable) {
      var allPropertyNames = Object.getOwnPropertyNames(parent);
      for (var i = 0; i < allPropertyNames.length; i++) {
        var propertyName = allPropertyNames[i];
        var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
        if (descriptor && descriptor.enumerable) {
          continue;
        }
        child[propertyName] = _clone(parent[propertyName], depth - 1);
        Object.defineProperty(child, propertyName, descriptor);
      }
    }

    return child;
  }

  return _clone(parent, depth);
}

/**
 * Simple flat clone using prototype, accepts only objects, usefull for property
 * override on FLAT configuration object (no nested props).
 *
 * USE WITH CAUTION! This may not behave as you wish if you do not know how this
 * works.
 */
clone.clonePrototype = function clonePrototype(parent) {
  if (parent === null)
    return null;

  var c = function () {};
  c.prototype = parent;
  return new c();
};

// private utility functions

function __objToStr(o) {
  return Object.prototype.toString.call(o);
}
clone.__objToStr = __objToStr;

function __isDate(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Date]';
}
clone.__isDate = __isDate;

function __isArray(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Array]';
}
clone.__isArray = __isArray;

function __isRegExp(o) {
  return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
}
clone.__isRegExp = __isRegExp;

function __getRegExpFlags(re) {
  var flags = '';
  if (re.global) flags += 'g';
  if (re.ignoreCase) flags += 'i';
  if (re.multiline) flags += 'm';
  return flags;
}
clone.__getRegExpFlags = __getRegExpFlags;

return clone;
})();

if (typeof module === 'object' && module.exports) {
  module.exports = clone;
}
<|endoftext|>


<commit_before>var fs = require('fs')
  , log4js = require('log4js')

var log_path = 'logs'
  , is_exist = fs.existsSync(log_path)
  , log = log4js.getLogger("moa-api");

/**
 * 创建log目录
 */
function _create_log_dir(log_path){
  var is_exist = fs.existsSync(log_path);

  if (is_exist !== true) {
    console.log('log_path is not exist, create folder:' + log_path);
    fs.mkdirSync(log_path, 0755);
  } else {
    console.log('log_path is exist, no operation!');
  }
}

function main(){
  _create_log_dir(log_path);
}

// 程序入口
main();<commit_msg>code format<commit_after>var fs = require('fs')
  , log4js = require('log4js')
  , log_path = 'logs'
  , is_exist = fs.existsSync(log_path)
  , log = log4js.getLogger("moa-api");

/**
 * 创建log目录
 */
function _create_log_dir(log_path){
  var is_exist = fs.existsSync(log_path);

  if (is_exist !== true) {
    console.log('log_path is not exist, create folder:' + log_path);
    fs.mkdirSync(log_path, 0755);
  } else {
    console.log('log_path is exist, no operation!');
  }
}

function main(){
  _create_log_dir(log_path);
}

// 程序入口
main();<|endoftext|>


<commit_before>// Set up module to run in browser and in Node.js
// Based loosely on https://github.com/umdjs/umd/blob/master/nodeAdapter.js
if ((typeof module === 'object' && typeof define !== 'function') || (window && window.atomRequire)) {
    // We are in Node.js or atom

    if (typeof window !== "undefined" && window.atomRequire) {
        var require = window.atomRequire;
    }

    var ChildProcess = require('child_process');
    var Promise = require('promise');

    var api = function(cmdList, method, url, data) {
        return new Promise(function(fulfill, reject) {
            var params = cmdList.concat(['--json']);
            var conda = ChildProcess.spawn('conda', params, {});
            var buffer = [];
            conda.stdout.on('data', function(data) {
                buffer.push(data.toString());
            });
            conda.on('close', function() {
                try {
                    fulfill(JSON.parse(buffer.join('')));
                }
                catch(ex) {
                    reject({
                        'exception': ex,
                        'result': buffer.join('')
                    });
                }
            });
        });
    };

    // Returns Promise like api(), but this object has additional callbacks
    // for progress bars. Retrieves data via ChildProcess.
    var progressApi = function(cmdList, url, data) {
        var callbacks = [];
        var progressing = true;
        var params = cmdList.concat(['--json']);
        var conda = ChildProcess.spawn('conda', params, {});
        var buffer = [];
        var promise = new Promise(function(fulfill, reject) {
            conda.stdout.on('data', function(data) {
                var rest = data.toString();
                if (rest.indexOf('\0') == -1) {
                    progressing = false;
                }

                if (!progressing) {
                    buffer.push(data);
                    return;
                }
                while (rest.indexOf('\0') > -1 && progressing) {
                    var dataEnd = rest.indexOf('\0');
                    var first = rest.slice(0, dataEnd);
                    rest = rest.slice(dataEnd + 1);
                    buffer.push(first);
                    var json = JSON.parse(buffer.join(''));
                    buffer = [];
                    promise.progress(json);

                    if (json.finished === true) {
                        progressing = false;
                    }
                }
            });
            conda.on('close', function() {
                try {
                    fulfill(JSON.parse(buffer.join('')));
                }
                catch(ex) {
                    reject({
                        'exception': ex,
                        'result': buffer.join('')
                    });
                }
            });
        });
        promise.onProgress = function(f) {
            callbacks.push(f);
        };
        promise.progress = function(data) {
            for (var i = 0; i < callbacks.length; i++) {
                callbacks[i](data);
            }
        };
        return promise;
    };

    if (process.argv.length == 3 && process.argv[2] == '--server') {
        var express = require('express');
        var app = express();
        var http = require('http').Server(app);
        var io = require('socket.io')(http);

        process.argv = [];
        console.log('running as server');

        var fs = require('fs');
        app.get('/', function(req, res) {
            res.sendfile(__dirname + '/test.html');
        });
        app.get('/conda.js', function(req, res) {
            res.sendfile(__dirname + '/conda.js');
        });
        app.get('/test.js', function(req, res) {
            res.sendfile(__dirname + '/test.js');
        });
        app.get('/api/*', function(req, res) {
            var parts = req.param('command');
            console.log('Handling', parts);
            api(parts).then(function(data) {
                res.send(JSON.stringify(data));
            });
        });

        io.on('connection', function(socket) {
            console.log('connected');
            socket.on('api', function(data) {
                var parts = data.data.command;

                var progress = progressApi(parts);
                progress.onProgress(function(progress) {
                    socket.emit('progress', progress);
                });
                progress.done(function(data) {
                    socket.emit('result', data);
                    socket.disconnect();
                });
            });
            socket.on('disconnect', function(data) {
                socket.disconnect();
            });
        });

        io.on('disconnect', function() {
            console.log('disconnected');
        });

        http.listen(8000);
    }

    module.exports = factory(api, progressApi);
}
else {
    // We are in the browser
    var parse = function(cmdList, url, data) {
        var parts = url;
        if (window.conda.DEV_SERVER) {
            return {
                path: '',
                data: {
                    command: cmdList
                }
            }
        }

        if (typeof data === "undefined") {
            data = {};
        }

        var path = parts.map(encodeURIComponent).join('/');
        return {
            data: data,
            path: path
        }
    };

    var api = function(cmdList, method, url, data) {
        var path = parse(cmdList, url, data);
        return Promise.resolve($.ajax({
            data: path.data,
            dataType: 'json',
            type: method,
            url: window.conda.API_ROOT + path.path
        }));
    };

    // Returns Promise like api(), but this object has additional callbacks
    // for progress bars. Retrieves data via websocket.
    var progressApi = function(cmdList, url, data) {
        var callbacks = [];
        var promise = new Promise(function(fulfill, reject) {
            var path = parse(cmdList, url, data);
            var socket = io();
            socket.emit('api', path);
            socket.on('progress', function(progress) {
                console.log(progress)
                promise.onProgress(progress);
            });
            socket.on('result', function(result) {
                console.log(result)
                socket.disconnect();
                fulfill(result);
            });
        });
        promise.onProgress = function(f) {
            callbacks.push(f);
        };
        promise.progress = function(data) {
            for (var i = 0; i < callbacks.length; i++) {
                callbacks[i](data);
            }
        };
        return promise;
    };

    window.conda = factory(api, progressApi);
}

function factory(api, progressApi) {
    var defaultOptions = function(options, defaults) {
        if (typeof options === "undefined" || options === null) {
            return defaults;
        }
        for (var key in defaults) {
            if (defaults.hasOwnProperty(key)) {
                if (!(key in options)) {
                    options[key] = defaults[key];
                }
            }
        }

        return options;
    };

    var nameOrPrefixOptions = function(name, options, defaults) {
        defaults.name = null;
        defaults.prefix = null;

        options = defaultOptions(options, defaults);
        if (!(options.name || options.prefix)) {
            throw new CondaError(name + ": either name or prefix required");
            };
        }
        if (options.name && options.prefix) {
            throw new CondaError(name + ": exactly one of name or prefix allowed");
        }

        var data = {};
        var cmdList = [];
        if (options.name) {
            data.name = options.name;
            cmdList.push('--name');
            cmdList.push(options.name);
        }
        if (options.prefix) {
            data.prefix = options.prefix;
            cmdList.push('--prefix');
            cmdList.push(options.prefix);
        }

        return {
            options: options,
            data: data,
            cmdList: cmdList
        }
    };

    var CondaError = (function() {
        function CondaError(message) {
            this.message = message;
        }

        CondaError.prototype.toString = function() {
            return "CondaError: " + this.message;
        };

        return CondaError;
    })();

    var Env = (function() {
        function Env(name, prefix) {
            this.name = name;
            this.prefix = prefix;

            this.isDefault = false;
            this.isRoot = false;
        }

        Env.prototype.linked = function(options) {
            options = defaultOptions(options, { simple: false });

            var cmdList = ['list', '--prefix', this.prefix];
            var path = ['envs', this.name, 'linked'];
            return api(cmdList, 'get', path).then(function(fns) {
                if (options.simple) {
                    return fns;
                }
                var promises = [];
                for (var i = 0; i < fns.length; i++) {
                    promises.push(Package.load(fns[i]));
                }

                return Promise.all(promises).then(function(pkgs) {
                    return pkgs;
                })
            });
        };

        Env.prototype.revisions = function() {
            return api(['list', '--prefix', this.prefix, '--revisions'],
                       'get', ['envs', this.name, 'revisions']);
        };

        Env.prototype.install = function(pkg, options) {
            options = defaultOptions(options, { progress: false });
            var cmdList = ['install', '--prefix', this.prefix, pkg];
            var path = ['envs', this.name, 'install', pkg];
            var data = {};
            if (!options.progress) {
                cmdList.push('--quiet');
                data.quiet = true;

                return api(cmdList, 'post', path, data);
            }
            else {
                return progressApi(cmdList, path, data);
            }
        };

        Env.prototype.remove = function(pkg) {
            return api(['remove', '--prefix', this.prefix, pkg],
                       'post', ['envs', this.name, 'install', pkg]);
        };

        Env.prototype.clone = function(options) {
            var result = nameOrPrefixOptions("Env.clone", options, {});
            options = result.options;

            var data = options.data;
            var cmdList = ['create', '--clone', this.prefix];
            cmdList = cmdList.concat(options.cmdList);

            return api(cmdList, 'post', ['env', this.prefix, 'clone'], data);
        };

        Env.prototype.removeEnv = function() {
            return progressApi(['remove', '--all', '--prefix', this.prefix],
                               ['envs', this.name, 'delete'], {});
        };

        Env.create = function(options) {
            var result = nameOrPrefixOptions("Env.create", options, {
                packages: []
            });
            options = result.options;

            if (options.packages.length === 0) {
                throw new CondaError("Env.create: at least one package required");
            }

            var data = options.data;
            var cmdList = ['create'];
            cmdList = cmdList.concat(options.cmdList);
            cmdList = cmdList.concat(options.packages);
        };

        Env.getEnvs = function() {
            return info().then(function(info) {
                var envs = [new Env('root', info['default_prefix'])];

                var prefixes = info['envs'];
                for (var i = 0; i < prefixes.length; i++) {
                    var prefix = prefixes[i];
                    var name = prefix.split('/'); // TODO Windows?
                    name = name[name.length - 1];
                    envs.push(new Env(name, prefix));
                }

                envs.forEach(function(env) {
                    env.isDefault = env.prefix == info['default_prefix'];
                    env.isRoot = env.prefix == info['root_prefix'];
                });
                return envs;
            });
        };
        return Env;
    })();

    var Package = (function() {
        function Package(fn, info) {
            this.fn = fn;
            this.info = info;
        }

        Package.load = function(fn) {
            return api(['info', fn + '.tar.bz2'], 'get', ['info', fn + '.tar.bz2']).then(function(info) {
                info = info[fn + '.tar.bz2'];
                var pkg = new Package(fn, info);
                return pkg;
            });
        };

        return Package;
    })();

    var info = function() {
        return api(['info'], 'get', ['info']);
    };

    var search = function(regex) {
        var cmdList = ['search'];
        if (typeof regex !== 'undefined' && regex !== null) {
            cmdList.push(regex);
        }
        return api(cmdList, 'get', cmdList);
    };

    var launch = function(command) {
        return api(['launch', command], 'get', ['launch', command]);
    };

    return {
        info: info,
        launch: launch,
        search: search,
        Env: Env,
        Package: Package,
        API_ROOT: '/api/',
        DEV_SERVER: false
    };
}
<commit_msg>Add conda.search({ spec: spec })<commit_after>// Set up module to run in browser and in Node.js
// Based loosely on https://github.com/umdjs/umd/blob/master/nodeAdapter.js
if ((typeof module === 'object' && typeof define !== 'function') || (window && window.atomRequire)) {
    // We are in Node.js or atom

    if (typeof window !== "undefined" && window.atomRequire) {
        var require = window.atomRequire;
    }

    var ChildProcess = require('child_process');
    var Promise = require('promise');

    var api = function(cmdList, method, url, data) {
        return new Promise(function(fulfill, reject) {
            var params = cmdList.concat(['--json']);
            var conda = ChildProcess.spawn('conda', params, {});
            var buffer = [];
            conda.stdout.on('data', function(data) {
                buffer.push(data.toString());
            });
            conda.on('close', function() {
                try {
                    fulfill(JSON.parse(buffer.join('')));
                }
                catch(ex) {
                    reject({
                        'exception': ex,
                        'result': buffer.join('')
                    });
                }
            });
        });
    };

    // Returns Promise like api(), but this object has additional callbacks
    // for progress bars. Retrieves data via ChildProcess.
    var progressApi = function(cmdList, url, data) {
        var callbacks = [];
        var progressing = true;
        var params = cmdList.concat(['--json']);
        var conda = ChildProcess.spawn('conda', params, {});
        var buffer = [];
        var promise = new Promise(function(fulfill, reject) {
            conda.stdout.on('data', function(data) {
                var rest = data.toString();
                if (rest.indexOf('\0') == -1) {
                    progressing = false;
                }

                if (!progressing) {
                    buffer.push(data);
                    return;
                }
                while (rest.indexOf('\0') > -1 && progressing) {
                    var dataEnd = rest.indexOf('\0');
                    var first = rest.slice(0, dataEnd);
                    rest = rest.slice(dataEnd + 1);
                    buffer.push(first);
                    var json = JSON.parse(buffer.join(''));
                    buffer = [];
                    promise.progress(json);

                    if (json.finished === true) {
                        progressing = false;
                    }
                }
            });
            conda.on('close', function() {
                try {
                    fulfill(JSON.parse(buffer.join('')));
                }
                catch(ex) {
                    reject({
                        'exception': ex,
                        'result': buffer.join('')
                    });
                }
            });
        });
        promise.onProgress = function(f) {
            callbacks.push(f);
        };
        promise.progress = function(data) {
            for (var i = 0; i < callbacks.length; i++) {
                callbacks[i](data);
            }
        };
        return promise;
    };

    if (process.argv.length == 3 && process.argv[2] == '--server') {
        var express = require('express');
        var app = express();
        var http = require('http').Server(app);
        var io = require('socket.io')(http);

        process.argv = [];
        console.log('running as server');

        var fs = require('fs');
        app.get('/', function(req, res) {
            res.sendfile(__dirname + '/test.html');
        });
        app.get('/conda.js', function(req, res) {
            res.sendfile(__dirname + '/conda.js');
        });
        app.get('/test.js', function(req, res) {
            res.sendfile(__dirname + '/test.js');
        });
        app.get('/api/*', function(req, res) {
            var parts = req.param('command');
            console.log('Handling', parts);
            api(parts).then(function(data) {
                res.send(JSON.stringify(data));
            });
        });

        io.on('connection', function(socket) {
            console.log('connected');
            socket.on('api', function(data) {
                var parts = data.data.command;

                var progress = progressApi(parts);
                progress.onProgress(function(progress) {
                    socket.emit('progress', progress);
                });
                progress.done(function(data) {
                    socket.emit('result', data);
                    socket.disconnect();
                });
            });
            socket.on('disconnect', function(data) {
                socket.disconnect();
            });
        });

        io.on('disconnect', function() {
            console.log('disconnected');
        });

        http.listen(8000);
    }

    module.exports = factory(api, progressApi);
}
else {
    // We are in the browser
    var parse = function(cmdList, url, data) {
        var parts = url;
        if (window.conda.DEV_SERVER) {
            return {
                path: '',
                data: {
                    command: cmdList
                }
            }
        }

        if (typeof data === "undefined") {
            data = {};
        }

        var path = parts.map(encodeURIComponent).join('/');
        return {
            data: data,
            path: path
        }
    };

    var api = function(cmdList, method, url, data) {
        var path = parse(cmdList, url, data);
        return Promise.resolve($.ajax({
            data: path.data,
            dataType: 'json',
            type: method,
            url: window.conda.API_ROOT + path.path
        }));
    };

    // Returns Promise like api(), but this object has additional callbacks
    // for progress bars. Retrieves data via websocket.
    var progressApi = function(cmdList, url, data) {
        var callbacks = [];
        var promise = new Promise(function(fulfill, reject) {
            var path = parse(cmdList, url, data);
            var socket = io();
            socket.emit('api', path);
            socket.on('progress', function(progress) {
                console.log(progress)
                promise.onProgress(progress);
            });
            socket.on('result', function(result) {
                console.log(result)
                socket.disconnect();
                fulfill(result);
            });
        });
        promise.onProgress = function(f) {
            callbacks.push(f);
        };
        promise.progress = function(data) {
            for (var i = 0; i < callbacks.length; i++) {
                callbacks[i](data);
            }
        };
        return promise;
    };

    window.conda = factory(api, progressApi);
}

function factory(api, progressApi) {
    var defaultOptions = function(options, defaults) {
        if (typeof options === "undefined" || options === null) {
            return defaults;
        }
        for (var key in defaults) {
            if (defaults.hasOwnProperty(key)) {
                if (!(key in options)) {
                    options[key] = defaults[key];
                }
            }
        }

        return options;
    };

    var nameOrPrefixOptions = function(name, options, defaults) {
        defaults.name = null;
        defaults.prefix = null;

        options = defaultOptions(options, defaults);
        if (!(options.name || options.prefix)) {
            throw new CondaError(name + ": either name or prefix required");
            };
        }
        if (options.name && options.prefix) {
            throw new CondaError(name + ": exactly one of name or prefix allowed");
        }

        var data = {};
        var cmdList = [];
        if (options.name) {
            data.name = options.name;
            cmdList.push('--name');
            cmdList.push(options.name);
        }
        if (options.prefix) {
            data.prefix = options.prefix;
            cmdList.push('--prefix');
            cmdList.push(options.prefix);
        }

        return {
            options: options,
            data: data,
            cmdList: cmdList
        }
    };

    var CondaError = (function() {
        function CondaError(message) {
            this.message = message;
        }

        CondaError.prototype.toString = function() {
            return "CondaError: " + this.message;
        };

        return CondaError;
    })();

    var Env = (function() {
        function Env(name, prefix) {
            this.name = name;
            this.prefix = prefix;

            this.isDefault = false;
            this.isRoot = false;
        }

        Env.prototype.linked = function(options) {
            options = defaultOptions(options, { simple: false });

            var cmdList = ['list', '--prefix', this.prefix];
            var path = ['envs', this.name, 'linked'];
            return api(cmdList, 'get', path).then(function(fns) {
                if (options.simple) {
                    return fns;
                }
                var promises = [];
                for (var i = 0; i < fns.length; i++) {
                    promises.push(Package.load(fns[i]));
                }

                return Promise.all(promises).then(function(pkgs) {
                    return pkgs;
                })
            });
        };

        Env.prototype.revisions = function() {
            return api(['list', '--prefix', this.prefix, '--revisions'],
                       'get', ['envs', this.name, 'revisions']);
        };

        Env.prototype.install = function(pkg, options) {
            options = defaultOptions(options, { progress: false });
            var cmdList = ['install', '--prefix', this.prefix, pkg];
            var path = ['envs', this.name, 'install', pkg];
            var data = {};
            if (!options.progress) {
                cmdList.push('--quiet');
                data.quiet = true;

                return api(cmdList, 'post', path, data);
            }
            else {
                return progressApi(cmdList, path, data);
            }
        };

        Env.prototype.remove = function(pkg) {
            return api(['remove', '--prefix', this.prefix, pkg],
                       'post', ['envs', this.name, 'install', pkg]);
        };

        Env.prototype.clone = function(options) {
            var result = nameOrPrefixOptions("Env.clone", options, {});
            options = result.options;

            var data = options.data;
            var cmdList = ['create', '--clone', this.prefix];
            cmdList = cmdList.concat(options.cmdList);

            return api(cmdList, 'post', ['env', this.prefix, 'clone'], data);
        };

        Env.prototype.removeEnv = function() {
            return progressApi(['remove', '--all', '--prefix', this.prefix],
                               ['envs', this.name, 'delete'], {});
        };

        Env.create = function(options) {
            var result = nameOrPrefixOptions("Env.create", options, {
                packages: []
            });
            options = result.options;

            if (options.packages.length === 0) {
                throw new CondaError("Env.create: at least one package required");
            }

            var data = options.data;
            var cmdList = ['create'];
            cmdList = cmdList.concat(options.cmdList);
            cmdList = cmdList.concat(options.packages);
        };

        Env.getEnvs = function() {
            return info().then(function(info) {
                var envs = [new Env('root', info['default_prefix'])];

                var prefixes = info['envs'];
                for (var i = 0; i < prefixes.length; i++) {
                    var prefix = prefixes[i];
                    var name = prefix.split('/'); // TODO Windows?
                    name = name[name.length - 1];
                    envs.push(new Env(name, prefix));
                }

                envs.forEach(function(env) {
                    env.isDefault = env.prefix == info['default_prefix'];
                    env.isRoot = env.prefix == info['root_prefix'];
                });
                return envs;
            });
        };
        return Env;
    })();

    var Package = (function() {
        function Package(fn, info) {
            this.fn = fn;
            this.info = info;
        }

        Package.load = function(fn) {
            return api(['info', fn + '.tar.bz2'], 'get', ['info', fn + '.tar.bz2']).then(function(info) {
                info = info[fn + '.tar.bz2'];
                var pkg = new Package(fn, info);
                return pkg;
            });
        };

        return Package;
    })();

    var info = function() {
        return api(['info'], 'get', ['info']);
    };

    var search = function(options) {
        options = defaultOptions(options, {
            regex: null,
            spec: null
        })
        var cmdList = ['search'];

        if (options.regex && options.spec) {
            throw new CondaError("conda.search: only one of regex and spec allowed");
        }

        if (options.regex !== null) {
            cmdList.push(regex);
        }
        if (options.spec !== null) {
            cmdList.push(spec);
            cmdList.push('--spec')
        }
        return api(cmdList, 'get', cmdList);
    };

    var launch = function(command) {
        return api(['launch', command], 'get', ['launch', command]);
    };

    return {
        info: info,
        launch: launch,
        search: search,
        Env: Env,
        Package: Package,
        API_ROOT: '/api/',
        DEV_SERVER: false
    };
}
<|endoftext|>


<commit_before>var HashCount = require('./src/HashCount');

var credoCount = new HashCount({
    organization: process.argv[2],
    organizations: require('./input/organizations'),
});
<commit_msg>Calling out missing organization tag<commit_after>var HashCount = require('./src/HashCount');

if (!process.argv[2]) {
    console.log('Please enter an organization tag. Ex: credo');
    process.exit();
}

new HashCount({
    organization: process.argv[2],
    organizations: require('./input/organizations'),
});
<|endoftext|>


<commit_before><commit_msg>Added email.js<commit_after><|endoftext|>


<commit_before>// emile.js (c) 2009 Thomas Fuchs
// Licensed under the terms of the MIT license.

(function(emile, object){
  var parseEl = document.createElement('div'),
    props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+
    'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+
    'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+
    'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+
    'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' ');

  function parse(value){
    var v = parseFloat(value), u = value.replace(/^[\d\.]+/,'');
    return { value: isNaN(v) ? u : v, unit: isNaN(v) ? 'color' : u };
  }

  function normalize(style){
    var css, rules = {}, i = props.length, v;
    parseEl.innerHTML = '

';
    css = parseEl.childNodes[0].style;
    while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
    return rules;
  }

  function color(source,target,pos){
    var i = 2, j, c, tmp, v = [], r = [];
    while(j=3,i--)
      if(arguments[i][0]=='r'){
        c = arguments[i].match(/\d+/g); while(j--) v.push(parseInt(c[j]));
      } else while(j--) v.push(parseInt(c.substr(1+j*2,2), 16));
    while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp<0?0:tmp>255?255:tmp); }
    return 'rgb('+r.join(',')+')';
  }

  (object||window)[emile] = function(el, style, opts){
    el = typeof el == 'string' ? document.getElementById(el) : el;
    opts = opts || {};
    var target = normalize(style), comp = el.currentStyle ? el.currentStyle : document.defaultView.getComputedStyle(el, null),
      prop, current = {}, start = (new Date).getTime(), dur = opts.duration||200, finish = start+dur, interval,
      easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; };
    for(prop in target) current[prop] = parse(comp[prop]);
    interval = setInterval(function(){
      var time = (new Date).getTime(), pos = time>finish ? 1 : (time-start)/dur;
      for(prop in target)
        el.style[prop] = target[prop].unit == 'color' ?
          color(current[prop].value,target[prop].value,easing(pos)) :
          (current[prop].value+(target[prop].value-current[prop].value)*easing(pos)).toFixed(3) + target[prop].unit;
      if(time>finish) { clearInterval(interval); opts.after && opts.after(); }
    },10);
  }
})('emile');<commit_msg>changed the logic to define the emile's host object<commit_after>// emile.js (c) 2009 Thomas Fuchs
// Licensed under the terms of the MIT license.

(function(emile, container){
  var parseEl = document.createElement('div'),
    props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+
    'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+
    'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+
    'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+
    'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' ');

  function parse(value){
    var v = parseFloat(value), u = value.replace(/^[\d\.]+/,'');
    return { value: isNaN(v) ? u : v, unit: isNaN(v) ? 'color' : u };
  }

  function normalize(style){
    var css, rules = {}, i = props.length, v;
    parseEl.innerHTML = '

';
    css = parseEl.childNodes[0].style;
    while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
    return rules;
  }

  function color(source,target,pos){
    var i = 2, j, c, tmp, v = [], r = [];
    while(j=3,i--)
      if(arguments[i][0]=='r'){
        c = arguments[i].match(/\d+/g); while(j--) v.push(parseInt(c[j]));
      } else while(j--) v.push(parseInt(c.substr(1+j*2,2), 16));
    while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp<0?0:tmp>255?255:tmp); }
    return 'rgb('+r.join(',')+')';
  }

  container[emile] = function(el, style, opts){
    el = typeof el == 'string' ? document.getElementById(el) : el;
    opts = opts || {};
    var target = normalize(style), comp = el.currentStyle ? el.currentStyle : document.defaultView.getComputedStyle(el, null),
      prop, current = {}, start = (new Date).getTime(), dur = opts.duration||200, finish = start+dur, interval,
      easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; };
    for(prop in target) current[prop] = parse(comp[prop]);
    interval = setInterval(function(){
      var time = (new Date).getTime(), pos = time>finish ? 1 : (time-start)/dur;
      for(prop in target)
        el.style[prop] = target[prop].unit == 'color' ?
          color(current[prop].value,target[prop].value,easing(pos)) :
          (current[prop].value+(target[prop].value-current[prop].value)*easing(pos)).toFixed(3) + target[prop].unit;
      if(time>finish) { clearInterval(interval); opts.after && opts.after(); }
    },10);
  }
})('emile', this);<|endoftext|>


<commit_before>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
      console.log(req);
      console.log(res);
    }
  });
});

var bot = controller.spawn({
  token: process.env.BOT_TOKEN
});

bot.startRTM(function(err) {
  if (err) {
    console.log('Even if you fall on your face, you\'re still moving forward.');
    throw new Error(err);
  }
});

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.hears([/[\s\S]*/], ['direct_message', 'direct_mention', 'mention', 'ambient'], function(bot, message) {
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    getRealNameFromId(bot, message.user).then(function(realName) {
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<commit_msg>log out config<commit_after>// Config ===============================================

var Q                    = require('q');
var moment               = require('moment');
var Botkit               = require('botkit');
var responses            = require('./responses.js');

var whitelistedUsers     = ['tyler shambora', 'daniel lerman', 'ryan little', 'cory cummings'];
var readOnlyChannels     = ['C1317518C'];

// Init ===============================================

if (!process.env.BOT_TOKEN) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

var controller = Botkit.slackbot({
  debug: true,
  logLevel: 6
});

controller.configureSlackApp({
  clientId: process.env.CLIENT_ID,
  clientSecret: process.env.CLIENT_SECRET,
  scopes: ['bot', 'chat:write:user']
});

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  if (err) {
    throw new Error(err);
  }
  controller.createWebhookEndpoints(controller.webserver);
  controller.createHomepageEndpoint(controller.webserver);
  controller.createOauthEndpoints(controller.webserver, function(err, req, res) {
    if (err) {
      res.status(500).send('ERROR: ' + err);
    } else {
      res.send('Great Success!');
    }
  });
});

// var bot = controller.spawn({
//   token: process.env.BOT_TOKEN
// });

// bot.startRTM(function(err) {
//   if (err) {
//     console.log('Even if you fall on your face, you\'re still moving forward.');
//     throw new Error(err);
//   }
// });

var _bots = {};
var trackBot = function(bot) {
  _bots[bot.config.token] = bot;
};

controller.on('create_bot', function(bot, config) {
  console.log(config);
  if (_bots[bot.config.token]) {
    // already online! do nothing.
  } else {
    bot.startRTM(function(err) {
      if (!err) {
        trackBot(bot);
      }
      bot.startPrivateConversation({user: config.createdBy},function(err, convo) {
        if (err) {
          console.log(err);
        } else {
          convo.say(responses.welcome);
        }
      });
    });
  }
});

// Helper Functions ===============================================

var getRealNameFromId = function(bot, userId) {
  var deferred = Q.defer();
  var realName = '';
  bot.api.users.info({user: userId}, function(err, response) {
    realName = response.user.real_name.toLowerCase();
    deferred.resolve(realName);
  });
  return deferred.promise;
};

var isValidChannelName = function(bot, channelName) {
  var deferred = Q.defer();
  bot.api.channels.list({}, function(err, response) {
    deferred.resolve(response.channels.some(function(channel) {
      return channel.name === channelName;
    }));
  });
  return deferred.promise;
};

var isValidUser = function(realName) {
  var deferred = Q.defer();
  deferred.resolve(whitelistedUsers.some(function(userName) {
    return userName === realName;
  }));
  return deferred.promise;
};

// Listeners  ===============================================

controller.hears([/post to (\S+)\n([\s\S]*)/], 'direct_message', function(bot, message) {
  var channelName = message.match[1];
  var update = message.match[2];

  var parsedMessages = update.split('\n\n\n').map(function(block) {
    var messageParts = block.split('\n___\n');
    return {
      fallback: messageParts[1],
      title: messageParts[0],
      text: messageParts[1],
      color: 'danger',
      mrkdwn_in: ['fallback', 'text']
    };
  });

  var validateChannel = isValidChannelName(bot, channelName);
  var validateName = getRealNameFromId(bot, message.user).then(isValidUser);
  var isValidated = Q.all([validateChannel, validateName]);

  isValidated.spread(function(validChannel, validUser) {
    if (!validUser) {
      return bot.reply(message, 'Sorry, you\'re not authenticated to post.');
    } else if (!validChannel) {
      return bot.reply(message, 'Sorry, I can\'t post to the channel: ' + channelName + '.');
    } else if (validUser && validChannel) {
      var theDate = moment().format('dddd, MMMM Do YYYY');
      bot.startConversation(message, function(err, convo) {
        convo.say('*I\'m about to post the following:*');
        convo.say({
          username: 'Brian Williams: Dev Team News Anchor',
          icon_url: 'http://dev.tylershambora.com/images/father-williams.jpg',
          text: '<!channel>\n\n*Updates for ' + theDate + ':*',
          attachments: parsedMessages
        });
        convo.ask(responses.confirm(bot, channelName, parsedMessages, theDate), [
          responses.yes(bot, channelName, parsedMessages, theDate),
          responses.no(bot),
          responses.default()
        ]);
      });
    }
  });
});

controller.hears(['hey mister'], ['direct_message', 'mention', 'direct_mention'], function(bot, message) {
  getRealNameFromId(bot, message.user)
    .then(isValidUser)
    .then(function(result) {
      bot.reply(message, 'Hello!');
      if (result) {
        bot.reply(message, 'Hey! You\'re pretty valid!');
      }
    });
});

controller.on('direct_message, mention, direct_mention', function(bot, message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'jesus',
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      bot.reply(message, 'go with christ brah.');
    }
  });
});

controller.hears([/[\s\S]*/], ['direct_message', 'direct_mention', 'mention', 'ambient'], function(bot, message) {
  if (readOnlyChannels.indexOf(message.channel) !== -1) {
    getRealNameFromId(bot, message.user).then(function(realName) {
      var options = {
        token: process.env.MEGA_TOKEN,
        ts: message.ts,
        channel: message.channel,
        as_user: true
      };

      console.log('%s said: "%s"', realName, message.text);
      console.log('Attempting to delete the message.' );

      // this whole block looks pretty ripe for some abstraction and recursion (tsham)
      bot.api.chat.delete(options, function(err, response) {
        if (!response.ok) {
          console.log('Unable to delete due to error: ' + err);
          console.log('Trying one more time in 2 seconds');
          setTimeout(function() {
            bot.api.chat.delete(options, function(err, response) {
              if (!response.ok) {
                console.log('Unable to delete after a second attempt due to error: ' + err);
              }
            });
          }, 2000);
        } else {
          console.log('Message successfully deleted!');
        }
      });
    });
  }
});

controller.on('rtm_open', function(bot) {
  console.log('** The RTM api just connected: ' + bot.identity.name);
});

controller.on('rtm_close', function() {
  console.log('** The RTM api just closed');
});
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.SidebarPane}
 */
WebInspector.EventListenersSidebarPane = function()
{
    WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners"));
    this.bodyElement.classList.add("events-pane");

    this.sections = [];

    this.settingsSelectElement = document.createElement("select");
    this.settingsSelectElement.className = "select-filter";

    var option = document.createElement("option");
    option.value = "all";
    option.label = WebInspector.UIString("All Nodes");
    this.settingsSelectElement.appendChild(option);

    option = document.createElement("option");
    option.value = "selected";
    option.label = WebInspector.UIString("Selected Node Only");
    this.settingsSelectElement.appendChild(option);

    var filter = WebInspector.settings.eventListenersFilter.get();
    if (filter === "all")
        this.settingsSelectElement[0].selected = true;
    else if (filter === "selected")
        this.settingsSelectElement[1].selected = true;
    this.settingsSelectElement.addEventListener("click", function(event) { event.consume() }, false);
    this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);

    this.titleElement.appendChild(this.settingsSelectElement);

    this._linkifier = new WebInspector.Linkifier();
}

WebInspector.EventListenersSidebarPane._objectGroupName = "event-listeners-sidebar-pane";

WebInspector.EventListenersSidebarPane.prototype = {
    update: function(node)
    {
        RuntimeAgent.releaseObjectGroup(WebInspector.EventListenersSidebarPane._objectGroupName);
        this._linkifier.reset();

        var body = this.bodyElement;
        body.removeChildren();
        this.sections = [];

        var self = this;
        function callback(error, eventListeners) {
            if (error)
                return;

            var selectedNodeOnly = "selected" === WebInspector.settings.eventListenersFilter.get();
            var sectionNames = [];
            var sectionMap = {};
            for (var i = 0; i < eventListeners.length; ++i) {
                var eventListener = eventListeners[i];
                if (selectedNodeOnly && (node.id !== eventListener.nodeId))
                    continue;
                eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
                delete eventListener.nodeId; // no longer needed
                if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.handlerBody.toString()))
                    continue; // ignore event listeners generated by monitorEvent
                var type = eventListener.type;
                var section = sectionMap[type];
                if (!section) {
                    section = new WebInspector.EventListenersSection(type, node.id, self._linkifier);
                    sectionMap[type] = section;
                    sectionNames.push(type);
                    self.sections.push(section);
                }
                section.addListener(eventListener);
            }

            if (sectionNames.length === 0) {
                var div = document.createElement("div");
                div.className = "info";
                div.textContent = WebInspector.UIString("No Event Listeners");
                body.appendChild(div);
                return;
            }

            sectionNames.sort();
            for (var i = 0; i < sectionNames.length; ++i) {
                var section = sectionMap[sectionNames[i]];
                body.appendChild(section.element);
            }
        }

        if (node)
            node.eventListeners(WebInspector.EventListenersSidebarPane._objectGroupName, callback);
        this._selectedNode = node;
    },

    willHide: function()
    {
        delete this._selectedNode;
    },

    _changeSetting: function()
    {
        var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
        WebInspector.settings.eventListenersFilter.set(selectedOption.value);
        this.update(this._selectedNode);
    },

    __proto__: WebInspector.SidebarPane.prototype
}

/**
 * @constructor
 * @extends {WebInspector.PropertiesSection}
 */
WebInspector.EventListenersSection = function(title, nodeId, linkifier)
{
    this.eventListeners = [];
    this._nodeId = nodeId;
    this._linkifier = linkifier;
    WebInspector.PropertiesSection.call(this, title);

    // Changed from a Properties List
    this.propertiesElement.remove();
    delete this.propertiesElement;
    delete this.propertiesTreeOutline;

    this._eventBars = document.createElement("div");
    this._eventBars.className = "event-bars";
    this.element.appendChild(this._eventBars);
}

WebInspector.EventListenersSection.prototype = {
    addListener: function(eventListener)
    {
        var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId, this._linkifier);
        this._eventBars.appendChild(eventListenerBar.element);
    },

    __proto__: WebInspector.PropertiesSection.prototype
}

/**
 * @constructor
 * @extends {WebInspector.ObjectPropertiesSection}
 */
WebInspector.EventListenerBar = function(eventListener, nodeId, linkifier)
{
    WebInspector.ObjectPropertiesSection.call(this, WebInspector.RemoteObject.fromPrimitiveValue(""));

    this.eventListener = eventListener;
    this._nodeId = nodeId;
    this._setNodeTitle();
    this._setFunctionSubtitle(linkifier);
    this.editable = false;
    this.element.className = "event-bar"; /* Changed from "section" */
    this.headerElement.classList.add("source-code");
    this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */
}

WebInspector.EventListenerBar.prototype = {
    update: function()
    {
        /**
         * @param {?WebInspector.RemoteObject} nodeObject
         * @this {WebInspector.EventListenerBar}
         */
        function updateWithNodeObject(nodeObject)
        {
            var properties = [];

            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("type", this.eventListener.type));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("useCapture", this.eventListener.useCapture));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("isAttribute", this.eventListener.isAttribute));
            if (nodeObject)
                properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));
            if (typeof this.eventListener.handler !== "undefined") {
                var remoteObject = WebInspector.RemoteObject.fromPayload(this.eventListener.handler);
                properties.push(new WebInspector.RemoteObjectProperty("handler", remoteObject));
            }
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("listenerBody", this.eventListener.handlerBody));
            if (this.eventListener.sourceName)
                properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("sourceName", this.eventListener.sourceName));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("lineNumber", this.eventListener.location.lineNumber + 1));

            this.updateProperties(properties);
        }
        WebInspector.RemoteObject.resolveNode(this.eventListener.node, WebInspector.EventListenersSidebarPane._objectGroupName, updateWithNodeObject.bind(this));
    },

    _setNodeTitle: function()
    {
        var node = this.eventListener.node;
        if (!node)
            return;

        if (node.nodeType() === Node.DOCUMENT_NODE) {
            this.titleElement.textContent = "document";
            return;
        }

        if (node.id === this._nodeId) {
            this.titleElement.textContent = WebInspector.DOMPresentationUtils.simpleSelector(node);
            return;
        }

        this.titleElement.removeChildren();
        this.titleElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(this.eventListener.node));
    },

    _setFunctionSubtitle: function(linkifier)
    {
        this.subtitleElement.removeChildren();
        var urlElement = linkifier.linkifyRawLocation(this.eventListener.location);
        if (!urlElement) {
            var url = this.eventListener.sourceName;
            var lineNumber = this.eventListener.location.lineNumber;
            var columnNumber = 0;
            urlElement = linkifier.linkifyLocation(url, lineNumber, columnNumber);
        }
        this.subtitleElement.appendChild(urlElement);
    },

    __proto__: WebInspector.ObjectPropertiesSection.prototype
}
<commit_msg>DevTools: [Event Listeners] Add "Refresh" button<commit_after>/*
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.SidebarPane}
 */
WebInspector.EventListenersSidebarPane = function()
{
    WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners"));
    this.bodyElement.classList.add("events-pane");

    this.sections = [];

    var refreshButton = document.createElement("button");
    refreshButton.className = "pane-title-button refresh";
    refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
    refreshButton.title = WebInspector.UIString("Refresh");
    this.titleElement.appendChild(refreshButton);

    this.settingsSelectElement = document.createElement("select");
    this.settingsSelectElement.className = "select-filter";

    var option = document.createElement("option");
    option.value = "all";
    option.label = WebInspector.UIString("All Nodes");
    this.settingsSelectElement.appendChild(option);

    option = document.createElement("option");
    option.value = "selected";
    option.label = WebInspector.UIString("Selected Node Only");
    this.settingsSelectElement.appendChild(option);

    var filter = WebInspector.settings.eventListenersFilter.get();
    if (filter === "all")
        this.settingsSelectElement[0].selected = true;
    else if (filter === "selected")
        this.settingsSelectElement[1].selected = true;
    this.settingsSelectElement.addEventListener("click", function(event) { event.consume() }, false);
    this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);

    this.titleElement.appendChild(this.settingsSelectElement);

    this._linkifier = new WebInspector.Linkifier();
}

WebInspector.EventListenersSidebarPane._objectGroupName = "event-listeners-sidebar-pane";

WebInspector.EventListenersSidebarPane.prototype = {
    update: function(node)
    {
        RuntimeAgent.releaseObjectGroup(WebInspector.EventListenersSidebarPane._objectGroupName);
        this._linkifier.reset();

        var body = this.bodyElement;
        body.removeChildren();
        this.sections = [];

        var self = this;
        function callback(error, eventListeners) {
            if (error)
                return;

            var selectedNodeOnly = "selected" === WebInspector.settings.eventListenersFilter.get();
            var sectionNames = [];
            var sectionMap = {};
            for (var i = 0; i < eventListeners.length; ++i) {
                var eventListener = eventListeners[i];
                if (selectedNodeOnly && (node.id !== eventListener.nodeId))
                    continue;
                eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
                delete eventListener.nodeId; // no longer needed
                if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.handlerBody.toString()))
                    continue; // ignore event listeners generated by monitorEvent
                var type = eventListener.type;
                var section = sectionMap[type];
                if (!section) {
                    section = new WebInspector.EventListenersSection(type, node.id, self._linkifier);
                    sectionMap[type] = section;
                    sectionNames.push(type);
                    self.sections.push(section);
                }
                section.addListener(eventListener);
            }

            if (sectionNames.length === 0) {
                var div = document.createElement("div");
                div.className = "info";
                div.textContent = WebInspector.UIString("No Event Listeners");
                body.appendChild(div);
                return;
            }

            sectionNames.sort();
            for (var i = 0; i < sectionNames.length; ++i) {
                var section = sectionMap[sectionNames[i]];
                body.appendChild(section.element);
            }
        }

        if (node)
            node.eventListeners(WebInspector.EventListenersSidebarPane._objectGroupName, callback);
        this._selectedNode = node;
    },

    willHide: function()
    {
        delete this._selectedNode;
    },

    _refreshButtonClicked: function()
    {
        if (!this._selectedNode)
            return;
        this.update(this._selectedNode);
    },

    _changeSetting: function()
    {
        var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
        WebInspector.settings.eventListenersFilter.set(selectedOption.value);
        this.update(this._selectedNode);
    },

    __proto__: WebInspector.SidebarPane.prototype
}

/**
 * @constructor
 * @extends {WebInspector.PropertiesSection}
 */
WebInspector.EventListenersSection = function(title, nodeId, linkifier)
{
    this.eventListeners = [];
    this._nodeId = nodeId;
    this._linkifier = linkifier;
    WebInspector.PropertiesSection.call(this, title);

    // Changed from a Properties List
    this.propertiesElement.remove();
    delete this.propertiesElement;
    delete this.propertiesTreeOutline;

    this._eventBars = document.createElement("div");
    this._eventBars.className = "event-bars";
    this.element.appendChild(this._eventBars);
}

WebInspector.EventListenersSection.prototype = {
    addListener: function(eventListener)
    {
        var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId, this._linkifier);
        this._eventBars.appendChild(eventListenerBar.element);
    },

    __proto__: WebInspector.PropertiesSection.prototype
}

/**
 * @constructor
 * @extends {WebInspector.ObjectPropertiesSection}
 */
WebInspector.EventListenerBar = function(eventListener, nodeId, linkifier)
{
    WebInspector.ObjectPropertiesSection.call(this, WebInspector.RemoteObject.fromPrimitiveValue(""));

    this.eventListener = eventListener;
    this._nodeId = nodeId;
    this._setNodeTitle();
    this._setFunctionSubtitle(linkifier);
    this.editable = false;
    this.element.className = "event-bar"; /* Changed from "section" */
    this.headerElement.classList.add("source-code");
    this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */
}

WebInspector.EventListenerBar.prototype = {
    update: function()
    {
        /**
         * @param {?WebInspector.RemoteObject} nodeObject
         * @this {WebInspector.EventListenerBar}
         */
        function updateWithNodeObject(nodeObject)
        {
            var properties = [];

            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("type", this.eventListener.type));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("useCapture", this.eventListener.useCapture));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("isAttribute", this.eventListener.isAttribute));
            if (nodeObject)
                properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));
            if (typeof this.eventListener.handler !== "undefined") {
                var remoteObject = WebInspector.RemoteObject.fromPayload(this.eventListener.handler);
                properties.push(new WebInspector.RemoteObjectProperty("handler", remoteObject));
            }
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("listenerBody", this.eventListener.handlerBody));
            if (this.eventListener.sourceName)
                properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("sourceName", this.eventListener.sourceName));
            properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("lineNumber", this.eventListener.location.lineNumber + 1));

            this.updateProperties(properties);
        }
        WebInspector.RemoteObject.resolveNode(this.eventListener.node, WebInspector.EventListenersSidebarPane._objectGroupName, updateWithNodeObject.bind(this));
    },

    _setNodeTitle: function()
    {
        var node = this.eventListener.node;
        if (!node)
            return;

        if (node.nodeType() === Node.DOCUMENT_NODE) {
            this.titleElement.textContent = "document";
            return;
        }

        if (node.id === this._nodeId) {
            this.titleElement.textContent = WebInspector.DOMPresentationUtils.simpleSelector(node);
            return;
        }

        this.titleElement.removeChildren();
        this.titleElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(this.eventListener.node));
    },

    _setFunctionSubtitle: function(linkifier)
    {
        this.subtitleElement.removeChildren();
        var urlElement = linkifier.linkifyRawLocation(this.eventListener.location);
        if (!urlElement) {
            var url = this.eventListener.sourceName;
            var lineNumber = this.eventListener.location.lineNumber;
            var columnNumber = 0;
            urlElement = linkifier.linkifyLocation(url, lineNumber, columnNumber);
        }
        this.subtitleElement.appendChild(urlElement);
    },

    __proto__: WebInspector.ObjectPropertiesSection.prototype
}
<|endoftext|>


<commit_before>odoo.define('mail.discuss_mobile_tests', function (require) {
"use strict";

var mailTestUtils = require('mail.testUtils');

var testUtils = require('web.test_utils');

var createDiscuss = mailTestUtils.createDiscuss;

QUnit.module('mail', {}, function () {

QUnit.module('Discuss in mobile', {
    beforeEach: function () {
        this.services = mailTestUtils.getMailServices();
        this.data = {
            'mail.channel': {
                fields: {},
            },
            'mail.message': {
                fields: {},
            },
        };
    },
});

QUnit.test('mobile basic rendering', async function (assert) {
    // This is a very basic first test for the client action. However, with
    // the chat_service, it is hard to override RPCs (for instance, the
    // /mail/client_action route is always called when the test suite is
    // launched), and we must wait for this RPC to be done before starting to
    // test the interface. This should be refactored to facilitate the testing.
    assert.expect(16);

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });
    // test basic rendering in mobile
    assert.containsOnce(discuss, '.o_mail_discuss_content .o_mail_no_content',
        "should display the no content message");
    assert.containsOnce(discuss, '.o_mail_mobile_tabs',
        "should have rendered the tabs");
    assert.hasClass(discuss.$('.o_mail_mobile_tab[data-type=mailbox_inbox]'),'active',
        "should be in inbox tab");
    assert.containsOnce(discuss, '.o_mail_discuss_mobile_mailboxes_buttons:visible',
        "inbox/starred buttons should be visible");
    assert.hasClass(discuss.$('.o_mail_discuss_mobile_mailboxes_buttons .o_mailbox_inbox_item[data-type=mailbox_inbox]'),'btn-primary',
        "should be in inbox");
    assert.hasClass($('.o_mail_discuss_button_dm_chat'),'d-none',
        "should have invisible button 'New Message'");
    assert.hasClass($('.o_mail_discuss_button_multi_user_channel'),'d-none',
        "should have invisible button 'New Channel'");

    // move to 'Chat' tab
    await testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type=dm_chat]'));
    assert.hasClass(discuss.$('.o_mail_mobile_tab[data-type=dm_chat]'),'active',
        "should be in 'Chat' tab");
    assert.containsNone(discuss, '.o_mail_discuss_content .o_mail_no_content',
        "should display the no content message");
    assert.strictEqual($('.o_mail_discuss_button_dm_chat').length, 1,
        "should have a button to open DM chat in 'Chat' tab");
    assert.doesNotHaveClass($('.o_mail_discuss_button_dm_chat'), 'd-none',
        "should be visible in 'Chat' tab");
    assert.hasClass($('.o_mail_discuss_button_multi_user_channel'),'d-none',
        "should have invisible button 'New Channel' in 'Chat' tab");
    await testUtils.dom.click($('.o_mail_discuss_button_dm_chat'));
    assert.containsOnce(discuss, '.o_mail_add_thread input:visible',
        "should display the input to add a channel");

    // move to 'Channels' tab
    await testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type=multi_user_channel]'));
    assert.hasClass($('.o_mail_discuss_button_dm_chat'),'d-none',
        "should have invisible button 'New Message' in 'Channels' tab");
    assert.doesNotHaveClass($('.o_mail_discuss_button_multi_user_channel'), 'd-none',
        "should have visible button 'New Channel' in 'Channels' tab");
    await testUtils.dom.click($('.o_mail_discuss_button_multi_user_channel')  );
    assert.containsOnce(discuss, '.o_mail_add_thread input:visible',
        "should display the input to add a channel");

    discuss.destroy();
});

QUnit.test('on_{attach/detach}_callback', async function (assert) {
    assert.expect(2);

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });

    discuss.on_attach_callback();
    assert.ok(true, 'should not crash on attach callback');
    discuss.on_detach_callback();
    assert.ok(true, 'should not crash on detach callback');
    discuss.destroy();
});

QUnit.test('extended composer in mass mailing channel', async function (assert) {
    assert.expect(4);

    this.data.initMessaging = {
        channel_slots: {
            channel_channel: [{
                id: 1,
                channel_type: "channel",
                name: "General",
                mass_mailing: true,
            }],
        },
    };

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });

    testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type="public"]'));
    testUtils.dom.click(discuss.$('.o_mail_preview[data-preview-id="1"]'));
    assert.containsOnce(
        $,
        '.o_thread_window',
        "should display a chat window");
    assert.strictEqual(
        $('.o_thread_window').data('thread-id'),
        1,
        "chat window should be from channel General");
    assert.containsOnce(
        $('.o_thread_window'),
        '.o_thread_composer',
        "chat window should have a composer");
    assert.ok(
        $('.o_thread_window .o_thread_composer').hasClass('o_thread_composer_extended'),
        "chat window composer should be extended composer");

    discuss.destroy();
});

});
});
<commit_msg>[FIX] mail: adapt mobile test to new version<commit_after>odoo.define('mail.discuss_mobile_tests', function (require) {
"use strict";

var mailTestUtils = require('mail.testUtils');

var testUtils = require('web.test_utils');

var createDiscuss = mailTestUtils.createDiscuss;

QUnit.module('mail', {}, function () {

QUnit.module('Discuss in mobile', {
    beforeEach: function () {
        this.services = mailTestUtils.getMailServices();
        this.data = {
            'mail.channel': {
                fields: {},
            },
            'mail.message': {
                fields: {},
            },
        };
    },
});

QUnit.test('mobile basic rendering', async function (assert) {
    // This is a very basic first test for the client action. However, with
    // the chat_service, it is hard to override RPCs (for instance, the
    // /mail/client_action route is always called when the test suite is
    // launched), and we must wait for this RPC to be done before starting to
    // test the interface. This should be refactored to facilitate the testing.
    assert.expect(16);

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });
    // test basic rendering in mobile
    assert.containsOnce(discuss, '.o_mail_discuss_content .o_mail_no_content',
        "should display the no content message");
    assert.containsOnce(discuss, '.o_mail_mobile_tabs',
        "should have rendered the tabs");
    assert.hasClass(discuss.$('.o_mail_mobile_tab[data-type=mailbox_inbox]'),'active',
        "should be in inbox tab");
    assert.containsOnce(discuss, '.o_mail_discuss_mobile_mailboxes_buttons:visible',
        "inbox/starred buttons should be visible");
    assert.hasClass(discuss.$('.o_mail_discuss_mobile_mailboxes_buttons .o_mailbox_inbox_item[data-type=mailbox_inbox]'),'btn-primary',
        "should be in inbox");
    assert.hasClass($('.o_mail_discuss_button_dm_chat'),'d-none',
        "should have invisible button 'New Message'");
    assert.hasClass($('.o_mail_discuss_button_multi_user_channel'),'d-none',
        "should have invisible button 'New Channel'");

    // move to 'Chat' tab
    await testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type=dm_chat]'));
    assert.hasClass(discuss.$('.o_mail_mobile_tab[data-type=dm_chat]'),'active',
        "should be in 'Chat' tab");
    assert.containsNone(discuss, '.o_mail_discuss_content .o_mail_no_content',
        "should display the no content message");
    assert.strictEqual($('.o_mail_discuss_button_dm_chat').length, 1,
        "should have a button to open DM chat in 'Chat' tab");
    assert.doesNotHaveClass($('.o_mail_discuss_button_dm_chat'), 'd-none',
        "should be visible in 'Chat' tab");
    assert.hasClass($('.o_mail_discuss_button_multi_user_channel'),'d-none',
        "should have invisible button 'New Channel' in 'Chat' tab");
    await testUtils.dom.click($('.o_mail_discuss_button_dm_chat'));
    assert.containsOnce(discuss, '.o_mail_add_thread input:visible',
        "should display the input to add a channel");

    // move to 'Channels' tab
    await testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type=multi_user_channel]'));
    assert.hasClass($('.o_mail_discuss_button_dm_chat'),'d-none',
        "should have invisible button 'New Message' in 'Channels' tab");
    assert.doesNotHaveClass($('.o_mail_discuss_button_multi_user_channel'), 'd-none',
        "should have visible button 'New Channel' in 'Channels' tab");
    await testUtils.dom.click($('.o_mail_discuss_button_multi_user_channel')  );
    assert.containsOnce(discuss, '.o_mail_add_thread input:visible',
        "should display the input to add a channel");

    discuss.destroy();
});

QUnit.test('on_{attach/detach}_callback', async function (assert) {
    assert.expect(2);

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });

    discuss.on_attach_callback();
    assert.ok(true, 'should not crash on attach callback');
    discuss.on_detach_callback();
    assert.ok(true, 'should not crash on detach callback');
    discuss.destroy();
});

QUnit.test('extended composer in mass mailing channel', async function (assert) {
    assert.expect(4);

    this.data.initMessaging = {
        channel_slots: {
            channel_channel: [{
                id: 1,
                channel_type: "channel",
                name: "General",
                mass_mailing: true,
            }],
        },
    };

    var discuss = await createDiscuss({
        id: 1,
        context: {},
        params: {},
        data: this.data,
        services: this.services,
    });

    await testUtils.dom.click(discuss.$('.o_mail_mobile_tab[data-type="multi_user_channel"]'));
    await testUtils.dom.click(discuss.$('.o_mail_preview[data-preview-id="1"]'));
    assert.containsOnce(
        $,
        '.o_thread_window',
        "should display a chat window");
    assert.strictEqual(
        $('.o_thread_window').data('thread-id'),
        1,
        "chat window should be from channel General");
    assert.containsOnce(
        $('.o_thread_window'),
        '.o_thread_composer',
        "chat window should have a composer");
    assert.ok(
        $('.o_thread_window .o_thread_composer').hasClass('o_thread_composer_extended'),
        "chat window composer should be extended composer");

    discuss.destroy();
});

});
});
<|endoftext|>