Last active
January 2, 2024 15:39
-
-
Save beastinman/4a617ad4292b358896ffad550051407c to your computer and use it in GitHub Desktop.
Скрипты для плагина Tampermonkey. Добавляют ценник за единицу (1кг, 1л, 1рулон) товара на некоторых сайтах.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 1кг-цена Впрок | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Показывает цену за 1кг на сайте Впрок | |
// @author You | |
// @match https://www.vprok.ru/* | |
// @match http://www.vprok.ru/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=vprok.ru | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
{ | |
const visitedNodes = new WeakSet(); | |
setInterval(renderCosts, 2000); | |
function renderCosts() { | |
let productCards = document.querySelectorAll('[class*="MainProductTile_root"]'); | |
for (const card of productCards) { | |
if (visitedNodes.has(card)) | |
continue; | |
visitedNodes.add(card); | |
renderCard(card); | |
} | |
} | |
function renderCard(card) { | |
let priceElem = card.querySelector('[class*="Price_role_regular"]') ?? card.querySelector('[class*="Price_role_discount"]'); | |
if(priceElem == null) return; | |
let priceText = priceElem.textContent; | |
let match = /([\d\s\.,]+)(\s₽\/)(кг|г|мл|л|шт)/g.exec(priceText); | |
if (match == null || match.length != 4 || match[3] == 'кг' || match[3] == 'л') | |
return null; | |
let price = parseRubles(priceText); | |
let weightElem = card.querySelector('[class*="MainProductTile_title"]'); | |
let rulon = parseRulons(weightElem.textContent); | |
if(rulon != null) | |
priceElem.textContent += `, ${roundToTwo(price / rulon)}/рулон`; | |
if(rulon == null){ | |
let weight = parseGrams(weightElem.textContent); | |
priceElem.textContent += `, ${roundToTwo(price / weight * 1000)}/кг`; | |
} | |
} | |
function parseRubles(s) { | |
let match = /([\d\s\.,]+)(\s₽\/)(кг|г|мл|л|шт)/g.exec(s); | |
if (match == null || match.length != 4) | |
return null; | |
match[1] = match[1].replace(/[,]/g, '\.'); | |
const res = parseFloat(match[1].replace(/[^\d^.]/g, '')); | |
if (Number.isNaN(res)) | |
return null; | |
return res; | |
} | |
function parseGrams(s) { | |
let match = /(\d*\S*\d+(г|кг|л|мл))/g.exec(s); | |
let match2 = /([\d\.,]+)\s?([а-яА-Я\w]+)/.exec(match[1]); | |
if (match == null || match.length != 3) | |
return null; | |
let unit = match2[2].toLowerCase(); | |
let weight = parseFloat(match2[1]); | |
if (Number.isNaN(weight)) | |
return null; | |
switch (unit) { | |
case 'кг': return weight * 1000; | |
case 'г': return weight; | |
case 'л': return weight * 1000; | |
case 'мл': return weight; | |
default: return null; | |
} | |
return match2[1]; | |
} | |
function parseRulons(s) | |
{ | |
let match = /(\d+)(\sрулон)/g.exec(s); | |
if(match == null || match[1] == null) return null; | |
const res = parseFloat(match[1]); | |
if (Number.isNaN(res)) | |
return null; | |
else | |
return res; | |
} | |
function roundToTwo(num) { | |
// @ts-ignore | |
return +(Math.round(num + "e+2") + "e-2"); | |
} | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 1кг-цена Яндекса | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Показывает цену за 1кг на сайте яндекс еды | |
// @author You | |
// @match https://eda.yandex.ru/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=yandex.ru | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
{ | |
const visitedNodes = new WeakSet(); | |
setInterval(renderCosts, 2000); | |
function renderCosts() { | |
let productCards = document.querySelectorAll('.UiKitDesktopProductCard_root'); | |
for (const card of productCards) { | |
if (visitedNodes.has(card)) | |
continue; | |
visitedNodes.add(card); | |
renderCard(card); | |
} | |
} | |
function renderCard(card) { | |
let weightElem = card.querySelector(".UiKitDesktopProductCard_weight"); | |
if (weightElem?.textContent == null) | |
return; | |
let priceElem = card.querySelector('.UiKitPrice_new') ?? card.querySelector('.UiKitPrice_default'); | |
if (priceElem?.textContent == null) | |
return; | |
let weight = parseGrams(weightElem.textContent); | |
let price = parseRubles(priceElem.textContent); | |
if (weight == null || price == null) | |
return; | |
weightElem.textContent += `, ${roundToTwo(price / weight * 1000)}/кг`; | |
} | |
function parseGrams(s) { | |
let match = /([\d\.,]+)\s?([а-яА-Я\w]+)/.exec(s); | |
if (match == null || match.length != 3) | |
return null; | |
let unit = match[2].toLowerCase(); | |
let weight = parseFloat(match[1]); | |
if (Number.isNaN(weight)) | |
return null; | |
switch (unit) { | |
case 'кг': return weight * 1000; | |
case 'г': return weight; | |
case 'л': return weight * 1000; | |
case 'мл': return weight; | |
default: return null; | |
} | |
} | |
function parseRubles(s) { | |
let match = /([\d.,\s]+)/.exec(s); | |
if (match == null || match.length != 2) | |
return null; | |
const res = parseFloat(match[1].replace(/[^\d]/g, '.')); | |
if (Number.isNaN(res)) | |
return null; | |
return res; | |
} | |
function roundToTwo(num) { | |
// @ts-ignore | |
return +(Math.round(num + "e+2") + "e-2"); | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment