diff --git a/lidarr/ARLChecker b/lidarr/ARLChecker index 1ce1906..6ee96b6 100644 --- a/lidarr/ARLChecker +++ b/lidarr/ARLChecker @@ -5,4 +5,4 @@ scriptName="ARLChecker" echo Starting ARL Token Check... python /custom-services.d/python/ARLChecker.py -c echo ARL Token Check Complete. Sleeping for 24hrs... -sleep 24h \ No newline at end of file +sleep 1m \ No newline at end of file diff --git a/lidarr/python/ARLChecker.py b/lidarr/python/ARLChecker.py index 91a2ca8..5389e9d 100644 --- a/lidarr/python/ARLChecker.py +++ b/lidarr/python/ARLChecker.py @@ -10,28 +10,25 @@ from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler import logging import os + +VERSION = 0.1 + +# Logging Setup logging.basicConfig( - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + format=f'%(asctime)s :: ARLChecker :: {VERSION} :: %(levelname)s :: %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO ) logger = logging.getLogger(__name__) -#Initialize colorama +# Initialize colorama init(autoreset=True) +# Web agent used to access Deezer USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/110.0' - -# Deezer Login Exception messages -CONNECTION_ERROR = 'Could not connect! Service down, API changed, wrong credentials or code-related issue.' -APP_ID_ERROR = 'Could not obtain App-Id! Service down or API changed.' -AUTH_ERROR = 'Could not login! Credentials wrong or non-existent account!' -PARSE_ERROR = 'Could not parse JSON!' - - - @dataclass class Plan: name: str @@ -88,22 +85,26 @@ class DeezerPlatformProvider: ) res.raise_for_status() except Exception as error: - raise ConnectionError(CONNECTION_ERROR) + logger.error(Fore.RED + 'Could not connect! Service down, API changed, wrong credentials or code-related issue.' + Fore.WHITE) + raise ConnectionError() self.session.cookies.clear() try: res = res.json() except Exception as error: - raise ParseError(PARSE_ERROR) + logger.error(Fore.RED + "Could not parse JSON response from DEEZER!" + Fore.WHITE) + raise ParseError() if 'error' in res and res['error']: - raise ServiceError(res["error"]) + logger.error(Fore.RED + "Deezer returned the following error:{}".format(res["error"]) + Fore.WHITE) + raise ServiceError() res = res['results'] if res['USER']['USER_ID'] == 0: - raise AuthError(AUTH_ERROR) + logger.error(Fore.RED+"ARL Token Expired. Update the token in extended.conf"+Fore.WHITE) + raise AuthError() return Account(username, secret, res['COUNTRY'], Plan( res['OFFER_NAME'], @@ -121,7 +122,7 @@ class LidarrExtendedAPI: workingDir = Path(os.getcwd()) print(workingDir) #self.parentDir = str(workingDir.parents[1]) - self.parentDir = str(workingDir.parents[3]) # TODO: Enable when pushing + self.parentDir = str(workingDir.parents[3]) print(self.parentDir) self.extendedConfDir = self.parentDir + '/config/extended.conf' self.newARLToken = new_arl_token @@ -133,6 +134,9 @@ class LidarrExtendedAPI: self.telegram_bot_running = False self.telegram_bot_token = None self.telegram_user_chat_id = None + self.telegramBotEnableLineText = None + self.telegramBotEnableLineIndex = None + self.bot = None self.parse_extended_conf() @@ -142,7 +146,6 @@ class LidarrExtendedAPI: deezer_active = False self.arlToken = None arl_token_match = None - #re_search_pattern = r'"([A-Za-z0-9_\./\\-]*)"' re_search_pattern = r'"([^"]*)"' try: # Try to open extended.conf and read all text into a var. with open(self.extendedConfDir, 'r', encoding='utf-8') as file: @@ -174,6 +177,8 @@ class LidarrExtendedAPI: for line in self.fileText: if 'telegramBotEnable=' in line: + self.telegramBotEnableLineText = line + self.telegramBotEnableLineIndex = self.fileText.index(self.telegramBotEnableLineText) self.enable_telegram_bot = re.search(re_search_pattern, line)[0].replace('"', '').lower() in 'true' if 'telegramBotToken=' in line: self.telegram_bot_token = re.search(re_search_pattern, line)[0].replace('"', '') @@ -191,6 +196,7 @@ class LidarrExtendedAPI: # Uses DeezerPlatformProvider to check if the token is valid def check_token(self, token=None): + logger.info('Checking ARL Token Validity...') if token is None: print('Invalid ARL Token Entry') return False @@ -198,13 +204,15 @@ class LidarrExtendedAPI: deezer_check = DeezerPlatformProvider() account = deezer_check.login('', token.replace('"','')) if account.plan: - print('Deezer Account Found.') - print(f'Plan: {account.plan.name}', end=' | ') - print(f'Expiration: {account.plan.expires}', end=' | ') - print(f'Active: {Fore.GREEN+"Y" if account.plan.active else "N"}', end=' | ') - print(f'Download: {Fore.GREEN+"Y" if account.plan.download else Fore.RED+"N"}', end=' | ') - print(f'Lossless: {Fore.GREEN+"Y" if account.plan.lossless else Fore.RED+"N"}', end=' | ') - print(f'Explicit: {Fore.GREEN+"Y" if account.plan.explicit else Fore.RED+"N"}') + logger.info(Fore.GREEN + f'Deezer Account Found.'+ Fore.WHITE) + logger.info('-------------------------------') + logger.info(f'Plan: {account.plan.name}') + logger.info(f'Expiration: {account.plan.expires}') + logger.info(f'Active: {Fore.GREEN+"Y" if account.plan.active else "N"}'+Fore.WHITE) + logger.info(f'Download: {Fore.GREEN+"Y" if account.plan.download else Fore.RED+"N"}'+Fore.WHITE) + logger.info(f'Lossless: {Fore.GREEN+"Y" if account.plan.lossless else Fore.RED+"N"}'+Fore.WHITE) + logger.info(f'Explicit: {Fore.GREEN+"Y" if account.plan.explicit else Fore.RED+"N"}'+Fore.WHITE) + logger.info('-------------------------------') return True except Exception as e: print(e) @@ -212,11 +220,10 @@ class LidarrExtendedAPI: if self.telegram_bot_running: return False if self.enable_telegram_bot: - logger.info('Starting Telegram bot') + logger.info('Starting Telegram bot...Check Telegram and follow instructions.') self.telegram_bot_running = True self.start_telegram_bot() exit(420) - # TODO: fix this def set_new_token(self): # Re-writes extended.conf with previously read-in text, replacing w/ new ARL self.fileText[self.arlLineIndex] = self.arlLineText.replace(self.arlToken, self.newARLToken) @@ -225,7 +232,7 @@ class LidarrExtendedAPI: file.close() logger.info("New ARL token written to extended.conf") - # After new token is set, clean up notfound and failed downloads to bypass the default 30 day wait + # After new token is set, clean up notfound and failed downloads to bypass the default 30 day wait def clear_not_found(self): paths = [self.parentDir + '/config/extended/logs/notfound',self.parentDir+'/config/extended/logs/downloaded/failed/deezer'] for path in paths: @@ -236,12 +243,22 @@ class LidarrExtendedAPI: def start_telegram_bot(self): self.bot = TelegramBotControl(self,self.telegram_bot_token,self.telegram_user_chat_id) + def disable_telegram_bot(self): + compiled = re.compile(re.escape('true'), re.IGNORECASE) + self.fileText[self.telegramBotEnableLineIndex] = compiled.sub('false', self.telegramBotEnableLineText) + with open(self.extendedConfDir, 'w', encoding='utf-8') as file: + file.writelines(self.fileText) + file.close() + logger.info("Telegram Bot Disabled.") + + + class TelegramBotControl: def __init__(self, parent,telegram_bot_token,telegram_user_chat_id): async def send_expired_token_notification(application): - await application.bot.sendMessage(chat_id=self.telegram_chat_id,text='---\U0001F6A8WARNING\U0001F6A8-----\nARL TOKEN EXPIRED\n Update Token by running "/set_token "\n You can find a new ARL at:\nhttps://rentry.org/firehawk52#deezer-arls',disable_web_page_preview=True) + await application.bot.sendMessage(chat_id=self.telegram_chat_id,text='---\U0001F6A8WARNING\U0001F6A8-----\nARL TOKEN EXPIRED\n Update Token by running "/set_token "\n You can find a new ARL at:\nhttps://rentry.org/firehawk52#deezer-arls\n\n\n Other Commands:\n/cancel - Cancel this session\n/disable - Disable Telegram Bot',disable_web_page_preview=True) # TODO: Get Chat ID/ test on new bot self.parent = parent @@ -250,12 +267,26 @@ class TelegramBotControl: # start bot control self.application = ApplicationBuilder().token(self.telegram_bot_token).post_init(send_expired_token_notification).build() token_handler = CommandHandler('set_token', self.set_token) + cancel_handler = CommandHandler('cancel', self.cancel) + disable_handler = CommandHandler('disable', self.disable_bot) self.application.add_handler(token_handler) + self.application.add_handler(cancel_handler) + self.application.add_handler(disable_handler) self.application.run_polling(allowed_updates=Update.ALL_TYPES) + async def disable_bot(self, update, context: ContextTypes.DEFAULT_TYPE): + self.parent.disable_telegram_bot() + await update.message.reply_text('Disabled Telegram Bot. \U0001F614\nIf you would like to re-enable,\nset telegramBotEnable to true\nin extended.conf') + self.application.stop_running() + async def cancel(self, update, context: ContextTypes.DEFAULT_TYPE): + await update.message.reply_text('Canceling...ARLToken is still expired.') + try: + self.application.stop_running() + except Exception: + pass async def set_token(self, update, context: ContextTypes.DEFAULT_TYPE): try: new_token = update.message.text.split('/set_token ')[1] @@ -304,7 +335,16 @@ def main(arlToken = None): if arlToken_instance.arlToken == '': print("ARL Token not set. re-run with -n flag") exit(1) - arlToken_instance.check_token(arlToken_instance.arlToken) + try: + arlToken_instance.check_token(arlToken_instance.arlToken) + except Exception as e: + if 'Chat not found' in str(e): + logger.error(Fore.RED + "Chat not found. Check your chat ID in extended.conf, or start a chat with your bot."+Fore.WHITE) + elif 'The token' in str(e): + logger.error(Fore.RED + "Check your Bot Token in extended.conf."+Fore.WHITE) + else: + print(e) + exit(1) elif args.new: