on-win notification
- added notifications when a won giveaway is detected - a notification will only be sent once a day
This commit is contained in:
parent
405dd11a9b
commit
3d3752de22
6 changed files with 99 additions and 50 deletions
|
@ -2,5 +2,4 @@ requests==2.27.1
|
|||
beautifulsoup4==4.11.1
|
||||
urllib3==1.26.9
|
||||
sqlalchemy==1.4.36
|
||||
sqlalchemy_utils==0.38.2
|
||||
pytz==2022.1
|
||||
sqlalchemy_utils==0.38.2
|
|
@ -1,17 +1,15 @@
|
|||
import json
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from time import sleep
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from requests.adapters import HTTPAdapter
|
||||
from sqlalchemy.orm import Session
|
||||
from urllib3.util import Retry
|
||||
|
||||
import log
|
||||
from giveaway import Giveaway
|
||||
from tables import engine, TableGiveaway
|
||||
from tables import TableNotification, TableGiveaway
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
@ -69,7 +67,7 @@ class SteamGifts:
|
|||
return session
|
||||
|
||||
def get_soup_from_page(self, url):
|
||||
r = self.requests_retry_session().get(url)
|
||||
self.requests_retry_session().get(url)
|
||||
r = requests.get(url, cookies=self.cookie)
|
||||
soup = BeautifulSoup(r.text, 'html.parser')
|
||||
return soup
|
||||
|
@ -85,6 +83,20 @@ class SteamGifts:
|
|||
logger.error("⛔ Cookie is not valid.")
|
||||
raise SteamGiftsException("Cookie is not valid.")
|
||||
|
||||
won = soup.select("a[title='Giveaways Won'] div.fade_infinite")
|
||||
if won:
|
||||
number_won = soup.select_one("a[title='Giveaways Won'] div.fade_infinite").text
|
||||
won_notifications = TableNotification.get_won_notifications_today()
|
||||
if won_notifications and len(won_notifications) >= 1:
|
||||
logger.debug("Win(s) detected, but we have already notified that there are won games waiting "
|
||||
"to be received. Doing nothing.")
|
||||
else:
|
||||
logger.debug("Win(s) detected. Going to send a notification.")
|
||||
logger.info(f"WINNER! You have {number_won} game(s) waiting to be claimed.")
|
||||
self.notification.send_won(f"WINNER! You have {number_won} game(s) waiting to be claimed.")
|
||||
else:
|
||||
logger.debug('No wins detected. Doing nothing.')
|
||||
|
||||
def should_we_enter_giveaway(self, giveaway):
|
||||
if giveaway.time_remaining_in_minutes is None:
|
||||
return False
|
||||
|
@ -139,25 +151,6 @@ class SteamGifts:
|
|||
logger.error(f"Failed entering giveaway {giveaway.giveaway_game_id}")
|
||||
return False
|
||||
|
||||
def create_or_update_giveaway(self, giveaway, entered):
|
||||
g = TableGiveaway(
|
||||
steam_app_id=giveaway.steam_app_id,
|
||||
steam_url=giveaway.steam_url,
|
||||
game_name=giveaway.game_name,
|
||||
giveaway_game_id=giveaway.giveaway_game_id,
|
||||
giveaway_uri=giveaway.giveaway_uri,
|
||||
user=giveaway.user,
|
||||
giveaway_created_at=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_created_timestamp),
|
||||
giveaway_ended_at=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_remaining_timestamp),
|
||||
cost=giveaway.cost,
|
||||
copies=giveaway.copies,
|
||||
contributor_level=giveaway.contributor_level,
|
||||
entered=entered,
|
||||
game_entries=giveaway.game_entries)
|
||||
with Session(engine) as session:
|
||||
session.merge(g)
|
||||
session.commit()
|
||||
|
||||
def evaluate_giveaways(self, page=1):
|
||||
n = page
|
||||
run = True
|
||||
|
@ -180,7 +173,6 @@ class SteamGifts:
|
|||
if not len(unentered_game_list) or (all_games_list_count == pinned_giveaway_count):
|
||||
txt = f"We have run out of gifts to consider."
|
||||
logger.info(txt)
|
||||
run = False
|
||||
break
|
||||
|
||||
for item in unentered_game_list:
|
||||
|
@ -200,15 +192,15 @@ class SteamGifts:
|
|||
if if_enter_giveaway:
|
||||
res = self.enter_giveaway(giveaway)
|
||||
if res:
|
||||
self.create_or_update_giveaway(giveaway, True)
|
||||
TableGiveaway.upsert_giveaway(giveaway, True)
|
||||
self.points -= int(giveaway.cost)
|
||||
txt = f"🎉 One more game! Has just entered {giveaway.game_name}"
|
||||
logger.info(txt)
|
||||
sleep(randint(4, 15))
|
||||
else:
|
||||
self.create_or_update_giveaway(giveaway, False)
|
||||
TableGiveaway.upsert_giveaway(giveaway, False)
|
||||
else:
|
||||
self.create_or_update_giveaway(giveaway, False)
|
||||
TableGiveaway.upsert_giveaway(giveaway, False)
|
||||
# if we are on any filter type except New and we get to a giveaway that exceeds our
|
||||
# max time left amount, then we don't need to continue to look at giveaways as any
|
||||
# after this point will also exceed the max time left
|
||||
|
|
|
@ -5,7 +5,7 @@ from logging.handlers import RotatingFileHandler
|
|||
|
||||
log_format = "%(levelname)s %(asctime)s - %(message)s"
|
||||
logging.basicConfig(
|
||||
handlers=[RotatingFileHandler('../config/debug.log', maxBytes=100000, backupCount=10)],
|
||||
handlers=[RotatingFileHandler('../config/debug.log', maxBytes=500000, backupCount=10)],
|
||||
level=logging.DEBUG,
|
||||
format=log_format)
|
||||
|
||||
|
@ -14,6 +14,7 @@ stream.setLevel(logging.INFO)
|
|||
stream_format = logging.Formatter(log_format)
|
||||
stream.setFormatter(stream_format)
|
||||
|
||||
|
||||
def get_logger(name):
|
||||
l = logging.getLogger(name)
|
||||
l.addHandler(stream)
|
||||
|
|
|
@ -17,11 +17,11 @@ class Notification:
|
|||
self.pushover_user_key = None
|
||||
self.message_prefix = "SG-bot: "
|
||||
|
||||
def send(self, type_of_error, message):
|
||||
logger.debug(f"Attempting to notify: {message}")
|
||||
if self.pushover:
|
||||
logger.debug("Pushover enabled. Sending message.")
|
||||
self.__pushover(type_of_error, message)
|
||||
def send_won(self, message):
|
||||
self.__send('won', message)
|
||||
|
||||
def send_error(self, message):
|
||||
self.__send('error', message)
|
||||
|
||||
def enable_pushover(self, token, user_key):
|
||||
logger.debug("Enabling pushover notifications.")
|
||||
|
@ -29,6 +29,12 @@ class Notification:
|
|||
self.pushover_token = token
|
||||
self.pushover_user_key = user_key
|
||||
|
||||
def __send(self, type_of_error, message):
|
||||
logger.debug(f"Attempting to notify: {message}")
|
||||
if self.pushover:
|
||||
logger.debug("Pushover enabled. Sending message.")
|
||||
self.__pushover(type_of_error, message)
|
||||
|
||||
def __pushover(self, type_of_error, message):
|
||||
conn = http.client.HTTPSConnection("api.pushover.net:443")
|
||||
conn.request("POST", "/1/messages.json",
|
||||
|
@ -47,5 +53,3 @@ class Notification:
|
|||
with Session(engine) as session:
|
||||
session.add(n)
|
||||
session.commit()
|
||||
|
||||
|
||||
|
|
|
@ -68,15 +68,15 @@ def run():
|
|||
logger.info(f"Going to sleep for {random_seconds / 60} minutes.")
|
||||
sleep(random_seconds)
|
||||
except SteamGiftsException as e:
|
||||
notification.send('error', e)
|
||||
notification.send_error(e)
|
||||
sleep(5)
|
||||
exit(-1)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
notification.send('error', "Something happened and the bot had to quit!")
|
||||
notification.send_error("Something happened and the bot had to quit!")
|
||||
sleep(5)
|
||||
exit(-1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
run()
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
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
|
||||
|
||||
from sqlalchemy import create_engine, Integer, String, Column, DateTime, Boolean, func, ForeignKey
|
||||
from sqlalchemy.orm import registry, relationship, Session
|
||||
from sqlalchemy_utils import database_exists, create_database
|
||||
|
||||
mapper_registry = registry()
|
||||
mapper_registry.metadata
|
||||
|
@ -19,16 +18,34 @@ class TableNotification(Base):
|
|||
medium = Column(String(50), nullable=False)
|
||||
success = Column(Boolean, nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
__mapper_args__ = {"eager_defaults": True}
|
||||
|
||||
@classmethod
|
||||
def get_won_notifications_today(cls):
|
||||
with Session(engine) as session:
|
||||
return session.query(TableNotification)\
|
||||
.filter(func.DATE(TableNotification.created_at) == datetime.utcnow().date())\
|
||||
.filter_by(type='won')\
|
||||
.all()
|
||||
|
||||
|
||||
class TableSteamItem(Base):
|
||||
__tablename__ = 'steam_item'
|
||||
steam_id = Column(String(15), primary_key=True, nullable=False)
|
||||
game_name = Column(String(200), nullable=False)
|
||||
steam_url = Column(String(100), nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
giveaways = relationship("TableGiveaway", back_populates="steam_item")
|
||||
|
||||
|
||||
class TableGiveaway(Base):
|
||||
__tablename__ = 'giveaway'
|
||||
steam_app_id = Column(String(15), primary_key=True, nullable=False)
|
||||
giveaway_game_id = Column(String(10), primary_key=True, nullable=False)
|
||||
steam_url = Column(String(100), nullable=False)
|
||||
game_name = Column(String(200), nullable=False)
|
||||
giveaway_id = Column(String(10), primary_key=True, nullable=False)
|
||||
steam_id = Column(Integer, ForeignKey('steam_item.steam_id'), primary_key=True)
|
||||
giveaway_uri = Column(String(200), nullable=False)
|
||||
user = Column(String(40), nullable=False)
|
||||
giveaway_created_at = Column(DateTime(timezone=True), nullable=False)
|
||||
|
@ -37,16 +54,52 @@ class TableGiveaway(Base):
|
|||
copies = Column(Integer(), nullable=False)
|
||||
contributor_level = Column(Integer(), nullable=False)
|
||||
entered = Column(Boolean(), nullable=False)
|
||||
won = Column(Boolean(), nullable=False)
|
||||
game_entries = Column(Integer(), nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
steam_item = relationship("TableSteamItem", back_populates="giveaways")
|
||||
|
||||
__mapper_args__ = {"eager_defaults": True}
|
||||
|
||||
@classmethod
|
||||
def unix_timestamp_to_utc_datetime(cls, timestamp):
|
||||
return datetime.utcfromtimestamp(timestamp)
|
||||
|
||||
@classmethod
|
||||
def upsert_giveaway(cls, giveaway, entered):
|
||||
with Session(engine) as session:
|
||||
result = session.query(TableGiveaway).filter_by(giveaway_id=giveaway.giveaway_game_id,
|
||||
steam_id=giveaway.steam_app_id).all()
|
||||
if result:
|
||||
steam_id = result[0].steam_id
|
||||
else:
|
||||
item = TableSteamItem(
|
||||
steam_id=giveaway.steam_app_id,
|
||||
steam_url=giveaway.steam_url,
|
||||
game_name=giveaway.game_name)
|
||||
session.merge(item)
|
||||
session.flush()
|
||||
steam_id = item.steam_id
|
||||
|
||||
g = TableGiveaway(
|
||||
giveaway_id=giveaway.giveaway_game_id,
|
||||
steam_id=steam_id,
|
||||
giveaway_uri=giveaway.giveaway_uri,
|
||||
user=giveaway.user,
|
||||
giveaway_created_at=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_created_timestamp),
|
||||
giveaway_ended_at=TableGiveaway.unix_timestamp_to_utc_datetime(giveaway.time_remaining_timestamp),
|
||||
cost=giveaway.cost,
|
||||
copies=giveaway.copies,
|
||||
contributor_level=giveaway.contributor_level,
|
||||
entered=entered,
|
||||
won=False,
|
||||
game_entries=giveaway.game_entries)
|
||||
|
||||
session.merge(g)
|
||||
session.commit()
|
||||
|
||||
|
||||
if not database_exists(engine.url):
|
||||
create_database(engine.url)
|
||||
|
@ -55,4 +108,4 @@ if not database_exists(engine.url):
|
|||
Base.metadata.create_all(engine)
|
||||
else:
|
||||
# Connect the database if exists.
|
||||
engine.connect()
|
||||
engine.connect()
|
||||
|
|
Loading…
Reference in a new issue