<commit_before>var dogeImgURL = '/doge.png';
var canvas = document.getElementById('canvas');
var lastCanvasData;

var dogeCanvas = require('./dogeCanvas')({
    callback: onDogeLoaded,
    imgURL: dogeImgURL,
    imageClass: Image,
    canvas: canvas
});

function prefillTextArea(lines){
    document.getElementById('textarea').value = lines.join('\n');
}

function onDogeLoaded(){
    if(providedLines.length) {
        writeAllDogeContent();
    }
}

prefillTextArea(providedLines);

$('#download').click(function(){
    var dataURL = canvas.toDataURL('image/jpeg');
    window.location.href = dataURL;
});

$('#wow').click(writeAllDogeContent);

function writeAllDogeContent(){
    var textLines = document.getElementById('textarea').value.split('\n');
    lastCanvasData = dogeCanvas.addLines(textLines);
}

$('#imgur').click(function uploadToImgur(){
    $.ajax({
        url: '/upload',
        type: 'POST',
        headers: {
            Accept: 'application/json'
        },
        data: {
            data: lastCanvasData
        },
        success: function(result) {
            // console.log('Image uploaded at ' + result.link + '. Delete hash: ' + result.deletehash);
            window.location.href = result.link;
        }
    });
});

$('.share').click(function(){
    var popup = {
            width: 500,
            height: 350
        },
        sharedUrl = 'http://www.dogr.io',
        sharedMsg = 'wow. much doge. such generator.',
        popupUrl,
        openOptions;

    popup.top = (screen.height/2) - (popup.height/2);
    popup.left = (screen.width/2) - (popup.width/2);

    openOptions = [
        "toolbar=no",
        "location=no",
        "status=no",
        "menubar=no",
        "scrollbars=yes",
        "resizable=yes",
        "left=" + popup.left,
        "top=" + popup.top,
        "width=" + popup.width,
        "height=" + popup.height
    ].join(',');

    if ($(this).is('.facebook')) {
        popupUrl = 'https://www.facebook.com/sharer/sharer.php?u=' + sharedUrl;
    } else if ($(this).is('.twitter')) {
        popupUrl = 'http://twitter.com/intent/tweet?text=' + sharedMsg + '&url=' + sharedUrl;
    } else if ($(this).is('.google-plus')) {
        popupUrl = 'https://plus.google.com/share?url=' + sharedUrl;
    }

    window.open(popupUrl, 'targetWindow', openOptions);
});<commit_msg>Wow such track. Very marketing doge.<commit_after>var dogeImgURL = '/doge.png';
var canvas = document.getElementById('canvas');
var lastCanvasData;

var dogeCanvas = require('./dogeCanvas')({
    callback: onDogeLoaded,
    imgURL: dogeImgURL,
    imageClass: Image,
    canvas: canvas
});

function prefillTextArea(lines){
    document.getElementById('textarea').value = lines.join('\n');
}

function onDogeLoaded(){
    if(providedLines.length) {
        writeAllDogeContent();
    }
}

prefillTextArea(providedLines);

$('#download').click(function(){
    var dataURL = canvas.toDataURL('image/jpeg');
    window.location.href = dataURL;
});

$('#wow').click(writeAllDogeContent);

function writeAllDogeContent(){
    var textLines = document.getElementById('textarea').value.split('\n');
    lastCanvasData = dogeCanvas.addLines(textLines);
}

$('#imgur').click(function uploadToImgur(){
    $.ajax({
        url: '/upload',
        type: 'POST',
        headers: {
            Accept: 'application/json'
        },
        data: {
            data: lastCanvasData
        },
        success: function(result) {
            // console.log('Image uploaded at ' + result.link + '. Delete hash: ' + result.deletehash);
            window.location.href = result.link;
        }
    });
});

$('.share').click(function(){
    var popup = {
            width: 500,
            height: 350
        },
        sharedUrl = 'http://www.dogr.io',
        sharedMsg = 'wow. much doge. such generator.',
        popupUrl,
        openOptions,
        shareType;

    popup.top = (screen.height/2) - (popup.height/2);
    popup.left = (screen.width/2) - (popup.width/2);

    openOptions = [
        "toolbar=no",
        "location=no",
        "status=no",
        "menubar=no",
        "scrollbars=yes",
        "resizable=yes",
        "left=" + popup.left,
        "top=" + popup.top,
        "width=" + popup.width,
        "height=" + popup.height
    ].join(',');

    if ($(this).is('.facebook')) {
        popupUrl = 'https://www.facebook.com/sharer/sharer.php?u=' + sharedUrl;
        shareType = 'facebook';
    } else if ($(this).is('.twitter')) {
        popupUrl = 'http://twitter.com/intent/tweet?text=' + sharedMsg + '&url=' + sharedUrl;
        shareType = 'twitter';
    } else if ($(this).is('.google-plus')) {
        popupUrl = 'https://plus.google.com/share?url=' + sharedUrl;
        shareType = 'google-plus';
    }

    window.open(popupUrl, 'targetWindow', openOptions);

    ga('send', 'event', 'share-button', 'click', shareType, popupUrl);
});<|endoftext|>


<commit_before>// Please visit http://go.microsoft.com/fwlink/?LinkID=761099&clcid=0x409 for more information on settting up Github Webhooks
var Bitly = require('bitly');
var bitly = new Bitly(process.env.bitly_token);
var Twitter = require('twitter');
var client = new Twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});

module.exports = function (context, data) {
    context.log('GitHub Webhook triggered!');
    var notifications = data.commits.map(commit => {
        if (!commit.message.startsWith("New post:")) {
            return;
        }
        return new Promise((resolved, rejected) => {
            let file = commit.added.filter(file => file.endsWith(".md"))[0];
            let filearray = file.match(/(\d{4})-(\d{2})-(\d{2})-(.*).md/i);
            let year = filearray[1];
            let month = filearray[2];
            let day = filearray[3]
            let title = filearray[4];
            var urlpath = title.replace(/\s/g, "-");
            let message = commit.message.match(/New post: (.*)/i)[1]

            var model = {
                url: `https://udbjorg.net/${year}/${urlpath}`,
                message: message
            };

            bitly.shorten(model.url)
                .then(function (response) {
                    model.shortUrl = response.data.url;
                    context.log(model);
                    return resolved(model)
                }, function (error) {
                    rejected(error);
                });
        });
    });

    Promise.all(notifications).then(values => {
        context.log(values);
        var model = values[0];
        client.post('statuses/update', { status: `${model.message} ${model.shortUrl}` }, function (error, tweet, response) {
            if (error) {
                throw error;
            }

            console.log(tweet);  // Tweet body.
            console.log(response);  // Raw response object.
        });

        context.res = { body: 'New GitHub comment: ' };
        context.done();
    });

};<commit_msg>updates<commit_after>// Please visit http://go.microsoft.com/fwlink/?LinkID=761099&clcid=0x409 for more information on settting up Github Webhooks
var Bitly = require('bitly');
var bitly = new Bitly(process.env.bitly_token);
var Twitter = require('twitter');
var client = new Twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});

module.exports = function (context, data) {
    context.log('GitHub Webhook triggered!');
    var notifications = data.commits.map(commit => {
        if (!commit.message.startsWith("New post:")) {
            return;
        }
        return new Promise((resolved, rejected) => {
            let file = commit.added.filter(file => file.endsWith(".md"))[0];
            let filearray = file.match(/(\d{4})-(\d{2})-(\d{2})-(.*).md/i);
            let year = filearray[1];
            let month = filearray[2];
            let day = filearray[3]
            let title = filearray[4];
            var urlpath = title.replace(/\s/g, "-");
            let message = commit.message.match(/New post: (.*)/i)[1]

            var model = {
                url: `https://udbjorg.net/${year}/${urlpath}`,
                message: message
            };

            bitly.shorten(model.url)
                .then(function (response) {
                    model.shortUrl = response.data.url;
                    context.log(model);
                    return resolved(model)
                }, function (error) {
                    rejected(error);
                });
        });
    });

    Promise.all(notifications).then(values => {
        context.log(values);
        var model = values[0];
        client.post('statuses/update', { status: `${model.message} ${model.shortUrl}` }, function (error, tweet, response) {
            if (error) {
                throw error;
            }

            context.log(tweet);  // Tweet body.
            context.log(response);  // Raw response object.
        });

        context.res = { body: 'New GitHub comment: ' };
        context.done();
    });

};<|endoftext|>


