This commit is contained in:
Your Name 2022-09-07 00:35:11 -04:00
parent 4adb204ea1
commit 0f03dfa785
10 changed files with 112 additions and 12 deletions

View file

@ -293,6 +293,10 @@ TMDB_API4_KEY = "deadbeef.deadbeef.deadbeef"
# Google Books API Key
GOOGLE_API_KEY = 'deadbeef-deadbeef-deadbeef'
# IGDB
IGDB_CLIENT_ID = 'deadbeef'
IGDB_ACCESS_TOKEN = 'deadbeef'
# Thumbnail setting
# It is possible to optimize the image size even more: https://easy-thumbnails.readthedocs.io/en/latest/ref/optimize/
THUMBNAIL_ALIASES = {

View file

@ -28,6 +28,7 @@ class SourceSiteEnum(models.TextChoices):
TMDB = "tmdb", _("The Movie Database")
GOOGLEBOOKS = "googlebooks", _("Google Books")
BANDCAMP = "bandcamp", _("BandCamp")
IGDB = "igdb", _("IGDB")
class Entity(models.Model):

View file

@ -232,6 +232,7 @@ from common.scrapers.google import GoogleBooksScraper
from common.scrapers.tmdb import TmdbMovieScraper
from common.scrapers.steam import SteamGameScraper
from common.scrapers.imdb import ImdbMovieScraper
from common.scrapers.igdb import IgdbGameScraper
from common.scrapers.spotify import SpotifyAlbumScraper, SpotifyTrackScraper
from common.scrapers.douban import DoubanAlbumScraper, DoubanBookScraper, DoubanGameScraper, DoubanMovieScraper
from common.scrapers.bangumi import BangumiScraper

78
common/scrapers/igdb.py Normal file
View file

@ -0,0 +1,78 @@
import requests
import re
from common.models import SourceSiteEnum
from games.models import Game
from games.forms import GameForm
from django.conf import settings
from common.scraper import *
from igdb.wrapper import IGDBWrapper
import json
import datetime
wrapper = IGDBWrapper(settings.IGDB_CLIENT_ID, settings.IGDB_ACCESS_TOKEN)
class IgdbGameScraper(AbstractScraper):
site_name = SourceSiteEnum.IGDB.value
host = 'https://www.igdb.com/'
data_class = Game
form_class = GameForm
regex = re.compile(r"https://www\.igdb\.com/games/([a-zA-Z0-9\-_]+)")
def scrape(self, url):
m = self.regex.match(url)
if m:
effective_url = m[0]
else:
raise ValueError("not valid url")
effective_url = m[0]
slug = m[1]
fields = '*, cover.url, genres.name, platforms.name, involved_companies.*, involved_companies.company.name'
r = json.loads(wrapper.api_request('games', f'fields {fields}; where url = "{effective_url}";'))[0]
raw_img, ext = self.download_image('https:' + r['cover']['url'].replace('t_thumb', 't_cover_big'), url)
developer = None
publisher = None
release_date = None
genre = None
platform = None
if 'involved_companies' in r:
developer = next(iter([c['company']['name'] for c in r['involved_companies'] if c['developer'] == True]), None)
publisher = next(iter([c['company']['name'] for c in r['involved_companies'] if c['publisher'] == True]), None)
if 'platforms' in r:
platform = [p['name'] for p in r['platforms']]
if 'first_release_date' in r:
release_date = datetime.datetime.fromtimestamp(r['first_release_date'], datetime.timezone.utc)
if 'genres' in r:
genre = [g['name'] for g in r['genres']]
other_info = {'igdb_id': r['id']}
websites = json.loads(wrapper.api_request('websites', f'fields *; where game.url = "{effective_url}";'))
for website in websites:
if website['category'] == 1:
other_info['official_site'] = website['url']
elif website['category'] == 13:
other_info['steam_url'] = website['url']
data = {
'title': r['name'],
'other_title': None,
'developer': developer,
'publisher': publisher,
'release_date': release_date,
'genre': genre,
'platform': platform,
'brief': r['storyline'],
'other_info': other_info,
'source_site': self.site_name,
'source_url': self.get_effective_url(url),
}
self.raw_data, self.raw_img, self.img_ext = data, raw_img, ext
return data, raw_img
@classmethod
def get_effective_url(cls, raw_url):
m = cls.regex.match(raw_url)
if raw_url:
return m[0]
else:
return None

View file

@ -1146,6 +1146,13 @@ select::placeholder {
font-weight: bold;
}
.source-label.source-label__igdb {
background-color: #323A44;
color: #DFE1E2;
border: none;
font-weight: bold;
}
.source-label.source-label__steam {
background: linear-gradient(30deg, #1387b8, #111d2e);
color: white;

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,8 @@ $spotify-color-primary: #1ed760
$spotify-color-secondary: black
$imdb-color-primary: #F5C518
$imdb-color-secondary: #121212
$igdb-color-primary: #323A44
$igdb-color-secondary: #DFE1E2
$steam-color-primary: #1387b8
$steam-color-secondary: #111d2e
$bangumi-color-primary: #F09199
@ -56,6 +58,11 @@ $bandcamp-color-secondary: white
color: $imdb-color-secondary
border: none
font-weight: bold
&.source-label__igdb
background-color: $igdb-color-primary
color: $igdb-color-secondary
border: none
font-weight: bold
&.source-label__steam
background: linear-gradient(30deg, $steam-color-primary, $steam-color-secondary)
color: white

View file

@ -60,7 +60,7 @@ class Game(Entity):
)
genre = postgres.ArrayField(
models.CharField(blank=True, default='', max_length=50),
models.CharField(blank=True, default='', max_length=200),
null=True,
blank=True,
default=list,
@ -68,7 +68,7 @@ class Game(Entity):
)
platform = postgres.ArrayField(
models.CharField(blank=True, default='', max_length=50),
models.CharField(blank=True, default='', max_length=200),
null=True,
blank=True,
default=list,

View file

@ -111,7 +111,15 @@
{% trans '发行日期:' %}{{ game.release_date }}
{% endif %}
</div>
{% if game.other_info %}
{% for k, v in game.other_info.items %}
<div>
{{ k }}{{ v | urlize }}
</div>
{% endfor %}
{% endif %}
</div>
<div class="entity-detail__fields">
@ -123,14 +131,7 @@
{% endif %}
</div>
{% if game.other_info %}
{% for k, v in game.other_info.items %}
<div>
{{ k }}{{ v | urlize }}
</div>
{% endfor %}
{% endif %}
{% if game.last_editor %}
<div>{% trans '最近编辑者:' %}<a href="{% url 'users:home' game.last_editor.mastodon_username %}">{{ game.last_editor | default:"" }}</a></div>

View file

@ -22,3 +22,4 @@ typesense
markdownify
sentry-sdk
gitpython
igdb-api-v4