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:
parent
6e0474b7ed
commit
1e5dd1b717
5 changed files with 77 additions and 45 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,4 +2,5 @@ env/
|
||||||
*.ini
|
*.ini
|
||||||
__pycache__/
|
__pycache__/
|
||||||
.idea
|
.idea
|
||||||
config/config.ini
|
config/config.ini
|
||||||
|
src/debug.log
|
|
@ -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
|
21
src/log.py
21
src/log.py
|
@ -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
|
||||||
|
|
90
src/main.py
90
src/main.py
|
@ -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()
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue