async def hltb(self, ctx, *, message: str): results = HowLongToBeat().search(message) if results is not None and len(results) > 0: best_element = max(results, key=lambda element: element.similarity) embed = discord.Embed(title=best_element.game_name, color=discord.Color.blue()) if best_element.gameplay_main_unit is not None: embed.add_field(name="Main Story", value=best_element.gameplay_main + " Hours", inline=True) if best_element.gameplay_main_extra_unit is not None: embed.add_field(name="Main + Extras", value=best_element.gameplay_main_extra + " Hours", inline=True) if best_element.gameplay_completionist_unit is not None: embed.add_field(name="Completionist", value=best_element.gameplay_completionist + " Hours", inline=True) embed.add_field(name="Get more info about this game", value=best_element.game_web_link, inline=False) await ctx.trigger_typing() msg = await ctx.send(embed=embed) else: await ctx.send( "No results found, please try redefining your search")
def search(game_name): response = {"HLTB": []} games_found = [] try: hltb_results = HowLongToBeat(0.1).search( game_name, similarity_case_sensitive=False) for i in hltb_results: game = { "game_id": i.game_id, "game_name": i.game_name, "game_image_url": "https://howlongtobeat.com" + i.game_image_url, "game_web_link": i.game_web_link, "gameplay_main": i.gameplay_main, "gameplay_main_unit": i.gameplay_main_unit, "gameplay_main_label": i.gameplay_main_label, "gameplay_main_extra": i.gameplay_main_extra, "gameplay_main_extra_unit": i.gameplay_main_extra_unit, "gameplay_main_extra_label": i.gameplay_main_extra_label, "gameplay_completionist": i.gameplay_completionist, "gameplay_completionist_unit": i.gameplay_completionist_unit, "gameplay_completionist_label": i.gameplay_completionist_label } response["HLTB"].append(game) except Exception as ex: print(ex) return response
def test_game_suffix_not_present(self): results = HowLongToBeat(0).search("The Witcher 3: Wild Hunt") self.assertNotEqual(None, results, "Search Results are None") self.assertNotEqual(0, len(results)) best_element = max(results, key=lambda element: element.similarity) self.assertEqual(None, best_element.game_name_suffix, "The suffix is not None, it should be")
def test_game_isolate_dlc_search(self): results = HowLongToBeat().search("Hearts of Stone", SearchModifiers.ISOLATE_DLC) self.assertNotEqual(None, results, "Search Results are None") best_result = TestNormalRequest.getMaxSimilarityElement(results) self.assertEqual("The Witcher 3: Wild Hunt - Hearts of Stone", best_result.game_name)
def hltb(update, context): """Find how long a game takes to beat""" message = update.message game = ' '.join(context.args) if not game: text = "*Usage:* `/hltb {GAME_NAME}`\n"\ "*Example:* `/hltb horizon zero dawn`" else: results = HowLongToBeat().search(game) if results: # Return result with highest similarity to query best_guess = max(results, key=lambda element: element.similarity) # check if non-zero value exists for main gameplay if best_guess.gameplay_main != -1: text = f"<b>{best_guess.gameplay_main_label}</b>: "\ f"{best_guess.gameplay_main} {best_guess.gameplay_main_unit}"\ f"<a href='{best_guess.game_image_url}'>‍</a>" # check if non-zero value exists for main+extra gameplay elif best_guess.gameplay_main_extra != -1: text = f"<b>{best_guess.gameplay_main_extra_label}</b>: "\ f"{best_guess.gameplay_main_extra} {best_guess.gameplay_main_extra_unit}"\ f"<a href='{best_guess.game_image_url}'>‍</a>" else: text = "No hours recorded." else: text = "No entry found." message.reply_text( text=text, parse_mode='HTML', disable_web_page_preview=False, )
def Game(id): game_url = "https://howlongtobeat.com/game.php?id=" + str(id) response = {} try: i = HowLongToBeat().search_from_id(id) extra_info = info_scraping.scraping(game_url) game = { "game_id": i.game_id, "game_name": i.game_name, "game_image_url": "https://howlongtobeat.com" + i.game_image_url, "game_web_link": i.game_web_link, "description": extra_info["description"], "rating": extra_info["rating"], "more_info": extra_info["game_info"], "gameplay_main": i.gameplay_main, "gameplay_main_unit": i.gameplay_main_unit, "gameplay_main_label": i.gameplay_main_label, "gameplay_main_extra": i.gameplay_main_extra, "gameplay_main_extra_unit": i.gameplay_main_extra_unit, "gameplay_main_extra_label": i.gameplay_main_extra_label, "gameplay_completionist": i.gameplay_completionist, "gameplay_completionist_unit": i.gameplay_completionist_unit, "gameplay_completionist_label": i.gameplay_completionist_label } response = game except Exception as ex: print(ex) return response
def test_game_link(self): results = HowLongToBeat().search("Battlefield 2142") self.assertNotEqual(None, results, "Search Results are None") best_result = TestNormalRequest.getMaxSimilarityElement(results) self.assertNotEqual(None, best_result, "Search Result is None") self.assertEqual("Battlefield 2142", best_result.game_name) self.assertEqual("https://howlongtobeat.com/game?id=936", best_result.game_web_link)
def HLTB_time(game_name): games_list = HowLongToBeat().search(game_name) if games_list and len(games_list) > 0: game = max(games_list, key=lambda x: x.similarity) return {'main': game.gameplay_main, 'extra': game.gameplay_main_extra, 'completionist': game.gameplay_completionist} else: return {'main': None, 'extra': None, 'completionist': None}
def test_game_case_sensitive(self): results_standard = HowLongToBeat(0).search("RED HOT VENGEANCE") results_not_case_sens = HowLongToBeat(0).search( "RED HOT VENGEANCE", similarity_case_sensitive=False) self.assertNotEqual(None, results_standard, "Search Results (standard) are None") self.assertNotEqual(None, results_not_case_sens, "Search Results (_not_case_sens) are None") self.assertNotEqual(0, len(results_standard)) self.assertNotEqual(0, len(results_not_case_sens)) best_element_standard = max(results_standard, key=lambda element: element.similarity) best_element_not_case = max(results_not_case_sens, key=lambda element: element.similarity) self.assertTrue( best_element_standard.similarity <= best_element_not_case.similarity, "Wrong similarity results")
def test_simple_game_name(self): result = HowLongToBeat().search_from_id(42818) self.assertNotEqual(None, result, "Search Result is None") self.assertEqual("Celeste", result.game_name) self.assertEqual("Main Story", result.gameplay_main_label) self.assertEqual("Main + Extra", result.gameplay_main_extra_label) self.assertEqual("Completionist", result.gameplay_completionist_label) self.assertAlmostEqual(12, TestNormalRequest.getSimpleNumber(result.gameplay_main_extra), delta=5)
def test_game_name_with_numbers(self): result = HowLongToBeat().search_from_id(10270) self.assertNotEqual(None, result, "Search Result is None") self.assertEqual("The Witcher 3: Wild Hunt", result.game_name) self.assertEqual("Main Story", result.gameplay_main_label) self.assertEqual("Main + Extra", result.gameplay_main_extra_label) self.assertEqual("Completionist", result.gameplay_completionist_label) self.assertAlmostEqual(50, TestNormalRequest.getSimpleNumber(result.gameplay_main), delta=5)
def test_game_name(self): result = HowLongToBeat().search_from_id(2071) self.assertNotEqual(None, result, "Search Result is None") self.assertEqual("Crysis Warhead", result.game_name) self.assertEqual("Main Story", result.gameplay_main_label) self.assertEqual("Main + Extra", result.gameplay_main_extra_label) self.assertEqual("Completionist", result.gameplay_completionist_label) self.assertAlmostEqual(7, TestNormalRequest.getSimpleNumber(result.gameplay_completionist), delta=3)
def get_hltb_search_result(game_name): key = f'hltb_search_{game_name.replace(" ", "_")}' results = cache.get(key, None) if results is None: results = HowLongToBeat(1.0).search(game_name.replace('’', '\''), similarity_case_sensitive=False) cache.set(key, results, CACHE_TIMEOUT) return results
def test_game_name(self): results = HowLongToBeat().search("A way out") self.assertNotEqual(None, results, "Search Results are None") best_result = self.getMaxSimilarityElement(results) self.assertEqual("A Way Out", best_result.game_name) self.assertEqual("Main Story", best_result.gameplay_main_label) self.assertEqual("Main + Extra", best_result.gameplay_main_extra_label) self.assertEqual("Completionist", best_result.gameplay_completionist_label) self.assertAlmostEqual(7, self.getSimpleNumber(best_result.gameplay_completionist), delta=3)
def test_game_suffix_present(self): results = HowLongToBeat(0).search("God Of War") self.assertNotEqual(None, results, "Search Results are None") self.assertNotEqual(0, len(results)) best_element = max(results, key=lambda element: element.similarity) self.assertEqual("God of War".lower(), best_element.game_name.lower()) self.assertNotEqual(None, best_element.game_name_suffix, "The suffix is still None, it should not be") self.assertEqual(best_element.game_name_suffix, "(2018)")
def test_game_name_with_numbers(self): results = HowLongToBeat().search("The Witcher 3") self.assertNotEqual(None, results, "Search Results are None") best_result = self.getMaxSimilarityElement(results) self.assertEqual("The Witcher 3: Wild Hunt", best_result.game_name) self.assertEqual("Main Story", best_result.gameplay_main_label) self.assertEqual("Main + Extra", best_result.gameplay_main_extra_label) self.assertEqual("Completionist", best_result.gameplay_completionist_label) self.assertAlmostEqual(50, self.getSimpleNumber(best_result.gameplay_main), delta=5)
def test_game_with_no_all_values(self): result = HowLongToBeat().search_from_id(936) self.assertNotEqual(None, result, "Search Result is None") self.assertEqual("Battlefield 2142", result.game_name) self.assertEqual(None, result.gameplay_main_label) self.assertEqual("Co-Op", result.gameplay_main_extra_label) self.assertEqual("Hours", result.gameplay_main_extra_unit) self.assertAlmostEqual(17, TestNormalRequest.getSimpleNumber(result.gameplay_main_extra), delta=5) self.assertEqual("Vs.", result.gameplay_completionist_label) self.assertAlmostEqual(65, TestNormalRequest.getSimpleNumber(result.gameplay_completionist), delta=5) self.assertEqual("Hours", result.gameplay_completionist_unit) self.assertEqual(None, result.gameplay_main_unit) self.assertEqual(-1, TestNormalRequest.getSimpleNumber(result.gameplay_main))
def test_game_with_no_all_values(self): results = HowLongToBeat().search("Battlefield 2142") self.assertNotEqual(None, results, "Search Results are None") best_result = TestNormalRequest.getMaxSimilarityElement(results) self.assertEqual("Battlefield 2142", best_result.game_name) self.assertEqual(None, best_result.gameplay_main_label) self.assertEqual("Co-Op", best_result.gameplay_main_extra_label) self.assertEqual("Vs.", best_result.gameplay_completionist_label) self.assertAlmostEqual(80, TestNormalRequest.getSimpleNumber(best_result.gameplay_completionist), delta=5) self.assertEqual("Hours", best_result.gameplay_completionist_unit) self.assertEqual(None, best_result.gameplay_main_unit) self.assertEqual(None, best_result.gameplay_main_extra_unit) self.assertEqual(-1, TestNormalRequest.getSimpleNumber(best_result.gameplay_main)) self.assertEqual(-1, TestNormalRequest.getSimpleNumber(best_result.gameplay_main_extra))
def hltb(bot: Bot, update: Update): message = update.message if len(message.text.strip().split(' ', 1)) >= 2: query = message.text.strip().split(' ', 1)[1] else: bot.send_message( chat_id=message.chat_id, text="*Usage:* `/hltb {GAME_NAME}`\n*Example:* `/hltb horizon zero dawn`", reply_to_message_id=message.message_id, parse_mode='Markdown' ) return results = HowLongToBeat().search(query) if results is not None and len(results) > 0: # Return result with highest similarity to query best_guess = max(results, key=lambda element: element.similarity) else: bot.send_message( chat_id=message.chat_id, text="No entry found.", reply_to_message_id=message.message_id, ) return # check if non-zero value exists for gameplay_main if best_guess.gameplay_main != -1: output = f'<b>{best_guess.gameplay_main_label}</b>: {best_guess.gameplay_main} {best_guess.gameplay_main_unit} ' # check if non-zero value exists for gameplay_extra elif best_guess.gameplay_main_extra != -1: output = f'{best_guess.gameplay_main_extra_label}: {best_guess.gameplay_main_extra} {best_guess.gameplay_main_extra_unit} ' else: bot.send_message( chat_id=message.chat_id, text="No hours recorded.", reply_to_message_id=message.message_id, ) return output += f'<a href=\"{best_guess.game_image_url}\">‍</a>' bot.send_message( chat_id=message.chat_id, text=output, reply_to_message_id=message.message_id, parse_mode='HTML', disable_web_page_preview=False, )
def getHowLongToBeat(elem): #f = open("howLong.txt", "a+", encoding="utf-8") doc_ref = db.collection('games').document(elem) results = HowLongToBeat(0.0).search(elem) try: doc_ref.update({ 'timeUrl': str(results[0].game_web_link), 'fullTime': str(results[0].gameplay_completionist), 'averTime': str(results[0].gameplay_main), 'plusTime': str(results[0].gameplay_main_extra), }) #f.write('Tiempo completo ' + str(results[0].gameplay_completionist) + ' tiempo promedio: ' + # str(results[0].gameplay_main) + ' tiempo mas extras: ' + str(results[0].gameplay_main_extra) + '\n') except: doc_ref.update({'Time': 'No existe'})
def hltb(update: 'telegram.Update', context: 'telegram.ext.CallbackContext') -> None: """Find how long a game takes to beat""" if update.message: message: 'telegram.Message' = update.message else: return game: str = ' '.join(context.args) if context.args else '' text: str if not game: text = "*Usage:* `/hltb {GAME_NAME}`\n" \ "*Example:* `/hltb Horizon Zero Dawn`" else: results: Optional[List] = HowLongToBeat().search( game, similarity_case_sensitive=False) if results: # Return result with highest similarity to query best_guess: Any = max(results, key=lambda element: element.similarity) # HLTB changed the image_url field to be a suffix to base URL image_url: str = "https://howlongtobeat.com" + best_guess.game_image_url # check if non-zero value exists for main gameplay if best_guess.gameplay_main != -1: text = f"<b>{best_guess.gameplay_main_label}</b>: " \ f"{best_guess.gameplay_main} {best_guess.gameplay_main_unit}" \ f"<a href='{image_url}'>‍</a>" # check if non-zero value exists for main+extra gameplay elif best_guess.gameplay_main_extra != -1: text = f"<b>{best_guess.gameplay_main_extra_label}</b>: " \ f"{best_guess.gameplay_main_extra} {best_guess.gameplay_main_extra_unit}" \ f"<a href='{image_url}'>‍</a>" else: text = "No hours recorded." else: text = "No entry found." message.reply_text( text=text, parse_mode='HTML', disable_web_page_preview=False, )
def tarea(args): global name print("Proceso HowLongToBeat") try: print('Iniciando tarea con ' + args[0].replace(" ", "-")) name = args[0] #es necesario para el metodo de arriba results = HowLongToBeat(0).search(name) result = max(results, key=lambda element: element.similarity).gameplay_main if result != -1: send_json( format_result(result) ) # Da formato al valor obtenido, intercambia '½' por '.30' else: send_json("n/a") except ValueError as e: print(e)
def game_completion_profile(games_owned: list) -> list: """Take list of games in steam library and convert to dictionaries containing information to build results page.""" list_of_game_info = [] for game in games_owned: result = HowLongToBeat(0).search(game["name"]) if result and result[0].gameplay_main != -1: game_time_played = game["playtime_forever"] / 60 time_to_complete = convert_completion_time(result[0].gameplay_main) percentage_complete = (game_time_played / time_to_complete) * 100 if percentage_complete < 100: list_of_game_info.append({"gamename": game["name"], "gamepic": result[0].game_image_url, "percentcomplete": round(percentage_complete, 2), "hourslogged": f"{game_time_played:.2f}"}) return list_of_game_info
def load_times(game): # This will remove accents stripped_title = unidecode.unidecode(game.title) results = HowLongToBeat().search(stripped_title) max_sim = -1 best_element = None for element in results: if element.similarity > max_sim: max_sim = element.similarity best_element = element # print("Pulled times for %s: [ %s, %s, %s]" % ( # game.title, best_element.gameplay_main, best_element.gameplay_main_extra, # best_element.gameplay_completionist)) return best_element
async def howlongtobeat(ctx, *game_full_name): game = '' if len(game_full_name) > 1: for element in game_full_name: game = game + element + ' ' else: game = game_full_name[0] results = HowLongToBeat().search(game) if results is not None and len(results) > 0: best_element = max(results, key=lambda element: element.similarity) else: await ctx.send('No results found') return embed = discord.Embed(title=best_element.game_name, description=best_element.game_web_link, colour=discord.Colour.blue()) embed.set_footer(text=":)") embed.set_image(url=best_element.game_image_url) if best_element.gameplay_main != -1: embed.add_field(name="Main Story", value=best_element.gameplay_main + "hours", inline=True) if best_element.gameplay_main_extra != -1: embed.add_field(name="Main + Extra", value=best_element.gameplay_main_extra + "hours", inline=True) if best_element.gameplay_completionist != -1: embed.add_field(name="Completionist", value=best_element.gameplay_completionist + "hours", inline=True) await ctx.send(embed=embed)
def get_howlongtobeat_infos(search): result = HowLongToBeat().search(search) if result: return { "howlongtobeat_url": result[0].game_web_link, "howlongtobeat_main": result[0].gameplay_main, "howlongtobeat_main_unit": result[0].gameplay_main_unit, "howlongtobeat_main_extra": result[0].gameplay_main_extra, "howlongtobeat_main_extra_unit": result[0].gameplay_main_extra_unit, "howlongtobeat_completionist": result[0].gameplay_completionist, "howlongtobeat_completionist_unit": result[0].gameplay_completionist_unit, } return None
def how_long_to_beat(): try: currentPath = os.getcwd() file_content = "" # string para dar formato al nuevo archivo txt file = open(str(sys.argv[1]), 'r') # lee el archivo con el nombre de los juegos for line in file: # para cada uno de los nombres de juegos... results = HowLongToBeat(0).search( line[:-1]) # se le resta 1 a line para no tomar en cuenta '\n' result = max(results, key=lambda element: element.similarity).gameplay_main if result != -1: n_result = format_result( result ) # Da formato al valor obtenido, intercambia '½' por '.30' else: n_result = "n/a" file_content = file_content + line[:-1] + ";" + n_result + '\n' # Formato de escritura: 'nombreJuego:horas' write_response( file_content) # Llamada a la función que crea el nuevo archivo except ValueError as e: print(e)
def query_hltb(self, game: Game, progress: str = '') -> (HowLongToBeatEntry): if game.dh_id in self.mapping: print( f'{progress} Zjišťuji: {game.title} (použito vlastní mapování) ...' ) hltb_id = self.mapping[game.dh_id]['hltb_id'] title = self.mapping[game.dh_id]['hltb_title'] else: print(f'{progress} Zjišťuji: {game.title} ...') hltb_id = None title = game.title tried_our_best = False while True: results = HowLongToBeat(input_minimum_similarity=0).search( game_name=title, search_modifiers=howlongtobeatpy.HTMLRequests.SearchModifiers. INCLUDE_DLC) if results or tried_our_best: break if results is None: print_error('CHYBA SPOJENÍ NEBO NEPLATNÝ DOTAZ!') raise HLTBError if not results: title = self.more_searchable_name(title) colorprint(msg=f'Nic nenalezeno, zkouším hledat: {title}', color=Color.INFO) tried_our_best = True continue if game.dh_id in self.ignored: # this happens if you force-include ignored games for querying print_args = {'color': Color.INFO} details_print_args = print_args prefix = 'IGNOROVÁNO: ' else: print_args = {'color': Color.ERROR, 'file': sys.stderr} details_print_args = { 'color': Color.ERROR_DETAILS, 'file': sys.stderr } prefix = '' if not results: colorprint(msg=f'{prefix}ŽÁDNÝ NÁLEZ PRO "{title}"! ' f'(DH ID: {game.dh_id})', **print_args) time.sleep(self.error_sleep_delay) return None results = sorted(results, key=lambda x: x.similarity, reverse=True) if hltb_id: matches = [ result for result in results if result.game_id == hltb_id ] if len(matches) != 1: colorprint( msg='OČEKÁVÁN PŘESNĚ JEDEN NÁLEZ S HLTB ID ' f'{hltb_id}, ZÍSKÁNO {len(matches)}\nVÝSLEDKY HLEDÁNÍ ' f'"{title}":', **print_args) for result in results: colorprint(msg=self.format_result(result), **print_args) time.sleep(self.error_sleep_delay) return None else: return matches[0] good_match_possible = True if len(results ) >= 2 and results[0].similarity == results[1].similarity: # we can't reliably distinguish several matches with the same similarity good_match_possible = False if (results[0].game_name != game.title and not self.equal_names(results[0].game_name, game.title)): # if the most similar result doesn't have the exact or almost equal # name, we can't say whether it is what we're looking for good_match_possible = False if not good_match_possible: colorprint(msg=f'{prefix}ŽÁDNÝ PŘESNÝ NÁLEZ PRO "{title}"! ' f'(DH ID: {game.dh_id})', **print_args) candidates = '\n\n'.join( [self.format_result(result) for result in results]) colorprint(msg=candidates, **details_print_args) time.sleep(self.error_sleep_delay) return None # now we have a good match, results[0] best_match = results[0] # if we matched by title (not by id) and the title match was not exact, # inform the user if (best_match.game_name != game.title and game.dh_id not in self.mapping): colorprint( msg=f'Přiřazen velice podobný název: {best_match.game_name}', color=Color.INFO) # FIXME: print also the year, when available # https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/issues/8 return best_match
def setup(bot): bot.add_cog(HowLongToBeat(bot))
import os import discord from discord.ext import commands from discord.utils import * from howlongtobeatpy import HowLongToBeat # # # Módulo: HowLongToBeat # # - Integra o PyBOT com o https://howlongtobeat.com/ via howlongtobeatpy # # - Permite consultar o tempo estimado de término de games, de acordo com os dados disponibilizados pela comunidade do HLTB # # # Utiliza: # # - Discord.py API (by Rapptz on: https://github.com/Rapptz/discord.py) # # - howlongtobeatpy API (by ScrappyCocco on: https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI) hltb = HowLongToBeat() class HowLongToBeat(commands.Cog): """Obtém dados de tempo de jogo dos games cadastrados no 'HowLongToBeat'""" def __init__(self, bot: commands.Bot): self.bot = bot @commands.command(name="hltb") async def hltb(self, ctx: commands.Context, *, game_title: str): """!hltb <game_title> => Retorna o resultado da busca no HowLongToBeat""" results = hltb.search(game_title) def hltb_pages_layout(i): embed_hltb = discord.Embed(