aa-fleetfinder 2.6.1__py3-none-any.whl → 2.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aa-fleetfinder might be problematic. Click here for more details.

Files changed (38) hide show
  1. {aa_fleetfinder-2.6.1.dist-info → aa_fleetfinder-2.7.0.dist-info}/METADATA +1 -1
  2. {aa_fleetfinder-2.6.1.dist-info → aa_fleetfinder-2.7.0.dist-info}/RECORD +38 -33
  3. fleetfinder/__init__.py +1 -1
  4. fleetfinder/locale/cs_CZ/LC_MESSAGES/django.po +82 -18
  5. fleetfinder/locale/de/LC_MESSAGES/django.mo +0 -0
  6. fleetfinder/locale/de/LC_MESSAGES/django.po +94 -19
  7. fleetfinder/locale/django.pot +84 -19
  8. fleetfinder/locale/es/LC_MESSAGES/django.po +93 -18
  9. fleetfinder/locale/fr_FR/LC_MESSAGES/django.po +86 -18
  10. fleetfinder/locale/it_IT/LC_MESSAGES/django.po +79 -18
  11. fleetfinder/locale/ja/LC_MESSAGES/django.po +83 -18
  12. fleetfinder/locale/ko_KR/LC_MESSAGES/django.po +93 -18
  13. fleetfinder/locale/nl_NL/LC_MESSAGES/django.po +79 -18
  14. fleetfinder/locale/pl_PL/LC_MESSAGES/django.po +81 -18
  15. fleetfinder/locale/ru/LC_MESSAGES/django.mo +0 -0
  16. fleetfinder/locale/ru/LC_MESSAGES/django.po +97 -22
  17. fleetfinder/locale/sk/LC_MESSAGES/django.po +79 -18
  18. fleetfinder/locale/uk/LC_MESSAGES/django.mo +0 -0
  19. fleetfinder/locale/uk/LC_MESSAGES/django.po +97 -22
  20. fleetfinder/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  21. fleetfinder/locale/zh_Hans/LC_MESSAGES/django.po +97 -22
  22. fleetfinder/static/fleetfinder/css/fleetfinder.css +21 -0
  23. fleetfinder/static/fleetfinder/css/fleetfinder.min.css +1 -1
  24. fleetfinder/static/fleetfinder/css/fleetfinder.min.css.map +1 -1
  25. fleetfinder/static/fleetfinder/js/fleetfinder.js +23 -0
  26. fleetfinder/static/fleetfinder/js/fleetfinder.min.js +2 -0
  27. fleetfinder/static/fleetfinder/js/fleetfinder.min.js.map +1 -0
  28. fleetfinder/tasks.py +21 -5
  29. fleetfinder/templates/fleetfinder/bundles/js/fleetfinder-js.html +3 -0
  30. fleetfinder/templates/fleetfinder/dashboard.html +38 -63
  31. fleetfinder/templates/fleetfinder/fleet-details.html +124 -33
  32. fleetfinder/templates/fleetfinder/join-fleet.html +11 -1
  33. fleetfinder/templates/fleetfinder/modals/kick-fleet-member.html +46 -0
  34. fleetfinder/tests/test_views.py +67 -10
  35. fleetfinder/urls.py +5 -0
  36. fleetfinder/views.py +141 -42
  37. {aa_fleetfinder-2.6.1.dist-info → aa_fleetfinder-2.7.0.dist-info}/WHEEL +0 -0
  38. {aa_fleetfinder-2.6.1.dist-info → aa_fleetfinder-2.7.0.dist-info}/licenses/LICENSE +0 -0
fleetfinder/views.py CHANGED
@@ -2,17 +2,22 @@
2
2
  Views
3
3
  """
4
4
 
5
+ # Standard Library
6
+ import json
7
+
5
8
  # Third Party
6
9
  from bravado.exception import HTTPNotFound
7
10
 
8
11
  # Django
9
12
  from django.contrib import messages
10
13
  from django.contrib.auth.decorators import login_required, permission_required
14
+ from django.core.handlers.wsgi import WSGIRequest
11
15
  from django.db.models import Q
12
16
  from django.http import JsonResponse
13
17
  from django.shortcuts import redirect, render
14
18
  from django.urls import reverse
15
19
  from django.utils import timezone
20
+ from django.utils.functional import Promise
16
21
  from django.utils.safestring import mark_safe
17
22
  from django.utils.translation import gettext_lazy as _
18
23
 
@@ -101,6 +106,54 @@ def ajax_dashboard(request) -> JsonResponse: # pylint: disable=too-many-locals
101
106
  :return:
102
107
  """
