Skip to content

Commit

Permalink
Merge pull request #14 from LeagueOfPoro/restartingthreads
Browse files Browse the repository at this point in the history
Restart threads on failure
  • Loading branch information
LeagueOfPoro committed Jan 20, 2023
2 parents da26fae + 8c43d5c commit a890719
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 89 deletions.
9 changes: 8 additions & 1 deletion Browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import threading
from time import sleep
from Config import Config
from StatusCodeAssertException import StatusCodeAssertException


class Browser:
Expand Down Expand Up @@ -106,6 +107,7 @@ def refreshTokens(self):
self.maintainSession()
else:
self.log.error("Failed to refresh session")
raise StatusCodeAssertException(200, resAccessToken.status_code, resAccessToken.request.url)

def maintainSession(self):
"""
Expand All @@ -129,6 +131,8 @@ def getLiveMatches(self):
"x-api-key": "0TvQnueqKa5mxJntVWt0w4LpLfEkrV1Ta8rQBb9Z"}
res = self.client.get(
"https://esports-api.lolesports.com/persisted/gw/getLive?hl=en-GB", headers=headers)
if res.status_code != 200:
raise StatusCodeAssertException(200, res.status_code, res.request.url)
resJson = res.json()
self.liveMatches = {}
try:
Expand Down Expand Up @@ -179,8 +183,11 @@ def __sendWatch(self, match: Match) -> object:
"tournament_id": match.tournamentId}
headers = {"Origin": "https://lolesports.com",
"Referrer": "https://lolesports.com"}
return self.client.post(
res = self.client.post(
"https://rex.rewards.lolesports.com/v1/events/watch", headers=headers, json=data)
if res.status_code != 201:
raise StatusCodeAssertException(201, res.status_code, res.request.url)
return res

def __getLoginTokens(self, form: str) -> tuple[str, str]:
"""
Expand Down
50 changes: 29 additions & 21 deletions FarmThread.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,35 @@ def run(self):
"""
Start watching every live match
"""
# self.log.info(f"Creating a farm for {self.account}")
self.stats.updateStatus(self.account, "[green]LOGIN")
if self.browser.login(self.config.getAccount(self.account)["username"], self.config.getAccount(self.account)["password"]):
self.stats.updateStatus(self.account, "[green]LIVE")
while True:
self.browser.getLiveMatches()
dropsAvailable = self.browser.sendWatchToLive()
if self.browser.liveMatches:
liveMatchesStatus = []
for m in self.browser.liveMatches.values():
status = dropsAvailable.get(m.league, False)
liveMatchesStatus.append(f"{'[green1]' if status else '[orange1]'}{m.league}{'[/]'}")
self.log.debug(f"{', '.join(liveMatchesStatus)}")
liveMatchesMsg = f"{', '.join(liveMatchesStatus)}"
else:
liveMatchesMsg = "None"
self.stats.update(self.account, 0, liveMatchesMsg)
sleep(Browser.STREAM_WATCH_INTERVAL)
else:
self.log.error(f"Login for {self.account} FAILED!")
self.stats.updateStatus(self.account, "[red]LOGIN FAILED")
try:
self.stats.updateStatus(self.account, "[green]LOGIN")
if self.browser.login(self.config.getAccount(self.account)["username"], self.config.getAccount(self.account)["password"]):
self.stats.updateStatus(self.account, "[green]LIVE")
self.stats.resetLoginFailed(self.account)
while True:
self.browser.getLiveMatches()
dropsAvailable = self.browser.sendWatchToLive()
if self.browser.liveMatches:
liveMatchesStatus = []
for m in self.browser.liveMatches.values():
status = dropsAvailable.get(m.league, False)
if status:
liveMatchesStatus.append(f"[green]{m.league}[/]")
else:
liveMatchesStatus.append(f"{m.league}")
self.log.debug(f"{', '.join(liveMatchesStatus)}")
liveMatchesMsg = f"{', '.join(liveMatchesStatus)}"
else:
liveMatchesMsg = "None"
self.stats.update(self.account, 0, liveMatchesMsg)
sleep(Browser.STREAM_WATCH_INTERVAL)
else:
self.log.error(f"Login for {self.account} FAILED!")
self.stats.updateStatus(self.account, "[red]LOGIN FAILED")
self.stats.addLoginFailed(self.account)
except Exception:
self.log.exception(f"Error in {self.account}. The program will try to recover.")