<commit_before>/**
 * Base component for a field option
 */
/* exported optionMixin */

var optionMixin = {

  props: ['option', 'name', 'value'],

  data: function () {
    return {
      // Default value from the api
      data: this.option.options.data
    };
  },

  /**
   * Update the value on component creation
   */
  created: function () {
    if (typeof this.value !== 'undefined') {
      this.data = this.value;
      if (typeof this.value !== 'string') {
        this.data = JSON.stringify(this.value);
      }
    }
  },

  /**
   * Update the value on component update
   */
  watch: {
    value: {
      handler: function (value) {
        if (typeof value !== 'undefined') {
          this.data = value;
          if (typeof value !== 'string') {
            this.data = JSON.stringify(value);
          }
        }
      }
    }
  },

  methods: {

    /**
     * Update an option value for the raw
     *
     * @param value
     */
    updateOption: function (value) {
      if (typeof value !== 'undefined') {
        this.data = value;
        this.$emit('changed', {
          name: this.name,
          value: value
        });
      }
    }
  }
};
<commit_msg>Only attempt to parse in json if of type object<commit_after>/**
 * Base component for a field option
 */
/* exported optionMixin */

var optionMixin = {

  props: ['option', 'name', 'value'],

  data: function () {
    return {
      // Default value from the api
      data: this.option.options.data
    };
  },

  /**
   * Update the value on component creation
   */
  created: function () {
    if (typeof this.value !== 'undefined') {
      this.data = this.value;
      if (typeof this.value === 'object') {
        this.data = JSON.stringify(this.value);
      }
    }
  },

  /**
   * Update the value on component update
   */
  watch: {
    value: {
      handler: function (value) {
        if (typeof value !== 'undefined') {
          this.data = value;
          if (typeof value === 'object') {
            this.data = JSON.stringify(value);
          }
        }
      }
    }
  },

  methods: {

    /**
     * Update an option value for the raw
     *
     * @param value
     */
    updateOption: function (value) {
      if (typeof value !== 'undefined') {
        this.data = value;
        this.$emit('changed', {
          name: this.name,
          value: value
        });
      }
    }
  }
};
<|endoftext|>


<commit_before>import React from 'react';

export default function Tooltip(props) {
  return (
    <div
      className="vx-tooltip-portal"
      style={{
        position: 'absolute',
        top: props.top,
        left: props.left,
        backgroundColor: 'white',
        color: '#666666',
        padding: '.3rem .5rem',
        borderRadius: '3px',
        fontSize: '14px',
        boxShadow: '0 1px 2px rgba(33,33,33,0.2)',
        lineHeight: '1em',
        pointerEvents: 'none',
        ...props.style
      }}
    >
      {props.children}
    </div>
  );
}
<commit_msg>[tooltip] add classnames, rest props<commit_after>import React from 'react';
import cx from 'classnames';

export default function Tooltip(props) {
  const { className, ...restProps } = props;
  return (
    <div
      className={cx('vx-tooltip-portal', className)}
      style={{
        position: 'absolute',
        top: props.top,
        left: props.left,
        backgroundColor: 'white',
        color: '#666666',
        padding: '.3rem .5rem',
        borderRadius: '3px',
        fontSize: '14px',
        boxShadow: '0 1px 2px rgba(33,33,33,0.2)',
        lineHeight: '1em',
        pointerEvents: 'none',
        ...restProps,
      }}
    >
      {props.children}
    </div>
  );
}
<|endoftext|>


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

/**
 * @fileoverview Definitions for all the extensions over W3C's DOM
 *  specification by WebKit. This file depends on w3c_dom2.js.
 *  All the provided definitions has been type annotated
 *
 * @externs
 */

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.cpp
 */
function MemoryInfo() {};

/** @type {number} */
MemoryInfo.prototype.totalJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.usedJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.jsHeapSizeLimit;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfileNode.idl
 */
function ScriptProfileNode() {};

/** @type {string} */
ScriptProfileNode.prototype.functionName;

/** @type {string} */
ScriptProfileNode.prototype.url;

/** @type {number} */
ScriptProfileNode.prototype.lineNumber;

/** @type {number} */
ScriptProfileNode.prototype.totalTime;

/** @type {number} */
ScriptProfileNode.prototype.selfTime;

/** @type {number} */
ScriptProfileNode.prototype.numberOfCalls;

/** @type {Array.<ScriptProfileNode>} */
ScriptProfileNode.prototype.children;

/** @type {boolean} */
ScriptProfileNode.prototype.visible;

/** @type {number} */
ScriptProfileNode.prototype.callUID;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfile.idl
 */
function ScriptProfile() {};

/** @type {string} */
ScriptProfile.prototype.title;

/** @type {number} */
ScriptProfile.prototype.uid;

/** @type {ScriptProfileNode} */
ScriptProfile.prototype.head;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.cpp
 */
function Console() {};

/**
 * @param {*} condition
 * @param {...*} var_args
 */
