123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- import logging
- from typing import Optional
- import requests
- from django.core.files.base import ContentFile
- from videogames.howlongtobeat import lookup_game_from_hltb
- from videogames.igdb import lookup_game_from_igdb
- from videogames.models import VideoGame, VideoGamePlatform
- from vrobbler.apps.videogames.exceptions import GameNotFound
- logger = logging.getLogger(__name__)
- def get_or_create_videogame(
- name_or_id: str,
- force_update: bool = False,
- ) -> Optional[VideoGame]:
- """Look up game by name or ID from HowLongToBeat"""
- game_dict = lookup_game_from_hltb(name_or_id)
- if not game_dict:
- game_dict = lookup_game_from_igdb(name_or_id)
- if not game_dict:
- return
- # Create missing platforms and prep for loading after create
- platform_ids = []
- if "platforms" in game_dict.keys():
- platforms = game_dict.get("platforms", [])
- if platforms:
- for platform in game_dict.get("platforms", []):
- p, _created = VideoGamePlatform.objects.get_or_create(
- name=platform
- )
- platform_ids.append(p.id)
- game_dict.pop("platforms")
- cover_url = game_dict.pop("cover_url")
- screenshot_url = ""
- if "screenshot_url" in game_dict.keys():
- screenshot_url = game_dict.pop("screenshot_url")
- genres = []
- if "genres" in game_dict.keys():
- genres = game_dict.pop("genres")
- title = game_dict.get("title")
- if not title:
- raise GameNotFound(name_or_id)
- hltb_id = game_dict.get("hltb_id")
- igdb_id = game_dict.get("igdb_id")
- if hltb_id:
- game, game_created = VideoGame.objects.get_or_create(
- hltb_id=hltb_id,
- title=title,
- )
- elif igdb_id:
- game, game_created = VideoGame.objects.get_or_create(
- igdb_id=igdb_id,
- title=title,
- )
- else:
- game, game_created = VideoGame.objects.get_or_create(title=title)
- if game_created or force_update:
- VideoGame.objects.filter(pk=game.id).update(**game_dict)
- game.refresh_from_db()
- # Associate plaforms
- if platform_ids:
- game.platforms.add(*platform_ids)
- if genres:
- game.genre.add(*genres)
- if not game.screenshot and screenshot_url:
- r = requests.get(screenshot_url)
- if r.status_code == 200:
- fname = f"{game.title}_{game.uuid}.jpg"
- game.screenshot.save(fname, ContentFile(r.content), save=True)
- # Go get cover image if the URL is present
- if cover_url and not game.hltb_cover:
- headers = {"User-Agent": "Vrobbler 0.11.12"}
- r = requests.get(cover_url, headers=headers)
- logger.debug(r.status_code)
- if r.status_code == 200:
- fname = f"{game.title}_cover_{game.uuid}.jpg"
- game.hltb_cover.save(fname, ContentFile(r.content), save=True)
- logger.debug("Loaded cover image from HLtB")
- game.fix_metadata()
- return game
- def load_game_data_from_igdb(
- game_id: int, igdb_id: str = ""
- ) -> Optional[VideoGame]:
- """Look up game, if it doesn't exist, lookup data from igdb"""
- game = VideoGame.objects.filter(id=game_id).first()
- if not game:
- logger.warn(f"Video game with ID {game_id} not found")
- return
- if not game.igdb_id and not igdb_id:
- logger.warn(f"Video game has no IGDB ID")
- return
- igdb_id = game.igdb_id or igdb_id
- logger.info(f"Looking up video game {igdb_id}")
- game_dict = lookup_game_from_igdb(igdb_id)
- if not game_dict:
- logger.warn(f"No game data found on IGDB for ID {igdb_id}")
- return
- screenshot_url = game_dict.pop("screenshot_url")
- cover_url = game_dict.pop("cover_url")
- genres = game_dict.pop("genres")
- VideoGame.objects.filter(pk=game.id).update(**game_dict)
- game.refresh_from_db()
- game.genre.add(*genres)
- if not game.screenshot and screenshot_url:
- r = requests.get(screenshot_url)
- if r.status_code == 200:
- fname = f"{game.title}_{game.uuid}.jpg"
- game.screenshot.save(fname, ContentFile(r.content), save=True)
- if not game.cover and cover_url:
- r = requests.get(cover_url)
- if r.status_code == 200:
- fname = f"{game.title}_{game.uuid}.jpg"
- game.cover.save(fname, ContentFile(r.content), save=True)
- return game
|