async def on_error(self, event_method: str, *args: Any, **kwargs: Any) -> None: await super().on_error(event_method, args, kwargs) (_, exception, __) = sys.exc_info() try: content = [arg.content for arg in args if hasattr(arg, 'content')] # The default string representation of a Message does not include the message content. repo.create_issue(f'Bot error {event_method}\n{args}\n{kwargs}\n{content}', 'discord user', 'discordbot', 'PennyDreadfulMTG/perf-reports', exception=exception) except GithubException as e: logging.error('Github error\n%s', e)
def internal_server_error(e): traceback.print_exception(e, e, None) path = request.path try: repo.create_issue('500 error at {path}\n {e}'.format(path=path, e=e), session.get('id', 'logged_out'), 'decksite', 'PennyDreadfulMTG/perf-reports', exception=e) except GithubException: print("Github error") view = InternalServerError(e) return view.page(), 500
async def close(self) -> None: try: p = await asyncio.create_subprocess_shell('git pull') await p.wait() p = await asyncio.create_subprocess_shell(f'{sys.executable} -m pip install -U -r requirements.txt --no-cache') await p.wait() except Exception as c: # pylint: disable=broad-except repo.create_issue('Bot error while closing', 'discord user', 'discordbot', 'PennyDreadfulMTG/perf-reports', exception=c) await super().close()
def do_push() -> None: gh_repo = os.path.join(configuration.get_str('legality_dir'), 'gh_pages') if not os.path.exists(gh_repo): subprocess.run(['git', 'clone', 'https://github.com/PennyDreadfulMTG/pennydreadfulmtg.github.io.git', gh_repo], check=True) setcode = rotation.next_rotation_ex().mtgo_code files = ['legal_cards.txt', f'{setcode}_legal_cards.txt'] for fn in files: source = os.path.join(configuration.get_str('legality_dir'), fn) dest = os.path.join(gh_repo, fn) shutil.copy(source, dest) os.chdir(gh_repo) subprocess.run(['git', 'add'] + files, check=True) subprocess.run(['git', 'commit', '-m', f'{setcode} rotation'], check=True) subprocess.run(['git', 'push'], check=True) checklist = f"""{setcode} rotation checklist https://pennydreadfulmagic.com/admin/rotation/ - [ ] upload legal_cards.txt to S3 - [ ] upload {setcode}_legal_cards.txt to S3 - [ ] ping scryfall - [ ] email mtggoldfish - [ ] ping tappedout """ if redis.get_str('discordbot:commit_id'): redis.store('discordbot:do_reboot', True) else: checklist += '- [ ] restart discordbot' ds = os.path.expanduser('~/decksite/') failed = False try: if os.path.exists(ds): os.chdir(ds) subprocess.run(['python3', 'run.py', 'maintenance', 'post_rotation'], check=True) else: failed = True except Exception: # pylint: disable=broad-except failed = True if failed: checklist += '- [ ] run post_rotation\n' try: fetch_tools.post('https://gatherling.com/util/updateDefaultFormats.php') except fetch_tools.FetchException: checklist += '- [ ] Update Gatherling legal cards list' for path in ['/etc/uwsgi/vassals/decksite.ini', '/home/discord/vassals/decksite.ini']: srv = pathlib.Path(path) if srv.exists(): srv.touch() break else: checklist += '- [ ] touch /etc/uwsgi/vassals/decksite.ini\n' repo.create_issue(checklist, 'rotation script', 'rotation')
def internal_server_error(self, e: Exception) -> Tuple[str, int]: log_exception(e) path = request.path try: repo.create_issue('500 error at {path}\n {e}'.format(path=path, e=e), session.get('mtgo_username', session.get('id', 'logged_out')), self.name, 'PennyDreadfulMTG/perf-reports', exception=e) except GithubException: logger.error('Github error', e) if request.path.startswith('/api/'): return return_json(generate_error('INTERNALERROR', 'Internal Error.', exception=e), status=404) view = InternalServerError(e) return view.page(), 500
async def on_error(self, event_method: str, *args: Any, **kwargs: Any) -> None: await super().on_error(event_method, args, kwargs) (_, exception, __) = sys.exc_info() try: repo.create_issue(f'Bot error {event_method}\n{args}\n{kwargs}', 'discord user', 'discordbot', 'PennyDreadfulMTG/perf-reports', exception=exception) except GithubException as e: print('Github error', e, file=sys.stderr)
def check(start_time, kind, detail, location): run_time = time.perf_counter() - start_time limit = configuration.get(kind) detail_s = detail if isinstance(detail, str) else '; '.join( map(str, list(detail))) if limit is not None and run_time > limit: msg = 'Exceeded {kind} limit ({run_time} > {limit}) in {location}: {detail_s} ({kind}, {run_time}, {location})'.format( kind=kind, run_time=round(run_time, 1), limit=limit, detail_s=detail_s, location=location) repo.create_issue(msg, 'perf', location, 'PennyDreadfulMTG/perf-reports')
async def gatherlingbug(ctx: MtgContext, *, text: str) -> None: """Report a Gatherling bug.""" issue = repo.create_issue(text, str(ctx.author), 'Discord', 'PennyDreadfulMTG/gatherling') if issue is None: await ctx.send('Report Gatherling issues at <https://github.com/PennyDreadfulMTG/gatherling/issues/new>') else: await ctx.send('Issue has been reported at <{url}>'.format(url=issue.html_url))
async def bug(ctx: MtgContext, *, text: str) -> None: """Report a bug/task for the Penny Dreadful Tools team. For Magic Online bugs see `!modobug`.""" issue = repo.create_issue(text, ctx.author) if issue is None: await ctx.send('Report issues at <https://github.com/PennyDreadfulMTG/Penny-Dreadful-Tools/issues/new>') else: await ctx.send('Issue has been reported at <{url}>'.format(url=issue.html_url))
async def gbug(self, client: Client, channel: Channel, args: str, author: Member, **_: Dict[str, Any]) -> None: """Report a Gatherling bug.""" await client.send_typing(channel) issue = repo.create_issue(args, author, 'Discord', 'PennyDreadfulMTG/gatherling') if issue is None: await client.send_message(channel, 'Report Gatherling issues at <https://github.com/PennyDreadfulMTG/gatherling/issues/new>') else: await client.send_message(channel, 'Issue has been reported at <{url}>.'.format(url=issue.html_url))
async def bug(self, client: Client, channel: Channel, args: str, author: Member, **_: Dict[str, Any]) -> None: """Report a bug/task for the Penny Dreadful Tools team. For Magic Online bugs see `!modobug`.""" await client.send_typing(channel) issue = repo.create_issue(args, author) if issue is None: await client.send_message(channel, 'Report issues at <https://github.com/PennyDreadfulMTG/Penny-Dreadful-Tools/issues/new>') else: await client.send_message(channel, 'Issue has been reported at <{url}>'.format(url=issue.html_url))
def check(start_time: float, kind: str, detail: Any, location: str) -> None: run_time = time.perf_counter() - start_time limit = configuration.get_float(kind) if limit is not None and run_time > limit: detail_s = detail if isinstance(detail, str) else '\n\n'.join( map(str, list(detail))) msg = 'Exceeded {kind} limit ({run_time} > {limit}) in {location}: {detail_s} ({kind}, {run_time}, {location})'.format( kind=kind, run_time=round(run_time, 1), limit=limit, detail_s=detail_s, location=location) try: flask_location = current_app.name except RuntimeError: # Working outside of application context flask_location = None repo.create_issue(msg, f'{location}-perf', flask_location or location, 'PennyDreadfulMTG/perf-reports')
def task(args: List[str]) -> None: try: module = args[0] if module == 'scraper': module = 'scrapers' if module == 'scrapers': module = 'decksite.scrapers' name = args[1] from magic import multiverse, oracle multiverse.init() if name != 'reprime_cache': oracle.init() if name == 'all': run_all_tasks(module) elif name == 'hourly': run_all_tasks(module, 'HOURLY') else: s = importlib.import_module('{module}.{name}'.format( name=name, module=module)) use_app_context = getattr(s, 'REQUIRES_APP_CONTEXT', True) if use_app_context: from decksite.main import APP APP.config['SERVER_NAME'] = configuration.server_name() app_context = APP.app_context() # type: ignore app_context.__enter__() # type: ignore if getattr(s, 'scrape', None) is not None: exitcode = s.scrape(*args[2:]) # type: ignore elif getattr(s, 'run', None) is not None: exitcode = s.run() # type: ignore # Only when called directly, not in 'all' elif getattr(s, 'ad_hoc', None) is not None: exitcode = s.ad_hoc() # type: ignore if use_app_context: app_context.__exit__(None, None, None) if exitcode is not None: sys.exit(exitcode) except Exception as c: from shared import repo repo.create_issue(f'Error running task {args}', 'CLI', 'CLI', 'PennyDreadfulMTG/perf-reports', exception=c) raise
def run_all_tasks(module: Any, with_flag: Optional[str] = None) -> None: error = None app_context = None m = importlib.import_module('{module}'.format(module=module)) # pylint: disable=unused-variable for _importer, modname, _ispkg in pkgutil.iter_modules( m.__path__): # type: ignore try: s = importlib.import_module('{module}.{name}'.format( name=modname, module=module)) use_app_context = getattr(s, 'REQUIRES_APP_CONTEXT', True) if use_app_context and app_context is None: from decksite import APP APP.config['SERVER_NAME'] = configuration.server_name() app_context = APP.app_context() # type: ignore app_context.__enter__() # type: ignore if with_flag and not getattr(s, with_flag, False): continue if getattr(s, 'scrape', None) is not None: timer = time.perf_counter() s.scrape() # type: ignore t = time.perf_counter() - timer print(f'{s.__name__} completed in {t}') elif getattr(s, 'run', None) is not None: timer = time.perf_counter() s.run() # type: ignore t = time.perf_counter() - timer print(f'{s.__name__} completed in {t}') except Exception as c: # pylint: disable=broad-except from shared import repo repo.create_issue(f'Error running task {s.__name__}', 'CLI', 'CLI', 'PennyDreadfulMTG/perf-reports', exception=c) error = c if app_context is not None: app_context.__exit__(None, None, None) if error: raise error
async def bug(self, bot, channel, args, author): """Report a bug/task for the Penny Dreadful Tools team. For MTGO bugs see `!modobug`.""" await bot.client.send_typing(channel) issue = repo.create_issue(args, author) if issue is None: await bot.client.send_message( channel, "Report issues at <https://github.com/PennyDreadfulMTG/Penny-Dreadful-Tools/issues/new>" ) else: await bot.client.send_message( channel, "Issue has been reported at <{url}>".format( url=issue.html_url))
async def modobug(self, bot, channel, args, author): """Report a Magic Online bug.""" await bot.client.send_typing(channel) issue = repo.create_issue(args, author, 'Discord', 'PennyDreadfulMTG/modo-bugs') if issue is None: await bot.client.send_message( channel, 'Report Magic Online issues at <https://github.com/PennyDreadfulMTG/modo-bugs/issues/new>' ) else: await bot.client.send_message( channel, 'Issue has been reported at <{url}>. Please add square brackets and screenshot as explained here: <https://github.com/PennyDreadfulMTG/modo-bugs/blob/master/README.md>' .format(url=issue.html_url))