diff --git a/pyfa.py b/pyfa.py index 706af752c..9c8d0b14a 100755 --- a/pyfa.py +++ b/pyfa.py @@ -150,6 +150,12 @@ def _process_args(self, largs, rargs, values): mf = MainFrame(options.title) ErrorHandler.SetParent(mf) + # Start ESI token validation, this helps avoid token expiry + from service.esi import Esi + esi = Esi.getInstance() + esi.startTokenValidation() + pyfalog.info("ESI token validation started") + if options.profile_path: profile_path = os.path.join(options.profile_path, 'pyfa-{}.profile'.format(datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))) pyfalog.debug("Starting pyfa with a profiler, saving to {}".format(profile_path)) diff --git a/service/esi.py b/service/esi.py index 35d92a56f..e176e223f 100644 --- a/service/esi.py +++ b/service/esi.py @@ -25,6 +25,44 @@ _t = wx.GetTranslation +class EsiTokenValidationThread(threading.Thread): + def __init__(self, callback=None): + threading.Thread.__init__(self) + self.name = "EsiTokenValidation" + self.callback = callback + self.running = True + + def run(self): + with config.logging_setup.threadbound(): + try: + esi = Esi.getInstance() + chars = esi.getSsoCharacters() + + for char in chars: + if not self.running: + return + + if char.is_token_expired(): + pyfalog.info(f"Token expired for {char.characterName}, attempting refresh") + try: + esi.refresh(char) + eos.db.save(char) + pyfalog.info(f"Successfully refreshed token for {char.characterName}") + except Exception as e: + pyfalog.error(f"Failed to refresh token for {char.characterName}: {e}") + else: + pyfalog.debug(f"Token valid for {char.characterName}") + + except Exception as e: + pyfalog.error(f"Error validating ESI tokens: {e}") + finally: + if self.callback: + wx.CallAfter(self.callback) + + def stop(self): + self.running = False + + class Esi(EsiAccess): _instance = None @@ -194,3 +232,9 @@ def handleServerRequest(self, message): pyfalog.debug("Handling SSO login with: {0}", message) self.handleLogin(message['code']) + + def startTokenValidation(self): + pyfalog.debug("Starting ESI token validation thread") + tokenValidationThread = EsiTokenValidationThread() + tokenValidationThread.daemon = True + tokenValidationThread.start()