sqlite db

- store entered giveaways into db
 - store notifications into db
 - future: add won notifications
This commit is contained in:
mcinj 2022-05-05 16:50:01 -04:00
parent 40d2256eb5
commit ac89e2e886
8 changed files with 95 additions and 13 deletions

View file

@ -1,2 +1,3 @@
config/config.ini config/config.ini
config/debug.log config/debug.log
config/sqlite.db

3
.gitignore vendored
View file

@ -4,4 +4,5 @@ venv/
__pycache__/ __pycache__/
.idea .idea
config/config.ini config/config.ini
config/debug.log config/debug.log
config/sqlite.db

View file

@ -1,3 +1,6 @@
requests==2.27.1 requests==2.27.1
beautifulsoup4==4.11.1 beautifulsoup4==4.11.1
urllib3==1.26.9 urllib3==1.26.9
sqlalchemy==1.4.36
sqlalchemy_utils==0.38.2
pytz==2022.1

View file

@ -1,14 +1,17 @@
import json import json
from datetime import datetime
from random import randint from random import randint
from time import sleep from time import sleep
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from requests.adapters import HTTPAdapter from requests.adapters import HTTPAdapter
from sqlalchemy.orm import Session
from urllib3.util import Retry from urllib3.util import Retry
import log import log
from giveaway import Giveaway from giveaway import Giveaway
from tables import engine, TableGiveaway
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
@ -117,12 +120,19 @@ class SteamGifts:
return True return True
def enter_giveaway(self, game_id): def enter_giveaway(self, giveaway):
payload = {'xsrf_token': self.xsrf_token, 'do': 'entry_insert', 'code': game_id} payload = {'xsrf_token': self.xsrf_token, 'do': 'entry_insert', 'code': giveaway.game_id}
entry = requests.post('https://www.steamgifts.com/ajax.php', data=payload, cookies=self.cookie) entry = requests.post('https://www.steamgifts.com/ajax.php', data=payload, cookies=self.cookie)
json_data = json.loads(entry.text) json_data = json.loads(entry.text)
if json_data['type'] == 'success': if json_data['type'] == 'success':
g = TableGiveaway(name=giveaway.game_name, game_id=giveaway.game_id, entries=giveaway.game_entries,
giveaway_created=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_created_timestamp),
giveaway_ended=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_remaining_timestamp),
cost=giveaway.game_cost, copies=giveaway.copies, entered=True)
with Session(engine) as session:
session.add(g)
session.commit()
return True return True
def evaluate_giveaways(self, page=1): def evaluate_giveaways(self, page=1):
@ -174,7 +184,7 @@ class SteamGifts:
break break
if if_enter_giveaway: if if_enter_giveaway:
res = self.enter_giveaway(giveaway.game_id) res = self.enter_giveaway(giveaway)
if res: if res:
self.points -= int(giveaway.game_cost) self.points -= int(giveaway.game_cost)
txt = f"🎉 One more game! Has just entered {giveaway.game_name}" txt = f"🎉 One more game! Has just entered {giveaway.game_name}"

View file

@ -15,8 +15,10 @@ class Giveaway:
self.game_cost = None self.game_cost = None
self.game_entries = None self.game_entries = None
self.copies = None self.copies = None
self.time_created_timestamp = None
self.time_remaining_string = None self.time_remaining_string = None
self.time_remaining_in_minutes = None self.time_remaining_in_minutes = None
self.time_remaining_timestamp = None
self.time_created_string = None self.time_created_string = None
self.time_created_in_minutes = None self.time_created_in_minutes = None
@ -27,8 +29,10 @@ class Giveaway:
self.game_cost, self.copies = self.determine_cost_and_copies(self.soup_item, self.game_name, self.game_id) self.game_cost, self.copies = self.determine_cost_and_copies(self.soup_item, self.game_name, self.game_id)
self.game_entries = int(soup_item.select('div.giveaway__links span')[0].text.split(' ')[0].replace(',', '')) self.game_entries = int(soup_item.select('div.giveaway__links span')[0].text.split(' ')[0].replace(',', ''))
times = soup_item.select('div span[data-timestamp]') times = soup_item.select('div span[data-timestamp]')
self.time_remaining_timestamp = int(times[0]['data-timestamp'])
self.time_remaining_string = times[0].text self.time_remaining_string = times[0].text
self.time_remaining_in_minutes = self.determine_time_in_minutes(times[0]['data-timestamp']) self.time_remaining_in_minutes = self.determine_time_in_minutes(times[0]['data-timestamp'])
self.time_created_timestamp = int(times[1]['data-timestamp'])
self.time_created_string = times[1].text self.time_created_string = times[1].text
self.time_created_in_minutes = self.determine_time_in_minutes(times[1]['data-timestamp']) self.time_created_in_minutes = self.determine_time_in_minutes(times[1]['data-timestamp'])

View file

@ -1,6 +1,9 @@
import http.client import http.client
import urllib import urllib
from sqlalchemy.orm import Session
from tables import engine, TableNotification
import log import log
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
@ -14,11 +17,11 @@ class Notification:
self.pushover_user_key = None self.pushover_user_key = None
self.message_prefix = "SG-bot: " self.message_prefix = "SG-bot: "
def send(self, message): def send(self, type_of_error, message):
logger.debug(f"Attempting to notify: {message}") logger.debug(f"Attempting to notify: {message}")
if self.pushover: if self.pushover:
logger.debug("Pushover enabled. Sending message.") logger.debug("Pushover enabled. Sending message.")
self.__pushover(message) self.__pushover(type_of_error, message)
def enable_pushover(self, token, user_key): def enable_pushover(self, token, user_key):
logger.debug("Enabling pushover notifications.") logger.debug("Enabling pushover notifications.")
@ -26,7 +29,7 @@ class Notification:
self.pushover_token = token self.pushover_token = token
self.pushover_user_key = user_key self.pushover_user_key = user_key
def __pushover(self, message): def __pushover(self, type_of_error, message):
conn = http.client.HTTPSConnection("api.pushover.net:443") conn = http.client.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json", conn.request("POST", "/1/messages.json",
urllib.parse.urlencode({ urllib.parse.urlencode({
@ -36,7 +39,13 @@ class Notification:
}), {"Content-type": "application/x-www-form-urlencoded"}) }), {"Content-type": "application/x-www-form-urlencoded"})
response = conn.getresponse() response = conn.getresponse()
logger.debug(f"Pushover response code: {response.getcode()}") logger.debug(f"Pushover response code: {response.getcode()}")
if response.getcode() != 200: if response.getcode() == 200:
n = TableNotification(type=type_of_error, message=f"{message}", medium='pushover', success=True)
else:
logger.error(f"Pushover notification failed. Code {response.getcode()}: {response.read().decode()}") logger.error(f"Pushover notification failed. Code {response.getcode()}: {response.read().decode()}")
n = TableNotification(type=type_of_error, message=f"{message}", medium='pushover', success=False)
with Session(engine) as session:
session.add(n)
session.commit()

View file

@ -6,11 +6,11 @@ from ConfigReader import ConfigReader, ConfigException
from SteamGifts import SteamGifts, SteamGiftsException from SteamGifts import SteamGifts, SteamGiftsException
from notification import Notification from notification import Notification
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
def run(): def run():
file_name = '../config/config.ini' file_name = '../config/config.ini'
config = None config = None
try: try:
@ -68,12 +68,12 @@ def run():
logger.info(f"Going to sleep for {random_seconds / 60} minutes.") logger.info(f"Going to sleep for {random_seconds / 60} minutes.")
sleep(random_seconds) sleep(random_seconds)
except SteamGiftsException as e: except SteamGiftsException as e:
notification.send(e) notification.send('error', e)
sleep(5) sleep(5)
exit(-1) exit(-1)
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
notification.send("Something happened and the bot had to quit!") notification.send('error', "Something happened and the bot had to quit!")
sleep(5) sleep(5)
exit(-1) exit(-1)

54
src/tables.py Normal file
View file

@ -0,0 +1,54 @@
from sqlalchemy import create_engine, Integer, String, Column, Table, \
MetaData, DateTime, Numeric, Enum, Boolean, TIMESTAMP, func
from sqlalchemy_utils import database_exists, create_database
from sqlalchemy.orm import registry
from datetime import datetime
import pytz
mapper_registry = registry()
mapper_registry.metadata
Base = mapper_registry.generate_base()
engine = create_engine('sqlite:///../config/sqlite.db', echo=True)
class TableNotification(Base):
__tablename__ = 'notification'
id = Column(Integer, primary_key=True, nullable=False)
type = Column(String(50), nullable=False)
message = Column(String(300), nullable=False)
medium = Column(String(50), nullable=False)
success = Column(Boolean, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
__mapper_args__ = {"eager_defaults": True}
class TableGiveaway(Base):
__tablename__ = 'giveaway'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(200), nullable=False)
game_id = Column(String(10), nullable=False)
entries = Column(Integer(), nullable=False)
giveaway_created = Column(DateTime(timezone=True), nullable=False)
giveaway_ended = Column(DateTime(timezone=True), nullable=False)
cost = Column(Integer(), nullable=False)
copies = Column(Integer(), nullable=False)
entered = Column(Boolean(), nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
added_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
__mapper_args__ = {"eager_defaults": True}
@classmethod
def unix_timestamp_to_utc_datetime(cls, timestamp):
return datetime.utcfromtimestamp(timestamp)
if not database_exists(engine.url):
create_database(engine.url)
# emitting DDL
mapper_registry.metadata.create_all(engine)
Base.metadata.create_all(engine)
else:
# Connect the database if exists.
engine.connect()