103
108
 
109
+ def _create_button_style_link(
110
+ url: str, fa_icon_class: str, btn_title: str | Promise, btn_modifier_class: str
111
+ ) -> str:
112
+ """
113
+ Helper function to create a button HTML string
114
+ This function generates an HTML anchor tag styled as a button with an icon.
115
+
116
+ :param url: The URL the button should link to
117
+ :type url: str
118
+ :param fa_icon_class: The Font Awesome class for the icon to be displayed
119
+ :type fa_icon_class: str
120
+ :param btn_title: The title attribute for the button, typically a translation string
121
+ :type btn_title: str | Promise
122
+ :param btn_modifier_class: The Bootstrap modifier class for the button styling
123
+ :type btn_modifier_class: str
124
+ :return: An HTML string representing the button
125
+ :rtype: str
126
+ """
127
+
128
+ return (
129
+ f'<a href="{url}" class="btn btn-sm {btn_modifier_class} ms-1" '
130
+ f'data-bs-tooltip="aa-fleetfinder" title="{btn_title}">'
131
+ f'<i class="{fa_icon_class}"></i></a>'
132
+ )
133
+
134
+ def _get_fleet_commander_information(fleet: Fleet) -> tuple[str, str]:
135
+ """
136
+ Helper function to get the fleet commander's HTML representation
137
+ This function retrieves the fleet commander's name and portrait URL,
138
+ and returns an HTML string with the portrait image and name.
139
+
140
+ :param fleet: The Fleet object containing the fleet commander's information
141
+ :type fleet: Fleet
142
+ :return: A tuple containing the HTML string for the fleet commander and the name for sorting
143
+ :rtype: tuple[str, str]
144
+ """
145
+
146
+ commander_name = fleet.fleet_commander.character_name
147
+ portrait_url = character_portrait_url(
148
+ character_id=fleet.fleet_commander.character_id, size=32
149
+ )
150
+ portrait_img = (
151
+ '<img class="rounded eve-character-portrait" '
152
+ f'src="{portrait_url}" alt="{commander_name}" loading="lazy">'
153
+ )
154
+
155
+ return portrait_img + commander_name, commander_name
156
+
104
157
  data = []
105
158
  groups = request.user.groups.all()
106
159
  user_characters = get_all_characters_from_user(user=request.user)
@@ -114,47 +167,39 @@ def ajax_dashboard(request) -> JsonResponse: # pylint: disable=too-many-locals
114
167
  .order_by("name")
115
168
  )
116
169
 
117
- for fleet in fleets:
118
- fleet_commander_name = fleet.fleet_commander.character_name
119
- fleet_commander_portrait_url = character_portrait_url(
120
- character_id=fleet.fleet_commander.character_id, size=32
121
- )
122
- fleet_commander_portrait = (
123
- '<img class="rounded eve-character-portrait" '
124
- f'src="{fleet_commander_portrait_url}" '
125
- f'alt="{fleet_commander_name}" loading="lazy">'
126
- )
127
- fleet_commander_html = fleet_commander_portrait + fleet_commander_name
170
+ can_manage_fleets = request.user.has_perm("fleetfinder.manage_fleets")
128
171
 
129
- button_join_url = reverse(
130
- viewname="fleetfinder:join_fleet", args=[fleet.fleet_id]
131
- )
132
- button_join_text = _("Join fleet")
133
- button_join = (
134
- f'<a href="{button_join_url}" '
135
- f'class="btn btn-sm btn-primary">{button_join_text}</a>'
172
+ for fleet in fleets:
173
+ fleet_commander_html, fleet_commander_name = _get_fleet_commander_information(
174
+ fleet
136
175
  )
137
176
 
138
- button_details = ""
139
- button_edit = ""
140
-
141
- if request.user.has_perm(perm="fleetfinder.manage_fleets"):
142
- button_details_url = reverse(
143
- viewname="fleetfinder:fleet_details", args=[fleet.fleet_id]
144
- )
145
- button_details_text = _("View fleet details")
146
- button_details = (
147
- f'<a href="{button_details_url}" '
148
- f'class="btn btn-sm btn-primary">{button_details_text}</a>'
149
- )
150
-
151
- button_edit_url = reverse(
152
- viewname="fleetfinder:edit_fleet", args=[fleet.fleet_id]
177
+ # Create buttons
178
+ buttons = [
179
+ _create_button_style_link(
180
+ reverse("fleetfinder:join_fleet", args=[fleet.fleet_id]),
181
+ "fa-solid fa-right-to-bracket",
182
+ _("Join fleet"),
183
+ "btn-success",
153
184
  )
154
- button_edit_text = _("Edit fleet advert")
155
- button_edit = (
156
- f'<a href="{button_edit_url}" '
157
- f'class="btn btn-sm btn-primary">{button_edit_text}</a>'
185
+ ]
186
+
187
+ if can_manage_fleets:
188
+ buttons.extend(
189
+ [
190
+ _create_button_style_link(
191
+ reverse("fleetfinder:fleet_details", args=[fleet.fleet_id]),
192
+ "fa-solid fa-eye",
193
+ _("View fleet details"),
194
+ "btn-info",
195
+ ),
196
+ _create_button_style_link(
197
+ reverse("fleetfinder:edit_fleet", args=[fleet.fleet_id]),
198
+ "fa-solid fa-pen-to-square",
199
+ _("Edit fleet advert"),
200
+ "btn-warning",
201
+ ),
202
+ ]
158
203
  )
159
204
 
160
205
  data.append(
@@ -165,9 +210,7 @@ def ajax_dashboard(request) -> JsonResponse: # pylint: disable=too-many-locals
165
210
  },
166
211
  "fleet_name": fleet.name,
167
212
  "created_at": fleet.created_at,
168
- "join": button_join,
169
- "details": button_details,
170
- "edit": button_edit,
213
+ "actions": "".join(buttons),
171
214
  }
172
215
  )
173
216
 
@@ -433,8 +476,7 @@ def fleet_details(request, fleet_id):
433
476
  @login_required()
434
477
  @permission_required(perm="fleetfinder.manage_fleets")
435
478
  def ajax_fleet_details(
436
- request, # pylint: disable=unused-argument
437
- fleet_id,
479
+ request, fleet_id # pylint: disable=unused-argument
438
480
  ) -> JsonResponse:
439
481
  """
440
482
  Ajax :: Fleet Details
@@ -454,3 +496,60 @@ def ajax_fleet_details(
454
496
  }
455
497
 
456
498
  return JsonResponse(data=data, safe=False)
499
+
500
+
501
+ @login_required()
502
+ @permission_required(perm="fleetfinder.manage_fleets")
503
+ def ajax_fleet_kick_member(request: WSGIRequest, fleet_id: int) -> JsonResponse:
504
+ """
505
+ Ajax :: Kick member from fleet
506
+
507
+ :param request: WSGIRequest object containing the request data
508
+ :type request: WSGIRequest
509
+ :param fleet_id: The ID of the fleet from which to kick a member
510
+ :type fleet_id: int
511
+ :return: JsonResponse indicating success or failure of the operation
512
+ :rtype: JsonResponse
513
+ """
514
+
515
+ if request.method != "POST":
516
+ return JsonResponse(
517
+ data={"success": False, "error": _("Method not allowed")}, status=405
518
+ )
519
+
520
+ try:
521
+ fleet = Fleet.objects.get(fleet_id=fleet_id)
522
+ data = json.loads(request.body)
523
+ member_id = data.get("memberId")
524
+
525
+ if not member_id:
526
+ return JsonResponse(
527
+ data={"success": False, "error": _("Member ID required")}, status=400
528
+ )
529
+
530
+ logger.debug(f"Request data for kicking member: {data}")
531
+
532
+ token = Token.get_token(
533
+ character_id=fleet.fleet_commander.character_id,
534
+ scopes=["esi-fleets.write_fleet.v1"],
535
+ )
536
+
537
+ esi.client.Fleets.delete_fleets_fleet_id_members_member_id(
538
+ fleet_id=fleet_id,
539
+ member_id=member_id,
540
+ token=token.valid_access_token(),
541
+ ).result()
542
+
543
+ return JsonResponse(data={"success": True}, status=200)
544
+ except Fleet.DoesNotExist:
545
+ return JsonResponse(
546
+ data={"success": False, "error": _("Fleet not found")}, status=404
547
+ )
548
+ except (json.JSONDecodeError, ValueError):
549
+ return JsonResponse(
550
+ data={"success": False, "error": _("Invalid request data")}, status=400
551
+ )
552
+ except HTTPNotFound:
553
+ return JsonResponse(
554
+ data={"success": False, "error": _("Member not found in fleet")}, status=404
555
+ )