Show Price as Hours of your Life

Gets the price displayed on shopping sites and shows the equivalent hours of your life spent to earn that money.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name            Show Price as Hours of your Life
// @description     Gets the price displayed on shopping sites and shows the equivalent hours of your life spent to earn that money.
// @author          navchandar
// @version         2.0
// @license         MIT
// @run-at          document-end
// @homepage        https://navchandar.github.io/
// @homepage        https://github.com/navchandar/
// @homepageURL     https://navchandar.github.io/
// @copyright       2019, navchandar (https://openuserjs.org/users/navchandar)
// @supportURL      https://openuserjs.org/scripts/navchandar/Show_Price_as_Hours_of_your_Life/issues
// @setupURL        https://openuserjs.org/install/navchandar/Show_Price_as_Hours_of_your_Life.user.js
// @icon            data:image/png;base64,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
// @grant           GM_addStyle
// @grant           GM_getValue
// @grant           GM_setValue
// @include         https://play.google.com/store/*
// @include         https://play.google.com/store*
// @include         http://play.google.com/store*
// @match           https://www.google.com/*shop*
// @match           https://google.com/*shop*
// @match           https://www.google.co.in/*shop*
// @match           https://google.co.in/*shop*
// @include         http://www.amazon.com
// @include         https://www.amazon.com
// @include         http://www.amazon.in
// @match           https://www.amazon.in/*
// @include         https://www.flipkart.com*
// @include         http://www.flipkart.com*
// @include         https://paytm.com*
// @include         http://paytm.com*
// @include         https://paytmmall.com*
// @include         http://paytmmall.com*
// @namespace https://greasyfork.org/users/302262
// ==/UserScript==

function has(String, search) {
  try {
    if (String.indexOf(search) > -1) {
      return true;
    }
  }
  catch (err) {}
  return false;
}

function updateValuesINR() {
  var approxHourlySalary = Number(GM_getValue("approxAnnualSalary", "")) / (9 * 22 * 12);
  if (!approxHourlySalary) {
    console.log("Error calculating approxHourlySalary.")
  }

  if (approxHourlySalary > 0) {
    var items, separator;
    // These xpaths cover most of the price elements shown. Feel free to comment/fork to update if required.
    var amazonINRxpath = "//span[contains(@class, 'CurrencyINR')]//following-sibling::span" + " | " +
      "//span[@class='currencyINR']/parent::*" + " | " +
      "//*[contains(@class, 'rice')][contains(text(), '₹')]" + " | " +
      "//*[contains(@class, 'price')]//*[contains(text(), '₹')]" + " | " +
      "//*[contains(@class, 'price-whole')]" + " | " +
      "//h2/span[contains(text(), '₹')]" + " | " +
      "//div[@data-id]//h3" + " | " +
      "//*[text() = 'Select Seats']//..//..//..//*[contains(text(), ',')]";

    var amazonUSDxpath = "//*[@class='dealPrice']" + " | " +
      "//*[@class='buyingPrice']" + " | " +
      "//*[contains(@class,'-price-whole')]" + " | " +
      "(//span[@class='dv-conditional-linebreak']//following-sibling::text())[1]" + " | " +
      "(//span[@class='dv-conditional-linebreak']//following-sibling::text())[2]" + " | " +
      "//span[contains(@class, 'price')][contains(text(), '$')]" + " | " +
      "//h2[contains(@class, 'headline') and contains(text(), '₹')]" + " | " +
      "//a[@id='dealTitle']" + " | " + "//div[contains(@class, 'priceBlock')]";

    var flipkartINRxpath = "//*[contains(@title, '₹')]/div[3]" + " | " +
      "//div[contains(text(), '₹')]";

    var paytmINRxpath = "//span/span[contains(text(), 'Rs')]" + " | " +
      "//a//*[contains(@class, 'iconRupess')]//.." + " | " +
      "//*[contains(@class, 'iconRupess')]//..";

    var playStoreINRxpath = "//*[@class='display-price' and contains(text(), '₹')]" + " | " +
      "//button[@jsmodel]//span[contains(text(), '₹')]" + " | " +
      "//button[contains(text(), '₹')]//text()" + " | " +
      "//meta[@itemprop='price']";

    var gShopINRxpath = "//div[contains(@class, 'content')]//*[contains(text(), '₹')]" + " | " +
      "//div[contains(@class, 'result')]//*[contains(text(), '₹')]" + " | " +
      "//a//div[contains(text(), '₹')]";

    var hostURL = window.location.href;
    if (has(hostURL, 'amazon.in')) {
      items = document.evaluate(amazonINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = " ";
    }

    else if (has(hostURL, 'amazon.com')) {
      items = document.evaluate(amazonUSDxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = " ";
    }

    else if (has(hostURL, 'flipkart')) {
      items = document.evaluate(flipkartINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = " ";
    }

    else if (has(hostURL, 'paytm')) {
      items = document.evaluate(paytmINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = "<br/>";
    }

    else if ((has(hostURL, 'google')) && (has(hostURL, 'details'))) {
      items = document.evaluate(playStoreINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = "&nbsp;";
    }

    else if ((has(hostURL, 'google')) && (has(hostURL, 'store'))) {
      items = document.evaluate(playStoreINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = "<br/>";
    }

    else if ((has(hostURL, 'google.co')) && (has(hostURL, 'shop'))) {
      items = document.evaluate(gShopINRxpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      separator = "&nbsp;";
    }

    else {
      console.log("Show Price Hours script didnt match with the current site.");
    }

    if (!items) {
      console.log("No items found with the xpath in this page.");
    }
    else if (items.snapshotLength <= 0) {
      console.log("No items found with the xpath in this page.");
    }
    else {
      var passCount = 0;
      for (let i = 0; i < items.snapshotLength; i++) {
        var thisitem = items.snapshotItem(i);
        var txt = thisitem.innerText;
        var htm = thisitem.innerHTML;
        if (txt == null | txt == "" | htm == null | htm == "") {
          txt = thisitem.textContent;
        }

        var alreadyUpdated = false;
        try {
          if (has(txt, 'hrs') | has(txt, 'Day') | has(txt, 'Month') | has(txt, 'YEARS')) {
            alreadyUpdated = true;
          }
        }
        catch (err) {}
        try {
          if (has(htm, 'hrs') | has(htm, 'Day') | has(htm, 'Month') | has(htm, 'YEARS')) {
            alreadyUpdated = true;
          }
        }
        catch (err) {}

        if (!alreadyUpdated) {
          try {
            // to remove +10% offers from flipkart
            if (has(txt, '+')) {
              txt = txt.split('+')[0];
            }

            // to remove hidden text from paytm
            if (has(txt, '%') && has(txt, '-')) {
              txt = txt.split('-')[0]
            }

            // to remove 100-200 range from amazon
            if (has(txt, '-')) {
              txt = txt.split('-')[1];
            }
            if (has(txt, 'to')) {
              txt = txt.split('to')[1];
            }
            if (has(txt, 'Buy')) {
              txt = txt.split('Buy')[0];
            }

            // remove unneccessary text and convert to number.
            txt = (txt.replace(/\d+ Used/i, "").replace(/\d+ New/i, "")).replace(/\(\d+%\)/g, "");
            txt = txt.replace(/[a-z]/gi, "");
            txt = txt.replace(",", "").replace("Rs.", "").replace("₹", "").replace("$", "").replace(".00", "").replace(" ", "");
            var amount = Number(txt);
            if (!amount || amount <= 0) {
              amount = Number(((txt.replace(".00", "").replace(/\.\d+/, "")).replace(/\.\d+\./, "")).replace(/\D+/g, ""));
            }
            var appender = "";

            if (amount > 0) {
              var calculated = (amount / approxHourlySalary);
              if (calculated) {
                if (calculated <= 10) {
                  appender = (separator + "<b>(" + (calculated).toFixed(1).toString() + " hrs)</b>");
                  thisitem.innerHTML += appender;
                }
                else if (calculated < 190) {
                  appender = (separator + "<b>(" + (calculated / 9).toFixed(1).toString() + " Days)</b>");
                  thisitem.innerHTML += appender;
                }
                else if (calculated < 2380) {
                  appender = (separator + "<b>(" + (calculated / 198).toFixed(1).toString() + " Months)</b>");
                  thisitem.innerHTML += appender;
                }
                else {
                  appender = (separator + "<b>(" + (calculated / 2376).toFixed(1).toString() + " YEARS)</b>");
                  thisitem.innerHTML += appender;
                }
                passCount++;
              }
              else {
                console.log("Error calculating amount : " + amount);
              }
            }
          }
          catch (err) {}
        }
      }
      console.log("Updated hours to " + passCount + " items.");
      items = "";
    }
  }
}

function ButtonClickAction(zEvent) {
  GM_setValue("approxAnnualSalary", "");
  var approxAnnualSalary = prompt('To calculate how many hours of your life, each item will cost, add an approximate Annual Salary/Wage Amount :', '');
  if (approxAnnualSalary) {
    GM_setValue("approxAnnualSalary", approxAnnualSalary);
    console.log("Stored approxAnnualSalary : " + approxAnnualSalary);
    GM_setValue("UserCancelledPrompt", false);
    self.location.assign(location);
  }
  else {
    GM_setValue("UserCancelledPrompt", true);
    console.log("User Cancelled prompt to update approxAnnualSalary.");
  }
}

function AddButton() {
  // Add a button element on div
  var zNode = document.createElement('div');
  zNode.innerHTML = '<button id="myButton" title="To update your stored wage/salary, Click me" type="button">Reset</button>';
  zNode.setAttribute('id', 'myContainer');
  document.body.appendChild(zNode);

  //--- Activate the newly added button.
  document.getElementById("myButton").addEventListener("click", ButtonClickAction, false);

  //--- Style our newly added element using CSS.
  GM_addStyle(`
#myContainer{position:fixed;bottom:0;left:0;font-size:11px;margin:0;opacity:.75}#myButton{cursor:pointer;background-color:lightgrey;color:black}
#myButton:hover{background-color:#555;color:white;box-shadow:0 2px 6px 0 rgba(0,0,0,.24),0 5px 10px 0 rgba(0,0,0,.19);opacity:1}
`);

}

(function () {
  'use strict';
  //GM_setValue("approxAnnualSalary", ""); // Reset here for test.
  var approxAnnualSalary = GM_getValue("approxAnnualSalary", "");
  var checkPriorCancellation = GM_getValue("UserCancelledPrompt");

  if ((approxAnnualSalary == "" || !approxAnnualSalary) && !checkPriorCancellation) {
    approxAnnualSalary = prompt('To calculate how many hours of your life, each item will cost, add an approximate Annual Salary/Wage Amount :', '');
    if (approxAnnualSalary) {
      GM_setValue("approxAnnualSalary", approxAnnualSalary);
      GM_setValue("UserCancelledPrompt", false);
      console.log("Stored approxAnnualSalary : " + approxAnnualSalary);
    }
    else {
      GM_setValue("UserCancelledPrompt", true);
      console.log("User Cancelled prompt to update approxAnnualSalary.");
    }
  }

  // call this function once
  AddButton();

  // call this every 2 seconds to update according to page load
  setInterval(function () {
    updateValuesINR();
  }, 2000);

})();