diff --git a/.dockerignore b/.dockerignore index d17bf38..fb2bb68 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,6 @@ config/config.ini config/debug.log config/sqlite.db -config/info.log \ No newline at end of file +config/info.log +alembic.ini +README.ini \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7835b0f..a3c179c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,25 @@ FROM python:3.9-alpine -RUN mkdir -p /app -WORKDIR /app - RUN apk add tzdata build-base libffi-dev py3-cffi --no-cache +RUN mkdir -p /app/src +WORKDIR /app + ENV TZ=America/New_York -ENV VIRTUAL_ENV=/app/env +ENV VIRTUAL_ENV=/src/env ENV PATH="$VIRTUAL_ENV/bin:$PATH" +ENV BOT_CONFIG_DIR="../config" +ENV BOT_DB_URL="sqlite:///../config/sqlite.db" +ENV BOT_ALEMBIC_CONFIG="./src/alembic" + RUN python -m venv $VIRTUAL_ENV -COPY requirements.txt . +COPY requirements.txt /app/ RUN pip3 install -r requirements.txt -COPY ./src/ /app/ + +COPY ./src/ /app/src/ +COPY main.py /app/ VOLUME /config -CMD ["python3", "run.py"] +CMD ["python3", "main.py"] diff --git a/README.md b/README.md index 7b9b8c3..66151da 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ The bot is specially designed for [SteamGifts.com](https://www.steamgifts.com/) python -m venv env source env/bin/activate pip install -r requirements.txt -cd src -python run.py +python main.py ``` ### Docker diff --git a/main.py b/main.py new file mode 100644 index 0000000..3131670 --- /dev/null +++ b/main.py @@ -0,0 +1,5 @@ +from src.bot import run + + +if __name__ == '__main__': + run.entry() \ No newline at end of file diff --git a/alembic/README b/src/alembic/README similarity index 100% rename from alembic/README rename to src/alembic/README diff --git a/alembic/env.py b/src/alembic/env.py similarity index 96% rename from alembic/env.py rename to src/alembic/env.py index d622584..f5b2ad8 100644 --- a/alembic/env.py +++ b/src/alembic/env.py @@ -18,9 +18,11 @@ if config.config_file_name is not None: # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata -from src.models import TableNotification, TableSteamItem, TableGiveaway, Base +from src.bot.models import TableNotification, TableSteamItem, TableGiveaway, Base + target_metadata = Base.metadata + # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") diff --git a/alembic/script.py.mako b/src/alembic/script.py.mako similarity index 100% rename from alembic/script.py.mako rename to src/alembic/script.py.mako diff --git a/alembic/versions/2022_05_19-15_50_19-1da33402b659_init.py b/src/alembic/versions/2022_05_19-15_50_19-1da33402b659_init.py similarity index 100% rename from alembic/versions/2022_05_19-15_50_19-1da33402b659_init.py rename to src/alembic/versions/2022_05_19-15_50_19-1da33402b659_init.py diff --git a/src/__init__.py b/src/bot/__init__.py similarity index 100% rename from src/__init__.py rename to src/bot/__init__.py diff --git a/src/config_reader.py b/src/bot/config_reader.py similarity index 98% rename from src/config_reader.py rename to src/bot/config_reader.py index d0e6520..5450023 100644 --- a/src/config_reader.py +++ b/src/bot/config_reader.py @@ -1,9 +1,9 @@ from configparser import ConfigParser from random import randint, randrange -import log +from .log import get_logger -logger = log.get_logger(__name__) +logger = get_logger(__name__) class ConfigException(Exception): diff --git a/src/database.py b/src/bot/database.py similarity index 95% rename from src/database.py rename to src/bot/database.py index 58f5542..849fcad 100644 --- a/src/database.py +++ b/src/bot/database.py @@ -1,3 +1,4 @@ +import os from datetime import datetime, timedelta import sqlalchemy @@ -8,18 +9,15 @@ from sqlalchemy import func from sqlalchemy.orm import Session from sqlalchemy_utils import database_exists -import log -from models import TableNotification, TableGiveaway, TableSteamItem +from .log import get_logger +from .models import TableNotification, TableGiveaway, TableSteamItem -logger = log.get_logger(__name__) -engine = None +logger = get_logger(__name__) +engine = sqlalchemy.create_engine(f"{os.getenv('BOT_DB_URL', 'sqlite:///./config/sqlite.db')}", echo=False) +engine.connect() def create_engine(db_url: str): - global engine - if not engine: - engine = sqlalchemy.create_engine(db_url, echo=False) - engine.connect() return engine @@ -49,9 +47,6 @@ def run_migrations(script_location: str, db_url: str) -> None: command.upgrade(alembic_cfg, 'head') - - - class NotificationHelper: @classmethod diff --git a/src/enter_giveaways.py b/src/bot/enter_giveaways.py similarity index 96% rename from src/enter_giveaways.py rename to src/bot/enter_giveaways.py index 81a3f99..bcd25c8 100644 --- a/src/enter_giveaways.py +++ b/src/bot/enter_giveaways.py @@ -7,11 +7,11 @@ from bs4 import BeautifulSoup from requests.adapters import HTTPAdapter from urllib3.util import Retry -import log -from database import NotificationHelper, GiveawayHelper -from giveaway import Giveaway +from .log import get_logger +from .database import NotificationHelper, GiveawayHelper +from .giveaway import Giveaway -logger = log.get_logger(__name__) +logger = get_logger(__name__) class SteamGiftsException(Exception): diff --git a/src/giveaway.py b/src/bot/giveaway.py similarity index 98% rename from src/giveaway.py rename to src/bot/giveaway.py index 936b846..ae23574 100644 --- a/src/giveaway.py +++ b/src/bot/giveaway.py @@ -1,8 +1,8 @@ import re -import log +from .log import get_logger import time -logger = log.get_logger(__name__) +logger = get_logger(__name__) class Giveaway: diff --git a/src/giveaway_thread.py b/src/bot/giveaway_thread.py similarity index 96% rename from src/giveaway_thread.py rename to src/bot/giveaway_thread.py index d1076e2..be15ae9 100644 --- a/src/giveaway_thread.py +++ b/src/bot/giveaway_thread.py @@ -7,10 +7,10 @@ from time import sleep from dateutil import tz -import log -from enter_giveaways import EnterGiveaways +from .log import get_logger +from .enter_giveaways import EnterGiveaways -logger = log.get_logger(__name__) +logger = get_logger(__name__) class GiveawayThread(threading.Thread): diff --git a/src/log.py b/src/bot/log.py similarity index 72% rename from src/log.py rename to src/bot/log.py index 36c702c..3228982 100644 --- a/src/log.py +++ b/src/bot/log.py @@ -1,11 +1,12 @@ import logging +import os from logging.handlers import RotatingFileHandler # log info level logs to stdout and debug to debug file log_format = "%(levelname)s %(asctime)s - %(message)s" logging.basicConfig( - handlers=[RotatingFileHandler('../config/debug.log', maxBytes=500000, backupCount=10)], + handlers=[RotatingFileHandler(f"{os.getenv('BOT_CONFIG_DIR', './config')}/debug.log", maxBytes=500000, backupCount=10)], level=logging.DEBUG, format=log_format) @@ -14,7 +15,7 @@ console_output.setLevel(logging.INFO) console_format = logging.Formatter(log_format) console_output.setFormatter(console_format) -info_log_file = RotatingFileHandler('../config/info.log', maxBytes=100000, backupCount=10) +info_log_file = RotatingFileHandler(f"{os.getenv('BOT_CONFIG_DIR', './config')}/info.log", maxBytes=100000, backupCount=10) info_log_file.setLevel(logging.INFO) info_log_format = logging.Formatter(log_format) info_log_file.setFormatter(info_log_format) diff --git a/src/models.py b/src/bot/models.py similarity index 100% rename from src/models.py rename to src/bot/models.py diff --git a/src/notification.py b/src/bot/notification.py similarity index 94% rename from src/notification.py rename to src/bot/notification.py index 57fb3b0..7a3089b 100644 --- a/src/notification.py +++ b/src/bot/notification.py @@ -1,10 +1,10 @@ import http.client import urllib -import log -from database import NotificationHelper +from .log import get_logger +from .database import NotificationHelper -logger = log.get_logger(__name__) +logger = get_logger(__name__) class Notification: diff --git a/src/run.py b/src/bot/run.py similarity index 50% rename from src/run.py rename to src/bot/run.py index 51a68ef..c5993fb 100644 --- a/src/run.py +++ b/src/bot/run.py @@ -1,17 +1,18 @@ +import os from time import sleep -import log -from config_reader import ConfigReader, ConfigException -from enter_giveaways import SteamGiftsException -from giveaway_thread import GiveawayThread -from notification import Notification -from database import run_migrations, create_engine -from webserver_thread import WebServerThread +from .log import get_logger +from .config_reader import ConfigReader, ConfigException +from .enter_giveaways import SteamGiftsException +from .giveaway_thread import GiveawayThread +from .notification import Notification +from .database import run_migrations, create_engine +from .webserver_thread import WebServerThread -logger = log.get_logger(__name__) -config_file_name = '../config/config.ini' -db_url = 'sqlite:///../config/sqlite.db' -alembic_migration_files = '../alembic' +logger = get_logger(__name__) +config_file_name = f"{os.getenv('BOT_CONFIG_DIR', './config')}/config.ini" +db_url = f"{os.getenv('BOT_DB_URL', 'sqlite:///./config/sqlite.db')}" +alembic_migration_files = os.getenv('BOT_ALEMBIC_CONFIG_DIR', './src/alembic') def run(): @@ -59,19 +60,22 @@ def run(): exit(-1) -if __name__ == '__main__': +def entry(): logger.info(""" - ------------------------------------------------------------------------------------- - _____ _ _ __ _ ____ _ - / ____|| | (_) / _|| | | _ \ | | - | (___ | |_ ___ __ _ _ __ ___ __ _ _ | |_ | |_ ___ | |_) | ___ | |_ - \___ \ | __|/ _ \ / _` || '_ ` _ \ / _` || || _|| __|/ __| | _ < / _ \ | __| - ____) || |_| __/| (_| || | | | | || (_| || || | | |_ \__ \ | |_) || (_) || |_ - |_____/ \__|\___| \__,_||_| |_| |_| \__, ||_||_| \__||___/ |____/ \___/ \__| - __/ | - |___/ - ------------------------------------------------------------------------------------- - """) + ------------------------------------------------------------------------------------- + _____ _ _ __ _ ____ _ + / ____|| | (_) / _|| | | _ \ | | + | (___ | |_ ___ __ _ _ __ ___ __ _ _ | |_ | |_ ___ | |_) | ___ | |_ + \___ \ | __|/ _ \ / _` || '_ ` _ \ / _` || || _|| __|/ __| | _ < / _ \ | __| + ____) || |_| __/| (_| || | | | | || (_| || || | | |_ \__ \ | |_) || (_) || |_ + |_____/ \__|\___| \__,_||_| |_| |_| \__, ||_||_| \__||___/ |____/ \___/ \__| + __/ | + |___/ + ------------------------------------------------------------------------------------- + """) run_migrations(alembic_migration_files, db_url) create_engine(db_url) run() + +if __name__ == '__main__': + entry() diff --git a/src/static/css/main.css b/src/bot/static/css/main.css similarity index 100% rename from src/static/css/main.css rename to src/bot/static/css/main.css diff --git a/src/templates/configuration.html b/src/bot/templates/configuration.html similarity index 100% rename from src/templates/configuration.html rename to src/bot/templates/configuration.html diff --git a/src/templates/log.html b/src/bot/templates/log.html similarity index 100% rename from src/templates/log.html rename to src/bot/templates/log.html diff --git a/src/webserver_thread.py b/src/bot/webserver_thread.py similarity index 97% rename from src/webserver_thread.py rename to src/bot/webserver_thread.py index 348f0bf..c62ebf0 100644 --- a/src/webserver_thread.py +++ b/src/bot/webserver_thread.py @@ -1,12 +1,11 @@ import threading from threading import Thread -from time import sleep from flask_basicauth import BasicAuth -import log +from .log import get_logger -logger = log.get_logger(__name__) +logger = get_logger(__name__) class WebServerThread(threading.Thread):