lib.itmens/catalog/sites/igdb.py

158 lines
5.1 KiB
Python
Raw Normal View History

2022-12-08 23:58:44 +00:00
"""
IGDB
use (e.g. "portal-2") as id, which is different from real id in IGDB API
"""
import datetime
import json
import logging
import requests
from django.conf import settings
from igdb.wrapper import IGDBWrapper
from catalog.common import *
from catalog.models import *
2022-12-08 23:58:44 +00:00
_logger = logging.getLogger(__name__)
def _igdb_access_token():
if not settings.IGDB_CLIENT_SECRET:
return "<missing>"
2022-12-08 23:58:44 +00:00
try:
2022-12-29 23:57:02 -05:00
token = requests.post(
f"https://id.twitch.tv/oauth2/token?client_id={settings.IGDB_CLIENT_ID}&client_secret={settings.IGDB_CLIENT_SECRET}&grant_type=client_credentials"
).json()["access_token"]
2022-12-08 23:58:44 +00:00
except Exception:
2022-12-29 23:57:02 -05:00
_logger.error("unable to obtain IGDB token")
token = "<invalid>"
2022-12-08 23:58:44 +00:00
return token
_wrapper = IGDBWrapper(settings.IGDB_CLIENT_ID, _igdb_access_token())
def search_igdb_by_3p_url(steam_url):
2022-12-29 23:57:02 -05:00
r = IGDB.api_query("websites", f'fields *, game.*; where url = "{steam_url}";')
2022-12-08 23:58:44 +00:00
if not r:
return None
2022-12-29 23:57:02 -05:00
r = sorted(r, key=lambda w: w["game"]["id"])
return IGDB(url=r[0]["game"]["url"])
2022-12-08 23:58:44 +00:00
2022-12-15 17:29:35 -05:00
@SiteManager.register
2022-12-08 23:58:44 +00:00
class IGDB(AbstractSite):
2022-12-16 01:08:10 -05:00
SITE_NAME = SiteName.IGDB
2022-12-08 23:58:44 +00:00
ID_TYPE = IdType.IGDB
2023-05-17 10:32:12 -04:00
URL_PATTERNS = [
r"\w+://www\.igdb\.com/games/([a-zA-Z0-9\-_]+)",
r"\w+://m\.igdb\.com/games/([a-zA-Z0-9\-_]+)",
]
2022-12-29 23:57:02 -05:00
WIKI_PROPERTY_ID = "?"
2022-12-08 23:58:44 +00:00
DEFAULT_MODEL = Game
@classmethod
2023-06-05 10:06:16 -04:00
def id_to_url(cls, id_value):
2022-12-08 23:58:44 +00:00
return "https://www.igdb.com/games/" + id_value
@classmethod
def api_query(cls, p, q):
2022-12-29 23:57:02 -05:00
key = "igdb:" + p + "/" + q
2022-12-08 23:58:44 +00:00
if get_mock_mode():
r = BasicDownloader(key).download().json()
else:
2023-08-11 11:55:42 -04:00
r = json.loads(_wrapper.api_request(p, q)) # type: ignore
2022-12-08 23:58:44 +00:00
if settings.DOWNLOADER_SAVEDIR:
2022-12-29 23:57:02 -05:00
with open(
settings.DOWNLOADER_SAVEDIR + "/" + get_mock_file(key),
"w",
encoding="utf-8",
) as fp:
2022-12-08 23:58:44 +00:00
fp.write(json.dumps(r))
return r
def scrape(self):
2022-12-29 23:57:02 -05:00
fields = "*, cover.url, genres.name, platforms.name, involved_companies.*, involved_companies.company.name"
r = self.api_query("games", f'fields {fields}; where url = "{self.url}";')[0]
brief = r["summary"] if "summary" in r else ""
brief += "\n\n" + r["storyline"] if "storyline" in r else ""
2022-12-08 23:58:44 +00:00
developer = None
publisher = None
release_date = None
genre = None
platform = None
2022-12-29 23:57:02 -05:00
if "involved_companies" in r:
developer = next(
iter(
[
c["company"]["name"]
for c in r["involved_companies"]
if c["developer"]
]
),
None,
)
publisher = next(
iter(
[
c["company"]["name"]
for c in r["involved_companies"]
if c["publisher"]
]
),
None,
)
if "platforms" in r:
ps = sorted(r["platforms"], key=lambda p: p["id"])
platform = [(p["name"] if p["id"] != 6 else "Windows") for p in ps]
if "first_release_date" in r:
release_date = datetime.datetime.fromtimestamp(
r["first_release_date"], datetime.timezone.utc
).strftime("%Y-%m-%d")
if "genres" in r:
genre = [g["name"] for g in r["genres"]]
websites = self.api_query(
"websites", f'fields *; where game.url = "{self.url}";'
)
2022-12-08 23:58:44 +00:00
steam_url = None
official_site = None
for website in websites:
2022-12-29 23:57:02 -05:00
if website["category"] == 1:
official_site = website["url"]
elif website["category"] == 13:
steam_url = website["url"]
pd = ResourceContent(
metadata={
"title": r["name"],
"other_title": [],
"developer": [developer],
"publisher": [publisher],
"release_date": release_date,
"genre": genre,
"platform": platform,
"brief": brief,
"official_site": official_site,
"igdb_id": r["id"],
"cover_image_url": "https:"
2023-02-12 13:06:08 -05:00
+ r["cover"]["url"].replace("t_thumb", "t_cover_big")
if r.get("cover")
else None,
2022-12-29 23:57:02 -05:00
}
)
2022-12-08 23:58:44 +00:00
if steam_url:
2023-06-05 10:06:16 -04:00
pd.lookup_ids[IdType.Steam] = SiteManager.get_site_cls_by_id_type(
2022-12-29 23:57:02 -05:00
IdType.Steam
).url_to_id(steam_url)
2022-12-08 23:58:44 +00:00
if pd.metadata["cover_image_url"]:
imgdl = BasicImageDownloader(pd.metadata["cover_image_url"], self.url)
try:
pd.cover_image = imgdl.download().content
pd.cover_image_extention = imgdl.extention
except Exception:
2022-12-29 23:57:02 -05:00
_logger.debug(
f'failed to download cover for {self.url} from {pd.metadata["cover_image_url"]}'
)
2022-12-08 23:58:44 +00:00
return pd