aa-intel-tool 2.6.1__py3-none-any.whl → 2.6.2__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.
Files changed (58) hide show
  1. aa_intel_tool/__init__.py +1 -1
  2. aa_intel_tool/helper/eve_character.py +24 -36
  3. aa_intel_tool/helper/static_files.py +2 -2
  4. aa_intel_tool/locale/cs_CZ/LC_MESSAGES/django.po +9 -9
  5. aa_intel_tool/locale/de/LC_MESSAGES/django.mo +0 -0
  6. aa_intel_tool/locale/de/LC_MESSAGES/django.po +13 -13
  7. aa_intel_tool/locale/django.pot +10 -10
  8. aa_intel_tool/locale/es/LC_MESSAGES/django.po +9 -9
  9. aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  10. aa_intel_tool/locale/fr_FR/LC_MESSAGES/django.po +13 -13
  11. aa_intel_tool/locale/it_IT/LC_MESSAGES/django.po +9 -9
  12. aa_intel_tool/locale/ja/LC_MESSAGES/django.po +9 -9
  13. aa_intel_tool/locale/ko_KR/LC_MESSAGES/django.po +9 -9
  14. aa_intel_tool/locale/nl_NL/LC_MESSAGES/django.po +9 -9
  15. aa_intel_tool/locale/pl_PL/LC_MESSAGES/django.po +9 -9
  16. aa_intel_tool/locale/ru/LC_MESSAGES/django.mo +0 -0
  17. aa_intel_tool/locale/ru/LC_MESSAGES/django.po +13 -13
  18. aa_intel_tool/locale/sk/LC_MESSAGES/django.po +9 -9
  19. aa_intel_tool/locale/uk/LC_MESSAGES/django.mo +0 -0
  20. aa_intel_tool/locale/uk/LC_MESSAGES/django.po +15 -15
  21. aa_intel_tool/locale/zh_Hans/LC_MESSAGES/django.po +9 -9
  22. aa_intel_tool/parser/general.py +11 -16
  23. aa_intel_tool/parser/helper/db.py +8 -11
  24. aa_intel_tool/parser/module/chatlist.py +97 -126
  25. aa_intel_tool/parser/module/dscan.py +115 -147
  26. aa_intel_tool/parser/module/fleetcomp.py +85 -102
  27. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.css +6 -19
  28. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css +1 -1
  29. aa_intel_tool/static/aa_intel_tool/css/aa-intel-tool.min.css.map +1 -1
  30. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.js +104 -64
  31. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan-highlight.min.js.map +1 -1
  32. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.js +2 -2
  33. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-chatscan.min.js +1 -1
  34. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.js +43 -43
  35. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan-highlight.min.js.map +1 -1
  36. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.js +31 -7
  37. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js +1 -1
  38. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-dscan.min.js.map +1 -1
  39. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.js +51 -51
  40. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition-highlight.min.js.map +1 -1
  41. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.js +9 -3
  42. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js +1 -1
  43. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-fleetcomposition.min.js.map +1 -1
  44. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.js +53 -31
  45. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js +1 -1
  46. aa_intel_tool/static/aa_intel_tool/javascript/aa-intel-tool-scan-result-common.min.js.map +1 -1
  47. aa_intel_tool/templates/aa_intel_tool/partials/scan/evetime.html +1 -1
  48. aa_intel_tool/tests/test-data/dscan.txt +250 -0
  49. aa_intel_tool/tests/test_admin.py +50 -38
  50. aa_intel_tool/tests/test_helper_eve_character.py +405 -0
  51. aa_intel_tool/tests/test_models.py +188 -4
  52. aa_intel_tool/tests/test_parser_general.py +771 -0
  53. aa_intel_tool/tests/test_parser_module_chatlist.py +154 -0
  54. {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/METADATA +1 -1
  55. {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/RECORD +57 -55
  56. aa_intel_tool/tests/test_parser.py +0 -135
  57. {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/WHEEL +0 -0
  58. {aa_intel_tool-2.6.1.dist-info → aa_intel_tool-2.6.2.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,9 @@
2
2
  Chat list parser
3
3
  """
4
4
 
5
+ # Standard Library
6
+ from collections import defaultdict
7
+
5
8
  # Django
6
9
  from django.db.models import QuerySet
7
10
  from django.utils.translation import gettext_lazy as _
@@ -38,22 +41,13 @@ def _get_character_info(scan_data: list) -> QuerySet[EveCharacter]:
38
41
  :rtype:
39
42
  """
40
43
 
41
- fetch_from_eveuniverse = False
44
+ # Excluding corporation_id=1000001 (Doomheim) to potentially force an update here …
45
+ eve_characters = EveCharacter.objects.filter(character_name__in=scan_data).exclude(
46
+ corporation_id=1000001
47
+ )
42
48
 
43
49
  # Check if we have to bother Eve Universe or if we have all characters already
44
- # Excluding corporation_id=1000001 (Doomheim) to force an update here …
45
- try:
46
- eve_characters = EveCharacter.objects.filter(
47
- character_name__in=scan_data
48
- ).exclude(corporation_id=1000001)
49
- except EveCharacter.DoesNotExist: # pylint: disable=no-member
50
- fetch_from_eveuniverse = True
51
- else:
52
- if len(scan_data) != eve_characters.count():
53
- fetch_from_eveuniverse = True
54
-
55
- # Fetch the character information from Eve Universe if needed
56
- if fetch_from_eveuniverse:
50
+ if len(scan_data) != eve_characters.count():
57
51
  try:
58
52
  eve_character_ids = (
59
53
  EveEntity.objects.fetch_by_names_esi(names=scan_data, update=True)
@@ -61,21 +55,16 @@ def _get_character_info(scan_data: list) -> QuerySet[EveCharacter]:
61
55
  .values_list("id", flat=True)
62
56
  )
63
57
  except EveEntity.DoesNotExist as exc: # pylint: disable=no-member
64
- message = _(
65
- "Something went wrong while fetching "
66
- "the character information from ESI."
67
- )
68
-
69
- raise ParserError(message=message) from exc
70
-
71
- logger.debug(msg=f"Got {len(eve_character_ids)} ID(s) back from Eve Universe …")
58
+ raise ParserError(
59
+ message=_(
60
+ "Something went wrong while fetching the character information from ESI."
61
+ )
62
+ ) from exc
72
63
 
73
64
  # In case the name does not belong to an Eve character,
74
65
  # EveEntity returns an empty object
75
- if len(eve_character_ids) == 0:
76
- message = _("Character unknown to ESI.")
77
-
78
- raise ParserError(message=message)
66
+ if not eve_character_ids:
67
+ raise ParserError(message=_("Character unknown to ESI."))
79
68
 
80
69
  eve_characters = get_or_create_character(character_ids=eve_character_ids)
81
70
 
@@ -110,22 +99,24 @@ def _parse_alliance_info(
110
99
  :rtype:
111
100
  """
112
101
 
113
- # Build alliance info dict
114
102
  if eve_character.alliance_id is None:
115
- alliance_info = _get_unaffiliated_alliance_info()
116
- else:
117
- alliance_info = {
118
- "id": eve_character.alliance_id,
119
- "name": eve_character.alliance_name,
120
- "ticker": eve_character.alliance_ticker,
121
- "logo": eve_character.alliance_logo_url_32,
122
- }
123
-
124
- if with_evelinks:
125
- alliance_info["dotlan"] = dotlan.alliance_url(eve_character.alliance_name)
126
- alliance_info["zkillboard"] = zkillboard.alliance_url(
127
- eve_character.alliance_id
128
- )
103
+ return _get_unaffiliated_alliance_info()
104
+
105
+ alliance_info = {
106
+ "id": eve_character.alliance_id,
107
+ "name": eve_character.alliance_name,
108
+ "ticker": eve_character.alliance_ticker,
109
+ "logo": eve_character.alliance_logo_url_32,
110
+ }
111
+
112
+ # Add eve links if requested
113
+ if with_evelinks:
114
+ alliance_info.update(
115
+ {
116
+ "dotlan": dotlan.alliance_url(eve_character.alliance_name),
117
+ "zkillboard": zkillboard.alliance_url(eve_character.alliance_id),
118
+ }
119
+ )
129
120
 
130
121
  return alliance_info
131
122
 
@@ -153,11 +144,13 @@ def _parse_corporation_info(
153
144
 
154
145
  # Add eve links if requested
155
146
  if with_evelinks:
156
- corporation_info["dotlan"] = dotlan.corporation_url(
157
- name=eve_character.corporation_name
158
- )
159
- corporation_info["zkillboard"] = zkillboard.corporation_url(
160
- eve_id=eve_character.corporation_id
147
+ corporation_info.update(
148
+ {
149
+ "dotlan": dotlan.corporation_url(name=eve_character.corporation_name),
150
+ "zkillboard": zkillboard.corporation_url(
151
+ eve_id=eve_character.corporation_id
152
+ ),
153
+ }
161
154
  )
162
155
 
163
156
  # Add alliance info if requested
@@ -205,52 +198,35 @@ def _parse_chatscan_data(eve_characters: QuerySet[EveCharacter]) -> dict:
205
198
  :rtype:
206
199
  """
207
200
 
208
- counter = {}
201
+ counter = defaultdict(int)
209
202
  alliance_info = {}
210
203
  corporation_info = {}
211
204
  character_info = {}
212
205
 
213
206
  # Loop through the characters
214
- for eve_character in eve_characters:
215
- eve_character__alliance_name = "Unaffiliated"
216
-
217
- # If the character is in an alliance, use the alliance name
218
- if eve_character.alliance_name is not None:
219
- eve_character__alliance_name = eve_character.alliance_name
220
-
221
- counter[eve_character__alliance_name] = (
222
- counter.get(eve_character__alliance_name, 0) + 1
223
- )
207
+ for eve_character in list(eve_characters):
208
+ alliance_name = eve_character.alliance_name or "Unaffiliated"
209
+ corporation_name = eve_character.corporation_name
224
210
 
225
- counter[eve_character.corporation_name] = (
226
- counter.get(eve_character.corporation_name, 0) + 1
227
- )
211
+ counter[alliance_name] += 1
212
+ counter[corporation_name] += 1
228
213
 
229
214
  # Alliance Info
230
- if eve_character__alliance_name not in alliance_info:
231
- alliance_info[eve_character__alliance_name] = _parse_alliance_info(
232
- eve_character=eve_character
233
- )
215
+ if alliance_name not in alliance_info:
216
+ alliance_info[alliance_name] = _parse_alliance_info(eve_character)
234
217
 
235
218
  # Corporation Info
236
- if eve_character.corporation_name not in corporation_info:
237
- corporation_info[eve_character.corporation_name] = _parse_corporation_info(
238
- eve_character=eve_character
239
- )
219
+ if corporation_name not in corporation_info:
220
+ corporation_info[corporation_name] = _parse_corporation_info(eve_character)
240
221
 
241
222
  # Character Info
242
223
  character_info[eve_character.character_name] = _parse_character_info(
243
- eve_character=eve_character
224
+ eve_character
244
225
  )
245
226
 
246
227
  # Update the counter
247
- alliance_info[eve_character__alliance_name]["count"] = counter[
248
- eve_character__alliance_name
249
- ]
250
-
251
- corporation_info[eve_character.corporation_name]["count"] = counter[
252
- eve_character.corporation_name
253
- ]
228
+ alliance_info[alliance_name]["count"] = counter[alliance_name]
229
+ corporation_info[corporation_name]["count"] = counter[corporation_name]
254
230
 
255
231
  return {
256
232
  "pilots": dict_to_list(input_dict=character_info),
@@ -275,60 +251,55 @@ def parse(
275
251
  :rtype:
276
252
  """
277
253
 
278
- message = _("The chat list module is currently disabled.")
279
-
280
254
  # Only parse the chat scan if the module is enabled
281
- if AppSettings.INTELTOOL_ENABLE_MODULE_CHATSCAN is True:
282
- logger.debug(msg=f"{len(scan_data)} name(s) to work through ")
283
-
284
- pilots_in_scan = len(scan_data)
285
- max_allowed_pilots = AppSettings.INTELTOOL_CHATSCAN_MAX_PILOTS
286
-
287
- # Check if the number of pilots in the scan exceeds the maximum allowed number
288
- if 0 < max_allowed_pilots < pilots_in_scan and ignore_limit is False:
289
- logger.debug(
290
- msg=(
291
- f"Number of pilots in scan ({pilots_in_scan}) exceeds the maximum "
292
- f"allowed number ({max_allowed_pilots}). Throwing a tantrum …"
293
- )
294
- )
255
+ if not AppSettings.INTELTOOL_ENABLE_MODULE_CHATSCAN:
256
+ raise ParserError(message=_("The chat list module is currently disabled."))
295
257
 
296
- # Throw a tantrum
297
- raise ParserError(
298
- message=ngettext(
299
- singular=f"Chat scans are currently limited to a maximum of {max_allowed_pilots} pilot per scan. Your list of pilots exceeds this limit.", # pylint: disable=line-too-long
300
- plural=f"Chat scans are currently limited to a maximum of {max_allowed_pilots} pilots per scan. Your list of pilots exceeds this limit.", # pylint: disable=line-too-long
301
- number=max_allowed_pilots,
302
- )
303
- )
258
+ logger.debug(msg=f"{len(scan_data)} name(s) to work through …")
304
259
 
305
- eve_characters = _get_character_info(scan_data=scan_data)
260
+ pilots_in_scan = len(scan_data)
261
+ max_allowed_pilots = AppSettings.INTELTOOL_CHATSCAN_MAX_PILOTS
306
262
 
263
+ # Check if the number of pilots in the scan exceeds the maximum allowed number
264
+ if 0 < max_allowed_pilots < pilots_in_scan and not ignore_limit:
307
265
  logger.debug(
308
- msg=f"Got {len(eve_characters)} EveCharacter object(s) back from AA …"
266
+ msg=(
267
+ f"Number of pilots in scan ({pilots_in_scan}) exceeds the maximum "
268
+ f"allowed number ({max_allowed_pilots}). Throwing a tantrum …"
269
+ )
270
+ )
271
+
272
+ # Throw a tantrum
273
+ raise ParserError(
274
+ message=ngettext(
275
+ singular=f"Chat scans are currently limited to a maximum of {max_allowed_pilots} pilot per scan. Your list of pilots exceeds this limit.",
276
+ plural=f"Chat scans are currently limited to a maximum of {max_allowed_pilots} pilots per scan. Your list of pilots exceeds this limit.",
277
+ number=max_allowed_pilots,
278
+ )
309
279
  )
310
280
 
311
- # Parse the data
312
- parsed_chatscan = _parse_chatscan_data(eve_characters=eve_characters)
313
-
314
- parsed_data = {
315
- "pilots": {
316
- "section": ScanData.Section.PILOTLIST,
317
- "data": parsed_chatscan["pilots"],
318
- },
319
- "corporations": {
320
- "section": ScanData.Section.CORPORATIONLIST,
321
- "data": parsed_chatscan["corporations"],
322
- },
323
- "alliances": {
324
- "section": ScanData.Section.ALLIANCELIST,
325
- "data": parsed_chatscan["alliances"],
326
- },
327
- }
328
-
329
- if safe_to_db is False:
330
- return parsed_data
331
-
332
- return safe_scan_to_db(scan_type=Scan.Type.CHATLIST, parsed_data=parsed_data)
333
-
334
- raise ParserError(message=message)
281
+ eve_characters = _get_character_info(scan_data=scan_data)
282
+ logger.debug(msg=f"Got {len(eve_characters)} EveCharacter object(s) back from AA …")
283
+
284
+ # Parse the data
285
+ parsed_chatscan = _parse_chatscan_data(eve_characters=eve_characters)
286
+ parsed_data = {
287
+ "pilots": {
288
+ "section": ScanData.Section.PILOTLIST,
289
+ "data": parsed_chatscan["pilots"],
290
+ },
291
+ "corporations": {
292
+ "section": ScanData.Section.CORPORATIONLIST,
293
+ "data": parsed_chatscan["corporations"],
294
+ },
295
+ "alliances": {
296
+ "section": ScanData.Section.ALLIANCELIST,
297
+ "data": parsed_chatscan["alliances"],
298
+ },
299
+ }
300
+
301
+ return (
302
+ parsed_data
303
+ if not safe_to_db
304
+ else safe_scan_to_db(scan_type=Scan.Type.CHATLIST, parsed_data=parsed_data)
305
+ )
@@ -4,6 +4,7 @@ D-Scan parser
4
4
 
5
5
  # Standard Library
6
6
  import re
7
+ from collections import defaultdict
7
8
 
8
9
  # Django
9
10
  from django.db.models import QuerySet
@@ -49,14 +50,12 @@ def _is_on_grid(distance: str) -> bool:
49
50
  )
50
51
 
51
52
  # Check if we have a distance
52
- if re.search(pattern=REGEX_PATTERN["localised_on_grid"], string=distance):
53
- distance_sanitised = int(re.sub(pattern=r"[^0-9]", repl="", string=distance))
54
-
55
- # Check if the distance is within the grid size
56
- if distance_sanitised <= AppSettings.INTELTOOL_DSCAN_GRID_SIZE:
57
- return True
53
+ match = re.search(pattern=REGEX_PATTERN["localised_on_grid"], string=distance)
58
54
 
59
- return False
55
+ # Check if the distance is within the grid size
56
+ if match:
57
+ distance_sanitised = int(re.sub(pattern=r"[^0-9]", repl="", string=distance))
58
+ return distance_sanitised <= AppSettings.INTELTOOL_DSCAN_GRID_SIZE
60
59
 
61
60
  return False
62
61
 
@@ -104,6 +103,25 @@ def _get_ships(eve_types: QuerySet, counter: dict) -> dict:
104
103
 
105
104
  ships = {"all": {}, "ongrid": {}, "offgrid": {}, "types": {}}
106
105
 
106
+ def _add_ship_info(ship_dict: dict, eve_type: tuple, count: int):
107
+ """
108
+ Add ship info to the ship_dict
109
+
110
+ :param ship_dict:
111
+ :type ship_dict:
112
+ :param eve_type:
113
+ :type eve_type:
114
+ :param count:
115
+ :type count:
116
+ :return:
117
+ :rtype:
118
+ """
119
+
120
+ if eve_type[1] not in ship_dict:
121
+ ship_dict[eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
122
+ ship_dict[eve_type[1]]["count"] = count
123
+ ship_dict[eve_type[1]]["mass"] = eve_type[4] * count
124
+
107
125
  # Ship types
108
126
  # Get all ship types
109
127
  #
@@ -118,33 +136,30 @@ def _get_ships(eve_types: QuerySet, counter: dict) -> dict:
118
136
  )
119
137
 
120
138
  # Loop through all ships types
121
- for eve_type in eve_types_ships:
139
+ for eve_type in list(eve_types_ships):
122
140
  # Info for "All Ships" table
123
141
  if eve_type[0] in counter["all"]:
124
- if eve_type[1] not in ships["all"]:
125
- ships["all"][eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
126
- ships["all"][eve_type[1]]["count"] = counter["all"][eve_type[0]]
127
- ships["all"][eve_type[1]]["mass"] = (
128
- eve_type[4] * counter["all"][eve_type[0]]
129
- )
142
+ _add_ship_info(
143
+ ship_dict=ships["all"],
144
+ eve_type=eve_type,
145
+ count=counter["all"][eve_type[0]],
146
+ )
130
147
 
131
148
  # Info for "On Grid" table
132
149
  if eve_type[0] in counter["ongrid"]:
133
- if eve_type[1] not in ships["ongrid"]:
134
- ships["ongrid"][eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
135
- ships["ongrid"][eve_type[1]]["count"] = counter["ongrid"][eve_type[0]]
136
- ships["ongrid"][eve_type[1]]["mass"] = (
137
- eve_type[4] * counter["ongrid"][eve_type[0]]
138
- )
150
+ _add_ship_info(
151
+ ship_dict=ships["ongrid"],
152
+ eve_type=eve_type,
153
+ count=counter["ongrid"][eve_type[0]],
154
+ )
139
155
 
140
156
  # Info for "Off Grid" table
141
157
  if eve_type[0] in counter["offgrid"]:
142
- if eve_type[1] not in ships["offgrid"]:
143
- ships["offgrid"][eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
144
- ships["offgrid"][eve_type[1]]["count"] = counter["offgrid"][eve_type[0]]
145
- ships["offgrid"][eve_type[1]]["mass"] = (
146
- eve_type[4] * counter["offgrid"][eve_type[0]]
147
- )
158
+ _add_ship_info(
159
+ ship_dict=ships["offgrid"],
160
+ eve_type=eve_type,
161
+ count=counter["offgrid"][eve_type[0]],
162
+ )
148
163
 
149
164
  # Info for "Ship Types" table
150
165
  if eve_type[3] not in ships["types"]:
@@ -183,25 +198,22 @@ def _get_upwell_structures_on_grid(
183
198
  eve_group__eve_category_id__exact=EveCategoryId.STRUCTURE
184
199
  )
185
200
 
186
- upwell_structures = {}
187
-
188
- # Loop through all Upwell structures
189
- for eve_type in eve_types_structures:
190
- if eve_type[0] in counter["ongrid"]:
191
- if eve_type[1] not in upwell_structures:
192
- upwell_structures[eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
193
- upwell_structures[eve_type[1]]["count"] = counter["ongrid"][eve_type[0]]
194
-
195
- # If it is an Ansiblex Jump Gate, add the destination system
196
- if (
197
- eve_type[0] == UpwellStructureId.ANSIBLEX_JUMP_GATE
198
- and ansiblex_destination
199
- ):
200
- upwell_structures[eve_type[1]][
201
- "name"
202
- ] += f" » {ansiblex_destination}"
201
+ upwell_structures = {
202
+ eve_type[1]: {
203
+ **_get_type_info_dict(eve_type=eve_type),
204
+ "count": counter["ongrid"][eve_type[0]],
205
+ "name": (
206
+ f"{eve_type[1]} » {ansiblex_destination}"
207
+ if eve_type[0] == UpwellStructureId.ANSIBLEX_JUMP_GATE
208
+ and ansiblex_destination
209
+ else eve_type[1]
210
+ ),
211
+ }
212
+ for eve_type in list(eve_types_structures)
213
+ if eve_type[0] in counter["ongrid"]
214
+ }
203
215
 
204
- return dict_to_list(upwell_structures)
216
+ return dict_to_list(input_dict=upwell_structures)
205
217
 
206
218
 
207
219
  def _get_deployables_on_grid(eve_types: QuerySet, counter: dict) -> list:
@@ -220,16 +232,16 @@ def _get_deployables_on_grid(eve_types: QuerySet, counter: dict) -> list:
220
232
  eve_group__eve_category_id__exact=AdditionalEveCategoryId.DEPLOYABLE
221
233
  )
222
234
 
223
- deployables = {}
224
-
225
- # Loop through all deployables
226
- for eve_type in eve_types_deployables:
227
- if eve_type[0] in counter["ongrid"]:
228
- if eve_type[1] not in deployables:
229
- deployables[eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
230
- deployables[eve_type[1]]["count"] = counter["ongrid"][eve_type[0]]
235
+ deployables = {
236
+ eve_type[1]: {
237
+ **_get_type_info_dict(eve_type=eve_type),
238
+ "count": counter["ongrid"][eve_type[0]],
239
+ }
240
+ for eve_type in list(eve_types_deployables)
241
+ if eve_type[0] in counter["ongrid"]
242
+ }
231
243
 
232
- return dict_to_list(deployables)
244
+ return dict_to_list(input_dict=deployables)
233
245
 
234
246
 
235
247
  def _get_starbases_on_grid(eve_types: QuerySet, counter: dict) -> list:
@@ -248,16 +260,16 @@ def _get_starbases_on_grid(eve_types: QuerySet, counter: dict) -> list:
248
260
  eve_group__eve_category_id__exact=AdditionalEveCategoryId.STARBASE
249
261
  )
250
262
 
251
- starbases = {}
252
-
253
- # Loop through all starbases
254
- for eve_type in eve_types_starbase:
255
- if eve_type[0] in counter["ongrid"]:
256
- if eve_type[1] not in starbases:
257
- starbases[eve_type[1]] = _get_type_info_dict(eve_type=eve_type)
258
- starbases[eve_type[1]]["count"] = counter["ongrid"][eve_type[0]]
263
+ starbases = {
264
+ eve_type[1]: {
265
+ **_get_type_info_dict(eve_type=eve_type),
266
+ "count": counter["ongrid"][eve_type[0]],
267
+ }
268
+ for eve_type in list(eve_types_starbase)
269
+ if eve_type[0] in counter["ongrid"]
270
+ }
259
271
 
260
- return dict_to_list(starbases)
272
+ return dict_to_list(input_dict=starbases)
261
273
 
262
274
 
263
275
  def _get_ansiblex_jumpgate_destination(ansiblex_name: str) -> str:
@@ -270,10 +282,9 @@ def _get_ansiblex_jumpgate_destination(ansiblex_name: str) -> str:
270
282
  :rtype:
271
283
  """
272
284
 
273
- name_parts = re.split(pattern=r" - ", string=ansiblex_name)
274
- gate_systems = re.split(pattern=r" » ", string=name_parts[0])
275
-
276
- return gate_systems[1]
285
+ return re.split(
286
+ pattern=r" » ", string=re.split(pattern=r" - ", string=ansiblex_name)[0]
287
+ )[1]
277
288
 
278
289
 
279
290
  def _get_scan_details(scan_data: list) -> tuple:
@@ -292,8 +303,8 @@ def _get_scan_details(scan_data: list) -> tuple:
292
303
  )
293
304
 
294
305
  ansiblex_destination = None
295
- counter = {"all": {}, "ongrid": {}, "offgrid": {}, "type": {}}
296
- eve_ids = {"all": [], "ongrid": [], "offgrid": []}
306
+ counter = defaultdict(lambda: defaultdict(int))
307
+ eve_ids = defaultdict(list)
297
308
 
298
309
  # Let's split this list up
299
310
  #
@@ -314,11 +325,11 @@ def _get_scan_details(scan_data: list) -> tuple:
314
325
  line = re.search(pattern=REGEX_PATTERN["dscan"], string=entry)
315
326
  entry_id = int(line.group(1))
316
327
 
317
- counter["all"][entry_id] = counter["all"].get(entry_id, 0) + 1
328
+ counter["all"][entry_id] += 1
318
329
 
319
330
  # Check if the entry is "on grid" or not
320
- if _is_on_grid(line.group(4)):
321
- counter["ongrid"][entry_id] = counter["ongrid"].get(entry_id, 0) + 1
331
+ if _is_on_grid(distance=line.group(4)):
332
+ counter["ongrid"][entry_id] += 1
322
333
 
323
334
  # If it is an Ansiblex Jump Gate, get its destination system
324
335
  if entry_id == UpwellStructureId.ANSIBLEX_JUMP_GATE:
@@ -328,8 +339,7 @@ def _get_scan_details(scan_data: list) -> tuple:
328
339
 
329
340
  eve_ids["ongrid"].append(entry_id)
330
341
  else:
331
- counter["offgrid"][entry_id] = counter["offgrid"].get(entry_id, 0) + 1
332
-
342
+ counter["offgrid"][entry_id] += 1
333
343
  eve_ids["offgrid"].append(entry_id)
334
344
 
335
345
  eve_ids["all"].append(entry_id)
@@ -347,82 +357,40 @@ def parse(scan_data: list) -> Scan:
347
357
  :rtype:
348
358
  """
349
359
 
350
- message = _("The D-Scan module is currently disabled.")
351
-
352
- # Only parse the D-Scan when the module is enabled
353
- if AppSettings.INTELTOOL_ENABLE_MODULE_DSCAN is True:
354
- parsed_data = {}
355
- (
356
- ansiblex_destination, # pylint: disable=unused-variable
357
- counter,
358
- eve_ids,
359
- ) = _get_scan_details(scan_data=scan_data)
360
-
361
- eve_types = EveType.objects.bulk_get_or_create_esi(
362
- ids=set(eve_ids["all"]), include_children=True
363
- ).values_list(
364
- "id", "name", "eve_group__id", "eve_group__name", "mass", named=True
365
- )
366
-
367
- # Parse the data parts
368
- ships = _get_ships(eve_types=eve_types, counter=counter)
369
- upwell_structures = _get_upwell_structures_on_grid(
370
- eve_types=eve_types,
371
- counter=counter,
372
- # ansiblex_destination=ansiblex_destination,
373
- )
374
- deployables = _get_deployables_on_grid(eve_types=eve_types, counter=counter)
375
- starbases = _get_starbases_on_grid(eve_types=eve_types, counter=counter)
376
-
377
- # Add "ships all" to the parsed data when available
378
- if ships["all"]:
379
- parsed_data["all"] = {
380
- "section": ScanData.Section.SHIPLIST,
381
- "data": ships["all"],
382
- }
383
-
384
- # Add "ships on grid" to the parsed data when available
385
- if ships["ongrid"]:
386
- parsed_data["ongrid"] = {
387
- "section": ScanData.Section.SHIPLIST_ON_GRID,
388
- "data": ships["ongrid"],
389
- }
360
+ # Only parse the d-scan if the module is enabled
361
+ if not AppSettings.INTELTOOL_ENABLE_MODULE_DSCAN:
362
+ raise ParserError(message=_("The D-Scan module is currently disabled."))
390
363
 
391
- # Add "ships off grid" to parsed data when available
392
- if ships["offgrid"]:
393
- parsed_data["offgrid"] = {
394
- "section": ScanData.Section.SHIPLIST_OFF_GRID,
395
- "data": ships["offgrid"],
396
- }
364
+ parsed_data = {}
365
+ ansiblex_destination, counter, eve_ids = _get_scan_details(scan_data=scan_data)
397
366
 
398
- # Add "ship types" to the parsed data when available
399
- if ships["types"]:
400
- parsed_data["shiptypes"] = {
401
- "section": ScanData.Section.SHIPTYPES,
402
- "data": ships["types"],
403
- }
367
+ eve_types = EveType.objects.bulk_get_or_create_esi(
368
+ ids=set(eve_ids["all"]), include_children=True
369
+ ).values_list("id", "name", "eve_group__id", "eve_group__name", "mass", named=True)
404
370
 
405
- # Add "Upwell structures on grid" to the parsed data when available
406
- if upwell_structures:
407
- parsed_data["sructures_on_grid"] = {
408
- "section": ScanData.Section.STRUCTURES_ON_GRID,
409
- "data": upwell_structures,
410
- }
411
-
412
- # Add "deployables on grid" to the parsed data when available
413
- if deployables:
414
- parsed_data["deployables"] = {
415
- "section": ScanData.Section.DEPLOYABLES_ON_GRID,
416
- "data": deployables,
417
- }
418
-
419
- # Add "starbases on grid" to parsed data when available
420
- if starbases:
421
- parsed_data["starbases"] = {
422
- "section": ScanData.Section.STARBASES_ON_GRID,
423
- "data": starbases,
424
- }
371
+ # Parse the data parts
372
+ ships = _get_ships(eve_types=eve_types, counter=counter)
373
+ upwell_structures = _get_upwell_structures_on_grid(
374
+ eve_types=eve_types,
375
+ counter=counter,
376
+ ansiblex_destination=ansiblex_destination,
377
+ )
378
+ deployables = _get_deployables_on_grid(eve_types=eve_types, counter=counter)
379
+ starbases = _get_starbases_on_grid(eve_types=eve_types, counter=counter)
380
+
381
+ # Add parsed data when available
382
+ sections = {
383
+ "all": (ScanData.Section.SHIPLIST, ships["all"]),
384
+ "ongrid": (ScanData.Section.SHIPLIST_ON_GRID, ships["ongrid"]),
385
+ "offgrid": (ScanData.Section.SHIPLIST_OFF_GRID, ships["offgrid"]),
386
+ "shiptypes": (ScanData.Section.SHIPTYPES, ships["types"]),
387
+ "structures_on_grid": (ScanData.Section.STRUCTURES_ON_GRID, upwell_structures),
388
+ "deployables": (ScanData.Section.DEPLOYABLES_ON_GRID, deployables),
389
+ "starbases": (ScanData.Section.STARBASES_ON_GRID, starbases),
390
+ }
425
391
 
426
- return safe_scan_to_db(scan_type=Scan.Type.DSCAN, parsed_data=parsed_data)
392
+ for key, (section, data) in sections.items():
393
+ if data:
394
+ parsed_data[key] = {"section": section, "data": data}
427
395
 
428
- raise ParserError(message=message)
396
+ return safe_scan_to_db(scan_type=Scan.Type.DSCAN, parsed_data=parsed_data)