Wishlist watching

- The [DEFAULT] config settings only pertain to the main page aka All
 - Another new section called [WISHLIST] pertains specifically to entering into games on your wishlist
 - Either [DEFAULT] or [WISHLIST] can be enabled/disabled
 - Script will first look at your wishlist items if both config settings are enabled
This commit is contained in:
mcinj 2022-05-04 11:14:38 -04:00
parent befbdf8675
commit de80790beb
4 changed files with 143 additions and 99 deletions

View file

@ -1,8 +1,11 @@
[DEFAULT] [DEFAULT]
cookie = PHPSESSIONCOOKIEGOESHERE cookie = PHPSESSIONCOOKIEGOESHERE
# gift_types options: All, Wishlist, Recommended, Copies, DLC, New # should we consider giveaways on the 'ALL' page? it is the main page
enabled = true
# gift_types options: All
gift_types = All gift_types = All
pinned = true # should we consider pinned-at-the-top giveaways
pinned = false
# minimum number of points in your account before entering into giveaways # minimum number of points in your account before entering into giveaways
minimum_points = 50 minimum_points = 50
# max number of entries in a giveaway for it to be considered # max number of entries in a giveaway for it to be considered
@ -12,4 +15,13 @@ max_time_left = 300
# the minimum point value for a giveaway to be considered # the minimum point value for a giveaway to be considered
minimum_game_points = 5 minimum_game_points = 5
# a comma separated list of keywords in game titles to ignore # a comma separated list of keywords in game titles to ignore
blacklist_keywords = hentai,adult blacklist_keywords = hentai,adult
[WISHLIST]
# should we consider giveaways on the 'Wishlist' page?
wishlist.enabled = true
# minimum number of points in your account before entering into giveaways
wishlist.minimum_points = 50
# max number of entries in a giveaway for it to be considered
wishlist.max_entries = 2000
# time left in minutes of a giveaway for it to be considered
wishlist.max_time_left = 300

87
src/ConfigReader.py Normal file
View file

@ -0,0 +1,87 @@
from configparser import ConfigParser
from random import randint
class ConfigException(Exception):
pass
class ConfigReader(ConfigParser):
def value_range(min, max):
return [str(x) for x in [*range(min, max + 1)]]
required_values = {
'DEFAULT': {
'enabled': ('true', 'false'),
'gift_types': ('All'),
'pinned': ('false'),
'minimum_points': '%s' % (value_range(0, 400)),
'max_entries': '%s' % (value_range(0, 100000)),
'max_time_left': '%s' % (value_range(0, 21600)),
'minimum_game_points': '%s' % (value_range(0, 50))
},
'WISHLIST': {
'wishlist.enabled': ('true', 'false'),
'wishlist.minimum_points': '%s' % (value_range(0, 400)),
'wishlist.max_entries': '%s' % (value_range(0, 100000)),
'wishlist.max_time_left': '%s' % (value_range(0, 21600))
}
}
default_values = {
'DEFAULT': {
'cookie': '',
'enabled': 'true',
'gift_types': 'All',
'pinned': 'false',
'minimum_points': f"{randint(20, 100)}",
'max_entries': f"{randint(1000, 2500)}",
'max_time_left': f"{randint(180,500)}",
'minimum_game_points': '1',
'blacklist_keywords': 'hentai,adult'
},
'WISHLIST': {
'wishlist.enabled': 'true',
'wishlist.minimum_points': f"{randint(20, 100)}",
'wishlist.max_entries': f"{randint(10000, 100000)}",
'wishlist.max_time_left': f"{randint(180,500)}"
}
}
def __init__(self, config_file):
super(ConfigReader, self).__init__()
self.read(config_file)
modified = self.create_defaults()
if modified:
with open(config_file, 'w+') as file:
self.write(file)
self.validate_config()
def create_defaults(self):
modified = False
for section, keys in self.default_values.items():
if section not in self:
self.add_section(section)
modified = True
for key, value in keys.items():
if key not in self[section]:
self.set(section, key, value)
modified = True
return modified
def validate_config(self):
for section, keys in self.required_values.items():
if section not in self:
raise ConfigException(
'Missing section "%s" in the config file' % section)
for key, values in keys.items():
if key not in self[section] or self[section][key] == '':
raise ConfigException((
'Missing value for "%s" under section "%s" in ' +
'the config file') % (key, section))
if values:
if self[section][key] not in values:
raise ConfigException((
'Invalid value for "%s" under section "%s" in ' +
'the config file') % (key, section))

View file

@ -131,12 +131,13 @@ class SteamGifts:
soup = self.get_soup_from_page(paginated_url) soup = self.get_soup_from_page(paginated_url)
pinned_giveaway_count = len(soup.select('div.pinned-giveaways__outer-wrap div.giveaway__row-inner-wrap'))
# this matches on a div with the exact class value so we discard ones # this matches on a div with the exact class value so we discard ones
# that also have a class 'is-faded' containing already entered giveaways # that also have a class 'is-faded' containing already entered giveaways
game_list = soup.select('div[class=giveaway__row-inner-wrap]') game_list = soup.select('div[class=giveaway__row-inner-wrap]')
# game_list = soup.find_all('div', {'class': 'giveaway__row-inner-wrap'}) # game_list = soup.find_all('div', {'class': 'giveaway__row-inner-wrap'})
if not len(game_list): if not len(game_list) or (len(game_list) == pinned_giveaway_count):
txt = f"We have run out of gifts to consider." txt = f"We have run out of gifts to consider."
logger.info(txt) logger.info(txt)
run = False run = False
@ -161,6 +162,7 @@ class SteamGifts:
# after this point will also exceed the max time left # after this point will also exceed the max time left
if self.gifts_type != "New" and not giveaway.pinned and \ if self.gifts_type != "New" and not giveaway.pinned and \
giveaway.time_remaining_in_minutes > self.max_time_left: giveaway.time_remaining_in_minutes > self.max_time_left:
logger.info("We have run out of gits to consider.")
run = False run = False
break break
@ -171,27 +173,18 @@ class SteamGifts:
txt = f"🎉 One more game! Has just entered {giveaway.game_name}" txt = f"🎉 One more game! Has just entered {giveaway.game_name}"
logger.info(txt) logger.info(txt)
sleep(randint(4, 15)) sleep(randint(4, 15))
else: n = n + 1
continue
n = n + 1
def start(self): def start(self):
self.update_info() self.update_info()
if self.points >= self.min_points: if self.points >= self.min_points:
txt = "🤖 You have %d points. Evaluating giveaways..." % self.points txt = f"🤖 You have {self.points} points. Evaluating '{self.gifts_type}' giveaways..."
logger.info(txt) logger.info(txt)
else:
random_seconds = randint(900, 1400)
txt = f"You have {self.points} points which is below your minimum point threshold of " \
f"{self.min_points} points. Sleeping for {random_seconds / 60} minutes."
logger.info(txt)
sleep(random_seconds)
while True:
self.evaluate_giveaways() self.evaluate_giveaways()
random_seconds = randint(900, 1400) else:
logger.info(f"Going to sleep for {random_seconds / 60 } minutes.") txt = f"You have {self.points} points which is below your minimum point threshold of " \
sleep(random_seconds) f"{self.min_points} points for '{self.gifts_type}' giveaways. Not evaluating right now."
self.update_info() logger.info(txt)

View file

