Containerize scraper and externalize credentials
Move DB host/user/password, Discord webhook, and log path to env vars so the script can be deployed via Docker compose. Discord notifications are now skipped silently when DISCORD_WEBHOOK is unset (the old hardcoded webhook is removed pending rotation). Adds Dockerfile, docker-compose.yml, requirements.txt, .env.example, and .gitignore for the cyrion deployment.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Knoebels scraper environment configuration.
|
||||
# Copy to .env on the deploy host and fill in real values.
|
||||
# Never commit the real .env.
|
||||
|
||||
# PostgreSQL connection (phlegethon by default)
|
||||
DB_HOST=192.168.88.9
|
||||
DB_PORT=5432
|
||||
DB_USER=kuhnobowls
|
||||
DB_PASSWORD=
|
||||
|
||||
# Optional Discord webhook for notifications.
|
||||
# Leave empty/unset to skip Discord calls entirely.
|
||||
DISCORD_WEBHOOK=
|
||||
|
||||
# Log path inside the container. Mapped to the knb_logs named volume by compose.
|
||||
LOG_PATH=/var/log/kuh-no-bowls/kuh-no-bowls.log
|
||||
@@ -0,0 +1,7 @@
|
||||
.env
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
venv/
|
||||
historical_data/
|
||||
*.log
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
FROM python:3.13-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY attractions_api_logger.py .
|
||||
|
||||
ENTRYPOINT ["python", "-u", "attractions_api_logger.py"]
|
||||
+18
-11
@@ -1,21 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from datetime import datetime, date, timedelta
|
||||
import json, requests, psycopg2, logging, sys
|
||||
from psycopg2 import sql
|
||||
|
||||
ATTRACTIONS_IO_ENDPOINT = "https://live-data.attractions.io/72f0ea9e-d196-508a-bee8-cce62c3228c7.json"
|
||||
DISCORD_WEBHOOK = 'https://discord.com/api/webhooks/878651005015842827/o_KXXiPgor-DhZQ9vgL-MNOYb-RDmQCAbuYmgUpsoEOqu3XCfBdUM6rDmF1cMrZg12b0'
|
||||
DISCORD_WEBHOOK = os.environ.get('DISCORD_WEBHOOK', '').strip()
|
||||
|
||||
DB_PASSWORD = os.environ.get('DB_PASSWORD')
|
||||
if not DB_PASSWORD:
|
||||
sys.stderr.write("ERROR: DB_PASSWORD env var is required\n")
|
||||
sys.exit(1)
|
||||
|
||||
db_params = {
|
||||
'dbname': 'gp0',
|
||||
'user': 'kuhnobowls',
|
||||
'password': 'saddog095',
|
||||
'host': '192.168.88.5',
|
||||
'port': '5432',
|
||||
'user': os.environ.get('DB_USER', 'kuhnobowls'),
|
||||
'password': DB_PASSWORD,
|
||||
'host': os.environ.get('DB_HOST', '192.168.88.9'),
|
||||
'port': os.environ.get('DB_PORT', '5432'),
|
||||
'options': '-c search_path=knoebels'
|
||||
}
|
||||
|
||||
LOG_PATH = os.environ.get('LOG_PATH', '/var/log/kuh-no-bowls.log')
|
||||
|
||||
park_hours_query = """
|
||||
SELECT *
|
||||
FROM knoebels."LZ_attractions_io_resort"
|
||||
@@ -24,16 +32,17 @@ LIMIT 1
|
||||
"""
|
||||
|
||||
def send_to_discord(message):
|
||||
# The payload to send to the webhook
|
||||
if not DISCORD_WEBHOOK:
|
||||
# Discord notifications disabled — skip silently.
|
||||
return
|
||||
|
||||
data = {
|
||||
"content": message
|
||||
}
|
||||
|
||||
try:
|
||||
# Send the POST request to the webhook URL
|
||||
response = requests.post(DISCORD_WEBHOOK, json=data)
|
||||
|
||||
# Check if the request was successful
|
||||
if response.status_code == 204:
|
||||
print("Message sent successfully.")
|
||||
else:
|
||||
@@ -157,7 +166,7 @@ def pull_data_and_log(log_park_hours):
|
||||
log_to_database('LZ_attractions_io_queuetimes', queueline_data)
|
||||
|
||||
|
||||
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG, filename="/home/hoid/git_repos/kuh-no-bowls/knb.log",filemode="a")
|
||||
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG, filename=LOG_PATH, filemode="a")
|
||||
|
||||
logging.info('--------------------------------------------------------------------------------')
|
||||
logging.info('Fetching most recent park hours entry from DB...')
|
||||
@@ -177,5 +186,3 @@ if park_hours_pull[2].date() == date.today():
|
||||
else:
|
||||
logging.info('Park hours for today not in DB')
|
||||
pull_data_and_log(True)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
scraper:
|
||||
build: .
|
||||
image: kuh-no-bowls:latest
|
||||
container_name: kuh-no-bowls-scraper
|
||||
env_file: .env
|
||||
environment:
|
||||
LOG_PATH: /var/log/kuh-no-bowls/kuh-no-bowls.log
|
||||
TZ: America/New_York
|
||||
volumes:
|
||||
- knb_logs:/var/log/kuh-no-bowls
|
||||
|
||||
volumes:
|
||||
knb_logs:
|
||||
@@ -0,0 +1,2 @@
|
||||
requests
|
||||
psycopg2-binary
|
||||
Reference in New Issue
Block a user