async def display_mtg_card(putter, card): msg = '' async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(f'{const.MTG_API}{card}') as r: resp = await r.text() all_cards = json.loads(resp) if r.status != 200: msg = all_cards['details'] else: card_info = all_cards['data'][0] card_name = card_info['name'] card_img = '' if 'card_faces' in card_info and 'image_uris' not in card_info: card_img = card_info['card_faces'][0]['image_uris'][ 'normal'] else: card_img = card_info['image_uris']['normal'] card_link = card_info['scryfall_uri'] img_uhtml = gen_uhtml_img_code(card_img, height_resize=200, alt=card_name) msg = f'/adduhtml hippomtg-{card}, <a href=\'{card_link}\'>{img_uhtml}</a>' await putter(f'{const.TCG_ROOM}|{msg}')
def profile(self, username): player = self.player_info(username) box = type(username, (PlayerBoxTable, ), {}) showcases = box.select().where(box.showcase > 0).order_by( box.showcase.asc()) sc_infos = [(const.BLANK_IMG, '', '', 1)] * 5 for i, sc in enumerate(showcases): sc_infos[i] = (sc.full_img, sc.name, sc.unit_url, sc.gacha) showcase_uhtmls = [] for i, info in enumerate(sc_infos): is_first = (i == 0) img_height = 100 if is_first else 85 img_uhtml = '' img_style = '"border-radius:5px; border: 1px solid #FFD700"' if info[3] == 'fgo': img_width = (img_height * 512 // 724) img_uhtml = gen_uhtml_img_code(info[0], dims=(img_width, img_height), alt=info[1], style=img_style) else: img_uhtml = gen_uhtml_img_code(info[0], height_resize=img_height, alt=info[1], style=img_style) sc_kwargs = { 'is_first': is_first, 'unit_url': info[2], 'img_uhtml': img_uhtml } showcase_uhtmls.append(UserInfo.showcase_uhtml(**sc_kwargs)) user_info = UserInfo(username, '', 'steam') kwargs = { 'roll_currency': player.roll_currency, 'reroll_currency': player.reroll_currency, 'showcases': showcase_uhtmls } uhtml = user_info.gacha_user(**kwargs) return f'/adduhtml gprofile-{username}, {uhtml}'
def unit_uhtml(unit, pm=False): """ Generates the uhtml for a unit. """ img_url = json.loads(unit.img_url_pv)[-1] img_uhtml = gen_uhtml_img_code(img_url, height_resize=40, center=False, alt=f'\'{unit.name}\'') all_uhtml = ('<span style=\'padding: 1px\'>' f'<a href=\'{unit.unit_url}\'>' f'{img_uhtml}</a></span>') return all_uhtml
async def gen_mangadex_question(self, session): series_id = '' cover_id = '' answers = [] while not series_id: await asyncio.sleep(0.2) async with session.get(f'{const.DEX_API}manga/random') as r: rand_series = await r.json() if r.status != 200: await asyncio.sleep(3) continue series_info = rand_series['data'] if series_info['attributes']['contentRating'] != 'safe': continue skip = False for tag in series_info['attributes']['tags']: if tag['attributes']['name']['en'] in [ 'Doujinshi', 'Oneshot' ]: skip = True break if skip: continue if not self.duplicate_check(series_info['id']): series_id = series_info['id'] answers = [series_info['attributes']['title']['en']] for title in series_info['attributes']['altTitles']: if len(find_true_name(title['en'])) > 0: answers.append(title['en']) async with session.get(f'{const.DEX_API}cover', params={'manga[]': [series_id]}) as r: covers = await r.json() cover_info = random.choice(covers['data']) cover_id = cover_info['attributes']['fileName'] img_url = f'https://uploads.mangadex.org/covers/{series_id}/{cover_id}.256.jpg' img_uhtml = gen_uhtml_img_code(img_url, height_resize=PIC_SIZE) await self.questions.put( ['/adduhtml {}, {}'.format(UHTML_NAME, img_uhtml), answers])
async def gen_uhtml_steam_game(game_id, recent_hours, total_hours): game_info = await steam_game_info(game_id) if not game_info: return None game_name = game_info['name'] img_uhtml = gen_uhtml_img_code(game_info['header_image'], height_resize=50) game_kwargs = { 'img_uhtml': img_uhtml, 'url': f'https://store.steampowered.com/app/{game_id}', 'name': game_name, 'recent_hours': round(recent_hours, 1), 'total_hours': round(total_hours, 1) } msg = UserInfo.steam_game_uhtml(**game_kwargs) return msg
async def gen_am_question(self, session, anilist_man, anagrams=False): base = await self.gen_am_base(session, anilist_man) while self.duplicate_check(base['id']) or not base['img_url']: base = await self.gen_am_base(session, anilist_man) self.q_bases.append(base['id']) if anagrams: answer = random.choice(base['answers']) scrambled = anagram_scramble(answer) await self.questions.put( [f'/announce Unscramble this: **{scrambled}**', [answer]]) return img_url = gen_uhtml_img_code(base['img_url'], dims=(140, 210)) await self.questions.put( ['/adduhtml {}, {}'.format(UHTML_NAME, img_url), base['answers']])
async def display_ygo_card(putter, card): msg = '' async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(f'{const.YGO_API}{card}') as r: resp = await r.text() all_cards = json.loads(resp) if r.status != 200: msg = all_cards['error'] else: card_info = all_cards['data'][0] card_name = card_info['name'] card_img = card_info['card_images'][0]['image_url'] img_uhtml = gen_uhtml_img_code(card_img, height_resize=200, alt=card_name) msg = f'/adduhtml hippoygo-{card}, {img_uhtml}' await putter(f'{const.TCG_ROOM}|{msg}')
async def display_ptcg_card(putter, card): msg = '' async with aiohttp.ClientSession(trust_env=True) as session: async with session.get(f'{const.PTCG_API}{card}') as r: resp = await r.text() all_cards = json.loads(resp) if r.status != 200: msg = all_cards['message'] elif not all_cards['data']: msg = 'No cards found with the given name.' else: card_info = all_cards['data'][0] card_name = card_info['name'] card_img = card_info['images']['small'] img_uhtml = gen_uhtml_img_code(card_img, height_resize=200, alt=card_name) msg = f'/adduhtml hippoptcg-{card}, {img_uhtml}' await putter(f'{const.TCG_ROOM}|{msg}')
async def show_steam_user(putter, username, true_caller, ctx): prefix = f'{ctx}|' if ctx == 'pm': prefix = f'|/w {true_caller},' userdata = await get_steam_user(username) if userdata: if ctx == 'pm': user_url = userdata['profileurl'] await putter(f'{prefix} {user_url}') return # Set image img_url = IMG_NOT_FOUND if userdata['avatarfull']: img_url = userdata['avatarfull'] img_uhtml = gen_uhtml_img_code(img_url, height_resize=100, width_resize=125) # Generate recently played uhtml id64 = userdata['steamid'] steam_key = os.getenv('STEAM_KEY') recent_games = [] async with aiohttp.ClientSession(trust_env=True) as session: async with session.get( f'{STEAM_API}IPlayerService/GetRecentlyPlayedGames/v0001/?key={steam_key}&steamid={id64}&count=all' ) as r: resp = await r.text() temp_json = json.loads(resp) if temp_json['response']: if 'games' in temp_json['response']: recent_games = temp_json['response']['games'] game_uhtmls = [] for game in recent_games: recent_hours = game['playtime_2weeks'] / 60 total_hours = game['playtime_forever'] / 60 game_uhtml = await gen_uhtml_steam_game(game['appid'], recent_hours, total_hours) if game_uhtml: game_uhtmls.append(game_uhtml) if len(game_uhtmls) >= 2: break # Fix spacing issues by appending blank game entry. if len(game_uhtmls) == 1: game_uhtmls.append( '<tr><td style=\'padding: 0px 5px 5px 5px\'><div style=\'min-height:50px\'></div></td></tr>' ) total_recent_hours = 0 for game in recent_games: total_recent_hours += game['playtime_2weeks'] total_recent_hours /= 60 profile_url = userdata['profileurl'] persona_name = userdata['personaname'] user_info = UserInfo(userdata['personaname'], userdata['profileurl'], 'steam') kwargs = { 'hours': round(total_recent_hours, 1), 'img_uhtml': img_uhtml, 'game_uhtmls': game_uhtmls } steam_uhtml = user_info.steam_user(**kwargs) await putter(f'{prefix}/adduhtml {username}-steam, {steam_uhtml}') else: await putter(f'{prefix} Could not find the Steam account {username}. ')
async def evaluate(self): self.msg = '/adduhtml ' eligibility = self.check_eligible() if eligibility and eligibility != 2: await self.pm_msg(self.msg) return '' elif eligibility: if self.is_pm and not self.room: await self.pm_msg(self.usage_with_error('')) return '' elif self.is_pm and self.bot.roomlist[self.room].get_user( self.caller): self.msg = f'/sendprivateuhtml {self.true_caller}, ' else: await self.pm_msg(f'You can only use {self.command} in PMs. ' 'Make sure you\'re in the specified room.') return '' elif self.is_pm: self.msg = f'/sendprivateuhtml {self.true_caller}, ' if self.command == 'plebs': uhtml = gen_uhtml_img_code(const.PLEB_URL, height_resize=250) self.msg += f'hippo-pleb, {uhtml}' elif self.command == 'calendar': curr_day_str = curr_cal_date() calendar = json.load(open(const.CALENDARFILE)) if self.room not in calendar: calendar[self.room] = {curr_day_str: []} json.dump(calendar, open(const.CALENDARFILE, 'w', indent=4)) if not calendar[self.room][curr_day_str]: return 'No images found for this date.' date_imgs = calendar[self.room][curr_day_str] uhtml = gen_uhtml_img_code(random.choice(date_imgs), height_resize=200) self.msg += f'hippo-calendar, {uhtml}' elif self.command == 'birthday': await self.bot.send_birthday_text(automatic=False) elif self.command == 'anime': query = ' '.join(self.args) self.msg += await anilist_search('anime', query, self.bot.anilist_man) elif self.command == 'manga': query = ' '.join(self.args) self.msg += await anilist_search('manga', query, self.bot.anilist_man) elif self.command == 'randanime': genres = [] tags = [] true_args = list(map(find_true_name, self.args)) for g in const.ANILIST_GENRES: if find_true_name(g) in true_args: genres.append(g) for t in list(const.ANILIST_TAGS): if find_true_name(t) in true_args: tags.append(t) self.msg += await anilist_rand_series('anime', self.bot.anilist_man, genres=genres, tags=tags) elif self.command == 'randmanga': genres = [] tags = [] true_args = list(map(find_true_name, self.args)) for g in const.ANILIST_GENRES: if find_true_name(g) in true_args: genres.append(g) for t in list(const.ANILIST_TAGS): if find_true_name(t) in true_args: tags.append(t) self.msg += await anilist_rand_series('manga', self.bot.anilist_man, genres=genres, tags=tags) elif self.command == 'mal': true_mal_user = find_true_name(''.join(self.mal_args.username)) if self.mal_args.roll is not None: media = ['anime', 'manga'] if 'anime' not in self.mal_args.roll: media.remove('anime') if 'manga' not in self.mal_args.roll: media.remove('manga') return_msg = await self.bot.mal_man.user_rand_series( true_mal_user, media, anotd=self.is_anotd) if return_msg.startswith('rolled'): self.msg = f'{self.caller} {return_msg}' else: self.msg = return_msg else: return_msg = await self.bot.mal_man.show_user( true_mal_user, self.bot.jikan_man) if is_uhtml(return_msg): self.msg += f'hippo-{true_mal_user}mal, {return_msg}' elif self.is_pm: self.pm_response = self.is_pm self.msg = return_msg else: self.msg = return_msg return self.msg
async def gen_lol_question(self, session): data = { 'all_champs': {}, 'champ': '', 'champ_data': {}, 'all_items': {}, 'item': {} } async with session.get(const.DDRAGON_API + 'champion.json') as r: resp = await r.text() data['all_champs'] = json.loads(resp)['data'] async with session.get(const.DDRAGON_API + 'item.json') as r: resp = await r.text() data['all_items'] = json.loads(resp)['data'] data, base = await self.gen_lol_base(session, data) while self.duplicate_check(base): data, base = await self.gen_lol_base(session, data) self.q_bases.append(base) if data['qtype'] == 'items': img_url = const.DDRAGON_IMG + 'item/{}.png'.format(data['item']) img_url = gen_uhtml_img_code(self.check_for_jpg(img_url)) await self.questions.put([ '/adduhtml {}, {}'.format(UHTML_NAME, img_url), [data['all_items'][data['item']]['name']] ]) elif data['qtype'] == 'skins': skin_name = '' for skin in data['champ_data']['skins']: if skin['num'] == data['cval']: skin_name = skin['name'] if skin[ 'name'] != 'default' else data['champ_data']['name'] break img_url = const.DDRAGON_SPL + '{}_{}.png'.format( data['champ'], data['cval']) img_url = gen_uhtml_img_code(self.check_for_jpg(img_url)) await self.questions.put( ['/adduhtml {}, {}'.format(UHTML_NAME, img_url), [skin_name]]) elif data['qtype'] == 'spells': ability = {} if data['cval'] == 0: ability = data['champ_data']['passive'] img_url = const.DDRAGON_IMG + 'passive/{}'.format( ability['image']['full']) img_url = gen_uhtml_img_code(self.check_for_jpg(img_url)) await self.questions.put([ '/adduhtml {}, {}'.format(UHTML_NAME, img_url), [ability['name']] ]) else: ability = data['champ_data']['spells'][data['cval'] - 1] img_url = const.DDRAGON_IMG + 'spell/{}'.format( ability['image']['full']) img_url = gen_uhtml_img_code(self.check_for_jpg(img_url)) await self.questions.put([ '/adduhtml {}, {}'.format(UHTML_NAME, img_url), [ability['name']] ])
async def anilist_search(medium, search, anilist_man): query = ''' query ($search: String) { Page (page: 1, perPage: 1) { media (MEDIUM_PLACEHOLDER, search: $search, isAdult: false) { id idMal title { english romaji } coverImage { extraLarge } status episodes chapters description averageScore } } } ''' mq = 'type: ANIME' if medium == 'anime' else 'type: MANGA' query = query.replace('MEDIUM_PLACEHOLDER', mq) query_vars = {'search': search} series_data = {} async with anilist_man.lock(): async with aiohttp.ClientSession() as session: async with session.post(const.ANILIST_API, json={ 'query': query, 'variables': query_vars }) as r: resp = await r.json() if r.status != 200: err_msg = resp['errors'][0]['message'] return f'hippoerror, Status code {r.status} when fetching {search}: {err_msg}' series_list = resp['data']['Page']['media'] if not series_list: return f'hippoerror, No {medium} found for {search}.' series_data = series_list[0] mal_url = f'https://myanimelist.net/{medium}/{series_data["idMal"]}' img_uhtml = gen_uhtml_img_code(series_data['coverImage']['extraLarge'], dims=(65, 100)) title = series_data['title']['english'] if not title: title = series_data['title']['romaji'] parts = 'Episodes' if medium == 'anime' else 'Chapters' score = f'{series_data["averageScore"]}%' if series_data[ 'averageScore'] else 'N/A' item_info = ItemInfo(title, mal_url, 'mal') kwargs = { 'img_uhtml': img_uhtml, 'al_link': f'https://anilist.co/{medium}/{series_data["id"]}', 'ongoing': series_data['status'], 'parts': f'{parts}: {series_data[parts.lower()]}', 'score': score, 'synopsis': series_data['description'] } uhtml = item_info.animanga(**kwargs) return f'hippo{medium}{series_data["idMal"]}, {uhtml}'
async def anilist_rand_series(medium, anilist_man, genres=[], tags=[]): query = ''' query ($page: Int) { Page (page: $page, perPage: 1) { pageInfo { total } media (CATEGORIES_PLACEHOLDER minimumTagRank: 50, type: TYPE_PLACEHOLDER, isAdult: false) { id idMal title { english userPreferred } coverImage { extraLarge } status episodes chapters description averageScore } } } ''' category_params = [] if genres: category_params.append(f'genre_in: {json.dumps(genres)}') if tags: category_params.append(f'tag_in: {json.dumps(tags)}') category_params_str = ','.join(category_params) if category_params_str: category_params_str += ',' query = query.replace('CATEGORIES_PLACEHOLDER', category_params_str) query = query.replace('TYPE_PLACEHOLDER', medium.upper()) query_vars = {'page': 1} num_entries = 0 async with aiohttp.ClientSession() as session: async with anilist_man.lock(): num_entries = await anilist_num_entries(query, query_vars, session) if not num_entries: return 'No series found with the given specifications.' query_vars['page'] = random.randint(1, num_entries) series_data = {} async with anilist_man.lock(): async with session.post(const.ANILIST_API, json={ 'query': query, 'variables': query_vars }) as r: resp = await r.json() if r.status != 200: err_msg = resp['errors'][0]['message'] return f'Status code {r.status} when fetching {query}: {err_msg}' series_data = resp['data']['Page']['media'][0] mal_url = f'https://myanimelist.net/{medium}/{series_data["idMal"]}' img_uhtml = gen_uhtml_img_code(series_data['coverImage']['extraLarge'], dims=(65, 100)) title = series_data['title']['english'] if not title: title = series_data['title']['userPreferred'] parts = 'Episodes' if medium == 'anime' else 'Chapters' score = f'{series_data["averageScore"]}%' if series_data[ 'averageScore'] else 'N/A' item_info = ItemInfo(title, mal_url, 'mal') kwargs = { 'img_uhtml': img_uhtml, 'al_link': f'https://anilist.co/{medium}/{series_data["id"]}', 'ongoing': series_data['status'], 'parts': f'{parts}: {series_data[parts.lower()]}', 'score': score, 'synopsis': series_data['description'] } uhtml = item_info.animanga(**kwargs) return f'hippo{medium}{series_data["idMal"]}, {uhtml}'