def stop(self):
"""
Expand Down
5 changes: 1 addition & 4 deletions GuiThread.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ def generateTable(self):
# table.add_column("Drops")

for acc in self.stats.accountData:
if acc not in self.stats.farmThreads :
status = "[yellow]WAIT"
else:
status = self.stats.accountData[acc]["status"] if self.stats.farmThreads[acc].is_alive() else "[red]ERROR"
status = self.stats.accountData[acc]["status"]
# table.add_row(f"{acc}", f"{status}", f"{self.stats.accountData[acc]['liveMatches']}", f"{self.stats.accountData[acc]['lastCheck']}", f"{self.stats.accountData[acc]['lastDrop']}", f"{self.stats.accountData[acc]['totalDrops']}")
table.add_row(f"{acc}", f"{status}", f"{self.stats.accountData[acc]['liveMatches']}", f"{self.stats.accountData[acc]['lastCheck']}")
return table
Expand Down
20 changes: 0 additions & 20 deletions Logger/Logger.py → Logger.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,10 @@
import logging
import logging.config
from Logger.CustomFormatter import CustomFormatter
from datetime import datetime


class Logger:
def createLogger(self, debug: bool):
# logging.config.dictConfig({
# 'version': 1,
# 'disable_existing_loggers': True,

# })

# log = logging.getLogger("League of Poro")
# if (debug):
# log.setLevel('DEBUG')
# else:
# log.setLevel('INFO')
# ch = logging.StreamHandler()
# if (debug):
# ch.setLevel('DEBUG')
# else:
# ch.setLevel('INFO')
# ch.setFormatter(CustomFormatter())
# log.addHandler(ch)

if (debug):
level = logging.DEBUG
else:
Expand Down
29 changes: 0 additions & 29 deletions Logger/CustomFormatter.py

This file was deleted.

11 changes: 10 additions & 1 deletion Stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def __init__(self, farmThreads) -> None:
self.accountData = {}

def initNewAccount(self, accountName: str):
self.accountData[accountName] = {"lastCheck": "", "totalDrops": 0, "lastDrop": "", "liveMatches": "", "status": ""}
self.accountData[accountName] = {"lastCheck": "", "totalDrops": 0, "lastDrop": "", "liveMatches": "", "status": "[yellow]WAIT", "failedLoginCounter": 0}

def update(self, accountName: str, newDrops: int = 0, liveMatches: str = ""):
self.accountData[accountName]["lastCheck"] = datetime.now().strftime("%H:%M:%S %d/%m")
Expand All @@ -17,4 +17,13 @@ def update(self, accountName: str, newDrops: int = 0, liveMatches: str = ""):

def updateStatus(self, accountName: str, msg: str):
self.accountData[accountName]["status"] = msg

def addLoginFailed(self, accountName: str):
self.accountData[accountName]["failedLoginCounter"] += 1

def resetLoginFailed(self, accountName: str):
self.accountData[accountName]["failedLoginCounter"] = 0

def getFailedLogins(self, accountName: str):
return self.accountData[accountName]["failedLoginCounter"]

6 changes: 6 additions & 0 deletions StatusCodeAssertException.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class StatusCodeAssertException(Exception):
def __init__(self, expected, received, url):
self.expected = expected
self.received = received
self.url = url
super().__init__(f"Received unexpected status code. Wanted {self.expected} but got {self.received} in {self.url}")
47 changes: 34 additions & 13 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

from FarmThread import FarmThread
from GuiThread import GuiThread
from Logger.Logger import Logger
from Logger import Logger
from Config import Config
import sys
import argparse
Expand All @@ -10,7 +10,7 @@
from Stats import Stats
from VersionManager import VersionManager

CURRENT_VERSION = 0.3
CURRENT_VERSION = 0.4

parser = argparse.ArgumentParser(description='Farm Esports Capsules by watching all matches on lolesports.com.')
parser.add_argument('-c', '--config', dest="configPath", default="./config.yaml",
Expand All @@ -37,20 +37,41 @@
for account in config.accounts:
stats.initNewAccount(account)

log.info(f"Starting a GUI thread.")
gui = GuiThread(log, config, stats)
gui.daemon = True
gui.start()

for account in config.accounts:
thread = FarmThread(log, config, account, stats)
thread.daemon = True
thread.start()
farmThreads[account] = thread

for thread in farmThreads.values():
try:
while thread.is_alive():
thread.join(1)
except (KeyboardInterrupt, SystemExit):
try:
while True:
toDelete = []
for account in config.accounts:
if account not in farmThreads:
if stats.getFailedLogins(account) < 3:
log.info(f"Starting a thread for {account}.")
thread = FarmThread(log, config, account, stats)
thread.daemon = True
thread.start()
farmThreads[account] = thread
log.info(f"Thread for {account} was created.")
else:
stats.updateStatus(account, "[red]LOGIN FAILED")
log.error(f"Maximum login retries reached for account {account}")
toDelete.append(account)
if not farmThreads:
break
for account in toDelete:
del config.accounts[account]

toDelete = []
for account in farmThreads:
if farmThreads[account].is_alive():
farmThreads[account].join(1)
else:
toDelete.append(account)
log.warning(f"Thread {account} has finished.")
for account in toDelete:
del farmThreads[account]
except (KeyboardInterrupt, SystemExit):
print('Exitting. Thank you for farming with us!')
sys.exit()

0 comments on commit a890719

Please sign in to comment.