Skip to content

Commit

Permalink
Add generalized product-pricelimiter.sh
Browse files Browse the repository at this point in the history
Replaces xxl-product-pricelimiter.sh
  • Loading branch information
oh2fih committed Jul 31, 2024
1 parent 3b95fa6 commit d857b2d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 74 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ Miscellaneous scripts for different purposes. Mostly unrelated to each other.
| Infosec<br>Automation | [`make-mac-prefixes.py`](bin/make-mac-prefixes.py)<br>Python 3 | Processes registered MAC address prefixes from [IEEE MA-L Assignments (CSV)](https://standards.ieee.org/products-programs/regauth/) (stdin) to Nmap's [`nmap-mac-prefixes`](https://github.com/nmap/nmap/blob/master/nmap-mac-prefixes) (stdout) with a few additional unregistered OUIs.<br>`curl https://standards-oui.ieee.org/oui/oui.csv \| make-mac-prefixes.py > nmap-mac-prefixes` |
| WordPress | [`test-cache-enabler.py`](bin/test-cache-enabler.py)<br>Python 3 | Tests whether the Cache Enabler by KeyCDN (WordPress) is working properly on the URLs given as arguments.<br>`test-cache-enabler.py https://example.com [...]` |
| Web | [`detect-modified-html-element.sh`](bin/detect-modified-html-element.sh)<br>Shell (bash) | Checks HTML element changes on a web page since last run. Configured via environment variables.<br>Recommended to be executed as a SystemD [service](systemd/detect-modified-html-element.service.example). |
| Web | [`product-pricelimiter.sh`](bin/product-pricelimiter.sh)<br>Shell (bash) | Compare product price on a web page with a given maximum price. Use, e.g., developer tools on your browser to find the HTML element containing the price.<br>`product-pricelimiter.sh ProductURL Element MaxPrice` |
| Web | <del>`koronarokotusaika.sh`</del><br>Shell (bash) | This script has been removed as koronarokotusaika.fi (bookcovidvaccine.fi) has been shut down on April 28, 2023. |
| Web | [`xxl-product-pricelimiter.sh`](bin/xxl-product-pricelimiter.sh)<br>Shell (bash) | XXL.fi product price checker / limiter.<br>`xxl-product-pricelimiter.sh XXL.fi-ProductURL MaxPrice` |
| Web | <del>`xxl-product-pricelimiter.sh`</del><br>Shell (bash) | This script has been replaced by the generalized [`product-pricelimiter.sh`](bin/product-pricelimiter.sh) as the HTML structure of XXL.fi has changed. |

## Scripts that require `sudo` privileges ([`sbin/`](sbin/))

Expand Down
118 changes: 118 additions & 0 deletions bin/product-pricelimiter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/bin/bash
read -r -d '' USAGE << EOM
# ------------------------------------------------------------------------------
# Compare product price on a web page with a given maximum price.
#
# Usage: product-pricelimiter.sh ProductURL Element MaxPrice
#
# ProductURL web page URL to fetch the current price from
# Element the HTML element containing the price (#id or .class)
# MaxPrice float number
#
# Exit codes:
#
# 0 OK Price is found and lower than or equal with the MaxPrice.
# 1 ERROR An error has occured; unable to tell the result.
# 2 WAIT Price is found but higher than the MaxPrice.
#
# Author : Esa Jokinen (oh2fih)
# Home : https://github.com/oh2fih/Misc-Scripts
# ------------------------------------------------------------------------------
EOM

# Fake user-agent for curl

UA="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
UA+="(KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

# Test the inputs...

if [ "$#" -ne 3 ]; then
echo -e "\033[0;33m${USAGE}\033[0m" >&2
exit 1
fi

if [[ "$3" =~ ^[+-]?[0-9]+[\.,]?[0-9]*$ ]] 2>/dev/null; then
producturl="$1"
selector="$2"
maxprice=$(printf "%s" "$3" | sed 's/,/./g')
else
echo -e "\033[0;31mMax price should be a (float) number!\033[0m" >&2
exit 1
fi

# Validate the URL

regex='(https?)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
if ! [[ $producturl =~ $regex ]]; then
echo -e "\033[0;31mThe first argument was not a valid URL!\033[0m" >&2
exit 1
fi

# Check for requirements. Print all unmet requirements at once.

required_command() {
if ! command -v "$1" &> /dev/null; then
if [ -z ${2+x} ]; then
echo -e "\033[0;31mThis script requires ${1}!\033[0m" >&2
else
echo -e "\033[0;31mThis script requires ${1} ${2}!\033[0m" >&2
fi
((UNMET=UNMET+1))
fi
}

UNMET=0

required_command "hxselect" "; Please install html-xml-utils"
required_command "hxnormalize" "; Please install html-xml-utils"
required_command "grep" "for parsing the page content"
required_command "sed" "for converting delimiters"
required_command "curl" "for fetching the web page"
required_command "sort" "for comparing float numbers"
required_command "head" "for comparing float numbers"

if [ "$UNMET" -gt 0 ]; then
exit 1
fi

# Normalize the web page and get the monitored element

curl_failure() {
echo -e "\033[0;31mFailed to fetch ${producturl}\033[0m" >&2
exit 1
}

element_contents=$(
curl -A "$UA" -s "$producturl" \
| hxnormalize -x \
| hxselect -c "$selector"
)
if [ "$element_contents" == "" ]; then
echo -e "\033[0;31mFailed to fetch \"$selector\" in ${producturl}\033[0m" >&2
exit 1
fi

# Extract price (first match) from the element and compare it with the limit

price=$(
echo "$element_contents" \
| grep -m 1 -Eo '[0-9]+([,\.][0-9]{0,2})?' \
| sed 's/,/./g' | head -n 1
)
if [ "$price" == "" ]; then
echo -e "\033[0;31mPrice not found from \"${selector}\"!\033[0m" >&2
exit 1
fi

lower=$(printf "%s\n%s" "$price" "$maxprice" | sort -g | head -1)

if [ "$lower" = "$price" ]; then
echo -ne "\033[0;32mGood to buy! "
echo -e "The price in \"$selector\" is now $price €\033[0m"
exit 0
else
echo -ne "\033[0;33mPlease be patient! "
echo -e "The price in \"$selector\" is still $price €\033[0m"
exit 2
fi
73 changes: 0 additions & 73 deletions bin/xxl-product-pricelimiter.sh

This file was deleted.

0 comments on commit d857b2d

Please sign in to comment.