Merge pull request #1116 from gabeklavans/feature/type_name_icons

feature: type name icons
This commit is contained in:
Alessandro Pezzè 2024-08-08 23:03:29 +09:00 committed by GitHub
commit 40bb39ec33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 183 additions and 23 deletions

View file

@ -629,6 +629,45 @@ def _build_types():
build_generic((TypeEfficacyPast,), "type_efficacy_past.csv", csv_record_to_objects) build_generic((TypeEfficacyPast,), "type_efficacy_past.csv", csv_record_to_objects)
def csv_record_to_objects(info):
game_map = {
"generation-iii": [
"colosseum",
"emerald",
"firered-leafgreen",
"ruby-saphire",
"xd",
],
"generation-iv": ["diamond-pearl", "heartgold-soulsilver", "platinum"],
"generation-v": ["black-2-white-2", "black-white"],
"generation-vi": ["omega-ruby-alpha-sapphire", "x-y"],
"generation-vii": [
"lets-go-pikachu-lets-go-eevee",
"sun-moon",
"ultra-sun-ultra-moon",
],
"generation-viii": [
"brilliant-diamond-and-shining-pearl",
"legends-arceus",
"sword-shield",
],
"generation-ix": ["scarlet-violet"],
}
sprites = {}
for generation in game_map.keys():
for game in game_map[generation]:
if generation not in sprites:
sprites[generation] = {}
sprites[generation][game] = {
"name_icon": file_path_or_none(
f"types/{generation}/{game}/{info[0]}.png"
)
}
yield TypeSprites(type_id=int(info[0]), sprites=sprites)
build_generic((TypeSprites,), "types.csv", csv_record_to_objects)
############# #############
# CONTEST # # CONTEST #

@ -1 +1 @@
Subproject commit ca5a7886c10753144e6fae3b69d45a4d42a449b4 Subproject commit 6e5b8ac354ddc347104840cbd14ad6e0b2fdb551

View file

@ -0,0 +1,41 @@
# Generated by Django 3.2.23 on 2024-07-29 02:09
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("pokemon_v2", "0015_pokemoncries"),
]
operations = [
migrations.CreateModel(
name="TypeSprites",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("sprites", models.JSONField()),
(
"type",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="typesprites",
to="pokemon_v2.type",
),
),
],
options={
"abstract": False,
},
),
]

View file

@ -773,6 +773,10 @@ class TypeEfficacyPast(HasTypeEfficacy, HasGeneration):
pass pass
class TypeSprites(HasType):
sprites = models.JSONField()
################# #################
# STAT MODELS # # STAT MODELS #
################# #################

View file

@ -2340,6 +2340,12 @@ class TypeNameSerializer(serializers.ModelSerializer):
fields = ("name", "language") fields = ("name", "language")
class TypeSpriteSerializer(serializers.ModelSerializer):
class Meta:
model = TypeSprites
fields = ("sprites",)
class TypeDetailSerializer(serializers.ModelSerializer): class TypeDetailSerializer(serializers.ModelSerializer):
""" """
Serializer for the Type resource Serializer for the Type resource
@ -2357,6 +2363,7 @@ class TypeDetailSerializer(serializers.ModelSerializer):
) )
pokemon = serializers.SerializerMethodField("get_type_pokemon") pokemon = serializers.SerializerMethodField("get_type_pokemon")
moves = MoveSummarySerializer(many=True, read_only=True, source="move") moves = MoveSummarySerializer(many=True, read_only=True, source="move")
sprites = serializers.SerializerMethodField("get_type_sprites")
class Meta: class Meta:
model = Type model = Type
@ -2371,8 +2378,13 @@ class TypeDetailSerializer(serializers.ModelSerializer):
"names", "names",
"pokemon", "pokemon",
"moves", "moves",
"sprites",
) )
def get_type_sprites(self, obj):
sprites_object = TypeSprites.objects.get(type_id=obj)
return sprites_object.sprites
# adds an entry for the given type with the given damage # adds an entry for the given type with the given damage
# factor in the given direction to the set of relations # factor in the given direction to the set of relations

View file

@ -312,7 +312,7 @@ class APIData:
@classmethod @classmethod
def setup_item_sprites_data(cls, item, default=True): def setup_item_sprites_data(cls, item, default=True):
sprite_path = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/%s.png" sprite_path = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/items/%s.png"
sprites = { sprites = {
"default": sprite_path % item.id if default else None, "default": sprite_path % item.id if default else None,
@ -692,6 +692,54 @@ class APIData:
return type_game_index return type_game_index
def setup_type_sprites_data(cls, type):
game_map = {
"generation-iii": [
"colosseum",
"emerald",
"firered-leafgreen",
"ruby-saphire",
"xd",
],
"generation-iv": ["diamond-pearl", "heartgold-soulsilver", "platinum"],
"generation-v": ["black-2-white-2", "black-white"],
"generation-vi": ["omega-ruby-alpha-sapphire", "x-y"],
"generation-vii": [
"lets-go-pikachu-lets-go-eevee",
"sun-moon",
"ultra-sun-ultra-moon",
],
"generation-viii": [
"brilliant-diamond-and-shining-pearl",
"legends-arceus",
"sword-shield",
],
"generation-ix": ["scarlet-violet"],
}
sprites = {}
for generation in game_map.keys():
for game in game_map[generation]:
if generation not in sprites:
sprites[generation] = {}
if type.id == 18 and generation.endswith(("-iii", "-iv", "-v")):
sprites[generation][game] = None
elif type.id == 19 and generation.endswith(
("-iii", "-iv", "-v", "-vi", "-vii", "-viii")
):
sprites[generation][game] = None
else:
sprites[generation][game] = {
"name_icon": f"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/types/{generation}/{game}/{type.id}.png"
}
type_sprites = TypeSprites.objects.create(
type=type, sprites=json.dumps(sprites)
)
type_sprites.save()
return type_sprites, game_map
# Move Data # Move Data
@classmethod @classmethod
def setup_move_ailment_data(cls, name="mv almnt"): def setup_move_ailment_data(cls, name="mv almnt"):
@ -2753,9 +2801,14 @@ class APITests(APIData, APITestCase):
"{}{}/evolution-chain/{}/".format(TEST_HOST, API_V2, evolution_chain.pk), "{}{}/evolution-chain/{}/".format(TEST_HOST, API_V2, evolution_chain.pk),
) )
sprites_data = json.loads(response.data["sprites"]) sprites_data = json.loads(item_sprites.sprites)
response_sprites_data = json.loads(response.data["sprites"])
# sprites # sprites
self.assertEqual(
sprites_data["default"],
response_sprites_data["default"],
)
self.assertEqual( self.assertEqual(
sprites_data["default"], sprites_data["default"],
"{}".format(sprites_data["default"]), "{}".format(sprites_data["default"]),
@ -3313,12 +3366,12 @@ class APITests(APIData, APITestCase):
# Type Tests # Type Tests
def test_type_api(self): def test_type_api(self):
type = self.setup_type_data(name="base tp") type_obj = self.setup_type_data(name="base tp")
type_name = self.setup_type_name_data(type, name="base tp nm") type_name = self.setup_type_name_data(type_obj, name="base tp nm")
type_game_index = self.setup_type_game_index_data(type, game_index=10) type_game_index = self.setup_type_game_index_data(type_obj, game_index=10)
move = self.setup_move_data(name="mv for base tp", type=type) move = self.setup_move_data(name="mv for base tp", type=type_obj)
pokemon = self.setup_pokemon_data(name="pkmn for base tp") pokemon = self.setup_pokemon_data(name="pkmn for base tp")
pokemon_type = self.setup_pokemon_type_data(pokemon=pokemon, type=type) pokemon_type = self.setup_pokemon_type_data(pokemon=pokemon, type=type_obj)
generation = self.setup_generation_data(name="past gen") generation = self.setup_generation_data(name="past gen")
@ -3345,39 +3398,41 @@ class APITests(APIData, APITestCase):
newer_type = self.setup_type_data(name="newer tp", generation=newer_generation) newer_type = self.setup_type_data(name="newer tp", generation=newer_generation)
type_sprites, game_map = self.setup_type_sprites_data(type=type_obj)
# type relations # type relations
no_damage_to_relation = TypeEfficacy( no_damage_to_relation = TypeEfficacy(
damage_type=type, target_type=no_damage_to, damage_factor=0 damage_type=type_obj, target_type=no_damage_to, damage_factor=0
) )
no_damage_to_relation.save() no_damage_to_relation.save()
half_damage_to_type_relation = TypeEfficacy( half_damage_to_type_relation = TypeEfficacy(
damage_type=type, target_type=half_damage_to, damage_factor=50 damage_type=type_obj, target_type=half_damage_to, damage_factor=50
) )
half_damage_to_type_relation.save() half_damage_to_type_relation.save()
double_damage_to_type_relation = TypeEfficacy( double_damage_to_type_relation = TypeEfficacy(
damage_type=type, target_type=double_damage_to, damage_factor=200 damage_type=type_obj, target_type=double_damage_to, damage_factor=200
) )
double_damage_to_type_relation.save() double_damage_to_type_relation.save()
no_damage_from_relation = TypeEfficacy( no_damage_from_relation = TypeEfficacy(
damage_type=no_damage_from, target_type=type, damage_factor=0 damage_type=no_damage_from, target_type=type_obj, damage_factor=0
) )
no_damage_from_relation.save() no_damage_from_relation.save()
half_damage_from_type_relation = TypeEfficacy( half_damage_from_type_relation = TypeEfficacy(
damage_type=half_damage_from, target_type=type, damage_factor=50 damage_type=half_damage_from, target_type=type_obj, damage_factor=50
) )
half_damage_from_type_relation.save() half_damage_from_type_relation.save()
double_damage_from_type_relation = TypeEfficacy( double_damage_from_type_relation = TypeEfficacy(
damage_type=double_damage_from, target_type=type, damage_factor=200 damage_type=double_damage_from, target_type=type_obj, damage_factor=200
) )
double_damage_from_type_relation.save() double_damage_from_type_relation.save()
double_damage_from_newer_type_relation = TypeEfficacy( double_damage_from_newer_type_relation = TypeEfficacy(
damage_type=newer_type, target_type=type, damage_factor=200 damage_type=newer_type, target_type=type_obj, damage_factor=200
) )
double_damage_from_newer_type_relation.save() double_damage_from_newer_type_relation.save()
@ -3385,20 +3440,20 @@ class APITests(APIData, APITestCase):
# type used to deal half damage rather than no damage # type used to deal half damage rather than no damage
past_no_damage_to_relation = TypeEfficacyPast( past_no_damage_to_relation = TypeEfficacyPast(
damage_type=type, damage_type=type_obj,
target_type=no_damage_to, target_type=no_damage_to,
damage_factor=50, damage_factor=50,
generation=generation, generation=generation,
) )
past_no_damage_to_relation.save() past_no_damage_to_relation.save()
response = self.client.get("{}/type/{}/".format(API_V2, type.pk)) response = self.client.get("{}/type/{}/".format(API_V2, type_obj.pk))
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
# base params # base params
self.assertEqual(response.data["id"], type.pk) self.assertEqual(response.data["id"], type_obj.pk)
self.assertEqual(response.data["name"], type.name) self.assertEqual(response.data["name"], type_obj.name)
# name params # name params
self.assertEqual(response.data["names"][0]["name"], type_name.name) self.assertEqual(response.data["names"][0]["name"], type_name.name)
self.assertEqual( self.assertEqual(
@ -3409,19 +3464,19 @@ class APITests(APIData, APITestCase):
"{}{}/language/{}/".format(TEST_HOST, API_V2, type_name.language.pk), "{}{}/language/{}/".format(TEST_HOST, API_V2, type_name.language.pk),
) )
# generation params # generation params
self.assertEqual(response.data["generation"]["name"], type.generation.name) self.assertEqual(response.data["generation"]["name"], type_obj.generation.name)
self.assertEqual( self.assertEqual(
response.data["generation"]["url"], response.data["generation"]["url"],
"{}{}/generation/{}/".format(TEST_HOST, API_V2, type.generation.pk), "{}{}/generation/{}/".format(TEST_HOST, API_V2, type_obj.generation.pk),
) )
# damage class params # damage class params
self.assertEqual( self.assertEqual(
response.data["move_damage_class"]["name"], type.move_damage_class.name response.data["move_damage_class"]["name"], type_obj.move_damage_class.name
) )
self.assertEqual( self.assertEqual(
response.data["move_damage_class"]["url"], response.data["move_damage_class"]["url"],
"{}{}/move-damage-class/{}/".format( "{}{}/move-damage-class/{}/".format(
TEST_HOST, API_V2, type.move_damage_class.pk TEST_HOST, API_V2, type_obj.move_damage_class.pk
), ),
) )
# move params # move params
@ -3570,6 +3625,15 @@ class APITests(APIData, APITestCase):
), ),
) )
sprites_data = json.loads(type_sprites.sprites)
for generation in game_map.keys():
for game in game_map[generation]:
self.assertEqual(
json.loads(response.data["sprites"])[generation][game]["name_icon"],
sprites_data[generation][game]["name_icon"],
)
# Pokedex Tests # Pokedex Tests
def test_pokedex_api(self): def test_pokedex_api(self):
pokedex = self.setup_pokedex_data(name="base pkdx") pokedex = self.setup_pokedex_data(name="base pkdx")