<commit_before>function round(n) {
    return Math.round(n * 100) / 100;
}

function doubledValueLabel(params) {
    var value = round(params.value);
    return "sliderValue = " + value +
        "; (2 * sliderValue) = " + (2 * value);
}

status.defineSubscription(
    // the name of subscription and the name of the value in bot-db
    // associated with this subscription
    "doubledValue",
    // the map of values on which subscription depends: keys are arbitrary names
    // and values are db paths to another value
    {value: ["sliderValue"]},
    // the function which will be called as reaction on changes of values above,
    // should be pure. Returned result will be associated with subscription in bot-db
    doubledValueLabel
);

status.defineSubscription(
    "roundedValue",
    {value: ["sliderValue"]},
    function (params) {
        return round(params.value);
    }
);

function superSuggestion(params, context) {
    var balance = parseFloat(web3.fromWei(web3.eth.getBalance(context.from), "ether"));
    var defaultSliderValue = balance / 2;

    var view = ["view", {},
        ["text", {}, "Balance " + balance + " ETH"],
        ["text", {}, ["subscribe", ["doubledValue"]]],
        ["slider", {
            maximumValue: ["subscribe", ["balance"]],
            value: defaultSliderValue,
            minimumValue: 0,
            onSlidingComplete: ["dispatch", ["set", "sliderValue"]],
            step: 0.05
        }],
        ['touchable',
            {onPress: ['dispatch', ["set-value-from-db", "roundedValue"]]},
            ["view", {}, ["text", {}, "Set value"]]
        ],
        ["text", {style: {color: "red"}}, ["subscribe", ["validationText"]]]
    ];

    status.setDefaultDb({
        sliderValue: defaultSliderValue,
        doubledValue: doubledValueLabel({value: defaultSliderValue})
    });

    var validationText = "";

    if (isNaN(params.message)) {
        validationText = "That's not a float number!";
    } else if (parseFloat(params.message) > balance) {
        validationText =
            "Input value is too big!" +
            " You have only " + balance + " ETH on your balance!";
    }

    status.updateDb({
        balance: balance,
        validationText: validationText
    });

    return {markup: view};
};

status.addListener("on-message-input-change", superSuggestion);
status.addListener("on-message-send", function (params, context) {
    if (isNaN(params.message)) {
        status.sendMessage("Seems that you don't want to send money :(");
        return;
    }

    var balance = web3.eth.getBalance(context.from);
    var value = parseFloat(params.message);
    var weiValue = web3.toWei(value, "ether");
    if (bn(weiValue).greaterThan(bn(balance))) {
        status.sendMessage("No way man, you don't have enough money! :)");
        return;
    }
    try {
        web3.eth.sendTransaction({
            from: context.from,
            to: context.from,
            value: weiValue
        });
        status.sendMessage("You are the hero, you sent " + value + " ETH to yourself!");
    } catch (err) {
        status.sendMessage("Something went wrong :(")
    }
});
<commit_msg>fix demo bot<commit_after>function round(n) {
    return Math.round(n * 100) / 100;
}

function doubledValueLabel(params) {
    var value = round(params.value);
    return "sliderValue = " + value +
        "; (2 * sliderValue) = " + (2 * value);
}

status.defineSubscription(
    // the name of subscription and the name of the value in bot-db
    // associated with this subscription
    "doubledValue",
    // the map of values on which subscription depends: keys are arbitrary names
    // and values are db paths to another value
    {value: ["sliderValue"]},
    // the function which will be called as reaction on changes of values above,
    // should be pure. Returned result will be associated with subscription in bot-db
    doubledValueLabel
);

status.defineSubscription(
    "roundedValue",
    {value: ["sliderValue"]},
    function (params) {
        return round(params.value);
    }
);

function superSuggestion(params, context) {
    var balance = parseFloat(web3.fromWei(web3.eth.getBalance(context.from), "ether"));
    var defaultSliderValue = balance / 2;

    var view = ["view", {},
        ["text", {}, "Balance " + balance + " ETH"],
        ["text", {}, ["subscribe", ["doubledValue"]]],
        ["slider", {
            maximumValue: ["subscribe", ["balance"]],
            value: defaultSliderValue,
            minimumValue: 0,
            onSlidingComplete: ["dispatch", ["set", "sliderValue"]],
            step: 0.05
        }],
        ['touchable',
            {onPress: ['dispatch', ["set-value-from-db", "roundedValue"]]},
            ["view", {}, ["text", {}, "Set value"]]
        ],
        ["text", {style: {color: "red"}}, ["subscribe", ["validationText"]]]
    ];

    status.setDefaultDb({
        sliderValue: defaultSliderValue,
        doubledValue: doubledValueLabel({value: defaultSliderValue})
    });

    var validationText = "";

    if (isNaN(params.message)) {
        validationText = "That's not a float number!";
    } else if (parseFloat(params.message) > balance) {
        validationText =
            "Input value is too big!" +
            " You have only " + balance + " ETH on your balance!";
    }

    status.updateDb({
        balance: balance,
        validationText: validationText
    });

    return {markup: view};
};

status.addListener("on-message-input-change", superSuggestion);
status.addListener("on-message-send", function (params, context) {
    if (isNaN(params.message)) {
        return {"text-message": "Seems that you don't want to send money :("};
    }

    var balance = web3.eth.getBalance(context.from);
    var value = parseFloat(params.message);
    var weiValue = web3.toWei(value, "ether");
    if (bn(weiValue).greaterThan(bn(balance))) {
        return {"text-message": "No way man, you don't have enough money! :)"};
    }
    try {
        web3.eth.sendTransaction({
            from: context.from,
            to: context.from,
            value: weiValue
        });
        return {"text-message": "You are the hero, you sent " + value + " ETH to yourself!"};
    } catch (err) {
        return {"text-message": "Something went wrong :("};
    }
});
<|endoftext|>


<commit_before>/*!
 * view.js
 * Swap visible elements in a single call.
 *
 * Copyright (c) 2013 Tony Ross
 * Released under the MIT license
 * http://github.com/antross/view
 */
(function(win, doc){
    'use strict';

    var _hidden = 'hidden';

    // Approximate `setImmediate` support until a simple, cross-browser option exists
    var setImmediate = win.setImmediate || function(fn) { setTimeout(fn, 0) };

    // Create a `view` instance with the provided `root` as the default context
    function _scope(root) {

        // Show a set of elements and hide their siblings.
        function view(targets, options) {
            _iterate(targets, _view, root, options);
        }

        // Hide elements without showing others.
        view.hide = function(targets, options) {
            _iterate(targets, _hide, root, options);
        };

        // Show elements without hiding others.
        view.show = function(targets, options) {
            _iterate(targets, _show, root, options);
        };

        // Obtain a `view` scoped to a given root.
        view.scope = function(root) {
            // Verify root can contain and query elements
            if(!root || !root.querySelectorAll) {
                throw new Error('[view.js] The `root` passed to `view.scope` must support `querySelectorAll`.');
            }
            return _scope(root);
        };

        return view;
    }

    // Convert a selector into a collection of targets
    function _find(selector, root) {
        var targets = [].slice.call(root.querySelectorAll(selector));
        // Facilitate debugging mis-typed selectors
        if(!targets.length) {
            throw new Error('[view.js] No targets found for "' + selector + '".');
        }
        // Return the converted target list
        return targets;
    }

    // Ensure the target element is hidden
    function _hide(target) {
        if(!target.hasAttribute(_hidden)) {
            target.setAttribute(_hidden, '');
            _notify(target, 'view:hide');
            // Notify visible descendants
            [].forEach.call(target.querySelectorAll('[hidden] ~ :not([hidden])'), function(item) {
                _notify(item, 'view:hide');
            });
        }
    }

    // Loop over and process the arguments passed to `view`, `view.show`, or `view.hide`
    function _iterate(targets, fn, root, options) {
        if(!options) options = {};
        // Extract data if provided
        var data = options.data;
        // Disambiguate target formats to produce a list of target references
        if(typeof targets == 'string') {
            targets = _find(targets, root);
        } else if(!targets.length) {
            targets = [targets];
        }
        // Iterate and call our provided function on each matched target
        targets.forEach(function(target) {
            fn(target, targets, data, options);
        });
    }

    // Create and dispatch a DOM event when elements are shown/hidden
    function _notify(element, name, detail) {
        var event = doc.createEvent('CustomEvent');
        event.initCustomEvent(name, false, false, detail || {});
        setImmediate(function(){ element.dispatchEvent(event) });
    }

    // Ensure the target element is visible
    function _show(target, targets, data) {
        if(target.hasAttribute(_hidden)) {
            target.removeAttribute(_hidden);
            _notify(target, 'view:show', {data: data});
            // Notify visible descendants
            [].forEach.call(target.querySelectorAll('[hidden] ~ :not([hidden])'), function(item) {
                _notify(item, 'view:show');
            });
        }
    }

    // Ensure the target element is visible and hide siblings.
    // Optionally ensure ancestors are also visible.
    function _view(target, targets, data, options) {
        // Show the target element
        _show(target, targets, data);
        // Walk all siblings to ensure only the target element is visible
        var parent = target.parentNode;
        var next = parent && parent.firstElementChild;
        while(next) {
            // Hide siblings that are not also in the targets list
            if(targets.indexOf(next) == -1) {
                _hide(next);
            }
            next = next.nextElementSibling;
        }
        // Check if we should force full visibility of the target
        if(options.deep && parent && parent.hasAttribute) {
            // Walk the parent chain to ensure each ancestor is visible
            _view(parent, targets, null, options);
        }
    }

    // Expose the `view` function globally and via AMD if available
    var view = win.view = _scope(doc);
    if(win.define) win.define(function(){ return view });
})(this, this.document);
<commit_msg>Update copyright<commit_after>/*!
 * view.js
 * Swap visible elements in a single call.
 *
 * Copyright (c) 2013-2014 Tony Ross
 * Released under the MIT license
 * http://github.com/antross/view
 */
(function(win, doc){
    'use strict';

    var _hidden = 'hidden';

    // Approximate `setImmediate` support until a simple, cross-browser option exists
    var setImmediate = win.setImmediate || function(fn) { setTimeout(fn, 0) };

    // Create a `view` instance with the provided `root` as the default context
    function _scope(root) {

        // Show a set of elements and hide their siblings.
        function view(targets, options) {
            _iterate(targets, _view, root, options);
        }

        // Hide elements without showing others.
        view.hide = function(targets, options) {
            _iterate(targets, _hide, root, options);
        };

        // Show elements without hiding others.
        view.show = function(targets, options) {
            _iterate(targets, _show, root, options);
        };

        // Obtain a `view` scoped to a given root.
        view.scope = function(root) {
            // Verify root can contain and query elements
            if(!root || !root.querySelectorAll) {
                throw new Error('[view.js] The `root` passed to `view.scope` must support `querySelectorAll`.');
            }
            return _scope(root);
        };

        return view;
    }

    // Convert a selector into a collection of targets
    function _find(selector, root) {
        var targets = [].slice.call(root.querySelectorAll(selector));
        // Facilitate debugging mis-typed selectors
        if(!targets.length) {
            throw new Error('[view.js] No targets found for "' + selector + '".');
        }
        // Return the converted target list
        return targets;
    }

    // Ensure the target element is hidden
    function _hide(target) {
        if(!target.hasAttribute(_hidden)) {
            target.setAttribute(_hidden, '');
            _notify(target, 'view:hide');
            // Notify visible descendants
            [].forEach.call(target.querySelectorAll('[hidden] ~ :not([hidden])'), function(item) {
                _notify(item, 'view:hide');
            });
        }
    }

    // Loop over and process the arguments passed to `view`, `view.show`, or `view.hide`
    function _iterate(targets, fn, root, options) {
        if(!options) options = {};
        // Extract data if provided
        var data = options.data;
        // Disambiguate target formats to produce a list of target references
        if(typeof targets == 'string') {
            targets = _find(targets, root);
        } else if(!targets.length) {
            targets = [targets];
        }
        // Iterate and call our provided function on each matched target
        targets.forEach(function(target) {
            fn(target, targets, data, options);
        });
    }

    // Create and dispatch a DOM event when elements are shown/hidden
    function _notify(element, name, detail) {
        var event = doc.createEvent('CustomEvent');
        event.initCustomEvent(name, false, false, detail || {});
        setImmediate(function(){ element.dispatchEvent(event) });
    }

    // Ensure the target element is visible
    function _show(target, targets, data) {
        if(target.hasAttribute(_hidden)) {
            target.removeAttribute(_hidden);
            _notify(target, 'view:show', {data: data});
            // Notify visible descendants
            [].forEach.call(target.querySelectorAll('[hidden] ~ :not([hidden])'), function(item) {
                _notify(item, 'view:show');
            });
        }
    }

    // Ensure the target element is visible and hide siblings.
    // Optionally ensure ancestors are also visible.
    function _view(target, targets, data, options) {
        // Show the target element
        _show(target, targets, data);
        // Walk all siblings to ensure only the target element is visible
        var parent = target.parentNode;
        var next = parent && parent.firstElementChild;
        while(next) {
            // Hide siblings that are not also in the targets list
            if(targets.indexOf(next) == -1) {
                _hide(next);
            }
            next = next.nextElementSibling;
        }
        // Check if we should force full visibility of the target
        if(options.deep && parent && parent.hasAttribute) {
            // Walk the parent chain to ensure each ancestor is visible
            _view(parent, targets, null, options);
        }
    }

    // Expose the `view` function globally and via AMD if available
    var view = win.view = _scope(doc);
    if(win.define) win.define(function(){ return view });
})(this, this.document);
<|endoftext|>


<commit_before>class VisualView {

    constructor(dom) {

        this.columns = 12;
        this.rows = this.getRows(this.columns);
        this.images = [];
        this.elements = [];
        this.dom = dom;

    }

    changeImages(images) {

        this.images = images;

    }

    getRows(columns) {
        return Math.ceil(columns / 16 * 9);
    }

    initGrid(images, columns) {

        this.images = images ? images : this.images;
        this.columns = columns ? columns : this.columns;

      	let imageWidth = window.innerWidth / columns;
      	let imageHeight = window.innerHeight / rows;

        this.rows = this.calculateRows(imageWidth);
        this.dom.innerHTML = "";

      	let imageWidth = window.innerWidth / columns;
        let imageHeight = window.innerHeight / rows;

        let elements = this.elements;
        let totalElements = this.columns * this.rows;
        let totalImages = this.images.length;
        let currentIndex = 0;

        for (let y = 0; y < this.rows; y++) {
            for (let x = 0; x < this.columns; x++) {

                let image = this.images[currentIndex];
                elements.push(image);
                this.addElement.call(this, image, x, y);

                currentIndex++;
                if (currentIndex == totalImages) {
                    currentIndex = 0;
                }
            }

        }
    }

    addElement(image, x, y) {

        let columns = this.columns;
        let rows = this.rows;
        let element = document.createElement("div");
        let inner = document.createElement("div");
        let imageWidth = window.innerWidth / columns;
        let imageHeight = window.innerHeight / rows;

        element.className = "gif";

        helpers.applyStyle(element, {
            width: imageWidth + "px",
            height: imageHeight + "px",
            top: imageHeight * y + "px",
            left: imageWidth * x + "px"
        });

        inner.className = "inner-div";
        inner.style.backgroundImage = "url(" + image + ")";
        element.appendChild(inner);
        this.dom.appendChild(element)

        helpers.saveProps(element, {
            top: imageHeight * y + "px",
            left: imageWidth * x + "px"
        });
    }

    flipImage(element, url) {
        let img = element.querySelector("img");
        let rotation = img.getAttribute("data-rotation").split(",");
        let random2 = Math.random() > 0.5 ? 180 : -180;
        if (Math.random() > 0) {
            rotation[1] = parseInt(rotation[1]) + 180;
        } else {
            rotation[0] = parseInt(rotation[0]) + random2;
            rotation[2] = parseInt(rotation[2]) + random2;
        }

        img.style.transform = "rotateX(" + rotation[0] + "deg)rotateY(" + rotation[1] + "deg)rotateZ(" + rotation[2] + "deg)";
        img.setAttribute("data-rotation", rotation);

        setTimeout(() => {
            img.src = url
        }, 100);
    }

}
<commit_msg>Updated view.js<commit_after>class VisualView {

    constructor(dom) {

        this.columns = 12;
        this.rows = this.getRows(this.columns);
        this.images = [];
        this.elements = [];
        this.dom = dom;

    }

    changeImages(images) {

        this.images = images;

    }

    calculateRows(columns) {
        return Math.ceil(columns / 16 * 9);
    }

    initGrid(images, columns) {

        this.images = images ? images : this.images;
        this.columns = columns ? columns : this.columns;

      	let imageWidth = window.innerWidth / columns;
      	let imageHeight = window.innerHeight / rows;

        this.rows = this.calculateRows(imageWidth);
        this.dom.innerHTML = "";

      	let imageWidth = window.innerWidth / columns;
        let imageHeight = window.innerHeight / rows;

        let elements = this.elements;
        let totalElements = this.columns * this.rows;
        let totalImages = this.images.length;
        let currentIndex = 0;

        for (let y = 0; y < this.rows; y++) {
            for (let x = 0; x < this.columns; x++) {

                let image = this.images[currentIndex];
                elements.push(image);
                this.addElement.call(this, image, x, y);

                currentIndex++;
                if (currentIndex == totalImages) {
                    currentIndex = 0;
                }
            }

        }
    }

    addElement(image, x, y) {

        let columns = this.columns;
        let rows = this.rows;
        let element = document.createElement("div");
        let inner = document.createElement("div");
        let imageWidth = window.innerWidth / columns;
        let imageHeight = window.innerHeight / rows;

        element.className = "gif";

        helpers.applyStyle(element, {
            width: imageWidth + "px",
            height: imageHeight + "px",
            top: imageHeight * y + "px",
            left: imageWidth * x + "px"
        });

        inner.className = "inner-div";
        inner.style.backgroundImage = "url(" + image + ")";
        element.appendChild(inner);
        this.dom.appendChild(element)

        helpers.saveProps(element, {
            top: imageHeight * y + "px",
            left: imageWidth * x + "px"
        });
    }

    flipImage(element, url) {
        let img = element.querySelector("img");
        let rotation = img.getAttribute("data-rotation").split(",");
        let random2 = Math.random() > 0.5 ? 180 : -180;
        if (Math.random() > 0) {
            rotation[1] = parseInt(rotation[1]) + 180;
        } else {
            rotation[0] = parseInt(rotation[0]) + random2;
            rotation[2] = parseInt(rotation[2]) + random2;
        }

        img.style.transform = "rotateX(" + rotation[0] + "deg)rotateY(" + rotation[1] + "deg)rotateZ(" + rotation[2] + "deg)";
        img.setAttribute("data-rotation", rotation);

        setTimeout(() => {
            img.src = url
        }, 100);
    }

}
<|endoftext|>


<commit_before>/**
 * Logic for translating a given Objective-C "type" encoding into a node-ffi
 * type.
 *
 * Reference: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
 * node-ffi Type List: https://github.com/rbranson/node-ffi/wiki/Node-FFI-Tutorial#wiki-type-list
 */

exports.map = translate
exports.mapArray = mapArray
exports.parse = parse

var struct = require('./struct')

var map = {
    'c': 'char'
  , 'i': 'int32'
  , 's': 'short'
  , 'l': 'long'
  , 'q': 'longlong'
  , 'C': 'uchar'
  , 'I': 'uint32'
  , 'S': 'ushort'
  , 'L': 'ulong'
  , 'Q': 'ulonglong'
  , 'f': 'float'
  , 'd': 'double'
  , 'B': 'int8'
  , 'v': 'void'
  , '*': 'string'   // String
  , '@': 'pointer'  // id
  , '#': 'pointer'  // Class
  , ':': 'pointer'  // SEL
  , '?': 'pointer'  // Unknown, used for function pointers
};

/**
 * Translates a single Obj-C 'type' into a valid node-ffi type.
 * This mapping logic is kind of a mess...
 */
function translate (type) {
  if (!type) throw new Error('got falsey "type" to map ('+type+'). this should NOT happen!');
  if (type.type) type = type.type
  if (struct.isStruct(type)) return struct.getStruct(type);
  var rtn = map[type];
  if (rtn) return rtn;
  if (type[0] === '^') return 'pointer';
  rtn = map[type[type.length-1]];
  if (rtn) return rtn;
  throw new Error('Could not convert type: ' + type);
}

/**
 * Accepts an Array of ObjC return type and argument types (i.e. the result of
 * parse() below), and returns a new Array with the values mapped to valid ffi
 * types.
 */
function mapArray (types) {
  return types.map(function (type) {
    return Array.isArray(type) ? exports.mapArray(type) : exports.map(type);
  });
}

/**
 * Parses a "types string" (i.e. "v@:") and returns a "types Array", where the
 * return type is the first array value, and an Array of argument types is the
 * array second value.
 */
function parse (types) {
  if (types[1] !== '@' || types[2] !== ':')
    throw new Error('Invalid types string: '+types)
  return [ types[0], types.substring(1).split('') ]
}
<commit_msg>Add the Obj-C Method Encodings. Not quite sure how these will be used yet...<commit_after>/**
 * Logic for translating a given Objective-C "type" encoding into a node-ffi
 * type.
 *
 * Reference: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
 * node-ffi Type List: https://github.com/rbranson/node-ffi/wiki/Node-FFI-Tutorial#wiki-type-list
 */

exports.map = map
exports.mapArray = mapArray
exports.parse = parse

var struct = require('./struct')

var typeEncodings = {
    'c': 'char'
  , 'i': 'int32'
  , 's': 'short'
  , 'l': 'long'
  , 'q': 'longlong'
  , 'C': 'uchar'
  , 'I': 'uint32'
  , 'S': 'ushort'
  , 'L': 'ulong'
  , 'Q': 'ulonglong'
  , 'f': 'float'
  , 'd': 'double'
  , 'B': 'int8'
  , 'v': 'void'
  , '*': 'string'   // String
  , '@': 'pointer'  // id
  , '#': 'pointer'  // Class
  , ':': 'pointer'  // SEL
  , '?': 'pointer'  // Unknown, used for function pointers
}

var methodEncodings = {
    'r': 'const'
  , 'n': 'in'
  , 'N': 'inout'
  , 'o': 'out'
  , 'O': 'bycopy'
  , 'R': 'byref'
  , 'V': 'oneway'
}

/**
 * Maps a single Obj-C 'type' into a valid node-ffi type.
 * This mapping logic is kind of a mess...
 */
function map (type) {
  if (!type) throw new Error('got falsey "type" to map ('+type+'). this should NOT happen!');
  if (type.type) type = type.type
  if (struct.isStruct(type)) return struct.getStruct(type);
  var rtn = typeEncodings[type];
  if (rtn) return rtn;
  if (type[0] === '^') return 'pointer';
  rtn = typeEncodings[type[type.length-1]];
  if (rtn) return rtn;
  throw new Error('Could not convert type: ' + type);
}

/**
 * Accepts an Array of ObjC return type and argument types (i.e. the result of
 * parse() below), and returns a new Array with the values mapped to valid ffi
 * types.
 */
function mapArray (types) {
  return types.map(function (type) {
    return Array.isArray(type) ? exports.mapArray(type) : exports.map(type);
  });
}

/**
 * Parses a "types string" (i.e. "v@:") and returns a "types Array", where the
 * return type is the first array value, and an Array of argument types is the
 * array second value.
 */
function parse (types) {
  if (types[1] !== '@' || types[2] !== ':')
    throw new Error('Invalid types string: '+types)
  return [ types[0], types.substring(1).split('') ]
}
<|endoftext|>


<commit_before>#!/bin/sh
':' // ; export MAX_MEM="--max-old-space-size=500"; exec "$(command -v node || command -v nodejs)" --harmony "${NODE_OPTIONS:-$MAX_MEM}" "$0" "$@"
'use strict'
/*
 * See the NOTICE.txt file distributed with this work for additional information
 * regarding copyright ownership.
 * Sematext licenses logagent-js to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var consoleLogger = require('../lib/util/logger.js')
var StatsPrinter = require('../lib/core/printStats.js')
var LogAnalyzer = require('../lib/parser/parser.js')

var mkpath = require('mkpath')

function LaCli (options) {
  this.eventEmitter = require('../lib/core/logEventEmitter.js')
  this.logseneDiskBufferDir = null
  this.fileManager = null
  this.la = null
  this.throng = null
  this.argv = options || require('../lib/core/cliArgs.js')
  this.globPattern = this.argv.glob || process.env.GLOB_PATTERN
  this.logseneToken = this.argv.index || process.env.LOGSENE_TOKEN
  this.loggers = {}
  this.WORKERS = process.env.WEB_CONCURRENCY || 1

  this.removeAnsiColor = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g
  this.laStats = StatsPrinter
  this.initState()
}

LaCli.prototype.initPugins = function (plugins) {
  consoleLogger.log('init plugins')
  var eventEmitter = require('../lib/core/logEventEmitter')
  this.plugins = []
  plugins.forEach(function (pluginName) {
    consoleLogger.log(pluginName)
    try {
      var Plugin = require(pluginName)
      var p = new Plugin(this.argv, eventEmitter)
      this.plugins.push(p)
      p.start()
    } catch (err) {
      consoleLogger.error('Error loading plugin: ' + pluginName + ' ' + err.stack)
    }
  }.bind(this))
}

LaCli.prototype.loadPlugins = function (configFile) {
  var plugins = [
    '../lib/plugins/input/files',
    '../lib/plugins/input/stdin',
    '../lib/plugins/input/syslog',
    '../lib/plugins/input/heroku',
    '../lib/plugins/input/cloudfoundry',
    '../lib/plugins/output/elasticsearch',
    '../lib/plugins/output/stdout'
  ]
  if (!configFile) {
    return plugins
  }

  var inputSections = Object.keys(configFile.input)
  inputSections.forEach(function (key) {
    if (configFile.input[key].module) {
      console.log('add ' + configFile.input[key].module + ' to plugin list')
      plugins.push(configFile.input[key].module)
    }
  })
  var outputSections = Object.keys(configFile.output)
  outputSections.forEach(function (key) {
    if (configFile.output[key].module) {
      plugins.push(configFile.output[key].module)
    }
  })
  return plugins
}

LaCli.prototype.initState = function () {
  var eventEmitter = this.eventEmitter
  var self = this
  var plugins = self.loadPlugins(this.argv.configFile)
  self.initPugins(plugins)

  self.logseneDiskBufferDir = self.argv['diskBufferDir'] || process.env.LOGSENE_TMP_DIR || require('os').tmpdir()
  mkpath(self.logseneDiskBufferDir, function (err) {
    if (err) {
      console.error('ERROR: create diskBufferDir (' + self.logseneDiskBufferDir + '): ' + err.message)
    }
  })

  this.la = new LogAnalyzer(self.argv.patternFiles, {}, function laReadyCb (lp) {
    if (self.argv.patterns && (self.argv.patterns instanceof Array)) {
      lp.patterns = self.argv.patterns.concat(lp.patterns)
    }
    if (self.argv.includeOriginalLine !== undefined) {
      lp.cfg.originalLine = self.argv.includeOriginalLine
    }
    self.cli()
  })
  self.eventEmitter.on('input.stdin.end', function endOnStdinEof (line, context) {
    self.terminateRequest = true
    self.terminateReason = 'stdin closed'
  })

  self.tid = setInterval(function () {
    if (self.terminateRequest && Date.now() - self.lastParsedTS > 1500) {
      self.terminate(self.terminateReason)
    }
  }, 1000)

  self.eventEmitter.on('data.raw', function parseRaw (line, context) {
    self.lastParsedTS = Date.now()
    var trimmedLine = line
    if (line && Buffer.byteLength(line, 'utf8') > self.argv.maxLogSize) {
      var cutMsg = new Buffer(self.argv.maxLogSize)
      cutMsg.write(line)
      trimmedLine = cutMsg.toString()
    }
    self.laStats.bytes = self.laStats.bytes + Buffer.byteLength(line, 'utf8')
    self.laStats.count++

    self.la.parseLine(
      trimmedLine.replace(self.removeAnsiColor, ''),
      context.sourceName || self.argv.sourceName,
      function parserCb (err, data) {
        if (data) {
          if (context.enrichEvent) {
            Object.keys(context.enrichEvent).forEach(function (key) {
              data[key] = context.enrichEvent[key]
            })
          }
          var filteredData = data
          if (context.filter) {
            filteredData = context.filter(data, context)
          }
          if (filteredData) {
            eventEmitter.parsedEvent(filteredData, context)
          }
        }
      })
  })
  process.once('SIGINT', function () { self.terminate('SIGINT') })
  process.once('SIGQUIT', function () { self.terminate('SIGQUIT')})
  process.once('SIGTERM', function () { self.terminate('SIGTERM')})
  process.once('beforeExit', self.terminate)
}

LaCli.prototype.log = function (err, data) {
  if (err && (!data)) {
    this.laStats.emptyLines++
    return
  }
  if (!data) {
    return
  }
  if (this.argv.tokenMapper) {
    var tokenForSource = this.argv.tokenMapper.findToken([data.logSource]) || this.argv.index
    if (tokenForSource) {
      this.logToLogsene(tokenForSource, data['_type'] || 'logs', data)
    }
  } else {
    if (this.argv.index) {
      this.logToLogsene(this.argv.index, data['_type'] || 'logs', data)
    }
  }
}

LaCli.prototype.parseLine = function (line, sourceName, cbf) {
  if (!line && cbf) {
    return cbf(new Error('empty line passed to parseLine()'))
  }
  var trimmedLine = line
  var bufLength = Buffer.byteLength(line, 'utf8')
  if (line && bufLength > this.argv.maxLogSize) {
    var cutMsg = new Buffer(this.argv.maxLogSize)
    cutMsg.write(line)
    trimmedLine = cutMsg.toString()
  }
  this.laStats.bytes = this.laStats.bytes + bufLength
  this.laStats.count++
  this.la.parseLine(
    trimmedLine.replace(this.removeAnsiColor, ''),
    this.argv.sourceName || sourceName,
    cbf || this.log.bind(this))
}

LaCli.prototype.parseChunks = function (chunk, enc, callback) {
  this.parseLine(chunk.toString())
  callback()
}

LaCli.prototype.terminate = function (reason) {
  consoleLogger.log('terminate reason: ' + reason)
  if (this.argv.heroku && reason !== 'exitWorker') {
    return
  }
  if (this.argv.suppress) {
    this.laStats.printStats()
  }
  var terminateCounter = this.plugins.length - 1
  function callBackWithATimeout (callback, timeout) {
    var run, timer
    run = function () {
      if (timer) {
        clearTimeout(timer)
        timer = null
        callback.apply(this, arguments)
      }
    }
    timer = setTimeout(run, timeout, 'timeout')
    return run
  }
  this.plugins.forEach(function pluginStop (p) {
    if (p.stop) {
      try {
        p.stop(callBackWithATimeout(function () {
          terminateCounter--
          if (terminateCounter == 0) {
            process.exit()
          }
        }, 5000))
      } catch (err) {
        consoleLogger.error('Error stopping plugin ' + err)
      }
    } else {
      terminateCounter--
      if (terminateCounter == 0) {
        process.exit()
      }
    }
  })
  setTimeout(process.exit, 10000)
}

LaCli.prototype.cli = function () {
  if (this.argv.printStats || this.argv.verbose) {
    setInterval(this.laStats.printStats.bind(this.laStats), ((Number(this.argv.printStats)) || 60) * 1000)
    this.laStats.printStats()
  }
}

if (require.main === module) {
  var logagent = new LaCli()
} else {
  module.exports = LaCli
}
<commit_msg>add log message for parser errors<commit_after>#!/bin/sh
':' // ; export MAX_MEM="--max-old-space-size=500"; exec "$(command -v node || command -v nodejs)" --harmony "${NODE_OPTIONS:-$MAX_MEM}" "$0" "$@"
'use strict'
/*
 * See the NOTICE.txt file distributed with this work for additional information
 * regarding copyright ownership.
 * Sematext licenses logagent-js to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var consoleLogger = require('../lib/util/logger.js')
var StatsPrinter = require('../lib/core/printStats.js')
var LogAnalyzer = require('../lib/parser/parser.js')

var mkpath = require('mkpath')

function LaCli (options) {
  this.eventEmitter = require('../lib/core/logEventEmitter.js')
  this.logseneDiskBufferDir = null
  this.fileManager = null
  this.la = null
  this.throng = null
  this.argv = options || require('../lib/core/cliArgs.js')
  this.globPattern = this.argv.glob || process.env.GLOB_PATTERN
  this.logseneToken = this.argv.index || process.env.LOGSENE_TOKEN
  this.loggers = {}
  this.WORKERS = process.env.WEB_CONCURRENCY || 1

  this.removeAnsiColor = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g
  this.laStats = StatsPrinter
  this.initState()
}

LaCli.prototype.initPugins = function (plugins) {
  consoleLogger.log('init plugins')
  var eventEmitter = require('../lib/core/logEventEmitter')
  this.plugins = []
  plugins.forEach(function (pluginName) {
    consoleLogger.log(pluginName)
    try {
      var Plugin = require(pluginName)
      var p = new Plugin(this.argv, eventEmitter)
      this.plugins.push(p)
      p.start()
    } catch (err) {
      consoleLogger.error('Error loading plugin: ' + pluginName + ' ' + err.stack)
    }
  }.bind(this))
}

LaCli.prototype.loadPlugins = function (configFile) {
  var plugins = [
    '../lib/plugins/input/files',
    '../lib/plugins/input/stdin',
    '../lib/plugins/input/syslog',
    '../lib/plugins/input/heroku',
    '../lib/plugins/input/cloudfoundry',
    '../lib/plugins/output/elasticsearch',
    '../lib/plugins/output/stdout'
  ]
  if (!configFile) {
    return plugins
  }

  var inputSections = Object.keys(configFile.input)
  inputSections.forEach(function (key) {
    if (configFile.input[key].module) {
      console.log('add ' + configFile.input[key].module + ' to plugin list')
      plugins.push(configFile.input[key].module)
    }
  })
  var outputSections = Object.keys(configFile.output)
  outputSections.forEach(function (key) {
    if (configFile.output[key].module) {
      plugins.push(configFile.output[key].module)
    }
  })
  return plugins
}

LaCli.prototype.initState = function () {
  var eventEmitter = this.eventEmitter
  var self = this
  var plugins = self.loadPlugins(this.argv.configFile)
  self.initPugins(plugins)

  self.logseneDiskBufferDir = self.argv['diskBufferDir'] || process.env.LOGSENE_TMP_DIR || require('os').tmpdir()
  mkpath(self.logseneDiskBufferDir, function (err) {
    if (err) {
      console.error('ERROR: create diskBufferDir (' + self.logseneDiskBufferDir + '): ' + err.message)
    }
  })

  this.la = new LogAnalyzer(self.argv.patternFiles, {}, function laReadyCb (lp) {
    if (self.argv.patterns && (self.argv.patterns instanceof Array)) {
      lp.patterns = self.argv.patterns.concat(lp.patterns)
    }
    if (self.argv.includeOriginalLine !== undefined) {
      lp.cfg.originalLine = self.argv.includeOriginalLine
    }
    self.cli()
  })
  self.eventEmitter.on('input.stdin.end', function endOnStdinEof (line, context) {
    self.terminateRequest = true
    self.terminateReason = 'stdin closed'
  })

  self.tid = setInterval(function () {
    if (self.terminateRequest && Date.now() - self.lastParsedTS > 1500) {
      self.terminate(self.terminateReason)
    }
  }, 1000)

  self.eventEmitter.on('data.raw', function parseRaw (line, context) {
    self.lastParsedTS = Date.now()
    var trimmedLine = line
    if (line && Buffer.byteLength(line, 'utf8') > self.argv.maxLogSize) {
      var cutMsg = new Buffer(self.argv.maxLogSize)
      cutMsg.write(line)
      trimmedLine = cutMsg.toString()
    }
    self.laStats.bytes = self.laStats.bytes + Buffer.byteLength(line, 'utf8')
    self.laStats.count++

    self.la.parseLine(
      trimmedLine.replace(self.removeAnsiColor, ''),
      context.sourceName || self.argv.sourceName,
      function parserCb (err, data) {
        if (err && !data) {
          consoleLogger.error('error during parsing: ' + err)
        }
        if (data) {
          if (context.enrichEvent) {
            Object.keys(context.enrichEvent).forEach(function (key) {
              data[key] = context.enrichEvent[key]
            })
          }
          var filteredData = data
          if (context.filter) {
            filteredData = context.filter(data, context)
          }
          if (filteredData) {
            eventEmitter.parsedEvent(filteredData, context)
          }
        }
      })
  })
  process.once('SIGINT', function () { self.terminate('SIGINT') })
  process.once('SIGQUIT', function () { self.terminate('SIGQUIT') })
  process.once('SIGTERM', function () { self.terminate('SIGTERM') })
  process.once('beforeExit', self.terminate)
}

LaCli.prototype.log = function (err, data) {
  if (err && (!data)) {
    this.laStats.emptyLines++
    return
  }
  if (!data) {
    return
  }
  if (this.argv.tokenMapper) {
    var tokenForSource = this.argv.tokenMapper.findToken([data.logSource]) || this.argv.index
    if (tokenForSource) {
      this.logToLogsene(tokenForSource, data['_type'] || 'logs', data)
    }
  } else {
    if (this.argv.index) {
      this.logToLogsene(this.argv.index, data['_type'] || 'logs', data)
    }
  }
}

LaCli.prototype.parseLine = function (line, sourceName, cbf) {
  if (!line && cbf) {
    return cbf(new Error('empty line passed to parseLine()'))
  }
  var trimmedLine = line
  var bufLength = Buffer.byteLength(line, 'utf8')
  if (line && bufLength > this.argv.maxLogSize) {
    var cutMsg = new Buffer(this.argv.maxLogSize)
    cutMsg.write(line)
    trimmedLine = cutMsg.toString()
  }
  this.laStats.bytes = this.laStats.bytes + bufLength
  this.laStats.count++
  this.la.parseLine(
    trimmedLine.replace(this.removeAnsiColor, ''),
    this.argv.sourceName || sourceName,
    cbf || this.log.bind(this))
}

LaCli.prototype.parseChunks = function (chunk, enc, callback) {
  this.parseLine(chunk.toString())
  callback()
}

LaCli.prototype.terminate = function (reason) {
  consoleLogger.log('terminate reason: ' + reason)
  if (this.argv.heroku && reason !== 'exitWorker') {
    return
  }
  if (this.argv.suppress) {
    this.laStats.printStats()
  }
  var terminateCounter = this.plugins.length - 1
  function callBackWithATimeout (callback, timeout) {
    var run, timer
    run = function () {
      if (timer) {
        clearTimeout(timer)
        timer = null
        callback.apply(this, arguments)
      }
    }
    timer = setTimeout(run, timeout, 'timeout')
    return run
  }
  this.plugins.forEach(function pluginStop (p) {
    if (p.stop) {
      try {
        p.stop(callBackWithATimeout(function () {
          terminateCounter--
          if (terminateCounter == 0) {
            process.exit()
          }
        }, 5000))
      } catch (err) {
        consoleLogger.error('Error stopping plugin ' + err)
      }
    } else {
      terminateCounter--
      if (terminateCounter == 0) {
        process.exit()
      }
    }
  })
  setTimeout(process.exit, 10000)
}

LaCli.prototype.cli = function () {
  if (this.argv.printStats || this.argv.verbose) {
    setInterval(this.laStats.printStats.bind(this.laStats), ((Number(this.argv.printStats)) || 60) * 1000)
    this.laStats.printStats()
  }
}

if (require.main === module) {
  var logagent = new LaCli()
} else {
  module.exports = LaCli
}
<|endoftext|>


<commit_before>Ext.namespace('Kwc.Abstract.Image');
Kwc.Abstract.Image.DimensionField = Ext.extend(Ext.form.TriggerField, {
    triggerClass: 'x-form-search-trigger',
    width: 300,
    readOnly: true,
    imageData: null,
    cropData: null,

    initComponent: function() {
        Kwc.Abstract.Image.DimensionField.superclass.initComponent.call(this);
    },
    getValue: function() {
        return this.value || {};
    },

    setValue: function(v) {
        this.value = v;
        if (this.rendered) {
            if (v.dimension) {
                this.setRawValue(this._getDimensionString(v));
            } else {
                this.setRawValue('');
            }
        }
    },
    afterRender: function() {
        Kwc.Abstract.Image.DimensionField.superclass.afterRender.call(this);
        if (this.value) {
            this.setValue(this.value);
        }
        this.findParentByType('kwf.autoform').// TODO: retrieve Upload-field more cleanly
            findByType('kwf.file')[0].on('change', function (el, value) {
                this.imageData = value;
        }, this);
    },

    _validateSizes: function()
    {
        var dim = this.dimensionField.getValue();
        if (this.widthField.getValue() < 1 && this.dimensions[dim].width == 'user'
            && this.heightField.getValue() < 1 && this.dimensions[dim].height == 'user'
        ) {
            if (this.widthField.getValue() < 1) {
                this.widthField.markInvalid(trlKwf('Width or height must be higher than 0 when using crop or bestfit.'));
            }
            if (this.heightField.getValue() < 1) {
                this.heightField.markInvalid(trlKwf('Width or height must be higher than 0 when using crop or bestfit.'));
            }
            return false;
        }

        this.widthField.clearInvalid();
        this.heightField.clearInvalid();

        return true;
    },

    onTriggerClick: function() {
        if (!this.sizeWindow) {
            var radios = [];
            for (var i in this.dimensions) {
                radios.push({
                    inputValue: i,
                    boxLabel: this._getDimensionString({dimension: i}),
                    name: 'dimension',
                    listeners: {
                        check: this._enableDisableFields,
                        scope: this
                    }
                });
            }
            this.dimensionField = new Kwf.Form.RadioGroup({
                columns: 1,
                hideLabel: true,
                vertical: false,
                items: radios
            });
            this.widthField = new Ext.form.NumberField({
                fieldLabel: trlKwf('Width'),
                width: 50,
                enableKeyEvents: true,
                validateOnBlur: false,
                validationEvent: false,
                allowNegative: false
            });
            this.heightField = new Ext.form.NumberField({
                fieldLabel: trlKwf('Height'),
                width: 50,
                enableKeyEvents: true,
                validateOnBlur: false,
                validationEvent: false,
                allowNegative: false
            });

            this.widthField.on('blur', this._validateSizes, this);
            this.widthField.on('keyup', this._validateSizes, this);
            this.heightField.on('blur', this._validateSizes, this);
            this.heightField.on('keyup', this._validateSizes, this);
            this.dimensionField.on('change', this._validateSizes, this);

            var button = new Ext.Button({
                text: trlKwf('Crop Image'),
                handler: function() {
                    var width, height;
                    var preserveRatio = false;
                    var cropData = null;
                    if (this.dimensionField.getValue() == this.getValue().dimension) {
                        // load saved crop-values if not 0
                        if (this.getValue().cropData.width > 0 && this.getValue().cropData.height > 0) {
                            cropData = this.getValue().cropData;
                        }
                    }
                    var dimension = this.dimensions[this.dimensionField.getValue()];
                    if (dimension.height == 'user' && this.heightField.getValue() != '') {
                        height = this.heightField.getValue();
                    } else if (dimension.height > 0) {
                        height = dimension.height;
                    } else {
                        //TODO throw exception no value set
                    }

                    if (dimension.width == 'user' && this.widthField.getValue() != '') {
                        width = this.widthField.getValue();
                    } else if (dimension.width > 0) {
                        width = dimension.width;
                    } else {
                        //TODO throw exception no value set
                    }

                    if (dimension.bestfit == false) {
                        preserveRatio = true;
                    }

                    // call controller to create image with nice size to work with
                    var imageURL = '/kwf/media/upload/download-handy?uploadId='+this.imageData.uploadId+'&hashKey='+this.imageData.hashKey;

                    var cw = new Kwc.Abstract.Image.CropWindow({
                        imageUrl: imageURL,
                        preserveRatio: preserveRatio,
                        outWidth: width,
                        outHeight: height,
                        cropData: cropData,
                        buttons: [{
                            text: trlKwf('OK'),
                            handler: function() {
                                this.cropData = cw.cropData;
                                cw.close();
                            },
                            scope: this
                        },{
                            text: trlKwf('Cancel'),
                            handler: function() {
                                cw.close();
                            },
                            scope: this
                        }]
                    });
                    cw.show();
                },
                scope: this
            });

            this.dimensionField.on('change', function () {
                var dimension = this.dimensions[this.dimensionField.getValue()];
                if (dimension.width == 0 && dimension.height == 0) {
                    button.disable();
                } else {
                    button.enable();
                }
            }, this);

            this.sizeWindow = new Ext.Window({
                title: trlKwf('Image Size'),
                closeAction: 'hide',
                modal: true,
                width: 350,
                height: 350,
                layout: 'fit',
                items: new Ext.FormPanel({
                    bodyStyle: 'padding: 10px',
                    items: [
                        this.dimensionField,
                        {
                            xtype: 'fieldset',
                            autoHeight: true,
                            title: trlKwf('Size'),
                            items: [
                                this.widthField,
                                this.heightField
                            ]
                        },
                        button
                    ]
                }),
                buttons: [{
                    text: trlKwf('OK'),
                    handler: function() {
                        if (this._validateSizes()) {
                            this.sizeWindow.hide();
                            this.setValue({
                                dimension: this.dimensionField.getValue(),
                                width: this.widthField.getValue(),
                                height: this.heightField.getValue(),
                                cropData: this.cropData
                            });
                        } else {
                            Ext.Msg.alert(trlKwf('Error'), trlKwf('Please fill the marked fields correctly.'));
                        }
                    },
                    scope: this
                },{
                    text: trlKwf('Cancel'),
                    handler: function() {
                        this.sizeWindow.hide();
                    },
                    scope: this
                }]
            });
        }

        if (!this.imageData) {
            //TODO better way to find button in panel
            this.sizeWindow.items.items[0].items.items[2].disable();
        } else {
            this.sizeWindow.items.items[0].items.items[2].enable();
        }

        var v = this.getValue();
        if (v && v.dimension) {
            this.dimensionField.setValue(v.dimension);
            this.widthField.setValue(v.width);
            this.heightField.setValue(v.height);
        } else {
            for (var i in this.dimensions) {
                break;
            }
            this.dimensionField.setValue(i);
        }
        this._enableDisableFields();
        this.sizeWindow.show();

        this._validateSizes();
    },

    _enableDisableFields: function()
    {
        var dim = this.dimensions[this.dimensionField.getValue()];
        this.widthField.setDisabled(!(dim && dim.width == 'user'));
        this.heightField.setDisabled(!(dim && dim.height == 'user'));
    },

    _getDimensionString: function(v)
    {
        var ret;
        if (this.dimensions[v.dimension] && this.dimensions[v.dimension].text) {
            ret = this.dimensions[v.dimension].text;
        } else {
            ret = v.dimension;
        }
        if (this.dimensions[v.dimension]) {
            var d = this.dimensions[v.dimension];
            ret += ' (';
            if (d.width == 'user') {
                if (v.width) {
                    ret += String(v.width);
                } else {
                    ret += '?';
                }
            } else if (d.width) {
                ret += String(d.width);
            } else {
                ret += '?';
            }
            ret += 'x';
            if (d.height == 'user') {
                if (v.height) {
                    ret += String(v.height);
                } else {
                    ret += '?';
                }
            } else if (d.height) {
                ret += String(d.height);
            } else {
                ret += '?';
            }
            ret += ' ';
            if (d.bestfit) {
                ret += trlKwf('Bestfit');
            } else {
                ret += trlKwf('Crop');
            }
            ret = ret.trim() + ')';
        }
        return ret;
    }
});

Ext.reg('kwc.image.dimensionfield', Kwc.Abstract.Image.DimensionField);
<commit_msg>Throw exceptions if problems, handle contentWidth-state<commit_after>Ext.namespace('Kwc.Abstract.Image');
Kwc.Abstract.Image.DimensionField = Ext.extend(Ext.form.TriggerField, {
    triggerClass: 'x-form-search-trigger',
    width: 300,
    readOnly: true,
    imageData: null,
    cropData: null,

    initComponent: function() {
        Kwc.Abstract.Image.DimensionField.superclass.initComponent.call(this);
    },
    getValue: function() {
        return this.value || {};
    },

    setValue: function(v) {
        this.value = v;
        if (this.rendered) {
            if (v.dimension) {
                this.setRawValue(this._getDimensionString(v));
            } else {
                this.setRawValue('');
            }
        }
    },
    afterRender: function() {
        Kwc.Abstract.Image.DimensionField.superclass.afterRender.call(this);
        if (this.value) {
            this.setValue(this.value);
        }
        this.findParentByType('kwf.autoform').// TODO: retrieve Upload-field more cleanly
            findByType('kwf.file')[0].on('change', function (el, value) {
                this.imageData = value;
        }, this);
    },

    _validateSizes: function()
    {
        var dim = this.dimensionField.getValue();
        if (this.widthField.getValue() < 1 && this.dimensions[dim].width == 'user'
            && this.heightField.getValue() < 1 && this.dimensions[dim].height == 'user'
        ) {
            if (this.widthField.getValue() < 1) {
                this.widthField.markInvalid(trlKwf('Width or height must be higher than 0 when using crop or bestfit.'));
            }
            if (this.heightField.getValue() < 1) {
                this.heightField.markInvalid(trlKwf('Width or height must be higher than 0 when using crop or bestfit.'));
            }
            return false;
        }

        this.widthField.clearInvalid();
        this.heightField.clearInvalid();

        return true;
    },

    onTriggerClick: function() {
        if (!this.sizeWindow) {
            var radios = [];
            for (var i in this.dimensions) {
                radios.push({
                    inputValue: i,
                    boxLabel: this._getDimensionString({dimension: i}),
                    name: 'dimension',
                    listeners: {
                        check: this._enableDisableFields,
                        scope: this
                    }
                });
            }
            this.dimensionField = new Kwf.Form.RadioGroup({
                columns: 1,
                hideLabel: true,
                vertical: false,
                items: radios
            });
            this.widthField = new Ext.form.NumberField({
                fieldLabel: trlKwf('Width'),
                width: 50,
                enableKeyEvents: true,
                validateOnBlur: false,
                validationEvent: false,
                allowNegative: false
            });
            this.heightField = new Ext.form.NumberField({
                fieldLabel: trlKwf('Height'),
                width: 50,
                enableKeyEvents: true,
                validateOnBlur: false,
                validationEvent: false,
                allowNegative: false
            });

            this.widthField.on('blur', this._validateSizes, this);
            this.widthField.on('keyup', this._validateSizes, this);
            this.heightField.on('blur', this._validateSizes, this);
            this.heightField.on('keyup', this._validateSizes, this);
            this.dimensionField.on('change', this._validateSizes, this);

            var button = new Ext.Button({
                text: trlKwf('Crop Image'),
                handler: function() {
                    var width, height;
                    var preserveRatio = false;
                    var cropData = null;
                    if (this.dimensionField.getValue() == this.getValue().dimension) {
                        // load saved crop-values if not 0
                        if (this.getValue().cropData.width > 0 && this.getValue().cropData.height > 0) {
                            cropData = this.getValue().cropData;
                        }
                    }
                    var dimension = this.dimensions[this.dimensionField.getValue()];
                    if (dimension.height == 'user' && this.heightField.getValue() != '') {
                        height = this.heightField.getValue();
                    } else if (dimension.height >= 0) {
                        height = dimension.height;
                    } else {
                        Ext.Msg.alert(trlKwf('Error'), trlKwf('No height value was set'));
                        return;
                    }

                    if (dimension.width == 'user' && this.widthField.getValue() != '') {
                        width = this.widthField.getValue();
                    } else if (dimension.width == 'contentWidth') {
                        width = 0;
                    } else if (dimension.width >= 0) {
                        width = dimension.width;
                    } else {
                        Ext.Msg.alert(trlKwf('Error'), trlKwf('No width value was set'));
                        return;
                    }

                    if (dimension.bestfit == false) {
                        preserveRatio = true;
                    }

                    // call controller to create image with nice size to work with
                    var imageURL = '/kwf/media/upload/download-handy?uploadId='+this.imageData.uploadId+'&hashKey='+this.imageData.hashKey;

                    var cw = new Kwc.Abstract.Image.CropWindow({
                        imageUrl: imageURL,
                        preserveRatio: preserveRatio,
                        outWidth: width,
                        outHeight: height,
                        cropData: cropData,
                        buttons: [{
                            text: trlKwf('OK'),
                            handler: function() {
                                this.cropData = cw.cropData;
                                cw.close();
                            },
                            scope: this
                        },{
                            text: trlKwf('Cancel'),
                            handler: function() {
                                cw.close();
                            },
                            scope: this
                        }]
                    });
                    cw.show();
                },
                scope: this
            });

            this.dimensionField.on('change', function () {
                var dimension = this.dimensions[this.dimensionField.getValue()];
                if (dimension.width == 0 && dimension.height == 0) {
                    button.disable();
                } else {
                    button.enable();
                }
            }, this);

            this.sizeWindow = new Ext.Window({
                title: trlKwf('Image Size'),
                closeAction: 'hide',
                modal: true,
                width: 350,
                height: 350,
                layout: 'fit',
                items: new Ext.FormPanel({
                    bodyStyle: 'padding: 10px',
                    items: [
                        this.dimensionField,
                        {
                            xtype: 'fieldset',
                            autoHeight: true,
                            title: trlKwf('Size'),
                            items: [
                                this.widthField,
                                this.heightField
                            ]
                        },
                        button
                    ]
                }),
                buttons: [{
                    text: trlKwf('OK'),
                    handler: function() {
                        if (this._validateSizes()) {
                            this.sizeWindow.hide();
                            this.setValue({
                                dimension: this.dimensionField.getValue(),
                                width: this.widthField.getValue(),
                                height: this.heightField.getValue(),
                                cropData: this.cropData
                            });
                        } else {
                            Ext.Msg.alert(trlKwf('Error'), trlKwf('Please fill the marked fields correctly.'));
                        }
                    },
                    scope: this
                },{
                    text: trlKwf('Cancel'),
                    handler: function() {
                        this.sizeWindow.hide();
                    },
                    scope: this
                }]
            });
        }

        if (!this.imageData) {
            //TODO better way to find button in panel
            this.sizeWindow.items.items[0].items.items[2].disable();
        } else {
            this.sizeWindow.items.items[0].items.items[2].enable();
        }

        var v = this.getValue();
        if (v && v.dimension) {
            this.dimensionField.setValue(v.dimension);
            this.widthField.setValue(v.width);
            this.heightField.setValue(v.height);
        } else {
            for (var i in this.dimensions) {
                break;
            }
            this.dimensionField.setValue(i);
        }
        this._enableDisableFields();
        this.sizeWindow.show();

        this._validateSizes();
    },

    _enableDisableFields: function()
    {
        var dim = this.dimensions[this.dimensionField.getValue()];
        this.widthField.setDisabled(!(dim && dim.width == 'user'));
        this.heightField.setDisabled(!(dim && dim.height == 'user'));
    },

    _getDimensionString: function(v)
    {
        var ret;
        if (this.dimensions[v.dimension] && this.dimensions[v.dimension].text) {
            ret = this.dimensions[v.dimension].text;
        } else {
            ret = v.dimension;
        }
        if (this.dimensions[v.dimension]) {
            var d = this.dimensions[v.dimension];
            ret += ' (';
            if (d.width == 'user') {
                if (v.width) {
                    ret += String(v.width);
                } else {
                    ret += '?';
                }
            } else if (d.width) {
                ret += String(d.width);
            } else {
                ret += '?';
            }
            ret += 'x';
            if (d.height == 'user') {
                if (v.height) {
                    ret += String(v.height);
                } else {
                    ret += '?';
                }
            } else if (d.height) {
                ret += String(d.height);
            } else {
                ret += '?';
            }
            ret += ' ';
            if (d.bestfit) {
                ret += trlKwf('Bestfit');
            } else {
                ret += trlKwf('Crop');
            }
            ret = ret.trim() + ')';
        }
        return ret;
    }
});

Ext.reg('kwc.image.dimensionfield', Kwc.Abstract.Image.DimensionField);
<|endoftext|>


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

/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence logparser-js is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */

var argv = require('minimist')(process.argv.slice(2))
var prettyjson = require('prettyjson')
var LogAnalyzer = require('../lib/index.js')
var la = new LogAnalyzer(argv.f)
var readline = require('readline')
var begin = new Date().getTime()
var count = 0
var emptyLines = 0
var bytes = 0
var Logsene = require('logsene-js')
var Tail = require('tail-forever')
var fs = require('fs')
var glob = require('glob')
var globPattern = argv.g || process.env.GLOB_PATTERN
var logseneToken = argv.t || process.env.LOGSENE_TOKEN
var http = require('http')
var loggers = {}

process.on('beforeExit', function () {})
function getFilesizeInBytes (filename) {
  var stats = fs.statSync(filename)
  var fileSizeInBytes = stats['size']
  return fileSizeInBytes
}

function getSyslogServer (appToken, port, type) {
  // var logger = new Logsene(appToken, type || 'logs')
  var Syslogd = require('syslogd')
  var syslogd = Syslogd(function (sysLogMsg) {
    parseLine(sysLogMsg.msg, 'log', function (e, data) {
      data['severity'] = sysLogMsg.severity
      data['syslog-tag'] = sysLogMsg.tag
      data['facility'] = sysLogMsg.facility
      data['hostname'] = sysLogMsg.hostname
      data['@timestamp'] = sysLogMsg['time']
      log(e, data)
    })
  })
  syslogd.listen(port, function (err) {
    console.log('start syslog server ' + port + ' ' + (err || ''))
  })
  return syslogd
// this.servers[appToken] = syslogd
}

function getLogger (token, type) {
  var key = token + type
  // console.log(token)
  if (!loggers[key]) {
    var logger = new Logsene(token, type)
    logger.on('log', function (data) {
      // console.log(data)
    })
    logger.on('error', function (err) {
      console.error('Error in Logsene request:' + err.message)
    })
    loggers[key] = logger
  }
  return loggers[key]
}

function logToLogsene (token, type, data) {
  var logger = getLogger(token, type)
  logger.log(data.level || data.severity || 'info', data.message, data)
}

function getLoggerForToken (token, type) {
  return function (err, data) {
    if (!err && data) {
      log(err, msg)
      // delete data.ts
      // data['_type'] = type
      var msg = data
      if (type === 'heroku') {
        msg = {
          '@timestamp': new Date(),
          message: data.message,
          app: data.app,
          host: data.host,
          severity: data.severity,
          facility: data.facility
        }
      }
      logToLogsene(token, type, msg)
    }
  }
}

function herokuHandler (req, res) {
  var path = req.url.split('/')
  var token = null
  if (path.length>0)
  {
    token = path[1]
  }
  if (token === null)
  {
    return res.end('Error: Missing Logsene Token ' + req.url)
  }
  var body = ''
  req.on('data', function (data) {
    body += data
  })
  req.on('end', function () {
    var lines = body.split('\n')
    lines.forEach(function () {
      parseLine(body, argv.n || 'heroku', getLoggerForToken(token, 'heroku'))
    })
    res.end('ok\n')
  })
}

function cloudFoundryHandler (req, res) {
  var body = ''
  req.on('data', function (data) {
    body += data
  })
  req.on('end', function () {
    parseLine(body, argv.n || 'cloudfoundry', log)
    res.end('ok\n')
  })
}
function getHttpServer (port, handler) {
  var _port = port || process.env.PORT
  if (port === true) { // a commadn line flag was set but no port given
    _port = process.env.PORT
  }
  var server = http.createServer(handler)
  console.log('Logagent listening (http): ' + _port)
  return server.listen(_port)
}

function tailFile (file) {
  var tail = new Tail(file, {start: getFilesizeInBytes(file)})
  tail.on('line', function (line) {
    parseLine(line, file, log)
  })
  tail.on('error', function (error) {
    console.log('ERROR: ', error)
  })
  console.log('Watching file:' + file)
  return tail
}

function tailFiles (fileList) {
  fileList.forEach(tailFile)
}

function tailFilesFromGlob (globPattern) {
  if (globPattern) {
    glob(globPattern, function (err, files) {
      if (!err) {
        tailFiles(files)
      } else {
        console.error('Error in glob file patttern ' + globPattern + ': ' + err)
      }
    })
  }
}

function log (err, data) {
  if (err) {
    return
  }
  if (!data) {
    emptyLines++
    return
  }
  if (argv.t) {
    logToLogsene(argv.t || logseneToken, data['_type'] || argv.n || 'logs', data)
  }
  if (argv.s) {
    return
  }
  if (argv.p) {
    console.log(JSON.stringify(data, null, '\t'))
  } else if (argv.y) {
    console.log(prettyjson.render(data, {noColor: false}) + '\n')
  } else {
    console.log(JSON.stringify(data))
  }
}

function parseLine (line, sourceName, cbf) {
  bytes += line.length
  count++
  la.parseLine(line, argv.n || sourceName, cbf || log)
}

function readStdIn () {
  var rl = readline.createInterface({
    input: process.stdin
  })
  rl.on('line', parseLine)
  rl.on('close', terminate)
  rl.on('finish', terminate)
}

function terminate () {
  var duration = new Date().getTime() - begin
  var throughput = count / (duration / 1000)
  var throughputBytes = (bytes / 1024 / 1024) / (duration / 1000)

  if (argv.s) {
    console.error(duration + ' ms ' + count + ' lines parsed.  ' + throughput.toFixed(0) + ' lines/s ' + throughputBytes.toFixed(3) + ' MB/s - empty lines: ' + emptyLines)
    console.error('Heap Used: ' + (process.memoryUsage().heapUsed / (1024 * 1024)) + ' MB')
    console.error('Heap Total: ' + (process.memoryUsage().heapTotal / (1024 * 1024)) + ' MB')
    console.error('Memory RSS: ' + (process.memoryUsage().rss / (1024 * 1024)) + ' MB')
  }
  setTimeout(function () {
    console.log(Object.keys(loggers))
    Object.keys(loggers).forEach(function (l, i) {
      console.log('send ' + l)
      loggers[l].send()
    })
  }, 300)
  setTimeout(function () {
    console.log('Good Bye!!!')
    process.exit()
  }, 1000)
}
if (argv.cfhttp) {
  getHttpServer(argv.cfhttp, cloudFoundryHandler)
}
if (argv.heroku) {
  getHttpServer(argv.heroku, herokuHandler)
}
if (argv._.length > 0) {
  // tail files
  console.log(argv._)
  tailFiles(argv._)
} else if (globPattern) {
  // checks for file list and start tail for all files
  console.log('using glob pattern:' + globPattern)
  tailFilesFromGlob(globPattern)
} else if (argv.u) {
  try {
    getSyslogServer(logseneToken, argv.u)
  } catch (err) {
    console.error(err)
    process.exit(-1)
  }
} else {
  readStdIn()
}
<commit_msg>handle wrong urls<commit_after>#!/usr/bin/env node

/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence logparser-js is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */

var argv = require('minimist')(process.argv.slice(2))
var prettyjson = require('prettyjson')
var LogAnalyzer = require('../lib/index.js')
var la = new LogAnalyzer(argv.f)
var readline = require('readline')
var begin = new Date().getTime()
var count = 0
var emptyLines = 0
var bytes = 0
var Logsene = require('logsene-js')
var Tail = require('tail-forever')
var fs = require('fs')
var glob = require('glob')
var globPattern = argv.g || process.env.GLOB_PATTERN
var logseneToken = argv.t || process.env.LOGSENE_TOKEN
var http = require('http')
var loggers = {}

process.on('beforeExit', function () {})
function getFilesizeInBytes (filename) {
  var stats = fs.statSync(filename)
  var fileSizeInBytes = stats['size']
  return fileSizeInBytes
}

function getSyslogServer (appToken, port, type) {
  // var logger = new Logsene(appToken, type || 'logs')
  var Syslogd = require('syslogd')
  var syslogd = Syslogd(function (sysLogMsg) {
    parseLine(sysLogMsg.msg, 'log', function (e, data) {
      data['severity'] = sysLogMsg.severity
      data['syslog-tag'] = sysLogMsg.tag
      data['facility'] = sysLogMsg.facility
      data['hostname'] = sysLogMsg.hostname
      data['@timestamp'] = sysLogMsg['time']
      log(e, data)
    })
  })
  syslogd.listen(port, function (err) {
    console.log('start syslog server ' + port + ' ' + (err || ''))
  })
  return syslogd
// this.servers[appToken] = syslogd
}

function getLogger (token, type) {
  var key = token + type
  // console.log(token)
  if (!loggers[key]) {
    var logger = new Logsene(token, type)
    logger.on('log', function (data) {
      // console.log(data)
    })
    logger.on('error', function (err) {
      console.error('Error in Logsene request:' + err.message)
    })
    loggers[key] = logger
  }
  return loggers[key]
}

function logToLogsene (token, type, data) {
  var logger = getLogger(token, type)
  logger.log(data.level || data.severity || 'info', data.message, data)
}

function getLoggerForToken (token, type) {
  return function (err, data) {
    if (!err && data) {
      log(err, msg)
      // delete data.ts
      // data['_type'] = type
      var msg = data
      if (type === 'heroku') {
        msg = {
          '@timestamp': new Date(),
          message: data.message,
          app: data.app,
          host: data.host,
          severity: data.severity,
          facility: data.facility
        }
      }
      logToLogsene(token, type, msg)
    }
  }
}

function herokuHandler (req, res) {
  try {
    var path = req.url.split('/')
    var token = undefined
    if (path.length > 1) {
      if(path[1] && path[1].length>12)
      token = path[1]
    }
    console.log(token + '  path:' + path)
    if (!token) {
      res.end('Error: Missing Logsene Token ' + req.url)
      return
    }
    var body = ''
    req.on('data', function (data) {
      body += data
    })
    req.on('end', function () {
      var lines = body.split('\n')
      lines.forEach(function () {
        parseLine(body, argv.n || 'heroku', getLoggerForToken(token, 'heroku'))
      })
      res.end('ok\n')
    })
  } catch (err) {
    console.error(err)
  }
}

function cloudFoundryHandler (req, res) {
  var body = ''
  req.on('data', function (data) {
    body += data
  })
  req.on('end', function () {
    parseLine(body, argv.n || 'cloudfoundry', log)
    res.end('ok\n')
  })
}
function getHttpServer (port, handler) {
  var _port = port || process.env.PORT
  if (port === true) { // a commadn line flag was set but no port given
    _port = process.env.PORT
  }
  var server = http.createServer(handler)
  console.log('Logagent listening (http): ' + _port)
  return server.listen(_port)
}

function tailFile (file) {
  var tail = new Tail(file, {start: getFilesizeInBytes(file)})
  tail.on('line', function (line) {
    parseLine(line, file, log)
  })
  tail.on('error', function (error) {
    console.log('ERROR: ', error)
  })
  console.log('Watching file:' + file)
  return tail
}

function tailFiles (fileList) {
  fileList.forEach(tailFile)
}

function tailFilesFromGlob (globPattern) {
  if (globPattern) {
    glob(globPattern, function (err, files) {
      if (!err) {
        tailFiles(files)
      } else {
        console.error('Error in glob file patttern ' + globPattern + ': ' + err)
      }
    })
  }
}

function log (err, data) {
  if (err) {
    return
  }
  if (!data) {
    emptyLines++
    return
  }
  if (argv.t) {
    logToLogsene(argv.t || logseneToken, data['_type'] || argv.n || 'logs', data)
  }
  if (argv.s) {
    return
  }
  if (argv.p) {
    console.log(JSON.stringify(data, null, '\t'))
  } else if (argv.y) {
    console.log(prettyjson.render(data, {noColor: false}) + '\n')
  } else {
    console.log(JSON.stringify(data))
  }
}

function parseLine (line, sourceName, cbf) {
  bytes += line.length
  count++
  la.parseLine(line, argv.n || sourceName, cbf || log)
}

function readStdIn () {
  var rl = readline.createInterface({
    input: process.stdin
  })
  rl.on('line', parseLine)
  rl.on('close', terminate)
  rl.on('finish', terminate)
}

function terminate () {
  var duration = new Date().getTime() - begin
  var throughput = count / (duration / 1000)
  var throughputBytes = (bytes / 1024 / 1024) / (duration / 1000)

  if (argv.s) {
    console.error(duration + ' ms ' + count + ' lines parsed.  ' + throughput.toFixed(0) + ' lines/s ' + throughputBytes.toFixed(3) + ' MB/s - empty lines: ' + emptyLines)
    console.error('Heap Used: ' + (process.memoryUsage().heapUsed / (1024 * 1024)) + ' MB')
    console.error('Heap Total: ' + (process.memoryUsage().heapTotal / (1024 * 1024)) + ' MB')
    console.error('Memory RSS: ' + (process.memoryUsage().rss / (1024 * 1024)) + ' MB')
  }
  setTimeout(function () {
    console.log(Object.keys(loggers))
    Object.keys(loggers).forEach(function (l, i) {
      console.log('send ' + l)
      loggers[l].send()
    })
  }, 300)
  setTimeout(function () {
    console.log('Good Bye!!!')
    process.exit()
  }, 1000)
}
if (argv.cfhttp) {
  getHttpServer(argv.cfhttp, cloudFoundryHandler)
}
if (argv.heroku) {
  getHttpServer(argv.heroku, herokuHandler)
}
if (argv._.length > 0) {
  // tail files
  console.log(argv._)
  tailFiles(argv._)
} else if (globPattern) {
  // checks for file list and start tail for all files
  console.log('using glob pattern:' + globPattern)
  tailFilesFromGlob(globPattern)
} else if (argv.u) {
  try {
    getSyslogServer(logseneToken, argv.u)
  } catch (err) {
    console.error(err)
    process.exit(-1)
  }
} else {
  readStdIn()
}
<|endoftext|>