@ -1,101 +1,30 @@
import configparser
from configparser import ConfigParser
from random import randint from random import randint
from time import sleep
import log import log
from src.ConfigReader import ConfigReader, ConfigException
from src.SteamGifts import SteamGifts
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
class MyException(Exception):
pass
def value_range(min, max):
return [str(x) for x in [*range(min, max + 1)]]
class MyConfig(ConfigParser):
required_values = {
'DEFAULT': {
'gift_types': ('All', 'Wishlist', 'Recommended', 'Copies', 'DLC', 'New'),
'pinned': ('true', 'false'),
'minimum_points': '%s' % (value_range(0, 400)),
'max_entries': '%s' % (value_range(0, 100000)),
'max_time_left': '%s' % (value_range(0, 21600)),
'minimum_game_points': '%s' % (value_range(0, 50))
}
}
default_values = {
'DEFAULT': {
'cookie': '',
'gift_types': 'All',
'pinned': 'true',
'minimum_points': f"{randint(20, 100)}",
'max_entries': f"{randint(1000, 2500)}",
'max_time_left': f"{randint(180,500)}",
'minimum_game_points': '1',
'blacklist_keywords': 'hentai,adult'
}
}
def __init__(self, config_file):
super(MyConfig, self).__init__()
self.read(config_file)
modified = self.create_defaults()
if modified:
with open(config_file, 'w+') as file:
self.write(file)
self.validate_config()
def create_defaults(self):
modified = False
for section, keys in self.default_values.items():
if section not in self:
self.add_section(section)
modified = True
for key, value in keys.items():
if key not in self[section]:
self.set(section, key, value)
modified = True
return modified
def validate_config(self):
for section, keys in self.required_values.items():
if section not in self:
raise MyException(
'Missing section %s in the config file' % section)
for key, values in keys.items():
if key not in self[section] or self[section][key] == '':
raise MyException((
'Missing value for %s under section %s in ' +
'the config file') % (key, section))
if values:
if self[section][key] not in values:
raise MyException((
'Invalid value for %s under section %s in ' +
'the config file') % (key, section))
def run(): def run():
from main import SteamGifts as SG
file_name = '../config/config.ini' file_name = '../config/config.ini'
config = None config = None
try: try:
config = MyConfig(file_name) config = ConfigReader(file_name)
except IOError: except IOError:
txt = f"{file_name} doesn't exist. Rename {file_name}.example to {file_name} and fill out." txt = f"{file_name} doesn't exist. Rename {file_name}.example to {file_name} and fill out."
logger.warning(txt) logger.warning(txt)
exit(-1) exit(-1)
except MyException as e: except ConfigException as e:
logger.error(e) logger.error(e)
exit(-1) exit(-1)
config.read(file_name) config.read(file_name)
cookie = config['DEFAULT'].get('cookie') cookie = config['DEFAULT'].get('cookie')
enabled = config['DEFAULT'].getboolean('enabled')
pinned_games = config['DEFAULT'].getboolean('pinned') pinned_games = config['DEFAULT'].getboolean('pinned')
gift_types = config['DEFAULT'].get('gift_types') gift_types = config['DEFAULT'].get('gift_types')
minimum_points = config['DEFAULT'].getint('minimum_points') minimum_points = config['DEFAULT'].getint('minimum_points')
@ -104,8 +33,31 @@ def run():
minimum_game_points = config['DEFAULT'].getint('minimum_game_points') minimum_game_points = config['DEFAULT'].getint('minimum_game_points')
blacklist = config['DEFAULT'].get('blacklist_keywords') blacklist = config['DEFAULT'].get('blacklist_keywords')
s = SG(cookie, gift_types, pinned_games, minimum_points, max_entries, max_time_left, minimum_game_points, blacklist) all_page = SteamGifts(cookie, gift_types, pinned_games, minimum_points, max_entries,
s.start() max_time_left, minimum_game_points, blacklist)
wishlist_enabled = config['WISHLIST'].getboolean('wishlist.enabled')
wishlist_minimum_points = config['WISHLIST'].getint('wishlist.minimum_points')
wishlist_max_entries = config['WISHLIST'].getint('wishlist.max_entries')
wishlist_max_time_left = config['WISHLIST'].getint('wishlist.max_time_left')
wishlist_page = SteamGifts(cookie, 'Wishlist', False, wishlist_minimum_points,
wishlist_max_entries, wishlist_max_time_left, 0, '')
if not enabled and not wishlist_enabled:
logger.error("Both 'Default' and 'Wishlist' configurations are disabled. Nothing will run. Exiting...")
sleep(10)
exit(-1)
while True:
if wishlist_enabled:
wishlist_page.start()
if enabled:
all_page.start()
random_seconds = randint(1740, 3540) # sometime between 29-59 minutes
logger.info(f"Going to sleep for {random_seconds / 60} minutes.")
sleep(random_seconds)
if __name__ == '__main__': if __name__ == '__main__':