Yodlee Time = Money

Converts money spent into time spent

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// vim: tw=80 ts=4 sw=4 et nu ai si
//
// ==UserScript==
// @name           Yodlee Time = Money
// @namespace      http://www.arthaey.com/
// @description    Converts money spent into time spent
// @include        https://moneycenter.yodlee.com/moneycenter/chart.moneycenter.do?*chartId=6*
// @version        1.0
//
// Backed up from http://userscripts.org/scripts/review/12875
// Last updated on 2007-10-09
// ==/UserScript==

/* HOW TO USE:
 *
 *  To set the "minutes-per-dollars" ratio:
 *
 *   1. right-click on the Greasemonkey monkey face in the status bar
 *   2. select the "Select User Script Commands" menu
 *   3. select the "Set Minutes Per Dollars" menu item
 *   4. enter in the numbers of minutes it takes you to earn $1
 *       - if it takes you more than an hour, multiply by 60 to get minutes
 *       - fractional minutes ARE allowed (15.5, for example)
 *
 * Now, go to the "Expenses Analysis" chart for your Yodlee Moneycenter account.
 * The table column titled "$ Amount" will now include the amount of time it
 * "cost" you to earn that money.
 *
 * Any time you want to update your minutes-per-dollars ratio, just select the
 * User Script Command from the Greasemonkey menu. The page will reload to
 * display the new calculations.
 *
 * CHANGELOG:
 *  v1.0 - initial release (inspired by the book "Your Money or Your Life")
 *
 */

window.addEventListener("load", function(){

    var DEBUG = true; // FIXME

    /* UTILITY FUNCTIONS *****************************************************/

    function debug(msg) {
        if (DEBUG) console.log("DEBUG: " + msg);
    }

    /* Finds elements whose id matches the given regexp. */
    function getElementsByIdRegExp(regex, restrict) {
        var matchingElements = [];

        if (!regex) return matchingElements;
        //if (restrict != "id" && restrict != "class") restrict = null;

        var elements = document.getElementsByTagName("*");
        var element;

        for (var i = 0; i < elements.length; i++) {
            element = elements[i];
            if (element.id.match(regex)) {
                matchingElements.push(element);
            }
        }

        return matchingElements;
    }

    /*
     * Written by Jonathan Snook, http://www.snook.ca/jonathan
     * Add-ons by Robert Nyman, http://www.robertnyman.com
     */
    function getElementsByClassName(className, tag, elm){
        var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
        var tag = tag || "*";
        var elm = elm || document;
        var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
        var returnElements = [];
        var current;
        var length = elements.length;
        for(var i=0; i<length; i++){
            current = elements[i];
            if(testClass.test(current.className)){
                returnElements.push(current);
            }
        }
        return returnElements;
    }

    // returns cents
    function stringToMoney(moneyStr) {
        if (!moneyStr) return null;

        // convert to string, if necessary
        if (!moneyStr.replace) {
            moneyStr = moneyStr.toString();
        }

        // remove any non-digit characters, excepting "."
        moneyStr = moneyStr.replace(/[^0-9.]/g, '');

        // add cents to even dollar amounts
        if (!moneyStr.match(/[.]/)) {
            moneyStr += ".00";
        }

        // convert to an integer amount of cents
        return Math.round(parseFloat(moneyStr) * 100);
    }

    function moneyToString(money) {
        var cents = Math.round(money);
        var even = (cents % 100 == 0);
        var moneyStr = new Number(Math.round(cents) / 100).toLocaleString();
        return "$" + moneyStr + (even ? ".00" : "");
    }

    const MIN_PER_HR  = 60;
    const MIN_PER_DAY = 60 * 24;
    const MIN_PER_YR  = 60 * 24 * 365;

    function timeToString(time) {
        if (!time) return;

        var years   = Math.floor(time / MIN_PER_YR);
        var days    = Math.floor((time - years * MIN_PER_YR) / MIN_PER_DAY);
        var hours   = Math.floor((time - days * MIN_PER_DAY) / MIN_PER_HR);
        var minutes = Math.floor(time % 60);

        var check = minutes +
                    hours * MIN_PER_HR +
                    days * MIN_PER_DAY +
                    years * MIN_PER_YR;

        if (check != Math.floor(time)) {
            debug("ERROR in time conversion: " + check + " vs " + time + " (" +
                minutes + "m, " +
                hours   + "h, " + 
                days    + "d, " + 
                years   + "y)");
        }

        var timeStr = minutes + "m";
        if (hours > 0) timeStr = hours + "h, " + timeStr;
        if (days  > 0) timeStr = days  + "d, " + timeStr;
        if (years > 0) timeStr = years + "y, " + timeStr;

        return timeStr;
    }

    String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

    /* MAIN FUNCTIONS ********************************************************/

    function promptMinutesPerDollar(oldValue) {
        return prompt("Minutes Per Dollar", oldValue);
    }

    function setMinutesPerDollar() {
        var oldValue = GM_getValue("MinutesPerDollar", null);
        GM_setValue("MinutesPerDollar", promptMinutesPerDollar(oldValue));
        if (oldValue) window.location.reload();
    }

    function getMinutesPerDollar() {
        var minutesPerDollar = GM_getValue("MinutesPerDollar", null);
        if (!minutesPerDollar) {
            minutesPerDollar = promptMinutesPerDollar("");
        }
        GM_setValue("MinutesPerDollar", minutesPerDollar);
        return minutesPerDollar;
    }

    function doConvertMoneyToTime() {
        minutesPerDollar = getMinutesPerDollar();
        if (!minutesPerDollar) return;

        var table = document.getElementById("expenseAnalysis");
        if (!table) return;

        var cells = getElementsByClassName("rcell", "td", table);
        var cell, money, moneyStr, time, timeStr;

        // both percent and money columns are "rcell", so skip every other cell
        for (var i = 1; i < cells.length; i += 2) {
            cell = cells[i];
            moneyStr = cell.textContent.trim();
            money = stringToMoney(moneyStr); // in cents, NOT dollars
            if (!money) continue;

            time = minutesPerDollar * (money / 100);
            timeStr = timeToString(time);
            debug("Row " + (i+1)/2 + ": " + moneyStr + " == " + timeStr);
            cell.innerHTML =
                "<span style='float:left'>(" + timeStr + ")</span>&nbsp;" +
                moneyStr;
        }
    }

    GM_registerMenuCommand("Set Minutes Per Dollar", setMinutesPerDollar);
    doConvertMoneyToTime();

}, true);