utils.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import logging
  2. from typing import Optional
  3. import requests
  4. from django.core.files.base import ContentFile
  5. from videogames.howlongtobeat import lookup_game_from_hltb
  6. from videogames.igdb import lookup_game_from_igdb
  7. from videogames.models import VideoGame, VideoGamePlatform
  8. from vrobbler.apps.videogames.exceptions import GameNotFound
  9. logger = logging.getLogger(__name__)
  10. def get_or_create_videogame(
  11. name_or_id: str,
  12. force_update: bool = False,
  13. ) -> Optional[VideoGame]:
  14. """Look up game by name or ID from HowLongToBeat"""
  15. game_dict = lookup_game_from_hltb(name_or_id)
  16. if not game_dict:
  17. game_dict = lookup_game_from_igdb(name_or_id)
  18. if not game_dict:
  19. return
  20. # Create missing platforms and prep for loading after create
  21. platform_ids = []
  22. if "platforms" in game_dict.keys():
  23. platforms = game_dict.get("platforms", [])
  24. if platforms:
  25. for platform in game_dict.get("platforms", []):
  26. p, _created = VideoGamePlatform.objects.get_or_create(
  27. name=platform
  28. )
  29. platform_ids.append(p.id)
  30. game_dict.pop("platforms")
  31. cover_url = game_dict.pop("cover_url")
  32. screenshot_url = ""
  33. if "screenshot_url" in game_dict.keys():
  34. screenshot_url = game_dict.pop("screenshot_url")
  35. genres = []
  36. if "genres" in game_dict.keys():
  37. genres = game_dict.pop("genres")
  38. title = game_dict.get("title")
  39. if not title:
  40. raise GameNotFound(name_or_id)
  41. hltb_id = game_dict.get("hltb_id")
  42. igdb_id = game_dict.get("igdb_id")
  43. if hltb_id:
  44. game, game_created = VideoGame.objects.get_or_create(
  45. hltb_id=hltb_id,
  46. title=title,
  47. )
  48. elif igdb_id:
  49. game, game_created = VideoGame.objects.get_or_create(
  50. igdb_id=igdb_id,
  51. title=title,
  52. )
  53. else:
  54. game, game_created = VideoGame.objects.get_or_create(title=title)
  55. if game_created or force_update:
  56. VideoGame.objects.filter(pk=game.id).update(**game_dict)
  57. game.refresh_from_db()
  58. # Associate plaforms
  59. if platform_ids:
  60. game.platforms.add(*platform_ids)
  61. if genres:
  62. game.genre.add(*genres)
  63. if not game.screenshot and screenshot_url:
  64. r = requests.get(screenshot_url)
  65. if r.status_code == 200:
  66. fname = f"{game.title}_{game.uuid}.jpg"
  67. game.screenshot.save(fname, ContentFile(r.content), save=True)
  68. # Go get cover image if the URL is present
  69. if cover_url and not game.hltb_cover:
  70. headers = {"User-Agent": "Vrobbler 0.11.12"}
  71. r = requests.get(cover_url, headers=headers)
  72. logger.debug(r.status_code)
  73. if r.status_code == 200:
  74. fname = f"{game.title}_cover_{game.uuid}.jpg"
  75. game.hltb_cover.save(fname, ContentFile(r.content), save=True)
  76. logger.debug("Loaded cover image from HLtB")
  77. game.fix_metadata()
  78. return game
  79. def load_game_data_from_igdb(
  80. game_id: int, igdb_id: str = ""
  81. ) -> Optional[VideoGame]:
  82. """Look up game, if it doesn't exist, lookup data from igdb"""
  83. game = VideoGame.objects.filter(id=game_id).first()
  84. if not game:
  85. logger.warn(f"Video game with ID {game_id} not found")
  86. return
  87. if not game.igdb_id and not igdb_id:
  88. logger.warn(f"Video game has no IGDB ID")
  89. return
  90. igdb_id = game.igdb_id or igdb_id
  91. logger.info(f"Looking up video game {igdb_id}")
  92. game_dict = lookup_game_from_igdb(igdb_id)
  93. if not game_dict:
  94. logger.warn(f"No game data found on IGDB for ID {igdb_id}")
  95. return
  96. screenshot_url = game_dict.pop("screenshot_url")
  97. cover_url = game_dict.pop("cover_url")
  98. genres = game_dict.pop("genres")
  99. VideoGame.objects.filter(pk=game.id).update(**game_dict)
  100. game.refresh_from_db()
  101. game.genre.add(*genres)
  102. if not game.screenshot and screenshot_url:
  103. r = requests.get(screenshot_url)
  104. if r.status_code == 200:
  105. fname = f"{game.title}_{game.uuid}.jpg"
  106. game.screenshot.save(fname, ContentFile(r.content), save=True)
  107. if not game.cover and cover_url:
  108. r = requests.get(cover_url)
  109. if r.status_code == 200:
  110. fname = f"{game.title}_{game.uuid}.jpg"
  111. game.cover.save(fname, ContentFile(r.content), save=True)
  112. return game