Skip to content

Commit

Permalink
Merge pull request #31 from Savage-Aim/multi-bis-per-job
Browse files Browse the repository at this point in the history
Massive BIS Updates!
  • Loading branch information
freyamade authored May 16, 2022
2 parents a1103a4 + 610a83a commit a4fa6b2
Show file tree
Hide file tree
Showing 75 changed files with 2,522 additions and 1,194 deletions.
26 changes: 26 additions & 0 deletions backend/api/migrations/0019_multi_bis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 3.2.13 on 2022-05-13 12:12

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0018_character_alias'),
]

operations = [
migrations.AlterModelOptions(
name='bislist',
options={'ordering': ['-job__role', 'job__ordering', 'name']},
),
migrations.AddField(
model_name='bislist',
name='name',
field=models.CharField(default='', max_length=64),
),
migrations.AlterUniqueTogether(
name='bislist',
unique_together=set(),
),
]
37 changes: 33 additions & 4 deletions backend/api/models/bis_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
The main class of the system;
Links together characters, jobs and gear into a single list
Currently is one gear list per character per job for ease, may change later
"""
from typing import List
from django.db import models
Expand Down Expand Up @@ -38,11 +36,14 @@ class BISList(models.Model):
current_right_ring = models.ForeignKey('Gear', on_delete=models.CASCADE, related_name='current_right_ring_set')
external_link = models.URLField(null=True)
job = models.ForeignKey('Job', on_delete=models.CASCADE)
name = models.CharField(max_length=64, default='')
owner = models.ForeignKey('Character', on_delete=models.CASCADE, related_name='bis_lists')

class Meta:
unique_together = ['job', 'owner']
ordering = ['-job__role', 'job__ordering']
ordering = ['-job__role', 'job__ordering', 'name']

def __str__(self) -> str:
return self.display_name

def accessory_augments_required(self, gear_name: str) -> int:
"""
Expand Down Expand Up @@ -82,6 +83,24 @@ def _check_augments(self, gear_name: str, slots: List[str]) -> int:
needed += 1
return needed

def sync(self, to_sync: 'BISList'):
"""
Given another list, sync the current gear from it to this one and save this one
"""
self.current_mainhand = to_sync.current_mainhand
self.current_offhand = to_sync.current_offhand
self.current_head = to_sync.current_head
self.current_body = to_sync.current_body
self.current_hands = to_sync.current_hands
self.current_legs = to_sync.current_legs
self.current_feet = to_sync.current_feet
self.current_earrings = to_sync.current_earrings
self.current_necklace = to_sync.current_necklace
self.current_bracelet = to_sync.current_bracelet
self.current_left_ring = to_sync.current_left_ring
self.current_right_ring = to_sync.current_right_ring
self.save()

@property
def item_level(self):
"""
Expand All @@ -102,6 +121,16 @@ def item_level(self):
self.current_right_ring.item_level,
]) / 12

@property
def display_name(self) -> str:
"""
Same as Character, use the list name if one exists otherwise use the job name
"""
if self.name != '':
return self.name
else:
return self.job.display_name

@staticmethod
def needs_accessory_augments(gear_name: str) -> models.QuerySet:
"""
Expand Down
2 changes: 1 addition & 1 deletion backend/api/models/character.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Character(models.Model):
world = models.CharField(max_length=60)

def __str__(self) -> str:
return f'{self.name} @ {self.world}'
return self.display_name

@staticmethod
def generate_token() -> str:
Expand Down
2 changes: 1 addition & 1 deletion backend/api/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _create_notif(user: User, text: str, link: str, type: str):

def loot_tracker_update(bis: models.BISList, team: models.Team):
char = bis.owner
text = f'"{char}"\'s {bis.job.id} BIS List was updated via "{team.name}"\'s Loot Tracker!'
text = f'"{char}"\'s BIS List "{bis}" was updated via "{team.name}"\'s Loot Tracker!'
link = f'/characters/{char.id}/bis_list/{bis.id}/'
user = char.user
_create_notif(user, text, link, 'loot_tracker_update')
Expand Down
18 changes: 6 additions & 12 deletions backend/api/serializers/bis_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ def _inner(value: int) -> int:
try:
obj = Gear.objects.get(pk=value)
except Gear.DoesNotExist:
raise serializers.ValidationError('Please ensure your value corresponds with a valid type of Gear.')
raise serializers.ValidationError('Please select a valid type of Gear.')

# Ensure valid Gear for the slot
if not getattr(obj, f'has_{gear_type}', False):
raise serializers.ValidationError('The chosen category of Gear does not have an item for this slot.')
raise serializers.ValidationError('The chosen type of Gear is invalid for this equipment slot.')

return value
return _inner
Expand Down Expand Up @@ -64,6 +64,7 @@ class BISListSerializer(serializers.ModelSerializer):
current_right_ring = GearSerializer()
item_level = serializers.IntegerField()
job = JobSerializer()
display_name = serializers.CharField()

class Meta:
exclude = ['owner']
Expand Down Expand Up @@ -99,6 +100,7 @@ class BISListModifySerializer(serializers.ModelSerializer):
current_offhand_id = serializers.IntegerField()
current_right_ring_id = serializers.IntegerField(validators=[_validate_gear_type('accessories')])
external_link = serializers.URLField(required=False, allow_null=True, allow_blank=True)
name = serializers.CharField(max_length=64, allow_blank=True)

class Meta:
model = BISList
Expand Down Expand Up @@ -129,7 +131,9 @@ class Meta:
'current_offhand_id',
'current_right_ring_id',
'external_link',
'name',
)
extra_kwargs = {'bis_head_id': {'error_messages': {'invalid': 'Please select a valid type of Gear.'}}}

def validate_job_id(self, job_id: str) -> str:
"""
Expand All @@ -141,16 +145,6 @@ def validate_job_id(self, job_id: str) -> str:
except Job.DoesNotExist:
raise serializers.ValidationError('Please select a valid Job.')

# Ensure that this is the only BISList for the Job
test = BISList.objects.filter(job_id=job_id)
if self.instance is not None:
test = test.filter(owner=self.instance.owner).exclude(pk=self.instance.pk)
else:
test = test.filter(owner=self.context['owner'])

if test.exists():
raise serializers.ValidationError('Currently SavageAim only supports one BISList per job.')

# Check the flag
if job_id == 'PLD':
self.offhand_is_mainhand = False
Expand Down
2 changes: 1 addition & 1 deletion backend/api/serializers/loot.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def validate_obtained(self, obtained):
Ensure we're not recording loot for the future
"""
if obtained > datetime.today().date():
raise serializers.ValidationError('Cannot record loot for a date in the future.')
raise serializers.ValidationError('Cannot record Loot for a date in the future.')
return obtained


Expand Down
8 changes: 4 additions & 4 deletions backend/api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)


async def xivapi_lookup(pk: str, token: str, log) -> Optional[str]:
def xivapi_lookup(pk: str, token: str, log) -> Optional[str]:
"""
Actually check XIVAPI for the specified token being present in the specified character's bio
"""
Expand Down Expand Up @@ -69,9 +69,9 @@ def verify_character(pk: int):
return

# Call the xivapi function in a sync context
logger.debug('calling async function')
err = async_to_sync(xivapi_lookup)(obj.lodestone_id, obj.token, logger)
logger.debug('finished async function')
logger.debug('calling lookup function')
err = xivapi_lookup(obj.lodestone_id, obj.token, logger)
logger.debug('finished lookup function')

if err is not None:
notifier.verify_fail(obj, err)
Expand Down
Loading

0 comments on commit a4fa6b2

Please sign in to comment.