Console.prototype.assert = function(condition, var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.error = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.info = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.log = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.warn = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.debug = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.dir = function(value) {};

/**
 * @param {...*} var_args
 */
Console.prototype.dirxml = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.trace = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.count = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.markTimeline = function(value) {};

/**
 * @param {string=} opt_title
 */
Console.prototype.profile = function(opt_title) {};

/** @type {Array.<ScriptProfile>} */
Console.prototype.profiles;

Console.prototype.profileEnd = function() {};

/**
 * @param {string} name
 */
Console.prototype.time = function(name) {};

/**
 * @param {string} name
 */
Console.prototype.timeEnd = function(name) {};

/**
 * @param {*} value
 */
Console.prototype.timeStamp = function(value) {};

Console.prototype.group = function() {};

Console.prototype.groupEnd = function() {};

/** @type {MemoryInfo} */
Console.prototype.memory;

/** @type {Console} */
Window.prototype.console;

/**
 * @type {number}
 * @see http://developer.android.com/reference/android/webkit/WebView.html
 */
Window.prototype.devicePixelRatio;

/** @type {Node} */
Selection.prototype.baseNode;

/** @type {number} */
Selection.prototype.baseOffset;

/** @type {Node} */
Selection.prototype.extentNode;

/** @type {number} */
Selection.prototype.extentOffset;

/** @type {string} */
Selection.prototype.type;

/**
 * @return {undefined}
 */
Selection.prototype.empty = function() {};

/**
 * @param {Node} baseNode
 * @param {number} baseOffset
 * @param {Node} extentNode
 * @param {number} extentOffset
 * @return {undefined}
 */
Selection.prototype.setBaseAndExtent =
 function(baseNode, baseOffset, extentNode, extentOffset) {};

/**
 * @param {string} alter
 * @param {string} direction
 * @param {string} granularity
 * @return {undefined}
 */
Selection.prototype.modify = function(alter, direction, granularity) {};

/**
 * @param {Element} element
 * @param {string} pseudoElement
 * @param {boolean=} opt_authorOnly
 * @return {CSSRuleList}
 * @nosideeffects
 */
ViewCSS.prototype.getMatchedCSSRules =
    function(element, pseudoElement, opt_authorOnly) {};

/**
 * @param {string} contextId
 * @param {string} name
 * @param {number} width
 * @param {number} height
 * @nosideeffects
 */
Document.prototype.getCSSCanvasContext =
    function(contextId, name, width, height) {};

/**
 * @type {string}
 * @see http://code.google.com/chrome/whitepapers/pagevisibility.html
 */
Document.prototype.webkitVisibilityState;
<commit_msg><commit_after>/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Definitions for all the extensions over W3C's DOM
 *  specification by WebKit. This file depends on w3c_dom2.js.
 *  All the provided definitions has been type annotated
 *
 * @externs
 */

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/MemoryInfo.cpp
 */
function MemoryInfo() {};

/** @type {number} */
MemoryInfo.prototype.totalJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.usedJSHeapSize;

/** @type {number} */
MemoryInfo.prototype.jsHeapSizeLimit;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfileNode.idl
 */
function ScriptProfileNode() {};

/** @type {string} */
ScriptProfileNode.prototype.functionName;

/** @type {string} */
ScriptProfileNode.prototype.url;

/** @type {number} */
ScriptProfileNode.prototype.lineNumber;

/** @type {number} */
ScriptProfileNode.prototype.totalTime;

/** @type {number} */
ScriptProfileNode.prototype.selfTime;

/** @type {number} */
ScriptProfileNode.prototype.numberOfCalls;

/** @type {Array.<ScriptProfileNode>} */
ScriptProfileNode.prototype.children;

/** @type {boolean} */
ScriptProfileNode.prototype.visible;

/** @type {number} */
ScriptProfileNode.prototype.callUID;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/inspector/ScriptProfile.idl
 */
function ScriptProfile() {};

/** @type {string} */
ScriptProfile.prototype.title;

/** @type {number} */
ScriptProfile.prototype.uid;

/** @type {ScriptProfileNode} */
ScriptProfile.prototype.head;

/**
 * @constructor
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.idl
 * @see http://trac.webkit.org/browser/trunk/Source/WebCore/page/Console.cpp
 */
function Console() {};

/**
 * @param {*} condition
 * @param {...*} var_args
 */
Console.prototype.assert = function(condition, var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.error = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.info = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.log = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.warn = function(var_args) {};

/**
 * @param {...*} var_args
 */
Console.prototype.debug = function(var_args) {};

/**
 * @param {*} value
 */
Console.prototype.dir = function(value) {};

/**
 * @param {...*} var_args
 */
Console.prototype.dirxml = function(var_args) {};

/**
 * @return {undefined}
 */
Console.prototype.trace = function() {};

/**
 * @param {*} value
 */
Console.prototype.count = function(value) {};

/**
 * @param {*} value
 */
Console.prototype.markTimeline = function(value) {};

/**
 * @param {string=} opt_title
 */
Console.prototype.profile = function(opt_title) {};

/** @type {Array.<ScriptProfile>} */
Console.prototype.profiles;

Console.prototype.profileEnd = function() {};

/**
 * @param {string} name
 */
Console.prototype.time = function(name) {};

/**
 * @param {string} name
 */
Console.prototype.timeEnd = function(name) {};

/**
 * @param {*} value
 */
Console.prototype.timeStamp = function(value) {};

Console.prototype.group = function() {};

Console.prototype.groupEnd = function() {};

/** @type {MemoryInfo} */
Console.prototype.memory;

/** @type {Console} */
Window.prototype.console;

/**
 * @type {number}
 * @see http://developer.android.com/reference/android/webkit/WebView.html
 */
Window.prototype.devicePixelRatio;

/** @type {Node} */
Selection.prototype.baseNode;

/** @type {number} */
Selection.prototype.baseOffset;

/** @type {Node} */
Selection.prototype.extentNode;

/** @type {number} */
Selection.prototype.extentOffset;

/** @type {string} */
Selection.prototype.type;

/**
 * @return {undefined}
 */
Selection.prototype.empty = function() {};

/**
 * @param {Node} baseNode
 * @param {number} baseOffset
 * @param {Node} extentNode
 * @param {number} extentOffset
 * @return {undefined}
 */
Selection.prototype.setBaseAndExtent =
 function(baseNode, baseOffset, extentNode, extentOffset) {};

/**
 * @param {string} alter
 * @param {string} direction
 * @param {string} granularity
 * @return {undefined}
 */
Selection.prototype.modify = function(alter, direction, granularity) {};

/**
 * @param {Element} element
 * @param {string} pseudoElement
 * @param {boolean=} opt_authorOnly
 * @return {CSSRuleList}
 * @nosideeffects
 */
ViewCSS.prototype.getMatchedCSSRules =
    function(element, pseudoElement, opt_authorOnly) {};

/**
 * @param {string} contextId
 * @param {string} name
 * @param {number} width
 * @param {number} height
 * @nosideeffects
 */
Document.prototype.getCSSCanvasContext =
    function(contextId, name, width, height) {};

/**
 * @type {string}
 * @see http://code.google.com/chrome/whitepapers/pagevisibility.html
 */
Document.prototype.webkitVisibilityState;
<|endoftext|>


<commit_before>if (cbio === undefined)
{
	var cbio = {};
}

/**
 * Singleton utility class for download related tasks.
 *
 * @author Selcuk Onur Sumer
 */
cbio.download = (function() {

	// Default client-side download options
	var _defaultOpts = {
		filename: "download.svg", // download file name
		contentType: "application/svg+xml", // download data type,
		dataType: null,      // servlet data type
		servletName: null,   // name of the data/conversion servlet (optional)
		servletParams: null, // servlet parameters (optional)
		preProcess: addSvgHeader,   // pre-process function for the provided data
		postProcess: cbio.util.b64ToByteArrays // post-process function for the data returned by the server (optional)
	};

	/**
	 * Submits the download form.
	 * This will send a request to the server.
	 *
	 * @param servletName       name of the action servlet
	 * @param servletParams     params to send with the form submit
	 * @param form              jQuery selector for the download form
	 */
	function submitDownload(servletName, servletParams, form)
	{
		// remove all previous input fields (if any)
		$(form).find("input").remove();

		// add new input fields
		for (var name in servletParams)
		{
			var value = servletParams[name];
			$(form).append('<input type="hidden" name="' + name + '">');
			$(form).find('input[name="' + name + '"]').val(value);
		}

		// update target servlet for the action
		$(form).attr("action", servletName);
		// submit the form
		$(form).submit();
	}

	/**
	 * Sends a download request to the hidden frame dedicated to file download.
	 *
	 * This function is implemented as a workaround to prevent JSmol crash
	 * due to window.location change after a download request.
	 *
	 * @param servletName
	 * @param servletParams
	 */
	function requestDownload(servletName, servletParams)
	{
		// TODO this is a workaround, frame download doesn't work for IE
		if (cbio.util.browser.msie)
		{
			initDownloadForm();
			submitDownload(servletName, servletParams, "#global_file_download_form");
			return;
		}

		initDownloadFrame(function() {
			var targetWindow = cbio.util.getTargetWindow("global_file_download_frame");

			targetWindow.postMessage(
				{servletName: servletName,
					servletParams: servletParams},
				getOrigin());
		});
	}

	/**
	 * Initializes the hidden download frame for the entire document.
	 * This is to isolate download requests from the main window.
	 */
	function initDownloadFrame(callback)
	{
		var frame = '' +
		            '';

		// only initialize if the frame doesn't exist
		if ($("#global_file_download_frame").length === 0)
		{
			$(document.body).append(frame);

			// TODO a workaround to enable target frame to get ready to listen messages
			setTimeout(callback, 500);
		}
		else
		{
			callback();
		}
	}

	/**
	 * This form is initialized only for IE
	 */
	function initDownloadForm()
	{
		var form = '<form id="global_file_download_form"' +
		           'style="display:inline-block"' +
		           'action="" method="post" target="_blank">' +
		           '</form>';

		// only initialize if the form doesn't exist
		if ($("#global_file_download_form").length === 0)
		{
			$(document.body).append(form);
		}
	}

	/**
	 * Initiates a client side download for the given content array.
	 *
	 * @param content   data array to download
	 * @param filename  download file name
	 * @param type      download type
	 */
	function clientSideDownload(content, filename, type)
	{
		if (type == null)
		{
			// text by default
			type = "text/plain;charset=utf-8"
		}

		if (filename == null)
		{
			filename = "download.txt";
		}

		var blob = new Blob(content, {type: type});

		saveAs(blob, filename);
	}

	/**
	 * Serializes the given html element into a string.
	 *
	 * @param element       html element
	 * @returns {string}    serialized string
	 */
	function serializeHtml(element)
	{
		// convert html element to string
		var xmlSerializer = new XMLSerializer();
		return xmlSerializer.serializeToString(element);
	}

	/**
	 * Adds missing xml and svg headers to the provided svg string
	 *
	 * @param xml   xml as a string
	 * @returns {string}    new xml string with additional headers
	 */
	function addSvgHeader(xml)
	{
		var xmlHeader = "<?xml version='1.0'?>";
		var svg = xmlHeader + xml;

		if(svg.indexOf("svg xmlns") == -1)
		{
			svg = svg.replace(
				"<svg", "<svg xmlns='http://www.w3.org/2000/svg' version='1.1'");
		}

		return svg;
	}

	/**
	 * Initializes a client side download for the given content.
	 *
	 * @param content   data content, either string or DOM element
	 * @param options   download options (see _defaultOpts)
	 */
	function initDownload(content, options)
	{
		options = jQuery.extend(true, {}, _defaultOpts, options);

		// try to serialize only if content is not string...
		if (!_.isString(content))
		{
			content = serializeHtml(content);
		}

		if (_.isFunction(options.preProcess))
		{
			content = options.preProcess(content);
		}

		if (options.contentType.toLowerCase().indexOf("pdf") != -1)
		{
			// if no servlet params provided, use default ones for pdf...
			options.servletParams = options.servletParams || {
				filetype: "pdf_data",
				svgelement: content
			};
		}

		// check if a servlet name provided
		if (options.servletName != null)
		{
			$.ajax({url: options.servletName,
					type: "POST",
					data: options.servletParams,
					dataType: options.dataType,
					success: function(servletData){
						var downloadData = servletData;

						if (_.isFunction(options.postProcess))
						{
							downloadData = options.postProcess(servletData);
						}

						clientSideDownload(downloadData, options.filename, options.contentType);
					}
			});
		}
		else
		{
			clientSideDownload([content], options.filename, options.contentType);
		}
	}

    return {
	    submitDownload: submitDownload,
	    requestDownload: requestDownload,
	    clientSideDownload: clientSideDownload,
	    initDownload: initDownload,
	    serializeHtml: serializeHtml,
	    addSvgHeader: addSvgHeader
    };
})();
<commit_msg>minor improvement for the client side download library<commit_after>if (cbio === undefined)
{
	var cbio = {};
}

/**
 * Singleton utility class for download related tasks.
 *
 * @author Selcuk Onur Sumer
 */
cbio.download = (function() {

	// Default client-side download options
	var _defaultOpts = {
		filename: "download.svg", // download file name
		contentType: "application/svg+xml", // download data type,
		dataType: null,      // servlet data type
		servletName: null,   // name of the data/conversion servlet (optional)
		servletParams: null, // servlet parameters (optional)
		preProcess: addSvgHeader,   // pre-process function for the provided data
		postProcess: cbio.util.b64ToByteArrays // post-process function for the data returned by the server (optional)
	};

	/**
	 * Submits the download form.
	 * This will send a request to the server.
	 *
	 * @param servletName       name of the action servlet
	 * @param servletParams     params to send with the form submit
	 * @param form              jQuery selector for the download form
	 */
	function submitDownload(servletName, servletParams, form)
	{
		// remove all previous input fields (if any)
		$(form).find("input").remove();

		// add new input fields
		for (var name in servletParams)
		{
			var value = servletParams[name];
			$(form).append('<input type="hidden" name="' + name + '">');
			$(form).find('input[name="' + name + '"]').val(value);
		}

		// update target servlet for the action
		$(form).attr("action", servletName);
		// submit the form
		$(form).submit();
	}

	/**
	 * Sends a download request to the hidden frame dedicated to file download.
	 *
	 * This function is implemented as a workaround to prevent JSmol crash
	 * due to window.location change after a download request.
	 *
	 * @param servletName
	 * @param servletParams
	 */
	function requestDownload(servletName, servletParams)
	{
		// TODO this is a workaround, frame download doesn't work for IE
		if (cbio.util.browser.msie)
		{
			initDownloadForm();
			submitDownload(servletName, servletParams, "#global_file_download_form");
			return;
		}

		initDownloadFrame(function() {
			var targetWindow = cbio.util.getTargetWindow("global_file_download_frame");

			targetWindow.postMessage(
				{servletName: servletName,
					servletParams: servletParams},
				getOrigin());
		});
	}

	/**
	 * Initializes the hidden download frame for the entire document.
	 * This is to isolate download requests from the main window.
	 */
	function initDownloadFrame(callback)
	{
		var frame = '' +
		            '';

		// only initialize if the frame doesn't exist
		if ($("#global_file_download_frame").length === 0)
		{
			$(document.body).append(frame);

			// TODO a workaround to enable target frame to get ready to listen messages
			setTimeout(callback, 500);
		}
		else
		{
			callback();
		}
	}

	/**
	 * This form is initialized only for IE
	 */
	function initDownloadForm()
	{
		var form = '<form id="global_file_download_form"' +
		           'style="display:inline-block"' +
		           'action="" method="post" target="_blank">' +
		           '</form>';

		// only initialize if the form doesn't exist
		if ($("#global_file_download_form").length === 0)
		{
			$(document.body).append(form);
		}
	}

	/**
	 * Initiates a client side download for the given content array.
	 *
	 * @param content   data array to download
	 * @param filename  download file name
	 * @param type      download type
	 */
	function clientSideDownload(content, filename, type)
	{
		if (type == null)
		{
			// text by default
			type = "text/plain;charset=utf-8"
		}

		if (filename == null)
		{
			filename = "download.txt";
		}

		var blob = new Blob(content, {type: type});

		saveAs(blob, filename);
	}

	/**
	 * Serializes the given html element into a string.
	 *
	 * @param element       html element
	 * @returns {string}    serialized string
	 */
	function serializeHtml(element)
	{
		// convert html element to string
		var xmlSerializer = new XMLSerializer();
		return xmlSerializer.serializeToString(element);
	}

	/**
	 * Adds missing xml and svg headers to the provided svg string
	 *
	 * @param xml   xml as a string
	 * @returns {string}    new xml string with additional headers
	 */
	function addSvgHeader(xml)
	{
		var svg = xml;

		var xmlHeader = "<?xml version='1.0'?>";
		var xmlVersion = "<?xml version=";

		// add xml header if not exist
		if(svg.indexOf(xmlVersion) == -1)
		{
			svg = xmlHeader + xml;
		}

		// add svg header if not exist
		if(svg.indexOf("svg xmlns") == -1)
		{
			svg = svg.replace(
				"<svg", "<svg xmlns='http://www.w3.org/2000/svg' version='1.1'");
		}

		return svg;
	}

	/**
	 * Initializes a client side download for the given content.
	 *
	 * @param content   data content, either string or DOM element
	 * @param options   download options (see _defaultOpts)
	 */
	function initDownload(content, options)
	{
		options = jQuery.extend(true, {}, _defaultOpts, options);

		// try to serialize only if content is not string...
		if (!_.isString(content))
		{
			content = serializeHtml(content);
		}

		if (_.isFunction(options.preProcess))
		{
			content = options.preProcess(content);
		}

		if (options.contentType.toLowerCase().indexOf("pdf") != -1)
		{
			// if no servlet params provided, use default ones for pdf...
			options.servletParams = options.servletParams || {
				filetype: "pdf_data",
				svgelement: content
			};
		}

		// check if a servlet name provided
		if (options.servletName != null)
		{
			$.ajax({url: options.servletName,
					type: "POST",
					data: options.servletParams,
					dataType: options.dataType,
					success: function(servletData){
						var downloadData = servletData;

						if (_.isFunction(options.postProcess))
						{
							downloadData = options.postProcess(servletData);
						}

						clientSideDownload(downloadData, options.filename, options.contentType);
					}
			});
		}
		else
		{
			clientSideDownload([content], options.filename, options.contentType);
		}
	}

    return {
	    submitDownload: submitDownload,
	    requestDownload: requestDownload,
	    clientSideDownload: clientSideDownload,
	    initDownload: initDownload,
	    serializeHtml: serializeHtml,
	    addSvgHeader: addSvgHeader
    };
})();
<|endoftext|>


<commit_before>var fibonacci = require ('fibonacci');

// Return last result object
fibonacci.on ('done', console.log);

// Run 1000 iterations
fibonacci.iterate (1000);
<commit_msg>Chore(example): Replace var with const<commit_after>const fibonacci = require ('fibonacci');

// Return last result object
fibonacci.on ('done', console.log);

// Run 1000 iterations
fibonacci.iterate (1000);
<|endoftext|>


<commit_before>import React from 'react';
import { interpolate } from 'd3-interpolate';
import * as Easing from 'd3-ease';

class Motion extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.move = this.move.bind(this);
        this.state = {items: []};
    }
    componentWillReceiveProps() {
        if (!this.moveId)
            this.moveId = requestAnimationFrame(this.move);
    }
    componentDidMount() {
        this.moveId = requestAnimationFrame(this.move)
    }
    componentWillUnmount() {
        cancelAnimationFrame(this.moveId);
    }
    move() {
        this.setState(({items: prevItems}) => {
            var {data, enter, leave, update, getKey, duration, easing, onRest} = this.props;
            var tick = performance.now();
            var dataByKey = data.reduce((acc, item) => ({...acc, [getKey(item)]: item}), {});
            var itemsByKey = prevItems.reduce((acc, item) => ({...acc, [item.key]: item}), {});
            var items = prevItems
                .map(item => {
                    var nextItem = {key: item.key, data: item.data, tick};
                    nextItem.end = !dataByKey[item.key] ? leave(item.data) : update(dataByKey[item.key]);
                    var unchanged = this.areEqual(item.end, nextItem.end);
                    if (unchanged) {
                        nextItem.start = item.start;
                        nextItem.rest = item.progress === 1;
                        var progressDelta = (nextItem.tick - item.tick) / duration(item.data);
                        nextItem.progress = Math.min(item.progress + progressDelta, 1);
                        nextItem.interpolators = item.interpolators;
                    } else {
                        nextItem.rest = false;
                        var reverse = !unchanged && this.areEqual(item.start, nextItem.end);
                        nextItem.start = reverse ? item.end : item.style;
                        nextItem.progress = reverse ? 1 - item.progress : 0;
                        nextItem.interpolators = this.getInterpolators(nextItem);
                    }
                    nextItem.style = this.interpolateStyle(nextItem, easing(item.data));
                    if (onRest && nextItem.rest && !item.rest) {
                        onRest(item.data);
                    }
                    return nextItem;
                })
                .filter(item => !item.rest || dataByKey[item.key])
                .concat(data
                    .filter(item => !itemsByKey[getKey(item)])
                    .map(item => {
                        var newItem = {key: getKey(item), data: item, progress: 0, tick, rest: false};
                        newItem.start = newItem.style = enter(item);
                        newItem.end = update(item);
                        newItem.interpolators = this.getInterpolators(newItem);
                        return newItem;
                    })
                );
            this.moveId = null;
            if (items.filter(({rest}) => !rest).length !== 0)
                this.moveId = requestAnimationFrame(this.move);
            return {items};
        })
    }
    areEqual(from, to) {
        if (Object.keys(from).length !== Object.keys(to).length)
            return false;
        for(var key in from) {
            if (from[key] !== to[key])
                return false;
        }
        return true;
    }
    getInterpolators({start, end}) {
        var interpolators = {};
        for(var key in start)
            interpolators[key] = interpolate(start[key], end[key]);
        return interpolators;
    }
    interpolateStyle({interpolators, end, progress}, easing) {
        var style = {};
        for(var key in end)
            style[key] = interpolators[key](Easing[easing](progress))
        return style;
    }
    render() {
        return this.props.children(this.state.items);
    }
}

export default Motion;
<commit_msg>Tweaked format<commit_after>import React from 'react';
import { interpolate } from 'd3-interpolate';
import * as Easing from 'd3-ease';

class Motion extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.move = this.move.bind(this);
        this.state = {items: []};
    }
    componentWillReceiveProps() {
        if (!this.moveId)
            this.moveId = requestAnimationFrame(this.move);
    }
    componentDidMount() {
        this.moveId = requestAnimationFrame(this.move)
    }
    componentWillUnmount() {
        cancelAnimationFrame(this.moveId);
    }
    move() {
        this.setState(({items: prevItems}) => {
            var {data, enter, leave, update, getKey, duration, easing, onRest} = this.props;
            var tick = performance.now();
            var dataByKey = data.reduce((acc, item) => ({...acc, [getKey(item)]: item}), {});
            var itemsByKey = prevItems.reduce((acc, item) => ({...acc, [item.key]: item}), {});
            var items = prevItems
                .map(item => {
                    var nextItem = {key: item.key, data: item.data, tick};
                    nextItem.end = !dataByKey[item.key] ? leave(item.data) : update(dataByKey[item.key]);
                    var unchanged = this.areEqual(item.end, nextItem.end);
                    if (unchanged) {
                        nextItem.start = item.start;
                        nextItem.rest = item.progress === 1;
                        var progressDelta = (nextItem.tick - item.tick) / duration(item.data);
                        nextItem.progress = Math.min(item.progress + progressDelta, 1);
                        nextItem.interpolators = item.interpolators;
                    } else {
                        nextItem.rest = false;
                        var reverse = !unchanged && this.areEqual(item.start, nextItem.end);
                        nextItem.start = reverse ? item.end : item.style;
                        nextItem.progress = reverse ? 1 - item.progress : 0;
                        nextItem.interpolators = this.getInterpolators(nextItem);
                    }
                    nextItem.style = this.interpolateStyle(nextItem, easing(item.data));
                    if (onRest && nextItem.rest && !item.rest)
                        onRest(item.data);
                    return nextItem;
                })
                .filter(item => !item.rest || dataByKey[item.key])
                .concat(data
                    .filter(item => !itemsByKey[getKey(item)])
                    .map(item => {
                        var newItem = {key: getKey(item), data: item, progress: 0, tick, rest: false};
                        newItem.start = newItem.style = enter(item);
                        newItem.end = update(item);
                        newItem.interpolators = this.getInterpolators(newItem);
                        return newItem;
                    })
                );
            this.moveId = null;
            if (items.filter(({rest}) => !rest).length !== 0)
                this.moveId = requestAnimationFrame(this.move);
            return {items};
        })
    }
    areEqual(from, to) {
        if (Object.keys(from).length !== Object.keys(to).length)
            return false;
        for(var key in from) {
            if (from[key] !== to[key])
                return false;
        }
        return true;
    }
    getInterpolators({start, end}) {
        var interpolators = {};
        for(var key in start)
            interpolators[key] = interpolate(start[key], end[key]);
        return interpolators;
    }
    interpolateStyle({interpolators, end, progress}, easing) {
        var style = {};
        for(var key in end)
            style[key] = interpolators[key](Easing[easing](progress))
        return style;
    }
    render() {
        return this.props.children(this.state.items);
    }
}

export default Motion;
<|endoftext|>


<commit_before>// thanks to Darius Kazemi and Courtney Stanton for sharing their code
//   for @101atron, on which this is heavily based.

var fs    = require('fs');
var url   = require('url');
var http  = require('http');
var twit  = require('twit');
var redis = require('redis');

var twitterClient = null;
var redisClient = null;

//connections
if (process.env.ON_HEROKU) {
  var credentials = {
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token: process.env.TWITTER_ACCESS_TOKEN,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
  };
  twitterClient = new twit(credentials);

  var rtg = url.parse(process.env.REDISTOGO_URL);
  redisClient = redis.createClient(rtg.port, rtg.hostname);
  redisClient.auth(rtg.auth.split(":")[1]);
}
else {
  try {
    var credentials = JSON.parse(fs.readFileSync('credentials.json', 'ascii'));
    twitterClient = new twit(credentials);
  }
  catch (err) {
    console.error("Error opening the credentials file:");
    console.log(err);
  }

  redisClient = redis.createClient();
}

var info = {};
info.Creator = "Shane Liesegang (@OptimistPanda)";
info.GitHub = "http://github.com/sjml/bot-innocence";
info.Description = "This is a centralized clearinghouse where bot creators can get an up-to-date list of potentially trending topics they may wish to avoid. It can be added to by trusted Twitter accounts.";
info.HowItWorks = "The 'muted' dictionary is an index of phrases to avoid and an expiration timestamp relative to the UNIX epoch.";
info.HowToAdd = "If you're one of the trusted sources, tweet @BotInnocence saying 'mute [offending phrase]' and it will be muted for 48 hours."
info.AlternateURL = "You can get just the muted list (without this extra data) at /muted or /muted_with_expirations";

var trustedSources = ["@OptimistPanda", "@tinysubversions", "@BooDooPerson"];
var trustedLower = trustedSources.map(
  function(x) {
    return x.substring(1).toLowerCase();
  }
);

var mutedPhrases = []; //TODO: pull from redis
var since_id = null; //TODO: pull from redis

function stringify(object) {
  return JSON.stringify(object, null, 2);
}

function getTime() {
  return Math.floor(Date.now() / 1000);
}

