mirror of
https://github.com/PokeAPI/pokeapi
synced 2024-11-22 03:13:06 +00:00
Merge pull request #1116 from gabeklavans/feature/type_name_icons
feature: type name icons
This commit is contained in:
commit
40bb39ec33
6 changed files with 183 additions and 23 deletions
|
@ -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
|
41
pokemon_v2/migrations/0016_typesprites.py
Normal file
41
pokemon_v2/migrations/0016_typesprites.py
Normal 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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -773,6 +773,10 @@ class TypeEfficacyPast(HasTypeEfficacy, HasGeneration):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TypeSprites(HasType):
|
||||||
|
sprites = models.JSONField()
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# STAT MODELS #
|
# STAT MODELS #
|
||||||
#################
|
#################
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue