mirror of
https://github.com/PokeAPI/pokeapi
synced 2024-11-21 19:03:08 +00:00
Merge branch 'master' into issue1024
This commit is contained in:
commit
5e37282c2f
9 changed files with 162 additions and 22 deletions
|
@ -13,6 +13,8 @@ services:
|
||||||
web:
|
web:
|
||||||
volumes:
|
volumes:
|
||||||
- graphiql:/public-console:ro
|
- graphiql:/public-console:ro
|
||||||
|
logging:
|
||||||
|
driver: gcplogs
|
||||||
|
|
||||||
graphql-engine:
|
graphql-engine:
|
||||||
cpus: 0.7
|
cpus: 0.7
|
||||||
|
|
|
@ -2,26 +2,32 @@ worker_processes 1;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
multi_accept on; # accept each connection as soon as you can
|
multi_accept on;
|
||||||
accept_mutex off;
|
accept_mutex off;
|
||||||
use epoll;
|
use epoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
http {
|
http {
|
||||||
include mime.types;
|
access_log off;
|
||||||
default_type application/octet-stream;
|
log_format pokeapilogformat
|
||||||
|
'$remote_addr '
|
||||||
|
'"$request" $status cs:$upstream_cache_status s:$bytes_sent '
|
||||||
|
'r:"$http_referer"';
|
||||||
|
error_log /dev/stdout warn;
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
server_tokens off; # dont send unnecessary server info (like version)
|
server_tokens off;
|
||||||
|
|
||||||
add_header X-XSS-Protection "1; mode=block"; # prevent XSS
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
|
||||||
client_body_buffer_size 10K; # raise the threshold by which requests are written to HDD instead of RAM
|
client_body_buffer_size 10K;
|
||||||
client_header_buffer_size 2k;
|
client_header_buffer_size 1k;
|
||||||
client_max_body_size 8m; # we dont accept requests larger that 8mb
|
client_max_body_size 8m;
|
||||||
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
tcp_nopush on;
|
tcp_nopush on;
|
||||||
tcp_nodelay on;
|
tcp_nodelay on;
|
||||||
|
|
||||||
keepalive_timeout 5;
|
keepalive_timeout 5;
|
||||||
|
|
||||||
|
@ -47,6 +53,16 @@ http {
|
||||||
192.168.0.0/24 0;
|
192.168.0.0/24 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map $http_user_agent $exclude_ua {
|
||||||
|
"~*monitoring*" 0;
|
||||||
|
default 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
map $request_method $only_post {
|
||||||
|
default 0;
|
||||||
|
POST $exclude_ua;
|
||||||
|
}
|
||||||
|
|
||||||
map $limit $limit_key {
|
map $limit $limit_key {
|
||||||
0 "";
|
0 "";
|
||||||
1 $binary_remote_addr;
|
1 $binary_remote_addr;
|
||||||
|
@ -69,7 +85,7 @@ http {
|
||||||
|
|
||||||
# Admin console
|
# Admin console
|
||||||
location /graphql/admin/ {
|
location /graphql/admin/ {
|
||||||
expires 1m; # client-side caching, one minute for each API resource
|
expires 1m;
|
||||||
add_header Cache-Control "public";
|
add_header Cache-Control "public";
|
||||||
add_header Pragma public;
|
add_header Pragma public;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
|
@ -89,21 +105,15 @@ http {
|
||||||
}
|
}
|
||||||
|
|
||||||
location /graphql/v1beta {
|
location /graphql/v1beta {
|
||||||
|
access_log /dev/stdout pokeapilogformat if=$only_post;
|
||||||
include /ssl/cache.conf*;
|
include /ssl/cache.conf*;
|
||||||
# proxy_cache small;
|
|
||||||
# proxy_cache_valid 200 10d;
|
|
||||||
# proxy_cache_valid any 0;
|
|
||||||
# proxy_cache_methods POST;
|
|
||||||
# proxy_cache_key "$request_method$request_uri$request_body";
|
|
||||||
limit_req zone=graphqlDefaultLimit burst=100 nodelay;
|
limit_req zone=graphqlDefaultLimit burst=100 nodelay;
|
||||||
limit_req_status 429;
|
limit_req_status 429;
|
||||||
expires 30m; # client-side caching, one minute for each API resource
|
expires 30m;
|
||||||
add_header Cache-Control "public";
|
add_header Cache-Control "public";
|
||||||
add_header Pragma public;
|
add_header Pragma public;
|
||||||
# add_header X-Proxy-Cache $upstream_cache_status;
|
|
||||||
proxy_hide_header Access-Control-Allow-Origin;
|
proxy_hide_header Access-Control-Allow-Origin;
|
||||||
add_header Access-Control-Allow-Origin *;
|
add_header Access-Control-Allow-Origin *;
|
||||||
# add_header X-Cache-Date $upstream_http_date;
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
@ -115,7 +125,7 @@ http {
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
expires 1m; # client-side caching, one minute for each API resource
|
expires 1m;
|
||||||
add_header Cache-Control "public";
|
add_header Cache-Control "public";
|
||||||
add_header Pragma public;
|
add_header Pragma public;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
|
@ -36,8 +36,16 @@ MEDIA_DIR = "{prefix}{{file_name}}".format(
|
||||||
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/",
|
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
SOUND_DIR = "{prefix}{{file_name}}".format(
|
||||||
|
prefix=os.environ.get(
|
||||||
|
"POKEAPI_CRIES_PREFIX",
|
||||||
|
"https://raw.githubusercontent.com/PokeAPI/cries/main/cries/",
|
||||||
|
)
|
||||||
|
)
|
||||||
IMAGE_DIR = os.getcwd() + "/data/v2/sprites/sprites/"
|
IMAGE_DIR = os.getcwd() + "/data/v2/sprites/sprites/"
|
||||||
|
CRIES_DIR = os.getcwd() + "/data/v2/cries/cries/"
|
||||||
RESOURCE_IMAGES = []
|
RESOURCE_IMAGES = []
|
||||||
|
RESOURCE_CRIES = []
|
||||||
|
|
||||||
for root, dirs, files in os.walk(IMAGE_DIR):
|
for root, dirs, files in os.walk(IMAGE_DIR):
|
||||||
for file in files:
|
for file in files:
|
||||||
|
@ -45,8 +53,20 @@ for root, dirs, files in os.walk(IMAGE_DIR):
|
||||||
image_path = image_path.replace("\\", "/") # convert Windows-style path to Unix
|
image_path = image_path.replace("\\", "/") # convert Windows-style path to Unix
|
||||||
RESOURCE_IMAGES.append(image_path)
|
RESOURCE_IMAGES.append(image_path)
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(CRIES_DIR):
|
||||||
|
for file in files:
|
||||||
|
cry_path = os.path.join(root.replace(CRIES_DIR, ""), file)
|
||||||
|
cry_path = cry_path.replace("\\", "/") # convert Windows-style path to Unix
|
||||||
|
RESOURCE_CRIES.append(cry_path)
|
||||||
|
|
||||||
def file_path_or_none(file_name):
|
|
||||||
|
def file_path_or_none(file_name, image_file=True):
|
||||||
|
if not image_file:
|
||||||
|
return (
|
||||||
|
SOUND_DIR.format(file_name=file_name)
|
||||||
|
if file_name in RESOURCE_CRIES
|
||||||
|
else None
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
MEDIA_DIR.format(file_name=file_name) if file_name in RESOURCE_IMAGES else None
|
MEDIA_DIR.format(file_name=file_name) if file_name in RESOURCE_IMAGES else None
|
||||||
)
|
)
|
||||||
|
@ -1931,6 +1951,26 @@ def _build_pokemons():
|
||||||
|
|
||||||
build_generic((PokemonSprites,), "pokemon.csv", csv_record_to_objects)
|
build_generic((PokemonSprites,), "pokemon.csv", csv_record_to_objects)
|
||||||
|
|
||||||
|
def try_cry_names(path, info, extension):
|
||||||
|
file_name = "%s.%s" % (info[0], extension)
|
||||||
|
return file_path_or_none(path + file_name, image_file=False)
|
||||||
|
|
||||||
|
def csv_record_to_objects(info):
|
||||||
|
poke_cries = "pokemon"
|
||||||
|
latest = f"{poke_cries}/latest/"
|
||||||
|
legacy = f"{poke_cries}/legacy/"
|
||||||
|
cries = {
|
||||||
|
"latest": try_cry_names(latest, info, "ogg"),
|
||||||
|
"legacy": try_cry_names(legacy, info, "ogg"),
|
||||||
|
}
|
||||||
|
yield PokemonCries(
|
||||||
|
id=int(info[0]),
|
||||||
|
pokemon=Pokemon.objects.get(pk=int(info[0])),
|
||||||
|
cries=cries,
|
||||||
|
)
|
||||||
|
|
||||||
|
build_generic((PokemonCries,), "pokemon.csv", csv_record_to_objects)
|
||||||
|
|
||||||
def csv_record_to_objects(info):
|
def csv_record_to_objects(info):
|
||||||
yield PokemonAbility(
|
yield PokemonAbility(
|
||||||
pokemon_id=int(info[0]),
|
pokemon_id=int(info[0]),
|
||||||
|
|
|
@ -27,6 +27,13 @@ array_relationships:
|
||||||
table:
|
table:
|
||||||
name: pokemon_v2_pokemonabilitypast
|
name: pokemon_v2_pokemonabilitypast
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: pokemon_v2_pokemoncries
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: pokemon_id
|
||||||
|
table:
|
||||||
|
name: pokemon_v2_pokemoncries
|
||||||
|
schema: public
|
||||||
- name: pokemon_v2_pokemonforms
|
- name: pokemon_v2_pokemonforms
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on:
|
foreign_key_constraint_on:
|
||||||
|
|
|
@ -110,6 +110,7 @@
|
||||||
- "!include public_pokemon_v2_pokemonabilitypast.yaml"
|
- "!include public_pokemon_v2_pokemonabilitypast.yaml"
|
||||||
- "!include public_pokemon_v2_pokemoncolor.yaml"
|
- "!include public_pokemon_v2_pokemoncolor.yaml"
|
||||||
- "!include public_pokemon_v2_pokemoncolorname.yaml"
|
- "!include public_pokemon_v2_pokemoncolorname.yaml"
|
||||||
|
- "!include public_pokemon_v2_pokemoncries.yaml"
|
||||||
- "!include public_pokemon_v2_pokemondexnumber.yaml"
|
- "!include public_pokemon_v2_pokemondexnumber.yaml"
|
||||||
- "!include public_pokemon_v2_pokemonegggroup.yaml"
|
- "!include public_pokemon_v2_pokemonegggroup.yaml"
|
||||||
- "!include public_pokemon_v2_pokemonevolution.yaml"
|
- "!include public_pokemon_v2_pokemonevolution.yaml"
|
||||||
|
|
41
pokemon_v2/migrations/0015_pokemoncries.py
Normal file
41
pokemon_v2/migrations/0015_pokemoncries.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Generated by Django 3.2.23 on 2024-02-02 18:02
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("pokemon_v2", "0014_auto_20231121_1209"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="PokemonCries",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("cries", models.JSONField()),
|
||||||
|
(
|
||||||
|
"pokemon",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="pokemoncries",
|
||||||
|
to="pokemon_v2.pokemon",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"abstract": False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -1796,3 +1796,7 @@ class PokemonTypePast(HasPokemon, HasType, HasGeneration):
|
||||||
|
|
||||||
class PokemonSprites(HasPokemon):
|
class PokemonSprites(HasPokemon):
|
||||||
sprites = models.JSONField()
|
sprites = models.JSONField()
|
||||||
|
|
||||||
|
|
||||||
|
class PokemonCries(HasPokemon):
|
||||||
|
cries = models.JSONField()
|
||||||
|
|
|
@ -2728,6 +2728,7 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
||||||
held_items = serializers.SerializerMethodField("get_pokemon_held_items")
|
held_items = serializers.SerializerMethodField("get_pokemon_held_items")
|
||||||
location_area_encounters = serializers.SerializerMethodField("get_encounters")
|
location_area_encounters = serializers.SerializerMethodField("get_encounters")
|
||||||
sprites = serializers.SerializerMethodField("get_pokemon_sprites")
|
sprites = serializers.SerializerMethodField("get_pokemon_sprites")
|
||||||
|
cries = serializers.SerializerMethodField("get_pokemon_cries")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Pokemon
|
model = Pokemon
|
||||||
|
@ -2748,6 +2749,7 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
||||||
"moves",
|
"moves",
|
||||||
"species",
|
"species",
|
||||||
"sprites",
|
"sprites",
|
||||||
|
"cries",
|
||||||
"stats",
|
"stats",
|
||||||
"types",
|
"types",
|
||||||
"past_types",
|
"past_types",
|
||||||
|
@ -2757,6 +2759,10 @@ class PokemonDetailSerializer(serializers.ModelSerializer):
|
||||||
sprites_object = PokemonSprites.objects.get(pokemon_id=obj)
|
sprites_object = PokemonSprites.objects.get(pokemon_id=obj)
|
||||||
return sprites_object.sprites
|
return sprites_object.sprites
|
||||||
|
|
||||||
|
def get_pokemon_cries(self, obj):
|
||||||
|
cries_object = PokemonCries.objects.get(pokemon_id=obj)
|
||||||
|
return cries_object.cries
|
||||||
|
|
||||||
def get_pokemon_moves(self, obj):
|
def get_pokemon_moves(self, obj):
|
||||||
version_objects = VersionGroup.objects.all()
|
version_objects = VersionGroup.objects.all()
|
||||||
version_data = VersionGroupSummarySerializer(
|
version_data = VersionGroupSummarySerializer(
|
||||||
|
|
|
@ -1725,6 +1725,21 @@ class APIData:
|
||||||
|
|
||||||
return pokemon_sprites
|
return pokemon_sprites
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_pokemon_cries_data(cls, pokemon, latest=True, legacy=False):
|
||||||
|
cries_path = (
|
||||||
|
"https://raw.githubusercontent.com/PokeAPI/cries/main/cries/pokemon/%s.ogg"
|
||||||
|
)
|
||||||
|
cries = {
|
||||||
|
"latest": cries_path % f"latest/{pokemon.id}" if latest else None,
|
||||||
|
"legacy": cries_path % f"legacy/{pokemon.id}" if legacy else None,
|
||||||
|
}
|
||||||
|
pokemon_cries = PokemonCries.objects.create(
|
||||||
|
pokemon=pokemon, cries=json.dumps(cries)
|
||||||
|
)
|
||||||
|
pokemon_cries.save()
|
||||||
|
return pokemon_cries
|
||||||
|
|
||||||
# Evolution Data
|
# Evolution Data
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_evolution_trigger_data(cls, name="evltn trgr"):
|
def setup_evolution_trigger_data(cls, name="evltn trgr"):
|
||||||
|
@ -4596,6 +4611,7 @@ class APITests(APIData, APITestCase):
|
||||||
pokemon_species=pokemon_species, name="pkm for base pkmn spcs"
|
pokemon_species=pokemon_species, name="pkm for base pkmn spcs"
|
||||||
)
|
)
|
||||||
self.setup_pokemon_sprites_data(pokemon)
|
self.setup_pokemon_sprites_data(pokemon)
|
||||||
|
self.setup_pokemon_cries_data(pokemon)
|
||||||
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
"{}/pokemon-species/{}/".format(API_V2, pokemon_species.pk),
|
"{}/pokemon-species/{}/".format(API_V2, pokemon_species.pk),
|
||||||
|
@ -4816,6 +4832,7 @@ class APITests(APIData, APITestCase):
|
||||||
)
|
)
|
||||||
pokemon_item = self.setup_pokemon_item_data(pokemon=pokemon)
|
pokemon_item = self.setup_pokemon_item_data(pokemon=pokemon)
|
||||||
pokemon_sprites = self.setup_pokemon_sprites_data(pokemon=pokemon)
|
pokemon_sprites = self.setup_pokemon_sprites_data(pokemon=pokemon)
|
||||||
|
pokemon_cries = self.setup_pokemon_cries_data(pokemon, latest=True, legacy=True)
|
||||||
pokemon_game_index = self.setup_pokemon_game_index_data(
|
pokemon_game_index = self.setup_pokemon_game_index_data(
|
||||||
pokemon=pokemon, game_index=10
|
pokemon=pokemon, game_index=10
|
||||||
)
|
)
|
||||||
|
@ -5052,7 +5069,9 @@ class APITests(APIData, APITestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
sprites_data = json.loads(pokemon_sprites.sprites)
|
sprites_data = json.loads(pokemon_sprites.sprites)
|
||||||
|
cries_data = json.loads(pokemon_cries.cries)
|
||||||
response_sprites_data = json.loads(response.data["sprites"])
|
response_sprites_data = json.loads(response.data["sprites"])
|
||||||
|
response_cries_data = json.loads(response.data["cries"])
|
||||||
|
|
||||||
# sprite params
|
# sprite params
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -5070,6 +5089,16 @@ class APITests(APIData, APITestCase):
|
||||||
response_sprites_data["other"]["showdown"]["back_default"],
|
response_sprites_data["other"]["showdown"]["back_default"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# cries params
|
||||||
|
self.assertEqual(
|
||||||
|
cries_data["latest"],
|
||||||
|
"{}".format(cries_data["latest"]),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
cries_data["legacy"],
|
||||||
|
"{}".format(cries_data["legacy"]),
|
||||||
|
)
|
||||||
|
|
||||||
def test_pokemon_form_api(self):
|
def test_pokemon_form_api(self):
|
||||||
pokemon_species = self.setup_pokemon_species_data()
|
pokemon_species = self.setup_pokemon_species_data()
|
||||||
pokemon = self.setup_pokemon_data(pokemon_species=pokemon_species)
|
pokemon = self.setup_pokemon_data(pokemon_species=pokemon_species)
|
||||||
|
|
Loading…
Reference in a new issue