function checkForCommands() {
  var needsPersistence = false;
  var params = {include_rts: false};
  if (since_id != null) {
    return; // don't run anything if values haven't been set yet
  }
  twitterClient.get("statuses/mentions_timeline", params,
    function (err, reply) {
      if (!err) {
        console.log("Checking " + reply.length + " tweets...");
        for (var i = reply.length - 1; i >= 0; i -= 1) {
          since_id = reply[i].id_str;
          console.log("\tTweet " + since_id);
          if (trustedLower.indexOf(reply[i].user.screen_name.toLowerCase()) < 0) {
            console.log("\t\tIgnoring tweet from " + reply[i].user.screen_name);
            continue;
          }
          var re = /mute\s+(.*)/i;
          var match = reply[i].text.match(re);
          if (match != null) {
            var toMute = match[1];
            mutePhrase(toMute, since_id, reply[i].user.screen_name);
            needsPersistence = true;
          }
        }
        redisClient.set("innocence:since_id", since_id);
      }
      else {
        console.error("Couldn't connect to the Twitters.");
        console.log(err);
      }

      // look for ones to expire
      console.log("Checking expiry...")
      var muteLength = mutedPhrases.length;
      var currentTimeStamp = getTime();
      mutedPhrases = mutedPhrases.filter(
        function(x) {
          return x[1] > currentTimeStamp;
        }
      );
      if (muteLength != mutedPhrases.length) {
        console.log("Trimmed list.");
        needsPersistence = true;
      }
      else {
        console.log("No expirations.");
      }

      if (needsPersistence) {
        redisClient.set("innocence:mute_list", stringify(mutedPhrases));
      }
    }
  );

  console.log("DONE with command check!");
}

function mutePhrase(phrase, requestingID, name) {
  var freshTime = getTime();
  var futureTime = freshTime + (60 * 60 * 24 * 2); // two days should do it, typically

  // let the world know what we've done
  var tweetString = "";

  var date = new Date(futureTime * 1000);
  var dateString =
    date.getUTCMonth().toString() + "/" +
    date.getUTCDate().toString() +
    " at " +
    date.getUTCHours().toString() + date.getUTCMinutes().toString() + " GMT";

  for (var i = mutedPhrases.length - 1; i >= 0; i--) {
    if (mutedPhrases[i][0] === phrase) {
      mutedPhrases[i][1] = futureTime;
      tweetString = "Extending mute of " + phrase + " until " + dateString + ", per @" + name + ".";
    }
  }
  if (tweetString.length == 0) {
    mutedPhrases[mutedPhrases.length] = [phrase, futureTime];
    tweetString = "Muting " + phrase + " until " + dateString + ", per @" + name + ".";
  }

  twitterClient.post("statuses/update",
    {
      status: tweetString,
      in_reply_to_status_id: requestingID
    },
    function(err, data, response) {
      if (err) {
        console.error("Trouble tweeting!");
        console.log(response);
      }
    }
  );
}

function buildFullOutput(withTimes) {
  var fullOutput = {}
  fullOutput.info = info;
  fullOutput.trustedSources = trustedSources;
  fullOutput.muted = mutedPhrases;
  fullOutput.currentTimeStamp = getTime();

  return stringify(fullOutput);
}

function buildMutedOutput(withTimes) {
  if (withTimes == undefined) {
    withTimes = true;
  }
  if (withTimes) {
    var output = {};
    output.muted = mutedPhrases;
    output.currentTimeStamp = getTime();
    return stringify(output);
  }
  else {
    var output = mutedPhrases.map(
      function(x) {
        return x[0];
      }
    );
  }

  return stringify(output);
}

// get redis values
redisClient.exists("innocence:since_id",
  function(existsErr, existsReply) {
    if (existsReply) {
      redisClient.get("innocence:since_id",
        function(getErr, getReply) {
          if (getErr) {
            since_id = "-1";
            console.error(getErr);
          }
          else {
            since_id = getReply;
          }
        }
      );
    }
    else {
      console.log("No since_id found.");
      since_id = "-1";
      redisClient.set("innocence:since_id", "-1");
    }
  }
);

redisClient.exists("innocence:mute_list",
  function(existsErr, existsReply) {
    if (existsReply) {
      redisClient.get("innocence:mute_list",
        function(getErr, getReply) {
          if (getErr) {
            mutedPhrases = [];
            console.error(getErr);
          }
          else {
            mutedPhrases = JSON.parse(getReply);
            console.log("Loaded phrases: " + getReply);
          }
        }
      );
    }
    else {
      console.log("No mute_list found.");
      mutedPhrases = [];
      redisClient.set("innocence:mute_list", "[]");
    }
  }
);

// start web
var server = http.createServer(
  function (request, response) {
    if (request.url === "/") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildFullOutput());
    }
    else if (request.url === "/muted") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildMutedOutput(false));
    }
    else if (request.url === "/muted_with_expirations") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildMutedOutput());
    }
    else {
      var errObj = {
        justOneQuestion : "What are you doing here?",
      };
      response.writeHead(404, {"Content-Type" : "application/json"});
      response.end(stringify(errObj));
    }
  }
);
server.listen(process.env.PORT || 5000);

setTimeout(
  function() {
    console.log("Initial check...");
    checkForCommands();
    // begin periodic checks
    console.log("Setting up intervals.");
    setInterval(
      function() {
        console.log("INTERVAL TICK");
        try {
          checkForCommands();
        }
        catch (e) {
          console.log(e);
        }
      },
      1000 * 60 * 2 // checks every 2 minutes
    );
  },
  2000 // wait a few seconds for initial check, to get values from redis
);
<commit_msg>Debugging redis access on Heroku<commit_after>// thanks to Darius Kazemi and Courtney Stanton for sharing their code
//   for @101atron, on which this is heavily based.

var fs    = require('fs');
var url   = require('url');
var http  = require('http');
var twit  = require('twit');
var redis = require('redis');

var twitterClient = null;
var redisClient = null;

//connections
if (process.env.ON_HEROKU) {
  var credentials = {
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token: process.env.TWITTER_ACCESS_TOKEN,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
  };
  twitterClient = new twit(credentials);

  var rtg = url.parse(process.env.REDISTOGO_URL);
  redisClient = redis.createClient(rtg.port, rtg.hostname);
  redisClient.auth(rtg.auth.split(":")[1]);
}
else {
  try {
    var credentials = JSON.parse(fs.readFileSync('credentials.json', 'ascii'));
    twitterClient = new twit(credentials);
  }
  catch (err) {
    console.error("Error opening the credentials file:");
    console.log(err);
  }

  redisClient = redis.createClient();
}

var info = {};
info.Creator = "Shane Liesegang (@OptimistPanda)";
info.GitHub = "http://github.com/sjml/bot-innocence";
info.Description = "This is a centralized clearinghouse where bot creators can get an up-to-date list of potentially trending topics they may wish to avoid. It can be added to by trusted Twitter accounts.";
info.HowItWorks = "The 'muted' dictionary is an index of phrases to avoid and an expiration timestamp relative to the UNIX epoch.";
info.HowToAdd = "If you're one of the trusted sources, tweet @BotInnocence saying 'mute [offending phrase]' and it will be muted for 48 hours."
info.AlternateURL = "You can get just the muted list (without this extra data) at /muted or /muted_with_expirations";

var trustedSources = ["@OptimistPanda", "@tinysubversions", "@BooDooPerson"];
var trustedLower = trustedSources.map(
  function(x) {
    return x.substring(1).toLowerCase();
  }
);

var mutedPhrases = []; //TODO: pull from redis
var since_id = null; //TODO: pull from redis

function stringify(object) {
  return JSON.stringify(object, null, 2);
}

function getTime() {
  return Math.floor(Date.now() / 1000);
}

function checkForCommands() {
  var needsPersistence = false;
  var params = {include_rts: false};
  if (since_id != null) {
    return; // don't run anything if values haven't been set yet
  }
  twitterClient.get("statuses/mentions_timeline", params,
    function (err, reply) {
      if (!err) {
        console.log("Checking " + reply.length + " tweets...");
        for (var i = reply.length - 1; i >= 0; i -= 1) {
          since_id = reply[i].id_str;
          console.log("\tTweet " + since_id);
          if (trustedLower.indexOf(reply[i].user.screen_name.toLowerCase()) < 0) {
            console.log("\t\tIgnoring tweet from " + reply[i].user.screen_name);
            continue;
          }
          var re = /mute\s+(.*)/i;
          var match = reply[i].text.match(re);
          if (match != null) {
            var toMute = match[1];
            mutePhrase(toMute, since_id, reply[i].user.screen_name);
            needsPersistence = true;
          }
        }
        redisClient.set("innocence:since_id", since_id);
      }
      else {
        console.error("Couldn't connect to the Twitters.");
        console.log(err);
      }

      // look for ones to expire
      console.log("Checking expiry...")
      var muteLength = mutedPhrases.length;
      var currentTimeStamp = getTime();
      mutedPhrases = mutedPhrases.filter(
        function(x) {
          return x[1] > currentTimeStamp;
        }
      );
      if (muteLength != mutedPhrases.length) {
        console.log("Trimmed list.");
        needsPersistence = true;
      }
      else {
        console.log("No expirations.");
      }

      if (needsPersistence) {
        redisClient.set("innocence:mute_list", stringify(mutedPhrases));
      }
    }
  );

  console.log("DONE with command check!");
}

function mutePhrase(phrase, requestingID, name) {
  var freshTime = getTime();
  var futureTime = freshTime + (60 * 60 * 24 * 2); // two days should do it, typically

  // let the world know what we've done
  var tweetString = "";

  var date = new Date(futureTime * 1000);
  var dateString =
    date.getUTCMonth().toString() + "/" +
    date.getUTCDate().toString() +
    " at " +
    date.getUTCHours().toString() + date.getUTCMinutes().toString() + " GMT";

  for (var i = mutedPhrases.length - 1; i >= 0; i--) {
    if (mutedPhrases[i][0] === phrase) {
      mutedPhrases[i][1] = futureTime;
      tweetString = "Extending mute of " + phrase + " until " + dateString + ", per @" + name + ".";
    }
  }
  if (tweetString.length == 0) {
    mutedPhrases[mutedPhrases.length] = [phrase, futureTime];
    tweetString = "Muting " + phrase + " until " + dateString + ", per @" + name + ".";
  }

  twitterClient.post("statuses/update",
    {
      status: tweetString,
      in_reply_to_status_id: requestingID
    },
    function(err, data, response) {
      if (err) {
        console.error("Trouble tweeting!");
        console.log(response);
      }
    }
  );
}

function buildFullOutput(withTimes) {
  var fullOutput = {}
  fullOutput.info = info;
  fullOutput.trustedSources = trustedSources;
  fullOutput.muted = mutedPhrases;
  fullOutput.currentTimeStamp = getTime();

  return stringify(fullOutput);
}

function buildMutedOutput(withTimes) {
  if (withTimes == undefined) {
    withTimes = true;
  }
  if (withTimes) {
    var output = {};
    output.muted = mutedPhrases;
    output.currentTimeStamp = getTime();
    return stringify(output);
  }
  else {
    var output = mutedPhrases.map(
      function(x) {
        return x[0];
      }
    );
  }

  return stringify(output);
}

// get redis values
redisClient.exists("innocence:since_id",
  function(existsErr, existsReply) {
    if (existsReply) {
      redisClient.get("innocence:since_id",
        function(getErr, getReply) {
          if (getErr) {
            since_id = "-1";
            console.error(getErr);
          }
          else {
            since_id = getReply;
            console.log("since_id: " + since_id);
          }
        }
      );
    }
    else {
      console.log("No since_id found.");
      since_id = "-1";
      redisClient.set("innocence:since_id", "-1");
    }
  }
);

redisClient.exists("innocence:mute_list",
  function(existsErr, existsReply) {
    if (existsReply) {
      redisClient.get("innocence:mute_list",
        function(getErr, getReply) {
          if (getErr) {
            mutedPhrases = [];
            console.error(getErr);
          }
          else {
            mutedPhrases = JSON.parse(getReply);
            console.log("Loaded phrases: " + getReply);
          }
        }
      );
    }
    else {
      console.log("No mute_list found.");
      mutedPhrases = [];
      redisClient.set("innocence:mute_list", "[]");
    }
  }
);

// start web
var server = http.createServer(
  function (request, response) {
    if (request.url === "/") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildFullOutput());
    }
    else if (request.url === "/muted") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildMutedOutput(false));
    }
    else if (request.url === "/muted_with_expirations") {
      response.writeHead(200, {"Content-Type": "application/json"});
      response.end(buildMutedOutput());
    }
    else {
      var errObj = {
        justOneQuestion : "What are you doing here?",
      };
      response.writeHead(404, {"Content-Type" : "application/json"});
      response.end(stringify(errObj));
    }
  }
);
server.listen(process.env.PORT || 5000);

setTimeout(
  function() {
    console.log("Initial check...");
    checkForCommands();
    // begin periodic checks
    console.log("Setting up intervals.");
    setInterval(
      function() {
        console.log("INTERVAL TICK");
        try {
          checkForCommands();
        }
        catch (e) {
          console.log(e);
        }
      },
      1000 * 60 * 2 // checks every 2 minutes
    );
  },
  2000 // wait a few seconds for initial check, to get values from redis
);
<|endoftext|>


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

var path  = require('path');
var fs    = require('fs');
var ytdl  = require('..');
var cliff = require('cliff');
require('colors');

var info = require('../package');

var opts = require('nomnom')
  .option('version', {
    abbr: 'v',
    flag: true,
    callback: function() {
      console.log(info.version);
      process.exit();
    },
    help: 'Print program version.'
  })
  .option('url', {
    position: 0,
    required: true,
    help: 'URL to the video.'
  })
  .option('quality', {
    abbr: 'q',
    metavar: 'ITAG',
    help: 'Video quality to download. Default: highest'
  })
  .option('range', {
    abbr: 'r',
    metavar: 'INT-INT',
    help: 'Byte range to download. ie 10355705-12452856'
  })
  .option('output', {
    abbr: 'o',
    metavar: 'FILE',
    help: 'Where to save the file. Default: stdout'
  })
  .option('filterContainer', {
    full: 'filter-container',
    metavar: 'REGEXP',
    help: 'Filter in format container. Default: -o ext'
  })
  .option('unfilterContainer', {
    full: 'unfilter-container',
    metavar: 'REGEXP',
    help: 'Filter out format container.'
  })
  .option('filterResolution', {
    full: 'filter-resolution',
    metavar: 'REGEXP',
    help: 'Filter in format resolution.'
  })
  .option('unfilterResolution', {
    full: 'unfilter-resolution',
    metavar: 'REGEXP',
    help: 'Filter out format resolution.'
  })
  .option('filterEncoding', {
    full: 'filter-encoding',
    metavar: 'REGEXP',
    help: 'Filter in format encoding.'
  })
  .option('unfilterEncoding', {
    full: 'unfilter-encoding',
    metavar: 'REGEXP',
    help: 'Filter out format encoding.'
  })
  .option('info', {
    abbr: 'i',
    flag: true,
    help: 'Print video info without downloading'
  })
  .script('ytdl')
  .colors()
  .parse()
  ;

/**
 * Converts seconds into human readable time hh:mm:ss
 *
 * @param {Number} seconds
 * @return {String}
 */
function toHumanTime(seconds) {
  var h = Math.floor(seconds / 3600);
  var m = Math.floor(seconds / 60) % 60;

  var time;
  if (h > 0) {
    time = h + ':';
    if (m < 10) { m = '0' + m; }
  } else {
    time = '';
  }

  var s = seconds % 60;
  if (s < 10) { s = '0' + s; }

  return time + m + ':' + s;
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log('title: '.grey.bold + info.title);
  console.log('author: '.grey.bold + info.author);
  var rating = typeof info.avg_rating === 'number' ?
    info.avg_rating.toFixed(1) : info.avg_rating;
  console.log('average rating: '.grey.bold + rating);
  console.log('view count: '.grey.bold + info.view_count);
  console.log('length: '.grey.bold + toHumanTime(info.length_seconds));
}

if (opts.info) {
  ytdl.getInfo(opts.url, function(err, info) {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    var cols = [
      'itag',
      'container',
      'resolution',
      'video enc',
      'audio bitrate',
      'audio enc'
    ];
    info.formats.forEach(function(format) {
      format['video enc']     = format.encoding;
      format['audio bitrate'] = format.audioBitrate;
      format['audio enc']     = format.audioEncoding;
      cols.forEach(function(col) {
        format[col] = format[col] || '';
      });
    });
    console.log('formats:'.grey.bold);
    var colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
    ytdl.cache.die();
  });
  return;
}

var output = opts.output;
var writeStream;
if (output) {
  writeStream = fs.createWriteStream(output);
  var ext = path.extname(output);
  if (ext && !opts.filterContainer) {
    opts.filterContainer = '^' + ext.slice(1) + '$';
  }
} else {
  writeStream = process.stdout;
}

var ytdlOptions = {};
ytdlOptions.quality = opts.quality;
ytdlOptions.range = opts.range;

// Create filters.
var filters = [];

/**
 * @param {String} field
 * @param {String} regexpStr
 * @param {Boolean|null} negated
 */
function createFilter(field, regexpStr, negated) {
  try {
    var regexp = new RegExp(regexpStr, 'i');
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }

  filters.push(function(format) {
    return negated !== regexp.test(format[field]);
  });
}

['container', 'resolution', 'encoding'].forEach(function(field) {
  var key = 'filter' + field[0].toUpperCase() + field.slice(1);
  if (opts[key]) {
    createFilter(field, opts[key], false);
  }

  key = 'un' + key;
  if (opts[key]) {
    createFilter(field, opts[key], true);
  }
});

ytdlOptions.filter = function(format) {
  return filters.every(function(filter) {
    return filter(format);
  });
};

var readStream = ytdl(opts.url, ytdlOptions);
readStream.pipe(writeStream);

readStream.on('error', function(err) {
  console.error(err.message);
  process.exit(1);
});

// Converst bytes to human readable unit.
// Thank you Amir from StackOverflow.
var units = ' KMGTPEZYXWVU';
function toHumanSize(bytes) {
  if (bytes <= 0) { return 0; }
  var t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12);
  return (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) +
          units.charAt(t2).replace(' ', '') + 'B';
}

// Print progress bar and some video info if not streaming to stdout.
if (output) {
  readStream.on('info', function(info, format) {
    printVideoInfo(info);
    console.log('container: '.grey.bold + format.container);
    console.log('resolution: '.grey.bold + format.resolution);
    console.log('encoding: '.grey.bold + format.encoding);
    console.log('size: '.grey.bold + toHumanSize(format.size));
    console.log('output: '.grey.bold + output);
    console.log();

    // Create progress bar.
    var bar = require('progress-bar').create(process.stdout, 50);
    bar.format = '$bar; $percentage;%';

    // Keep track of progress.
    var dataRead = 0;
    readStream.on('data', function(data) {
      dataRead += data.length;
      var percent = dataRead / format.size;
      bar.update(percent);
    });

    ytdl.cache.die();

  });
}

readStream.on('end', function onend() {
  console.log();
});

process.on('SIGINT', function onsigint() {
  console.log();
  process.exit();
});
<commit_msg>check --quality is not given either for auto container<commit_after>#!/usr/bin/env node

var path  = require('path');
var fs    = require('fs');
var ytdl  = require('..');
var cliff = require('cliff');
require('colors');

var info = require('../package');

var opts = require('nomnom')
  .option('version', {
    abbr: 'v',
    flag: true,
    callback: function() {
      console.log(info.version);
      process.exit();
    },
    help: 'Print program version.'
  })
  .option('url', {
    position: 0,
    required: true,
    help: 'URL to the video.'
  })
  .option('quality', {
    abbr: 'q',
    metavar: 'ITAG',
    help: 'Video quality to download. Default: highest'
  })
  .option('range', {
    abbr: 'r',
    metavar: 'INT-INT',
    help: 'Byte range to download. ie 10355705-12452856'
  })
  .option('output', {
    abbr: 'o',
    metavar: 'FILE',
    help: 'Where to save the file. Default: stdout'
  })
  .option('filterContainer', {
    full: 'filter-container',
    metavar: 'REGEXP',
    help: 'Filter in format container. Default: -o ext'
  })
  .option('unfilterContainer', {
    full: 'unfilter-container',
    metavar: 'REGEXP',
    help: 'Filter out format container.'
  })
  .option('filterResolution', {
    full: 'filter-resolution',
    metavar: 'REGEXP',
    help: 'Filter in format resolution.'
  })
  .option('unfilterResolution', {
    full: 'unfilter-resolution',
    metavar: 'REGEXP',
    help: 'Filter out format resolution.'
  })
  .option('filterEncoding', {
    full: 'filter-encoding',
    metavar: 'REGEXP',
    help: 'Filter in format encoding.'
  })
  .option('unfilterEncoding', {
    full: 'unfilter-encoding',
    metavar: 'REGEXP',
    help: 'Filter out format encoding.'
  })
  .option('info', {
    abbr: 'i',
    flag: true,
    help: 'Print video info without downloading'
  })
  .script('ytdl')
  .colors()
  .parse()
  ;

/**
 * Converts seconds into human readable time hh:mm:ss
 *
 * @param {Number} seconds
 * @return {String}
 */
function toHumanTime(seconds) {
  var h = Math.floor(seconds / 3600);
  var m = Math.floor(seconds / 60) % 60;

  var time;
  if (h > 0) {
    time = h + ':';
    if (m < 10) { m = '0' + m; }
  } else {
    time = '';
  }

  var s = seconds % 60;
  if (s < 10) { s = '0' + s; }

  return time + m + ':' + s;
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 */
function printVideoInfo(info) {
  console.log();
  console.log('title: '.grey.bold + info.title);
  console.log('author: '.grey.bold + info.author);
  var rating = typeof info.avg_rating === 'number' ?
    info.avg_rating.toFixed(1) : info.avg_rating;
  console.log('average rating: '.grey.bold + rating);
  console.log('view count: '.grey.bold + info.view_count);
  console.log('length: '.grey.bold + toHumanTime(info.length_seconds));
}

if (opts.info) {
  ytdl.getInfo(opts.url, function(err, info) {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info);

    var cols = [
      'itag',
      'container',
      'resolution',
      'video enc',
      'audio bitrate',
      'audio enc'
    ];
    info.formats.forEach(function(format) {
      format['video enc']     = format.encoding;
      format['audio bitrate'] = format.audioBitrate;
      format['audio enc']     = format.audioEncoding;
      cols.forEach(function(col) {
        format[col] = format[col] || '';
      });
    });
    console.log('formats:'.grey.bold);
    var colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
    ytdl.cache.die();
  });
  return;
}

var output = opts.output;
var writeStream;
if (output) {
  writeStream = fs.createWriteStream(output);
  var ext = path.extname(output);
  if (ext && !opts.quality && !opts.filterContainer) {
    opts.filterContainer = '^' + ext.slice(1) + '$';
  }
} else {
  writeStream = process.stdout;
}

var ytdlOptions = {};
ytdlOptions.quality = opts.quality;
ytdlOptions.range = opts.range;

// Create filters.
var filters = [];

/**
 * @param {String} field
 * @param {String} regexpStr
 * @param {Boolean|null} negated
 */
function createFilter(field, regexpStr, negated) {
  try {
    var regexp = new RegExp(regexpStr, 'i');
  } catch (err) {
    console.error(err.message);
    process.exit(1);
  }

  filters.push(function(format) {
    return negated !== regexp.test(format[field]);
  });
}

['container', 'resolution', 'encoding'].forEach(function(field) {
  var key = 'filter' + field[0].toUpperCase() + field.slice(1);
  if (opts[key]) {
    createFilter(field, opts[key], false);
  }

  key = 'un' + key;
  if (opts[key]) {
    createFilter(field, opts[key], true);
  }
});

ytdlOptions.filter = function(format) {
  return filters.every(function(filter) {
    return filter(format);
  });
};

var readStream = ytdl(opts.url, ytdlOptions);
readStream.pipe(writeStream);

readStream.on('error', function(err) {
  console.error(err.message);
  process.exit(1);
});

// Converst bytes to human readable unit.
// Thank you Amir from StackOverflow.
var units = ' KMGTPEZYXWVU';
function toHumanSize(bytes) {
  if (bytes <= 0) { return 0; }
  var t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12);
  return (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) +
          units.charAt(t2).replace(' ', '') + 'B';
}

// Print progress bar and some video info if not streaming to stdout.
if (output) {
  readStream.on('info', function(info, format) {
    printVideoInfo(info);
    console.log('container: '.grey.bold + format.container);
    console.log('resolution: '.grey.bold + format.resolution);
    console.log('encoding: '.grey.bold + format.encoding);
    console.log('size: '.grey.bold + toHumanSize(format.size));
    console.log('output: '.grey.bold + output);
    console.log();

    // Create progress bar.
    var bar = require('progress-bar').create(process.stdout, 50);
    bar.format = '$bar; $percentage;%';

    // Keep track of progress.
    var dataRead = 0;
    readStream.on('data', function(data) {
      dataRead += data.length;
      var percent = dataRead / format.size;
      bar.update(percent);
    });

    ytdl.cache.die();

  });
}

readStream.on('end', function onend() {
  console.log();
});

process.on('SIGINT', function onsigint() {
  console.log();
  process.exit();
});
<|endoftext|>