min cost and logging

- added ability to have a minimum point cost so that we can filter games like 1P out
 - updated logging to log INFO to stdout and DEBUG to a debug.log file which gets rotated
This commit is contained in:
mcinj 2022-04-24 09:34:03 -04:00
parent 6e0474b7ed
commit 1e5dd1b717
5 changed files with 77 additions and 45 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@ env/
__pycache__/ __pycache__/
.idea .idea
config/config.ini config/config.ini
src/debug.log

View file

@ -9,3 +9,5 @@ minimum_points = 50
max_entries = 900 max_entries = 900
# time left in minutes of a giveaway for it to be considered # time left in minutes of a giveaway for it to be considered
max_time_left = 180 max_time_left = 180
# the minimum point value for a giveaway to be considered
minimum_game_points = 5

View file

@ -1,13 +1,20 @@
import logging import logging
import sys from logging.handlers import RotatingFileHandler
Log_Format = "%(levelname)s %(asctime)s - %(message)s" # log info level logs to stdout and debug to debug file
logging.basicConfig(stream = sys.stdout, log_format = "%(levelname)s %(asctime)s - %(message)s"
filemode = "w", logging.basicConfig(
format = Log_Format, handlers=[RotatingFileHandler('./debug.log', maxBytes=100000, backupCount=10)],
level = logging.INFO) level=logging.DEBUG,
format=log_format)
stream = logging.StreamHandler()
stream.setLevel(logging.INFO)
stream_format = logging.Formatter(log_format)
stream.setFormatter(stream_format)
def get_logger(name): def get_logger(name):
return logging.getLogger(name) l = logging.getLogger(name)
l.addHandler(stream)
return l

View file

