style: clean up code formatting
This commit is contained in:
110
main.py
110
main.py
@@ -1,9 +1,9 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import logging
|
|
||||||
import requests
|
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
# =========================
|
# =========================
|
||||||
# Configuration
|
# Configuration
|
||||||
@@ -16,7 +16,6 @@ DISCORD_WEBHOOK_URL = os.environ["DISCORD_WEBHOOK_URL"]
|
|||||||
CHECK_INTERVAL_SECONDS = 30
|
CHECK_INTERVAL_SECONDS = 30
|
||||||
POST_DETECTION_COOLDOWN_SECONDS = 600
|
POST_DETECTION_COOLDOWN_SECONDS = 600
|
||||||
|
|
||||||
|
|
||||||
# =========================
|
# =========================
|
||||||
# Logging Setup
|
# Logging Setup
|
||||||
# =========================
|
# =========================
|
||||||
@@ -24,17 +23,10 @@ POST_DETECTION_COOLDOWN_SECONDS = 600
|
|||||||
logger = logging.getLogger("FormDStockMonitor")
|
logger = logging.getLogger("FormDStockMonitor")
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
log_format = logging.Formatter(
|
log_format = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||||
"%(asctime)s - %(levelname)s - %(message)s",
|
|
||||||
datefmt="%Y-%m-%d %H:%M:%S"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Write logs to a rotating file so disk space is not exhausted
|
# Write logs to a rotating file so disk space is not exhausted
|
||||||
file_handler = RotatingFileHandler(
|
file_handler = RotatingFileHandler("formd_monitor.log", maxBytes=5 * 1024 * 1024, backupCount=2)
|
||||||
"formd_monitor.log",
|
|
||||||
maxBytes=5 * 1024 * 1024,
|
|
||||||
backupCount=2
|
|
||||||
)
|
|
||||||
file_handler.setFormatter(log_format)
|
file_handler.setFormatter(log_format)
|
||||||
logger.addHandler(file_handler)
|
logger.addHandler(file_handler)
|
||||||
|
|
||||||
@@ -55,14 +47,10 @@ def send_discord_notification(product_name, variant_name, checkout_link):
|
|||||||
|
|
||||||
logger.critical("Stock detected! Sending Discord notification.")
|
logger.critical("Stock detected! Sending Discord notification.")
|
||||||
|
|
||||||
payload = {
|
payload = {"content": ("🚨 **RESTOCK ALERT** 🚨\n\n"
|
||||||
"content": (
|
f"**{product_name}**\n"
|
||||||
"🚨 **RESTOCK ALERT** 🚨\n\n"
|
f"Variant: {variant_name}\n\n"
|
||||||
f"**{product_name}**\n"
|
f"👉 [ONE-CLICK CHECKOUT]({checkout_link})")}
|
||||||
f"Variant: {variant_name}\n\n"
|
|
||||||
f"👉 [ONE-CLICK CHECKOUT]({checkout_link})"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = requests.post(DISCORD_WEBHOOK_URL, json=payload)
|
response = requests.post(DISCORD_WEBHOOK_URL, json=payload)
|
||||||
@@ -70,16 +58,11 @@ def send_discord_notification(product_name, variant_name, checkout_link):
|
|||||||
if response.status_code == 204:
|
if response.status_code == 204:
|
||||||
logger.info("Discord notification sent successfully.")
|
logger.info("Discord notification sent successfully.")
|
||||||
else:
|
else:
|
||||||
logger.error(
|
logger.error("Discord notification failed. "
|
||||||
"Discord notification failed. "
|
f"HTTP status code: {response.status_code}")
|
||||||
f"HTTP status code: {response.status_code}"
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
logger.error(
|
logger.error("Failed to send Discord notification due to an exception.", exc_info=exception)
|
||||||
"Failed to send Discord notification due to an exception.",
|
|
||||||
exc_info=exception
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# =========================
|
# =========================
|
||||||
@@ -92,31 +75,18 @@ def check_stock_continuously():
|
|||||||
variant is available for purchase.
|
variant is available for purchase.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger.info(
|
logger.info(f"Stock monitor started. Watching variant ID: {TARGET_VARIANT_ID}")
|
||||||
f"Stock monitor started. Watching variant ID: {TARGET_VARIANT_ID}"
|
|
||||||
)
|
|
||||||
|
|
||||||
request_headers = {
|
request_headers = {"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||||
"User-Agent": (
|
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
"Chrome/120.0.0.0 Safari/537.36"), "Accept": "application/json"}
|
||||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
||||||
"Chrome/120.0.0.0 Safari/537.36"
|
|
||||||
),
|
|
||||||
"Accept": "application/json"
|
|
||||||
}
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
response = requests.get(
|
response = requests.get(PRODUCT_URL, headers=request_headers, timeout=10)
|
||||||
PRODUCT_URL,
|
|
||||||
headers=request_headers,
|
|
||||||
timeout=10
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
logger.error(
|
logger.error(f"HTTP request failed. Status code: {response.status_code}")
|
||||||
f"HTTP request failed. Status code: {response.status_code}"
|
|
||||||
)
|
|
||||||
time.sleep(CHECK_INTERVAL_SECONDS)
|
time.sleep(CHECK_INTERVAL_SECONDS)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -124,18 +94,10 @@ def check_stock_continuously():
|
|||||||
product_name = product_data.get("title", "FormD T1")
|
product_name = product_data.get("title", "FormD T1")
|
||||||
variants = product_data.get("variants", [])
|
variants = product_data.get("variants", [])
|
||||||
|
|
||||||
target_variant = next(
|
target_variant = next((variant for variant in variants if variant.get("id") == TARGET_VARIANT_ID), None)
|
||||||
(
|
|
||||||
variant for variant in variants
|
|
||||||
if variant.get("id") == TARGET_VARIANT_ID
|
|
||||||
),
|
|
||||||
None
|
|
||||||
)
|
|
||||||
|
|
||||||
if not target_variant:
|
if not target_variant:
|
||||||
logger.error(
|
logger.error(f"Variant ID {TARGET_VARIANT_ID} was not found in the product data.")
|
||||||
f"Variant ID {TARGET_VARIANT_ID} was not found in the product data."
|
|
||||||
)
|
|
||||||
time.sleep(CHECK_INTERVAL_SECONDS)
|
time.sleep(CHECK_INTERVAL_SECONDS)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -143,44 +105,26 @@ def check_stock_continuously():
|
|||||||
is_in_stock = target_variant.get("available", False)
|
is_in_stock = target_variant.get("available", False)
|
||||||
|
|
||||||
if is_in_stock:
|
if is_in_stock:
|
||||||
logger.warning(
|
logger.warning(f"Stock available! Variant detected: {variant_name}")
|
||||||
f"Stock available! Variant detected: {variant_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
checkout_link = (
|
checkout_link = (f"https://formdt1.com/cart/{TARGET_VARIANT_ID}:1")
|
||||||
f"https://formdt1.com/cart/{TARGET_VARIANT_ID}:1"
|
|
||||||
)
|
|
||||||
|
|
||||||
send_discord_notification(
|
send_discord_notification(product_name, variant_name, checkout_link)
|
||||||
product_name,
|
|
||||||
variant_name,
|
|
||||||
checkout_link
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(
|
logger.info("Cooldown started to prevent duplicate alerts.")
|
||||||
"Cooldown started to prevent duplicate alerts."
|
|
||||||
)
|
|
||||||
time.sleep(POST_DETECTION_COOLDOWN_SECONDS)
|
time.sleep(POST_DETECTION_COOLDOWN_SECONDS)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(f"Out of stock. Checked variant: {variant_name}")
|
||||||
f"Out of stock. Checked variant: {variant_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
logger.error(
|
logger.error("Network connection error. Unable to reach the product server.")
|
||||||
"Network connection error. Unable to reach the product server."
|
|
||||||
)
|
|
||||||
|
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
logger.warning(
|
logger.warning("Request timed out. The server may be slow or blocking requests.")
|
||||||
"Request timed out. The server may be slow or blocking requests."
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
logger.exception(
|
logger.exception("An unexpected error occurred during the stock check.")
|
||||||
"An unexpected error occurred during the stock check."
|
|
||||||
)
|
|
||||||
|
|
||||||
time.sleep(CHECK_INTERVAL_SECONDS)
|
time.sleep(CHECK_INTERVAL_SECONDS)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user