Compare commits
8 Commits
a0243fab2f
...
d3fd8a3839
Author | SHA1 | Date | |
---|---|---|---|
|
d3fd8a3839 | ||
|
4c2b050539 | ||
|
f88065b3fc | ||
|
9b575219ca | ||
|
60db6886c1 | ||
|
86e29fa6da | ||
|
2417c53970 | ||
|
505249bcf4 |
1
Pipfile
1
Pipfile
@ -10,6 +10,7 @@ discord = "*"
|
||||
requests = "*"
|
||||
autopep8 = "*"
|
||||
discum = {git = "https://github.com/Merubokkusu/Discord-S.C.U.M.git"}
|
||||
pyyaml = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
37
Pipfile.lock
generated
37
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "22839cb267eac519dce4f8e4fb437a235d1368d104b1954f48ed1bc1b3beb428"
|
||||
"sha256": "348b7a4b9a09aa84979ffba688a2c99ef003af505160a95d93aa56a8a8144cbd"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -194,6 +194,41 @@
|
||||
"index": "pypi",
|
||||
"version": "==0.18.0"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf",
|
||||
"sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696",
|
||||
"sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393",
|
||||
"sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77",
|
||||
"sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922",
|
||||
"sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5",
|
||||
"sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8",
|
||||
"sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10",
|
||||
"sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc",
|
||||
"sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018",
|
||||
"sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e",
|
||||
"sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253",
|
||||
"sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347",
|
||||
"sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183",
|
||||
"sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541",
|
||||
"sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb",
|
||||
"sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185",
|
||||
"sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc",
|
||||
"sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db",
|
||||
"sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa",
|
||||
"sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46",
|
||||
"sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122",
|
||||
"sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b",
|
||||
"sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63",
|
||||
"sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df",
|
||||
"sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc",
|
||||
"sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247",
|
||||
"sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6",
|
||||
"sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.4.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
|
||||
|
169
app.py
169
app.py
@ -5,38 +5,50 @@ import re
|
||||
from bs4 import BeautifulSoup
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
from os.path import realpath, dirname
|
||||
from os import getenv
|
||||
from yaml import load
|
||||
from pathlib import Path
|
||||
|
||||
PRICE_REGEX = re.compile(
|
||||
"(?:(?P<currency>[GBP|EUR|£|€])(?P<price>[0-9]+(?:\.[0-9]{1,2})))")
|
||||
MODEL_REGEX = re.compile("[Rr][Tt][Xx] ?(?P<model>30[6789]0( [Tt][Ii])?).?")
|
||||
CONFIG_FILE = Path(f"{dirname(realpath(__file__))}/config.yaml")
|
||||
URL_REGEX = re.compile(
|
||||
"(?:(?:https?|ftp):\/\/|\b(?:[a-z\d]+\.))(?:(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))?\))+(?:\((?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))?\)|[^\s`!()\[\]{};:'.,<>?«»“”‘’]))?")
|
||||
|
||||
PARTALERT_ASIN = re.compile("asin=(?P<asin>[0-9a-zA-Z]{1,10})")
|
||||
PARTALERT_TLD = re.compile("tld=(?P<tld>\.(?:it|es|de|fr|co\.uk))")
|
||||
# consoles
|
||||
PS5_CHANNELS = [713321461124694056, 721009876893040682,
|
||||
781965674838753331, 802674800786145311,
|
||||
780190141599580161, 780190104357961759]
|
||||
|
||||
MONITORED_CHANNELS = [802674527850725377, 802674601519611925, 755728127069519913,
|
||||
802674384120446996, 755727814912901170, 783425011116539964,
|
||||
783682409635250187, 761002102804709448, 802674800786145311,
|
||||
758224323843850250, 760577787332788315, 802674552541806662,
|
||||
706910639959834738, 802674584473567303, 839507735531749446,
|
||||
833700313819119676, 713321461124694056, 721009876893040682]
|
||||
# gpus
|
||||
FOUNDERS_CHANNELS = [802674384120446996]
|
||||
RTX3060_CHANNELS = [809731473669619730] + FOUNDERS_CHANNELS
|
||||
RTX3060TI_CHANNELS = [783682409635250187, 783425011116539964,
|
||||
802674527850725377, 796451904401834015] + FOUNDERS_CHANNELS
|
||||
RTX3070_CHANNELS = [755728127069519913, 761002102804709448,
|
||||
802674552541806662, 796451880224948274] + FOUNDERS_CHANNELS
|
||||
RTX3070TI_CHANNELS = [839507735531749446,
|
||||
849924994686910504] + FOUNDERS_CHANNELS
|
||||
RTX3080_CHANNELS = [755727814912901170, 758224323843850250,
|
||||
802674584473567303, 796451854808121414] + FOUNDERS_CHANNELS
|
||||
RTX3080TI_CHANNELS = [833700313819119676,
|
||||
849924965842419722] + FOUNDERS_CHANNELS
|
||||
RTX3090_CHANNELS = [755728368413966387, 760577787332788315,
|
||||
796451832968642561] + FOUNDERS_CHANNELS
|
||||
|
||||
MONITORED_CHANNELS = []
|
||||
|
||||
# load .env
|
||||
load_dotenv()
|
||||
|
||||
# load env vars from .env file
|
||||
########################################
|
||||
# Globals
|
||||
########################################
|
||||
|
||||
token = getenv("TOKEN")
|
||||
|
||||
if not token:
|
||||
print("Could not load environmental variables. Make sure TOKEN is set in .env")
|
||||
exit(0)
|
||||
|
||||
|
||||
bot = discum.Client(token=token, log=False)
|
||||
|
||||
########################################
|
||||
# Callbacks
|
||||
# Functions
|
||||
########################################
|
||||
|
||||
|
||||
@ -50,7 +62,15 @@ def get_stockinformer_url(url: str) -> str:
|
||||
|
||||
for a in bs.find_all("a"):
|
||||
if "view at" in a.text.lower():
|
||||
return f"https://stockinformer.co.uk/{a.get('href')}"
|
||||
url = a.get("href")
|
||||
|
||||
if "stockinformer" in url:
|
||||
return f"https://stockinformer.co.uk/{url}"
|
||||
elif "amazon" in url:
|
||||
return f"{url.split('?')[0]}"
|
||||
|
||||
return url
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@ -70,8 +90,6 @@ def get_partalert_url(url: str) -> str:
|
||||
|
||||
def check_urls(urls: List[str]):
|
||||
for url in urls:
|
||||
print(f"Received {url}")
|
||||
|
||||
if "partalert" in url:
|
||||
url = get_partalert_url(url)
|
||||
|
||||
@ -87,37 +105,26 @@ def check_urls(urls: List[str]):
|
||||
webbrowser.open(url)
|
||||
|
||||
|
||||
def check_price(message: str) -> bool:
|
||||
prices = {
|
||||
"3060 ti": {"gbp": 500, "eur": 600},
|
||||
"3070": {"gbp": 680, "eur": 850},
|
||||
"3080": {"gbp": 880, "eur": 1000},
|
||||
"3090": {"gbp": 1450, "eur": 1650}
|
||||
}
|
||||
|
||||
try:
|
||||
price = float(PRICE_REGEX.search(message).group("price"))
|
||||
currency = PRICE_REGEX.search(message).group("currency")
|
||||
model = MODEL_REGEX.search(message).group("model").lower()
|
||||
|
||||
if currency == "£":
|
||||
currency = "gbp"
|
||||
elif currency == "€":
|
||||
currency = "eur"
|
||||
else:
|
||||
currency = currency.lower()
|
||||
|
||||
if model == "3060":
|
||||
return False
|
||||
|
||||
print(f"Model: {model}, Price: {currency}{price:0.2f}")
|
||||
if price <= prices[model][currency]:
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
return False
|
||||
def identify_channel(channel_id: int):
|
||||
# checking for founders first as this contains multiple models
|
||||
if channel_id in FOUNDERS_CHANNELS:
|
||||
print("Found a FE")
|
||||
elif channel_id in PS5_CHANNELS:
|
||||
print("Found a PS5")
|
||||
elif channel_id in RTX3060_CHANNELS:
|
||||
print("Found a RTX 3060")
|
||||
elif channel_id in RTX3060TI_CHANNELS:
|
||||
print("Found a RTX 3060 Ti")
|
||||
elif channel_id in RTX3070_CHANNELS:
|
||||
print("Found a RTX 3070")
|
||||
elif channel_id in RTX3070TI_CHANNELS:
|
||||
print("Found a RTX 3070 Ti")
|
||||
elif channel_id in RTX3080_CHANNELS:
|
||||
print("Found a RTX 3080")
|
||||
elif channel_id in RTX3080TI_CHANNELS:
|
||||
print("Found a RTX 3080 Ti")
|
||||
elif channel_id in RTX3090_CHANNELS:
|
||||
print("Found a RTX 3090")
|
||||
|
||||
|
||||
@bot.gateway.command
|
||||
@ -143,12 +150,62 @@ def on_message(resp):
|
||||
for f in [x['value'] for x in e['fields']]:
|
||||
urls.extend(URL_REGEX.findall(f))
|
||||
|
||||
if not urls:
|
||||
print(m)
|
||||
|
||||
if (urls):
|
||||
identify_channel(channel_id)
|
||||
check_urls(urls)
|
||||
|
||||
|
||||
def main():
|
||||
global MONITORED_CHANNELS
|
||||
|
||||
if not token:
|
||||
print("Could not load environmental variables. Make sure TOKEN is set in .env")
|
||||
exit(0)
|
||||
|
||||
if not CONFIG_FILE.exists():
|
||||
print(f"Could not find {CONFIG_FILE}.")
|
||||
exit(0)
|
||||
|
||||
print(f"Loading configuration \"{CONFIG_FILE}\"")
|
||||
|
||||
with open(CONFIG_FILE, "r") as f:
|
||||
config_data = load(f.read())
|
||||
|
||||
if "3060" in config_data and config_data["3060"] == True:
|
||||
print("[*] Monitoring RTX 3060")
|
||||
MONITORED_CHANNELS.extend(RTX3060_CHANNELS)
|
||||
if "3060ti" in config_data and config_data["3060ti"] == True:
|
||||
print("[*] Monitoring RTX 3060 Ti")
|
||||
MONITORED_CHANNELS.extend(RTX3060TI_CHANNELS)
|
||||
if "3070" in config_data and config_data["3070"] == True:
|
||||
print("[*] Monitoring RTX 3070")
|
||||
MONITORED_CHANNELS.extend(RTX3070_CHANNELS)
|
||||
if "3070ti" in config_data and config_data["3070ti"] == True:
|
||||
print("[*] Monitoring RTX 3070 Ti")
|
||||
MONITORED_CHANNELS.extend(RTX3070TI_CHANNELS)
|
||||
if "3080" in config_data and config_data["3080"] == True:
|
||||
print("[*] Monitoring RTX 3080")
|
||||
MONITORED_CHANNELS.extend(RTX3080_CHANNELS)
|
||||
if "3080ti" in config_data and config_data["3080ti"] == True:
|
||||
print("[*] Monitoring RTX 3080 Ti")
|
||||
MONITORED_CHANNELS.extend(RTX3080TI_CHANNELS)
|
||||
if "3090" in config_data and config_data["3090"] == True:
|
||||
print("[*] Monitoring RTX 3090")
|
||||
MONITORED_CHANNELS.extend(RTX3090_CHANNELS)
|
||||
if "founders" in config_data and config_data["founders"] == True:
|
||||
print("[*] Monitoring Founders Editions")
|
||||
MONITORED_CHANNELS.extend(FOUNDERS_CHANNELS)
|
||||
if "ps5" in config_data and config_data["ps5"] == True:
|
||||
print("[*] Monitoring PS5")
|
||||
MONITORED_CHANNELS.extend(PS5_CHANNELS)
|
||||
|
||||
# removing duplicate channels (if any) by making monitored channels a set
|
||||
MONITORED_CHANNELS = set(MONITORED_CHANNELS)
|
||||
|
||||
# starting bot
|
||||
print("Initialized.")
|
||||
bot.gateway.run(auto_reconnect=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
13
config.yaml
Normal file
13
config.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
# GPUs
|
||||
"founders": true
|
||||
"3060": true
|
||||
"3060ti": true
|
||||
"3070": true
|
||||
"3070ti": true
|
||||
"3080": true
|
||||
"3080ti": true
|
||||
"3090": true
|
||||
|
||||
# Consoles
|
||||
"ps5": true
|
Loading…
Reference in New Issue
Block a user