@ -13,7 +13,7 @@ import log
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
class SteamGifts: class SteamGifts:
def __init__(self, cookie, gifts_type, pinned, min_points, max_entries, max_time_left): def __init__(self, cookie, gifts_type, pinned, min_points, max_entries, max_time_left, minimum_game_points):
self.cookie = { self.cookie = {
'PHPSESSID': cookie 'PHPSESSID': cookie
} }
@ -22,6 +22,7 @@ class SteamGifts:
self.min_points = int(min_points) self.min_points = int(min_points)
self.max_entries = int(max_entries) self.max_entries = int(max_entries)
self.max_time_left = int(max_time_left) self.max_time_left = int(max_time_left)
self.minimum_game_points = int(minimum_game_points)
self.base = "https://www.steamgifts.com" self.base = "https://www.steamgifts.com"
self.session = requests.Session() self.session = requests.Session()
@ -70,6 +71,7 @@ class SteamGifts:
sleep(10) sleep(10)
exit() exit()
# this isn't exact because 'a week' could mean 8 days or 'a day' could mean 27 hours
def determine_time_in_minutes(self, string_time): def determine_time_in_minutes(self, string_time):
if not string_time: if not string_time:
logger.error(f"Could not determine time from string {string_time}") logger.error(f"Could not determine time from string {string_time}")
@ -89,7 +91,7 @@ class SteamGifts:
elif time_unit == 'week': elif time_unit == 'week':
return number * 7 * 24 * 60 return number * 7 * 24 * 60
else: else:
logger.error(f"Unkown time unit displayed in giveaway: {string_time}") logger.error(f"Unknown time unit displayed in giveaway: {string_time}")
return None return None
else: else:
return None return None
@ -134,42 +136,20 @@ class SteamGifts:
game_cost = item.find_all('span', {'class': 'giveaway__heading__thin'})[-1] game_cost = item.find_all('span', {'class': 'giveaway__heading__thin'})[-1]
if game_cost: if game_cost:
game_cost = game_cost.getText().replace('(', '').replace(')', '').replace('P', '') game_cost = game_cost.getText().replace('(', '').replace(')', '').replace('P', '')
game_cost = int(game_cost)
else: else:
continue continue
times = item.select('div span[data-timestamp]') if_enter_giveaway = self.should_we_enter_giveaway(item, game_name, game_cost)
game_remaining = times[0].text
game_remaining_in_minutes = self.determine_time_in_minutes(game_remaining)
if game_remaining_in_minutes is None:
continue
game_created = times[1].text
game_created_in_minutes = self.determine_time_in_minutes(game_created)
if game_created_in_minutes is None:
continue
game_entries = int(item.select('div.giveaway__links span')[0].text.split(' ')[0].replace(',' ,''))
txt = f"{game_name} {game_cost} - {game_entries} - Created {game_created} ago with {game_remaining} remaining." if if_enter_giveaway:
logger.debug(txt) res = self.enter_giveaway(game_id)
if self.points - int(game_cost) < 0:
txt = f"⛔ Not enough points to enter: {game_name}"
logger.debug(txt)
continue
if game_remaining_in_minutes > self.max_time_left:
txt = f"Game {game_name} has {game_remaining_in_minutes} minutes left and is above your cutoff of {self.max_time_left} minutes."
logger.debug(txt)
continue
if game_entries > self.max_entries:
txt = f"Game {game_name} has {game_entries} entries is above your cutoff of {self.max_entries} entries."
logger.debug(txt)
continue
# defensive move
if self.points - int(game_cost) >= 0:
res = self.entry_gift(game_id)
if res: if res:
self.points -= int(game_cost) self.points -= int(game_cost)
txt = f"🎉 One more game! Has just entered {game_name}" txt = f"🎉 One more game! Has just entered {game_name}"
logger.info(txt) logger.info(txt)
sleep(randint(3, 7)) sleep(randint(4, 15))
else:
continue
n = n+1 n = n+1
@ -177,7 +157,41 @@ class SteamGifts:
sleep(120) sleep(120)
self.start() self.start()
def entry_gift(self, game_id): def should_we_enter_giveaway(self, item, game_name, game_cost):
times = item.select('div span[data-timestamp]')
game_remaining = times[0].text
game_remaining_in_minutes = self.determine_time_in_minutes(game_remaining)
if game_remaining_in_minutes is None:
return False
game_created = times[1].text
game_created_in_minutes = self.determine_time_in_minutes(game_created)
if game_created_in_minutes is None:
return False
game_entries = int(item.select('div.giveaway__links span')[0].text.split(' ')[0].replace(',', ''))
txt = f"{game_name} - {game_cost}P - {game_entries} entries - Created {game_created} ago with {game_remaining} remaining."
logger.debug(txt)
if self.points - int(game_cost) < 0:
txt = f"⛔ Not enough points to enter: {game_name}"
logger.debug(txt)
return False
if game_cost < self.minimum_game_points:
txt = f"Game {game_name} costs {game_cost}P and is below your cutoff of {self.minimum_game_points}P."
logger.debug(txt)
return False
if game_remaining_in_minutes > self.max_time_left:
txt = f"Game {game_name} has {game_remaining_in_minutes} minutes left and is above your cutoff of {self.max_time_left} minutes."
logger.debug(txt)
return False
if game_entries > self.max_entries:
txt = f"Game {game_name} has {game_entries} entries is above your cutoff of {self.max_entries} entries."
logger.debug(txt)
return False
return True
def enter_giveaway(self, game_id):
payload = {'xsrf_token': self.xsrf_token, 'do': 'entry_insert', 'code': game_id} payload = {'xsrf_token': self.xsrf_token, 'do': 'entry_insert', 'code': 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)
@ -188,8 +202,14 @@ class SteamGifts:
def start(self): def start(self):
self.update_info() self.update_info()
if self.points > 0: if self.points >= self.min_points:
txt = "🤖 Hoho! I am back! You have %d points. Lets hack." % self.points txt = "🤖 You have %d points. Evaluating giveaways..." % self.points
logger.info(txt) logger.info(txt)
self.get_game_content()
else:
random_seconds = randint(900, 1400)
txt = f"You have {self.points} points which is below your minimum point threshold of {self.min_points} points. Sleeping for {random_seconds} seconds."
logger.info(txt)
sleep(random_seconds)
self.get_game_content()
self.get_game_content()

View file

@ -29,7 +29,8 @@ class MyConfig(ConfigParser):
'pinned': ('true', 'false'), 'pinned': ('true', 'false'),
'minimum_points': '%s' % (value_range(0,400)), 'minimum_points': '%s' % (value_range(0,400)),
'max_entries': '%s' % (value_range(0,10000)), 'max_entries': '%s' % (value_range(0,10000)),
'max_time_left': '%s' % (value_range(0,21600)) 'max_time_left': '%s' % (value_range(0,21600)),
'minimum_game_points': '%s' % (value_range(0,50))
} }
} }
@ -74,8 +75,9 @@ def run():
minimum_points = config['DEFAULT'].getint('minimum_points') minimum_points = config['DEFAULT'].getint('minimum_points')
max_entries = config['DEFAULT'].getint('max_entries') max_entries = config['DEFAULT'].getint('max_entries')
max_time_left = config['DEFAULT'].getint('max_time_left') max_time_left = config['DEFAULT'].getint('max_time_left')
minimum_game_points = config['DEFAULT'].getint('minimum_game_points')
s = SG(cookie, gift_types, pinned_games, minimum_points, max_entries, max_time_left) s = SG(cookie, gift_types, pinned_games, minimum_points, max_entries, max_time_left, minimum_game_points)
s.start() s.start()