From cca8b263752bddb72b0a6e0727a3ad494f7c556f Mon Sep 17 00:00:00 2001 From: Adarnof Date: Tue, 3 Oct 2017 21:50:32 -0400 Subject: [PATCH 1/4] Handle FAT ZeroDivisionErrors --- allianceauth/fleetactivitytracking/views.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/allianceauth/fleetactivitytracking/views.py b/allianceauth/fleetactivitytracking/views.py index 92dbed38..81406c3d 100644 --- a/allianceauth/fleetactivitytracking/views.py +++ b/allianceauth/fleetactivitytracking/views.py @@ -37,8 +37,12 @@ class CorpStat(object): self.n_fats = Fat.objects.filter(character__corporation_id=self.corp.corporation_id).filter( fatlink__fatdatetime__gte=start_of_month).filter(fatlink__fatdatetime__lte=start_of_next_month).count() + @property def avg_fat(self): - return "%.2f" % (float(self.n_fats) / float(self.corp.member_count)) + try: + return "%.2f" % (float(self.n_fats) / float(self.corp.member_count)) + except ZeroDivisionError: + return "%.2f" % 0 class MemberStat(object): @@ -55,8 +59,12 @@ class MemberStat(object): self.n_fats = Fat.objects.filter(user_id=member.pk).filter( fatlink__fatdatetime__gte=start_of_month).filter(fatlink__fatdatetime__lte=start_of_next_month).count() + @property def avg_fat(self): - return "%.2f" % (float(self.n_fats) / float(self.n_chars)) + try: + return "%.2f" % (float(self.n_fats) / float(self.n_chars)) + except ZeroDivisionError: + return "%.2f" % 0 def first_day_of_next_month(year, month): @@ -117,7 +125,7 @@ def fatlink_statistics_corp_view(request, corpid, year=None, month=None): # collect and sort stats stat_list = [fat_stats[x] for x in fat_stats] stat_list.sort(key=lambda stat: stat.mainchar.character_name) - stat_list.sort(key=lambda stat: (stat.n_fats, stat.n_fats / stat.n_chars), reverse=True) + stat_list.sort(key=lambda stat: (stat.n_fats, stat.avg_fat), reverse=True) context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year, 'previous_month': start_of_previous_month, 'corpid': corpid} @@ -153,7 +161,7 @@ def fatlink_statistics_view(request, year=datetime.date.today().year, month=date # collect and sort stats stat_list = [fat_stats[x] for x in fat_stats] stat_list.sort(key=lambda stat: stat.corp.corporation_name) - stat_list.sort(key=lambda stat: (stat.n_fats, stat.n_fats / stat.corp.member_count), reverse=True) + stat_list.sort(key=lambda stat: (stat.n_fats, stat.avg_fat), reverse=True) context = {'fatStats': stat_list, 'month': start_of_month.strftime("%B"), 'year': year, 'previous_month': start_of_previous_month} From c63464c4c92d49375a0225f89198cbafeed4e3a6 Mon Sep 17 00:00:00 2001 From: Adarnof Date: Sun, 1 Oct 2017 12:53:03 -0400 Subject: [PATCH 2/4] Handle new zKillboard API format --- allianceauth/srp/managers.py | 13 +++++++------ allianceauth/srp/views.py | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/allianceauth/srp/managers.py b/allianceauth/srp/managers.py index d59e5366..b7547e28 100644 --- a/allianceauth/srp/managers.py +++ b/allianceauth/srp/managers.py @@ -6,7 +6,7 @@ import logging logger = logging.getLogger(__name__) -class SRPManager: +class srpManager: def __init__(self): pass @@ -26,11 +26,12 @@ class SRPManager: r = requests.get(url, headers=headers) result = r.json()[0] if result: - ship_type = result['victim']['shipTypeID'] - logger.debug("Ship type for kill ID %s is determined to be %s" % (kill_id, ship_type)) + ship_type = result['victim']['ship_type_id'] + logger.debug("Ship type for kill ID %s is %s" % (kill_id, ship_type)) ship_value = result['zkb']['totalValue'] - logger.debug("total loss value for kill id %s is %s" % (kill_id, ship_value)) - victim_name = result['victim']['characterName'] - return ship_type, ship_value, victim_name + logger.debug("Total loss value for kill id %s is %s" % (kill_id, ship_value)) + victim_id = result['victim']['character_id'] + return ship_type, ship_value, victim_id else: raise ValueError("Invalid Kill ID") + diff --git a/allianceauth/srp/views.py b/allianceauth/srp/views.py index 0c660a4a..5b94e257 100755 --- a/allianceauth/srp/views.py +++ b/allianceauth/srp/views.py @@ -186,7 +186,7 @@ def srp_request_view(request, fleet_srp): try: srp_kill_link = SRPManager.get_kill_id(srp_request.killboard_link) - (ship_type_id, ship_value, victim_name) = SRPManager.get_kill_data(srp_kill_link) + (ship_type_id, ship_value, victim_id) = SRPManager.get_kill_data(srp_kill_link) except ValueError: logger.debug("User %s Submitted Invalid Killmail Link %s or server could not be reached" % ( request.user, srp_request.killboard_link)) @@ -196,7 +196,7 @@ def srp_request_view(request, fleet_srp): "Your SRP request Killmail link is invalid. Please make sure you are using zKillboard.")) return redirect("srp:management") - if request.user.character_ownerships.filter(character__character_name=victim_name).exists(): + if request.user.character_ownerships.filter(character__character_id=str(victim_id)).exists(): srp_request.srp_ship_name = provider.get_itemtype(ship_type_id).name srp_request.kb_total_loss = ship_value srp_request.post_time = post_time @@ -209,8 +209,8 @@ def srp_request_view(request, fleet_srp): else: messages.error(request, _( - "%(charname)s does not belong to your Auth account. Please add the API key for this character and try again") - % {"charname": victim_name}) + "Character %(charid)s does not belong to your Auth account. Please add the API key for this character and try again") + % {"charid": victim_id}) return redirect("srp:management") else: logger.debug("Returning blank SrpFleetUserRequestForm") @@ -237,7 +237,7 @@ def srp_request_remove(request): srpuserrequest = SrpUserRequest.objects.get(id=srp_request_id) stored_fleet_view = srpuserrequest.srp_fleet_main.id srpuserrequest.delete() - logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user)) + logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user)) if stored_fleet_view is None: logger.error("Unable to delete srp requests for user %s - request matching id not found." % (request.user)) messages.error(request, _('Unable to locate selected SRP request.')) From f961db3130e79315d5f6390f4370bbb72d26000d Mon Sep 17 00:00:00 2001 From: phaynu <32961342+phaynu@users.noreply.github.com> Date: Tue, 24 Oct 2017 23:35:19 -0500 Subject: [PATCH 3/4] Extending Choices for Questions in hrapplications to Allow Multiselect (#911) An additional field at the question level defines whether the choices for the question are multi-select or not. The template will render the choices with radio buttons or checkboxes depending on multi-select. Multiple selected choices are saved with a line break between them. --- allianceauth/hrapplications/admin.py | 2 +- .../0006_applicationquestion_multi_select.py | 20 +++++++++++++++++++ allianceauth/hrapplications/models.py | 1 + .../templates/hrapplications/create.html | 2 +- allianceauth/hrapplications/views.py | 4 ++-- 5 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 allianceauth/hrapplications/migrations/0006_applicationquestion_multi_select.py diff --git a/allianceauth/hrapplications/admin.py b/allianceauth/hrapplications/admin.py index e6b80f09..de3cff38 100755 --- a/allianceauth/hrapplications/admin.py +++ b/allianceauth/hrapplications/admin.py @@ -12,7 +12,7 @@ class ChoiceInline(admin.TabularInline): class QuestionAdmin(admin.ModelAdmin): fieldsets = [ - (None, {'fields': ['title', 'help_text']}), + (None, {'fields': ['title', 'help_text', 'multi_select']}), ] inlines = [ChoiceInline] diff --git a/allianceauth/hrapplications/migrations/0006_applicationquestion_multi_select.py b/allianceauth/hrapplications/migrations/0006_applicationquestion_multi_select.py new file mode 100644 index 00000000..28618899 --- /dev/null +++ b/allianceauth/hrapplications/migrations/0006_applicationquestion_multi_select.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10 on 2017-10-20 13:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hrapplications', '0005_remove_legacy_models'), + ] + + operations = [ + migrations.AddField( + model_name='applicationquestion', + name='multi_select', + field=models.BooleanField(default=False), + ), + ] diff --git a/allianceauth/hrapplications/models.py b/allianceauth/hrapplications/models.py index a9bf57e8..b5c8f39a 100755 --- a/allianceauth/hrapplications/models.py +++ b/allianceauth/hrapplications/models.py @@ -9,6 +9,7 @@ from allianceauth.eveonline.models import EveCorporationInfo class ApplicationQuestion(models.Model): title = models.CharField(max_length=254, verbose_name='Question') help_text = models.CharField(max_length=254, blank=True, null=True) + multi_select = models.BooleanField(default=False) def __str__(self): return "Question: " + self.title diff --git a/allianceauth/hrapplications/templates/hrapplications/create.html b/allianceauth/hrapplications/templates/hrapplications/create.html index e0770545..1f26562b 100644 --- a/allianceauth/hrapplications/templates/hrapplications/create.html +++ b/allianceauth/hrapplications/templates/hrapplications/create.html @@ -19,7 +19,7 @@
{{ question.help_text }}
{% endif %} {% for choice in question.choices.all %} - +
{% empty %} diff --git a/allianceauth/hrapplications/views.py b/allianceauth/hrapplications/views.py index 8e751feb..493b0368 100755 --- a/allianceauth/hrapplications/views.py +++ b/allianceauth/hrapplications/views.py @@ -62,8 +62,8 @@ def hr_application_create_view(request, form_id=None): application.save() for question in app_form.questions.all(): response = ApplicationResponse(question=question, application=application) - response.answer = request.POST.get(str(question.pk), - "Failed to retrieve answer provided by applicant.") + response.answer = "\n".join(request.POST.getlist(str(question.pk), + "")) response.save() logger.info("%s created %s" % (request.user, application)) return redirect('hrapplications:view') From 4a94f379b4dc471df985db84d26e579f8d39c518 Mon Sep 17 00:00:00 2001 From: Adarnof Date: Fri, 17 Nov 2017 17:29:01 -0500 Subject: [PATCH 4/4] Correct issues with the SRP merge from v1 --- allianceauth/srp/managers.py | 2 +- allianceauth/srp/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/allianceauth/srp/managers.py b/allianceauth/srp/managers.py index b7547e28..bdb9911a 100644 --- a/allianceauth/srp/managers.py +++ b/allianceauth/srp/managers.py @@ -6,7 +6,7 @@ import logging logger = logging.getLogger(__name__) -class srpManager: +class SRPManager: def __init__(self): pass diff --git a/allianceauth/srp/views.py b/allianceauth/srp/views.py index 5b94e257..6f400318 100755 --- a/allianceauth/srp/views.py +++ b/allianceauth/srp/views.py @@ -237,7 +237,7 @@ def srp_request_remove(request): srpuserrequest = SrpUserRequest.objects.get(id=srp_request_id) stored_fleet_view = srpuserrequest.srp_fleet_main.id srpuserrequest.delete() - logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user)) + logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user)) if stored_fleet_view is None: logger.error("Unable to delete srp requests for user %s - request matching id not found." % (request.user)) messages.error(request, _('Unable to locate selected SRP request.'))