From 4eb01b47dd8e9a20726231a5445f31588179bca5 Mon Sep 17 00:00:00 2001 From: stilManiac Date: Mon, 9 Mar 2020 20:32:32 +0200 Subject: [PATCH 1/9] config instead of .txt --- main.py | 99 +++++++++++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 56 deletions(-) diff --git a/main.py b/main.py index 307159e..44b6a30 100644 --- a/main.py +++ b/main.py @@ -1,34 +1,49 @@ import sys +import configparser import requests -from bs4 import BeautifulSoup import json -import time import threading + +from time import sleep +from random import randint from requests import RequestException +from bs4 import BeautifulSoup + +CONFIG_DEFAULT = { + 'cookie': 'Paste you cookie here', + 'sleeptime': 900 +} + +def exitMessage(msg): + print(msg) + input() + sys.exit() + +def readConfig(): + config = configparser.ConfigParser() + + def initConfig(): + config['STEAMGIFTS'] = CONFIG_DEFAULT + with open('config.ini', 'w') as configfile: + config.write(configfile) + + if not len(config.read('config.ini')): + initConfig() + exitMessage('Init file was created. Please, look into it and set up your cookie.') + elif list(CONFIG_DEFAULT.keys()) != list(config['STEAMGIFTS'].keys()): + initConfig() + exitMessage('Init file was reinitialised due to incorrect format. Please, look into it and set up your cookie.') + + global timeout, cookies + timeout = config['STEAMGIFTS']['sleeptime'] + cookies = {'PHPSESSID': config['STEAMGIFTS']['cookie']} -try: - file = open('cookie.txt', 'r') - cook = file.readline() - if len(cook) == 0: - print('There is no cookie in cookie.txt file') - time.sleep(30) - sys.exit(0) -except FileNotFoundError: - print('Cant find cookie.txt file') - time.sleep(30) - sys.exit(0) -timeout = 900 pages = 1 - def get_soup_from_page(url): - global cookies - - cookies = {'PHPSESSID': cook} r = requests.get(url, cookies=cookies) soup = BeautifulSoup(r.text, 'html.parser') - return soup def get_page(): @@ -42,11 +57,11 @@ def get_page(): except RequestException: print('Cant connect to the site') print('Waiting 2 minutes and reconnect...') - time.sleep(120) + sleep(120) get_page() except TypeError: print('Cant recognize your cookie value.') - time.sleep(30) + sleep(30) sys.exit(0) @@ -67,7 +82,7 @@ def get_games(): for item in gifts_list: if int(points) == 0: print('> Sleeping to get 6 points') - time.sleep(timeout) + sleep(timeout) get_games() break @@ -88,11 +103,11 @@ def get_games(): entry_gift(item.find('a', {'class': 'giveaway__heading__name'})['href'].split('/')[2]) n = n+1 - except AttributeError as e: + except AttributeError: break print('List of games is ended. Waiting 2 min to update...') - time.sleep(120) + sleep(120) get_page() get_games() @@ -107,39 +122,11 @@ def entry_gift(code): # updating points after entered a giveaway if json_data['type'] == 'success': - print('> Bot has entered giveaway: ' + game_name) - time.sleep(5) - - -def inputs_data(): - global timeout - global pages - - while 1: - cmd = input().split() - if cmd == '!help': - print(' [ HELP BOX ]') - print('!sleep [arg]\t- change a sleeping interval in sec (default is 900 sec)') - print('!page [arg]\t- set a final page') - if len(cmd) == 1: - print('!help to see available commands') - if cmd[0] == '!sleep': - try: - timeout = int(cmd[1]) - print('Successfuly set interval to ' + (timeout)) - except ValueError: - print('Expect a digit!') - - elif cmd[0] == '!page': - try: - pages = int(cmd[1]) - print('Successfuly set final page to ' + str(pages)) - except ValueError: - print('Expect a digit!') - + print('> Bot has entered giveaway: ' + game_name.decode("utf-8")) + sleep(randint(10, 30)) if __name__ == '__main__': - thread = threading.Thread(target=inputs_data) - thread.start() + readConfig() + get_page() get_games() From 927f2d568cb241407968be55fd99338d7187fe65 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Fri, 26 Jun 2020 22:21:56 +0300 Subject: [PATCH 2/9] Add interactive CLI --- .gitignore | 1 + cli.py | 101 +++++++++++++++++++++++++++++++++++++++++++++++ config.ini | 3 ++ main.py | 2 +- requirements.txt | 16 ++++++++ 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 cli.py create mode 100644 config.ini create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae412d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +env/ \ No newline at end of file diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..9a160af --- /dev/null +++ b/cli.py @@ -0,0 +1,101 @@ +import six +import configparser + +from pyfiglet import figlet_format +from pyconfigstore import ConfigStore +from PyInquirer import (Token, ValidationError, Validator, print_json, prompt, + style_from_dict) + +# from main import SteamGifts + +try: + import colorama + colorama.init() +except ImportError: + colorama = None + +try: + from termcolor import colored +except ImportError: + colored = None + +config = configparser.ConfigParser() + +style = style_from_dict({ + Token.QuestionMark: '#fac731 bold', + Token.Answer: '#4688f1 bold', + Token.Selected: '#0abf5b', # default + Token.Pointer: '#673ab7 bold', +}) + +def log(string, color, font="slant", figlet=False): + if colored: + if not figlet: + six.print_(colored(string, color)) + else: + six.print_(colored(figlet_format( + string, font=font), color)) + else: + six.print_(string) + + +def ask(type, name, message, validator=None, choices=[]): + questions = [ + { + 'type': type, + 'name': name, + 'message': message, + 'validator': validator, + }, + ] + if choices: + questions[0].update({ + 'choices': choices, + }) + answers = prompt(questions, style=style) + return answers + + +def main(): + + def askCookie(): + cookie = ask(type='input', + name='cookie', + message='Enter PHPSESSID cookie (Only needed to provide once):') + config['DEFAULT']['cookie'] = cookie['cookie'] + + with open('config.ini', 'w') as configfile: + config.write(configfile) + return cookie['cookie'] + + log("SteamGifts Bot", color="blue", figlet=True) + log("Welcome to SteamGifts Bot!", "green") + log("Created by: github.com/stilManiac", "white") + + config.read('config.ini') + if not config['DEFAULT'].get('cookie'): + cookie = askCookie() + + re_enter_cookie = ask(type='confirm', + name='reenter', + message='Do you want to enter new cookie?')['reenter'] + if re_enter_cookie: + cookie = askCookie() + + gift_type = ask(type='list', + name='gift_type', + message='Select type:', + choices=[ + 'All', + 'Wishlist', + 'Recommended', + 'Copies', + 'DLC', + 'New' + ])['gift_type'] + + # s = SteamGifts(cookie, gift_type) + # s.start() + +if __name__ == '__main__': + main() diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..0c039bc --- /dev/null +++ b/config.ini @@ -0,0 +1,3 @@ +[DEFAULT] +cookie = sdf + diff --git a/main.py b/main.py index 44b6a30..8e77c99 100644 --- a/main.py +++ b/main.py @@ -101,7 +101,7 @@ def get_games(): continue elif int(points) - int(game_cost) > 0: entry_gift(item.find('a', {'class': 'giveaway__heading__name'})['href'].split('/')[2]) - + n = n+1 except AttributeError: break diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..519474b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +astroid==2.4.2 +isort==4.3.21 +lazy-object-proxy==1.4.3 +mccabe==0.6.1 +prompt-toolkit==1.0.14 +pyconfigstore3==1.0.1 +pyfiglet==0.8.post1 +Pygments==2.6.1 +PyInquirer==1.0.3 +pylint==2.5.3 +regex==2020.6.8 +six==1.15.0 +termcolor==1.1.0 +toml==0.10.1 +wcwidth==0.2.5 +wrapt==1.12.1 From 5b82582ca1797235e9e9da4a609dc714689b9937 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Fri, 26 Jun 2020 22:24:52 +0300 Subject: [PATCH 3/9] Reorganise project dir --- .gitignore | 3 ++- config.ini | 1 + cli.py => src/cli.py | 0 main.py => src/main.py | 0 4 files changed, 3 insertions(+), 1 deletion(-) rename cli.py => src/cli.py (100%) rename main.py => src/main.py (100%) diff --git a/.gitignore b/.gitignore index ae412d6..eadcc92 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -env/ \ No newline at end of file +env/ +.ini \ No newline at end of file diff --git a/config.ini b/config.ini index 0c039bc..4827842 100644 --- a/config.ini +++ b/config.ini @@ -1,3 +1,4 @@ [DEFAULT] cookie = sdf +123 \ No newline at end of file diff --git a/cli.py b/src/cli.py similarity index 100% rename from cli.py rename to src/cli.py diff --git a/main.py b/src/main.py similarity index 100% rename from main.py rename to src/main.py From 2b541fde2ccbe43bc528814235a3ee92ec68a268 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Fri, 26 Jun 2020 22:27:50 +0300 Subject: [PATCH 4/9] Delete config.ini from project dir --- config.ini | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 config.ini diff --git a/config.ini b/config.ini deleted file mode 100644 index 4827842..0000000 --- a/config.ini +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -cookie = sdf - -123 \ No newline at end of file From 0c047fbaa85013621328176006f4e280db9e5c53 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Fri, 26 Jun 2020 23:46:13 +0300 Subject: [PATCH 5/9] Refactoring --- .gitignore | 3 +- requirements.txt | 16 ---- src/__init__.py | 0 src/cli.py | 26 ++++--- src/main.py | 194 +++++++++++++++++++++++------------------------ 5 files changed, 113 insertions(+), 126 deletions(-) create mode 100644 src/__init__.py diff --git a/.gitignore b/.gitignore index eadcc92..30ddd3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ env/ -.ini \ No newline at end of file +*.ini +__pycache__/ \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 519474b..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +0,0 @@ -astroid==2.4.2 -isort==4.3.21 -lazy-object-proxy==1.4.3 -mccabe==0.6.1 -prompt-toolkit==1.0.14 -pyconfigstore3==1.0.1 -pyfiglet==0.8.post1 -Pygments==2.6.1 -PyInquirer==1.0.3 -pylint==2.5.3 -regex==2020.6.8 -six==1.15.0 -termcolor==1.1.0 -toml==0.10.1 -wcwidth==0.2.5 -wrapt==1.12.1 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/cli.py b/src/cli.py index 9a160af..2214754 100644 --- a/src/cli.py +++ b/src/cli.py @@ -6,8 +6,6 @@ from pyconfigstore import ConfigStore from PyInquirer import (Token, ValidationError, Validator, print_json, prompt, style_from_dict) -# from main import SteamGifts - try: import colorama colorama.init() @@ -56,7 +54,8 @@ def ask(type, name, message, validator=None, choices=[]): return answers -def main(): +def run(): + from main import SteamGifts as SG def askCookie(): cookie = ask(type='input', @@ -75,12 +74,14 @@ def main(): config.read('config.ini') if not config['DEFAULT'].get('cookie'): cookie = askCookie() - - re_enter_cookie = ask(type='confirm', - name='reenter', - message='Do you want to enter new cookie?')['reenter'] - if re_enter_cookie: - cookie = askCookie() + else: + re_enter_cookie = ask(type='confirm', + name='reenter', + message='Do you want to enter new cookie?')['reenter'] + if re_enter_cookie: + cookie = askCookie() + else: + cookie = config['DEFAULT'].get('cookie') gift_type = ask(type='list', name='gift_type', @@ -94,8 +95,9 @@ def main(): 'New' ])['gift_type'] - # s = SteamGifts(cookie, gift_type) - # s.start() + s = SG(cookie, gift_type) + s.start() + if __name__ == '__main__': - main() + run() \ No newline at end of file diff --git a/src/main.py b/src/main.py index 8e77c99..fa59e4c 100644 --- a/src/main.py +++ b/src/main.py @@ -4,129 +4,129 @@ import requests import json import threading +from requests.adapters import HTTPAdapter +from urllib3.util import Retry from time import sleep from random import randint from requests import RequestException from bs4 import BeautifulSoup -CONFIG_DEFAULT = { - 'cookie': 'Paste you cookie here', - 'sleeptime': 900 -} - -def exitMessage(msg): - print(msg) - input() - sys.exit() - -def readConfig(): - config = configparser.ConfigParser() - - def initConfig(): - config['STEAMGIFTS'] = CONFIG_DEFAULT - with open('config.ini', 'w') as configfile: - config.write(configfile) - - if not len(config.read('config.ini')): - initConfig() - exitMessage('Init file was created. Please, look into it and set up your cookie.') - elif list(CONFIG_DEFAULT.keys()) != list(config['STEAMGIFTS'].keys()): - initConfig() - exitMessage('Init file was reinitialised due to incorrect format. Please, look into it and set up your cookie.') - - global timeout, cookies - timeout = config['STEAMGIFTS']['sleeptime'] - cookies = {'PHPSESSID': config['STEAMGIFTS']['cookie']} +from cli import log -pages = 1 +class SteamGifts: + def __init__(self, cookie, gifts_type): + self.cookie = { + 'PHPSESSID': cookie + } + self.gifts_type = gifts_type -def get_soup_from_page(url): - r = requests.get(url, cookies=cookies) - soup = BeautifulSoup(r.text, 'html.parser') - return soup + self.base = "https://www.steamgifts.com" + self.session = requests.Session() -def get_page(): - global xsrf_token, points + self.filter_url = { + 'All': "search?page=%d", + 'Wishlist': "search?page=%d&type=wishlist", + 'Recommended': "search?page=%d&type=recommended", + 'Copies': "search?page=%d©_min=2", + 'DLC': "search?page=%d&dlc=true", + 'New': "search?page=%d&type=new" + } - try: - soup = get_soup_from_page('https://www.steamgifts.com') + def requests_retry_session( + self, + retries=5, + backoff_factor=0.3 + ): + session = self.session or requests.Session() + retry = Retry( + total=retries, + read=retries, + connect=retries, + backoff_factor=backoff_factor, + status_forcelist=(500, 502, 504), + ) + adapter = HTTPAdapter(max_retries=retry) + session.mount('http://', adapter) + session.mount('https://', adapter) + return session - xsrf_token = soup.find('input', {'name': 'xsrf_token'})['value'] - points = soup.find('span', {'class': 'nav__points'}).text # storage points - except RequestException: - print('Cant connect to the site') - print('Waiting 2 minutes and reconnect...') - sleep(120) - get_page() - except TypeError: - print('Cant recognize your cookie value.') - sleep(30) - sys.exit(0) + def get_soup_from_page(self, url): + r = self.requests_retry_session().get(url) + r = requests.get(url, cookies=self.cookie) + soup = BeautifulSoup(r.text, 'html.parser') + return soup + def update_info(self): + soup = self.get_soup_from_page(self.base) -# get codes of the games -def get_games(): - global game_name - global pages + self.xsrf_token = soup.find('input', {'name': 'xsrf_token'})['value'] + self.points = int(soup.find('span', {'class': 'nav__points'}).text) # storage points - n = 1 - while n <= pages: - print('Proccessing games from %d page.' % n) + def get_game_content(self, page=1): + n = page + while True: + txt = "โš™๏ธ Retrieving games from %d page." % n + log(txt, "magenta") - soup = get_soup_from_page('https://www.steamgifts.com/giveaways/search?page=' + str(n)) + filtered_url = self.filter_url[self.gifts_type] % n + paginated_url = f"{self.base}/giveaways/{filtered_url}" - try: - gifts_list = soup.find_all(lambda tag: tag.name == 'div' and tag.get('class') == ['giveaway__row-inner-wrap']) + soup = self.get_soup_from_page(paginated_url) - for item in gifts_list: - if int(points) == 0: - print('> Sleeping to get 6 points') - sleep(timeout) - get_games() + game_list = soup.find_all(lambda tag: tag.name == 'div' and tag.get('class') == ['giveaway__row-inner-wrap']) + + for item in game_list: + if self.points == 0: + log("๐Ÿ›‹๏ธ Sleeping to get 6 points", "yellow") + sleep(900) + self.get_game_content(page=n) break - game_cost = item.find_all('span', {'class': 'giveaway__heading__thin'}) + game_cost = item.find_all('span', {'class': 'giveaway__heading__thin'})[-1] - last_div = None - for last_div in game_cost: - pass - if last_div: - game_cost = last_div.getText().replace('(', '').replace(')', '').replace('P', '') - - game_name = item.find('a', {'class': 'giveaway__heading__name'}).text.encode('utf-8') - - if int(points) - int(game_cost) < 0: - print('Not enough points to enter: ' + game_name) + if game_cost: + game_cost = game_cost.getText().replace('(', '').replace(')', '').replace('P', '') + else: continue - elif int(points) - int(game_cost) > 0: - entry_gift(item.find('a', {'class': 'giveaway__heading__name'})['href'].split('/')[2]) + + game_name = item.find('a', {'class': 'giveaway__heading__name'}).text + + if self.points - int(game_cost) < 0: + txt = f"โ›” Not enough points to enter: {game_name}" + log(txt, "red") + continue + + elif self.points - int(game_cost) >= 0: + game_id = item.find('a', {'class': 'giveaway__heading__name'})['href'].split('/')[2] + res = self.entry_gift(game_id) + if res: + txt = f"๐ŸŽ‰ One more game! Have just entered {game_name}" + log(txt, "green") + # sleep(randint(10, 30)) n = n+1 - except AttributeError: - break - - print('List of games is ended. Waiting 2 min to update...') - sleep(120) - get_page() - get_games() -def entry_gift(code): - payload = {'xsrf_token': xsrf_token, 'do': 'entry_insert', 'code': code} - entry = requests.post('https://www.steamgifts.com/ajax.php', data=payload, cookies=cookies) - json_data = json.loads(entry.text) + log("๐Ÿ›‹๏ธ List of games is ended. Waiting 2 min to update...", "yellow") + sleep(120) + self.start() - get_page() - # print(json_data) + def entry_gift(self, 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) + json_data = json.loads(entry.text) - # updating points after entered a giveaway - if json_data['type'] == 'success': - print('> Bot has entered giveaway: ' + game_name.decode("utf-8")) - sleep(randint(10, 30)) + self.update_info() -if __name__ == '__main__': - readConfig() + if json_data['type'] == 'success': + return True - get_page() - get_games() + def start(self): + self.update_info() + + if self.points > 0: + txt = "๐Ÿค– Hoho! I am back! You have %d points. Lets hack." % self.points + log(txt, "blue") + + self.get_game_content() From 977f03355bd085b42363d90d5951f5b291d165c4 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Fri, 26 Jun 2020 23:55:25 +0300 Subject: [PATCH 6/9] Update README --- README.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5c89068..673739b 100644 --- a/README.md +++ b/README.md @@ -3,25 +3,27 @@ ### About The bot is specially designed for [SteamGifts.com](https://www.steamgifts.com/) -## TODO -* Add GUI - ### Features - Automatically enters giveaways. - Undetectable. +- ะกonvenient user interface. +- ะกonfigurable. - Sleeps to restock the points. - Can run 24/7. -### Instructions +### How to run 1. Download the latest version: https://github.com/stilManiac/steamgifts-bot/releases 2. Sign in on [SteamGifts.com](https://www.steamgifts.com/) by Steam. -3. Find `PHPSESSID` cookie in your browser and write it in `cookie.txt` file. -4. Make sure your cookie is right. -5. Start the bot. +3. Find `PHPSESSID` cookie in your browser. +4. Start the bot and follow instructions. -### Commands -`!sleep [arg]` - change a sleeping interval in sec. Default and recommended is 900 sec (15 min.). -`!page` - set a final websites page bot reaches +### Run from sources +```bash +python -m venv env +source env/bin/activate +pip install -r requirements.txt +python cli.py +``` ### Help -Please leave your feedback and bugs in `Issues` page. Thank you! +Please leave your feedback and bugs in `Issues` page. From 1ab5d688ff40478da7566097f39511b065057722 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Sat, 27 Jun 2020 00:00:08 +0300 Subject: [PATCH 7/9] Update requirements.txt --- requirements.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/requirements.txt b/requirements.txt index e69de29..53dd215 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,23 @@ +astroid==2.4.2 +beautifulsoup4==4.9.1 +certifi==2020.6.20 +chardet==3.0.4 +idna==2.9 +isort==4.3.21 +lazy-object-proxy==1.4.3 +mccabe==0.6.1 +prompt-toolkit==1.0.14 +pyconfigstore3==1.0.1 +pyfiglet==0.8.post1 +Pygments==2.6.1 +PyInquirer==1.0.3 +pylint==2.5.3 +regex==2020.6.8 +requests==2.24.0 +six==1.15.0 +soupsieve==2.0.1 +termcolor==1.1.0 +toml==0.10.1 +urllib3==1.25.9 +wcwidth==0.2.5 +wrapt==1.12.1 From eb202894101e365d9041618139a82e322aa1046d Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 27 Jun 2020 11:15:11 +0300 Subject: [PATCH 8/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 673739b..1feb828 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![](https://i.imgur.com/dKA3udT.png) +![](https://i.imgur.com/oCob3wQ.gif) ### About The bot is specially designed for [SteamGifts.com](https://www.steamgifts.com/) From a420a498dd728e3a20558345a2483fef3a2837c2 Mon Sep 17 00:00:00 2001 From: stilmaniac Date: Sat, 27 Jun 2020 12:05:58 +0300 Subject: [PATCH 9/9] Add to configuration: minimum points and pinned games --- README.md | 4 ++-- src/cli.py | 30 +++++++++++++++++++++++++++--- src/main.py | 39 +++++++++++++++++++++++++++------------ 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 673739b..e24df00 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![](https://i.imgur.com/dKA3udT.png) +![](https://i.imgur.com/oCob3wQ.gif) ### About The bot is specially designed for [SteamGifts.com](https://www.steamgifts.com/) @@ -22,7 +22,7 @@ The bot is specially designed for [SteamGifts.com](https://www.steamgifts.com/) python -m venv env source env/bin/activate pip install -r requirements.txt -python cli.py +python src/cli.py ``` ### Help diff --git a/src/cli.py b/src/cli.py index 2214754..bbd7f3d 100644 --- a/src/cli.py +++ b/src/cli.py @@ -1,10 +1,12 @@ import six import configparser +import re from pyfiglet import figlet_format from pyconfigstore import ConfigStore from PyInquirer import (Token, ValidationError, Validator, print_json, prompt, style_from_dict) +from prompt_toolkit import document try: import colorama @@ -37,13 +39,26 @@ def log(string, color, font="slant", figlet=False): six.print_(string) -def ask(type, name, message, validator=None, choices=[]): +class PointValidator(Validator): + def validate(self, document: document.Document): + value = document.text + try: + value = int(value) + except Exception: + raise ValidationError(message = 'Value should be greater than 0', cursor_position = len(document.text)) + + if value <= 0: + raise ValidationError(message = 'Value should be greater than 0', cursor_position = len(document.text)) + return True + + +def ask(type, name, message, validate=None, choices=[]): questions = [ { 'type': type, 'name': name, 'message': message, - 'validator': validator, + 'validate': validate, }, ] if choices: @@ -83,6 +98,10 @@ def run(): else: cookie = config['DEFAULT'].get('cookie') + pinned_games = ask(type='confirm', + name='pinned', + message='Should bot enter pinned games?')['pinned'] + gift_type = ask(type='list', name='gift_type', message='Select type:', @@ -95,7 +114,12 @@ def run(): 'New' ])['gift_type'] - s = SG(cookie, gift_type) + min_points = ask(type='input', + name='min_points', + message='Enter minimum points to start working (bot will try to enter giveaways until minimum value is reached):', + validate=PointValidator)['min_points'] + + s = SG(cookie, gift_type, pinned_games, min_points) s.start() diff --git a/src/main.py b/src/main.py index fa59e4c..4e0bcea 100644 --- a/src/main.py +++ b/src/main.py @@ -15,11 +15,13 @@ from cli import log class SteamGifts: - def __init__(self, cookie, gifts_type): + def __init__(self, cookie, gifts_type, pinned, min_points): self.cookie = { 'PHPSESSID': cookie } self.gifts_type = gifts_type + self.pinned = pinned + self.min_points = int(min_points) self.base = "https://www.steamgifts.com" self.session = requests.Session() @@ -60,8 +62,13 @@ class SteamGifts: def update_info(self): soup = self.get_soup_from_page(self.base) - self.xsrf_token = soup.find('input', {'name': 'xsrf_token'})['value'] - self.points = int(soup.find('span', {'class': 'nav__points'}).text) # storage points + try: + self.xsrf_token = soup.find('input', {'name': 'xsrf_token'})['value'] + self.points = int(soup.find('span', {'class': 'nav__points'}).text) # storage points + except TypeError: + log("โ›” Cookie is not valid.", "red") + sleep(10) + exit() def get_game_content(self, page=1): n = page @@ -74,13 +81,22 @@ class SteamGifts: soup = self.get_soup_from_page(paginated_url) - game_list = soup.find_all(lambda tag: tag.name == 'div' and tag.get('class') == ['giveaway__row-inner-wrap']) + game_list = soup.find_all('div', {'class': 'giveaway__row-inner-wrap'}) + + if not len(game_list): + log("โ›” Page is empty. Please, select another type.", "red") + sleep(10) + exit() for item in game_list: - if self.points == 0: - log("๐Ÿ›‹๏ธ Sleeping to get 6 points", "yellow") + if len(item.get('class', [])) == 2 and not self.pinned: + continue + + if self.points == 0 or self.points < self.min_points: + txt = f"๐Ÿ›‹๏ธ Sleeping to get 6 points. We have {self.points} points, but we need {self.min_points} to start." + log(txt, "yellow") sleep(900) - self.get_game_content(page=n) + self.start() break game_cost = item.find_all('span', {'class': 'giveaway__heading__thin'})[-1] @@ -101,14 +117,15 @@ class SteamGifts: game_id = item.find('a', {'class': 'giveaway__heading__name'})['href'].split('/')[2] res = self.entry_gift(game_id) if res: - txt = f"๐ŸŽ‰ One more game! Have just entered {game_name}" + self.points -= int(game_cost) + txt = f"๐ŸŽ‰ One more game! Has just entered {game_name}" log(txt, "green") - # sleep(randint(10, 30)) + sleep(randint(3, 7)) n = n+1 - log("๐Ÿ›‹๏ธ List of games is ended. Waiting 2 min to update...", "yellow") + log("๐Ÿ›‹๏ธ List of games is ended. Waiting 2 mins to update...", "yellow") sleep(120) self.start() @@ -117,8 +134,6 @@ class SteamGifts: entry = requests.post('https://www.steamgifts.com/ajax.php', data=payload, cookies=self.cookie) json_data = json.loads(entry.text) - self.update_info() - if json_data['type'] == 'success': return True