firefighter-incident 0.0.9__py3-none-any.whl → 0.0.10__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.
firefighter/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.0.9'
21
- __version_tuple__ = version_tuple = (0, 0, 9)
20
+ __version__ = version = '0.0.10'
21
+ __version_tuple__ = version_tuple = (0, 0, 10)
@@ -25,7 +25,7 @@ class Kwargs(TypedDict, total=False):
25
25
 
26
26
 
27
27
  @component.register("avatar")
28
- class Avatar(component.Component): # type: ignore[type-var]
28
+ class Avatar(component.Component):
29
29
  template_name = "avatar/avatar.html"
30
30
 
31
31
  def get_context_data(self, user: User, **kwargs: Any) -> Data:
@@ -14,7 +14,7 @@ class Data(TypedDict, total=False):
14
14
 
15
15
 
16
16
  @component.register("card")
17
- class Card(component.Component): # type: ignore[type-var]
17
+ class Card(component.Component):
18
18
  template_name = "card/card.html"
19
19
 
20
20
  def get_context_data(self, *args: Any, **kwargs: Unpack[Data]) -> Data:
@@ -27,7 +27,7 @@ class Kwargs(TypedDict, total=False):
27
27
 
28
28
 
29
29
  @component.register("export_button")
30
- class ExportButton(component.Component): # type: ignore[type-var]
30
+ class ExportButton(component.Component):
31
31
  template_name = "export_button/export_button.html"
32
32
 
33
33
  def get_context_data(
@@ -19,8 +19,8 @@ class Data(TypedDict):
19
19
 
20
20
 
21
21
  @component.register("form")
22
- class Form(component.Component): # type: ignore[type-var] # type: ignore[override]
22
+ class FormComponent(component.Component):
23
23
  template_name = "form/form.html"
24
24
 
25
- def get_context_data(self, form: forms.Form, **kwargs: Any) -> Data: # type: ignore[override]
25
+ def get_context_data(self, form: forms.Form, **kwargs: Any) -> Data:
26
26
  return Data(form=form)
@@ -22,7 +22,7 @@ class Kwargs(TypedDict, total=True):
22
22
 
23
23
 
24
24
  @component.register("form_field")
25
- class FormField(component.Component): # type: ignore[type-var]
25
+ class FormField(component.Component):
26
26
  template_name = "form_field/form_field.html"
27
27
 
28
28
  def get_context_data(
@@ -14,7 +14,7 @@ class Data(TypedDict):
14
14
 
15
15
 
16
16
  @component.register("messages")
17
- class Messages(component.Component): # type: ignore[type-var]
17
+ class MessagesComponent(component.Component):
18
18
  template_name = "messages/messages.html"
19
19
 
20
20
  def get_context_data(self, messages: BaseStorage, **kwargs: Any) -> Data:
@@ -28,7 +28,7 @@ class Slots(TypedDict):
28
28
 
29
29
 
30
30
  @component.register("modal")
31
- class Modal(component.Component): # type: ignore[type-var]
31
+ class Modal(component.Component):
32
32
  template_name = "modal/modal.html"
33
33
 
34
34
  def get_context_data(self, *args: Any, **kwargs: Unpack[Kwargs]) -> Data:
@@ -39,7 +39,7 @@ class SelectImpactForm(forms.Form):
39
39
 
40
40
  super().__init__(*args, **kwargs)
41
41
 
42
- for impact_type in ImpactType.objects.all().order_by("-order"):
42
+ for impact_type in ImpactType.objects.all().order_by("order"):
43
43
  field_name = f"set_impact_type_{impact_type.value}"
44
44
  self.fields[field_name] = forms.ModelChoiceField(
45
45
  label=impact_type.emoji + " " + impact_type.name,
@@ -0,0 +1,28 @@
1
+ # Generated by ChatGPT on 2024-06-24
2
+ from django.db import migrations
3
+
4
+
5
+ def reorder_impact_types(apps, schema_editor):
6
+ ImpactType = apps.get_model("incidents", "ImpactType")
7
+ # On suppose que les valeurs sont :
8
+ # business_impact, customers_impact, sellers_impact, employees_impact
9
+ order_map = {
10
+ "business_impact": 1,
11
+ "customers_impact": 2,
12
+ "sellers_impact": 3,
13
+ "employees_impact": 4,
14
+ }
15
+ for value, order in order_map.items():
16
+ impact_type = ImpactType.objects.filter(value=value).first()
17
+ if impact_type:
18
+ impact_type.order = order
19
+ impact_type.save(update_fields=["order"])
20
+
21
+
22
+ class Migration(migrations.Migration):
23
+ dependencies = [
24
+ ("incidents", "0016_update_business_incidents_and_level"),
25
+ ]
26
+ operations = [
27
+ migrations.RunPython(reorder_impact_types),
28
+ ]
@@ -0,0 +1,48 @@
1
+ # Generated by ChatGPT on 2024-06-24
2
+ from django.db import migrations
3
+
4
+
5
+ def update_impactlevel_names(apps, schema_editor):
6
+ ImpactType = apps.get_model("incidents", "ImpactType")
7
+ ImpactLevel = apps.get_model("incidents", "ImpactLevel")
8
+
9
+ # Map: (impact_type.value, impact_level.value) -> new name
10
+ updates = {
11
+ ("business_impact", "HT"): "Critical Impact (>5% BV loss)",
12
+ ("business_impact", "HI"): "Major Impact (<5% BV loss)",
13
+ ("business_impact", "MD"): "Uncertain Business Impact",
14
+ ("business_impact", "LO"): "Low Impact not measurable",
15
+ ("business_impact", "LT"): "Very Low Impact not measurable",
16
+ ("customers_impact", "HT"): "Critical issue for many customers",
17
+ ("customers_impact", "HI"): "Major issue for many customers",
18
+ ("customers_impact", "MD"): "Major issue for few customers",
19
+ ("customers_impact", "LO"): "Minor issue for customers",
20
+ ("customers_impact", "LT"): "Cosmetic minor issue for customers",
21
+ ("sellers_impact", "HT"): "Critical issue for many sellers",
22
+ ("sellers_impact", "HI"): "Major issue for many sellers",
23
+ ("sellers_impact", "MD"): "Major issue for few sellers",
24
+ ("sellers_impact", "LO"): "Minor issue for sellers",
25
+ ("sellers_impact", "LT"): "Cosmetic minor issue for sellers",
26
+ ("employees_impact", "MD"): "Departments fully blocked",
27
+ ("employees_impact", "LO"): "Some employees affected",
28
+ ("employees_impact", "LT"): "Degraded service for employees",
29
+ ("employees_impact", "NO"): "No impact for employees",
30
+ }
31
+
32
+ for (impact_type_value, level_value), new_name in updates.items():
33
+ impact_type = ImpactType.objects.filter(value=impact_type_value).first()
34
+ if not impact_type:
35
+ continue
36
+ impact_level = ImpactLevel.objects.filter(impact_type=impact_type, value=level_value).first()
37
+ if impact_level:
38
+ impact_level.name = new_name
39
+ impact_level.save(update_fields=["name"])
40
+
41
+
42
+ class Migration(migrations.Migration):
43
+ dependencies = [
44
+ ("incidents", "0017_reorder_impact_types"),
45
+ ]
46
+ operations = [
47
+ migrations.RunPython(update_impactlevel_names),
48
+ ]
@@ -23,6 +23,7 @@ from slack_sdk.models.views import View
23
23
  from firefighter.firefighter.utils import is_during_office_hours
24
24
  from firefighter.incidents.enums import IncidentStatus
25
25
  from firefighter.incidents.forms.select_impact import SelectImpactForm
26
+ from firefighter.incidents.models.impact import ImpactType
26
27
  from firefighter.incidents.models.incident import Incident
27
28
  from firefighter.incidents.models.priority import Priority
28
29
  from firefighter.slack.slack_app import SlackApp
@@ -410,18 +411,25 @@ class OpenModal(SlackModal):
410
411
  priority: Priority = Priority.objects.get(
411
412
  value=impact_form.suggest_priority_from_impact()
412
413
  )
414
+ process = ":slack: Slack :jira_new: Jira ticket" if open_incident_context.get("response_type") == "critical" else ":jira_new: Jira ticket"
415
+
416
+ impact_descriptions = OpenModal._get_impact_descriptions(open_incident_context)
413
417
  blocks.append(
414
418
  ContextBlock(
415
419
  elements=[
416
420
  MarkdownTextObject(
417
- text=f"> {priority.emoji} Selected priority: {priority}"
421
+ text=f"> {priority.emoji} Selected priority: *{priority} - {priority.description}*\n"
422
+ f"> ⏱️ SLA: {priority.sla}\n"
423
+ f"> :gear: Process: {process}\n"
424
+ f"> :pushpin: Selected impacts:\n"
425
+ f"{impact_descriptions}\n"
418
426
  + (
419
427
  (
420
428
  "\n> Critical incidents are for *emergency* only"
421
429
  + (
422
- f"<{SLACK_SEVERITY_HELP_GUIDE_URL}|learn more>"
430
+ f" <{SLACK_SEVERITY_HELP_GUIDE_URL}|learn more>"
423
431
  if SLACK_SEVERITY_HELP_GUIDE_URL
424
- else "" + "."
432
+ else "."
425
433
  )
426
434
  )
427
435
  if selected_response_type == "critical"
@@ -448,6 +456,21 @@ class OpenModal(SlackModal):
448
456
 
449
457
  return blocks
450
458
 
459
+ @staticmethod
460
+ def _get_impact_descriptions(open_incident_context: OpeningData) -> str:
461
+ impact_form_data = open_incident_context.get("impact_form_data", {})
462
+ impact_descriptions = ""
463
+ if impact_form_data:
464
+ for value in impact_form_data.values():
465
+ if value.name != "NO" and value.description:
466
+ if hasattr(value, "impact_type_id") and value.impact_type_id:
467
+ impact_type = ImpactType.objects.get(pk=value.impact_type_id)
468
+ if impact_type:
469
+ impact_descriptions += f"> \u00A0\u00A0 :exclamation: {impact_type} - {value}\n"
470
+ for line in str(value.description).splitlines():
471
+ impact_descriptions += f"> \u00A0\u00A0\u00A0\u00A0\u00A0\u00A0 • {line}\n"
472
+ return impact_descriptions
473
+
451
474
  @staticmethod
452
475
  def get_details_modal_form_class(
453
476
  open_incident_context: OpeningData,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firefighter-incident
3
- Version: 0.0.9
3
+ Version: 0.0.10
4
4
  Summary: Incident Management tool made for Slack using Django
5
5
  Project-URL: Repository, https://github.com/ManoManoTech/firefighter-incident
6
6
  Project-URL: Documentation, https://manomanotech.github.io/firefighter-incident/latest/
@@ -6,7 +6,7 @@ gunicorn.conf.py,sha256=vHsTGjaKOr8FDMp6fTKYTX4AtokmPgYvvt5Mr0Q6APc,273
6
6
  main.py,sha256=CsbprHoOYhjCLpTJmq9Z_aRYFoFgWxoz2pDLuwm8Eqg,1558
7
7
  manage.py,sha256=5ivHGD13C6nJ8QvltKsJ9T9akA5he8da70HLWaEP3k8,689
8
8
  firefighter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- firefighter/_version.py,sha256=J0-psBAr052UgYPFe4_RoTpIwBL8wFdIM3d_qC8JwcE,511
9
+ firefighter/_version.py,sha256=Gdu8ebkoRvvSp8uMsCgaPOF73AAzSJAhOOfRVCoJCTk,513
10
10
  firefighter/api/__init__.py,sha256=JQW0Bv6xwGqy7ioxx3h6UGMzkkJ4DntDpbvV1Ncgi8k,136
11
11
  firefighter/api/admin.py,sha256=x9Ysy-GiYjb0rynmFdS9g56e6n24fkN0ouGy5QD9Yrc,4629
12
12
  firefighter/api/apps.py,sha256=P5uU1_gMrDfzurdMbfqw1Bnb2uNKKcMq17WBPg2sLhc,204
@@ -32,25 +32,25 @@ firefighter/api/views/severities.py,sha256=mdkR4GjZibydC1Dx-Sglm-f35GZxWbjmqStAx
32
32
  firefighter/components/__init__.py,sha256=Vd_Uk5Uq7Mqp6NOFp5QiniWZAyzmYLqNSFEEw1x7COk,167
33
33
  firefighter/components/avatar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  firefighter/components/avatar/avatar.html,sha256=oleFPTy1qs9X6hZx3iWppBteHummFvSxoNzPOOl5aeA,773
35
- firefighter/components/avatar/avatar.py,sha256=Gx2IFJz5sfw8sziAViiqU7oVRNfCT8YV7UVeYiopzzw,849
35
+ firefighter/components/avatar/avatar.py,sha256=AIqffX8I_sJ7oEpuyIswJkB6KuW51FuEa4tBn9eSths,823
36
36
  firefighter/components/card/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  firefighter/components/card/card.html,sha256=ziahql8X7WiQdprMktzy7sx0gVXNIxqtAsh_Rc5Iy0g,725
38
- firefighter/components/card/card.py,sha256=lro45nf9Z02rhlGU6706r1jbPhtidGKVYeFqZ_A5puU,513
38
+ firefighter/components/card/card.py,sha256=yB4veoRQ3zfdJPCsAGIYtmLCDz3G2kmcYFg12jzkNks,487
39
39
  firefighter/components/export_button/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  firefighter/components/export_button/export_button.html,sha256=XTA9FbDxho8aIqnfTcsDUm7swGWfn2JSw5WndDaThYY,1989
41
- firefighter/components/export_button/export_button.py,sha256=0jzBjMTjduM7DF0-czv9B7J_PVPUQ2RUufUJtNdT-tk,1729
41
+ firefighter/components/export_button/export_button.py,sha256=AqkkaZFGVzuLKpIxcPZ-vcXG9VXf9jqpfyxYePiGe4E,1703
42
42
  firefighter/components/form/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  firefighter/components/form/form.html,sha256=LtW07AxFsR-MI-iGVq0CsUVsUN3af5rS2R4SbAlfI5s,312
44
- firefighter/components/form/form.py,sha256=DowWqIk8oSz3Z5zKKMqXlclCJMiVveaqrSD8AnfQ3bY,665
44
+ firefighter/components/form/form.py,sha256=92qb1HTO3YvYlQMsw6uN8QUQZpbRbyGaCnPGuGX7VDs,596
45
45
  firefighter/components/form_field/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  firefighter/components/form_field/form_field.html,sha256=k5yyxvETqJSt5jHb8Z2v5o9oJRDLwWBKhISy0j0184Y,450
47
- firefighter/components/form_field/form_field.py,sha256=s_TXauUVNDUcyynCPKHgh-RTNYEVfJE_Dwd-8WPeC84,760
47
+ firefighter/components/form_field/form_field.py,sha256=QZrmEh-3wN8TUdx6db9_8rSpKuTfbyQ-1K0N7st4CYg,734
48
48
  firefighter/components/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  firefighter/components/messages/messages.html,sha256=P0V6Wsz7lTZL0xNPu_5w-J6Dc_aPkP0wqbHjMJ1D4qs,3157
50
- firefighter/components/messages/messages.py,sha256=FL8Um_j66qsAqMJ4tppjANrr2g3uib6amvsUgZ0DHTM,536
50
+ firefighter/components/messages/messages.py,sha256=vQ1aaIkRo9T9xtIfYneelrUbBw0cf9BOoaphEznmWS4,519
51
51
  firefighter/components/modal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  firefighter/components/modal/modal.html,sha256=PrOtS8eJHvzTHqILlXmjE4KsGVdbubSCexHiPa_I3Yk,2391
53
- firefighter/components/modal/modal.py,sha256=PNlncLbCir-WPd8en18OXe9OQAzS7hICNR7P4sHU-Us,895
53
+ firefighter/components/modal/modal.py,sha256=rpleZPmOWNCSQAEXTsQRfETwbyodjT3o7ni-pIqMWiI,869
54
54
  firefighter/confluence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  firefighter/confluence/admin.py,sha256=aDXghuuLc7G_TLt-655M31smx-H6vkIgLtEmmNCA3lg,1490
56
56
  firefighter/confluence/apps.py,sha256=vKswBwQL7L9e2JQwvRb7xy3myyE_GRldYX78jSY3XCM,406
@@ -140,7 +140,7 @@ firefighter/incidents/forms/__init__.py,sha256=OU0r5eZc2A0UJNsL83n8AI5EvwUvg4Yx0
140
140
  firefighter/incidents/forms/close_incident.py,sha256=syT5Lpr_WXNFT3KGCe1oy-FzOqMt98S7YEzovdnp7To,940
141
141
  firefighter/incidents/forms/create_incident.py,sha256=Wpp0qqUJQs5-5BXrS-P5-dGvM5zgr9XqaEEl6tpNZi4,2739
142
142
  firefighter/incidents/forms/edit.py,sha256=2rQkiKak-vac-K3cIsqlGv4R5nhI7JLxw3DhFMXbWms,956
143
- firefighter/incidents/forms/select_impact.py,sha256=0cnV2DFHuO1In6CgRATjg0zNLd9YN_LbQnPL7Fm9pAU,4631
143
+ firefighter/incidents/forms/select_impact.py,sha256=jLbzVj4UeUGwOYYa5P92PXkEu1J_6H43UATZYzDgSLY,4630
144
144
  firefighter/incidents/forms/update_key_events.py,sha256=1Xmnxe5OgZqLFS2HmMzQm3VGFPQipsdrLgKSwdh-fKc,4441
145
145
  firefighter/incidents/forms/update_roles.py,sha256=Q26UPfwAj-8N23RNZLQkvmHGnS1_j_X5KQWjJmPjMKY,3635
146
146
  firefighter/incidents/forms/update_status.py,sha256=QCRKfDhSYZhVsJ6oofQxOXGMWMDRQEDnH29y8YnFn_Y,1034
@@ -161,6 +161,8 @@ firefighter/incidents/migrations/0013_add_missing_component.py,sha256=qVLQEl-riF
161
161
  firefighter/incidents/migrations/0014_update_components_slack_groups.py,sha256=5tiQnrtOpYVUztFdvZ6xTUReuJfpDX0cOvqIvDZpBv0,8700
162
162
  firefighter/incidents/migrations/0015_update_impact_level.py,sha256=OQVTVrWvQ1orxqdrqwrhBMjxKY5qzqN2ZRobHc_tGDc,5451
163
163
  firefighter/incidents/migrations/0016_update_business_incidents_and_level.py,sha256=O5AL9twmjstSw44ndJ2-Og6dpKreReXVw_brpQb-t0w,3600
164
+ firefighter/incidents/migrations/0017_reorder_impact_types.py,sha256=7NN2KjcDRHNInXyEh8YKZli2LWT_i0UHXBbI21dXB6w,877
165
+ firefighter/incidents/migrations/0018_update_impactlevel_names.py,sha256=E37png_LiXABzuXk-vmxTgikw8YmULODkiytE2mkxT0,2227
164
166
  firefighter/incidents/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
167
  firefighter/incidents/models/__init__.py,sha256=dCNP-zRYNNDOZB3JDDWp7vCl084Jh6RgDT_iP57RkOY,862
166
168
  firefighter/incidents/models/component.py,sha256=7GyXKNFk1MZns6RUGLpkNw5u6He7H9N1LexzXbG4sBM,7445
@@ -383,7 +385,7 @@ firefighter/slack/views/modals/close.py,sha256=ur1SSRWk9NYFfL24gjOqoIiXKquDy6qeE
383
385
  firefighter/slack/views/modals/downgrade_workflow.py,sha256=S0y0_GYH4q7ewZUr_eA9Ly2c1FQueZzNCTiuIiWYUoY,3109
384
386
  firefighter/slack/views/modals/edit.py,sha256=60xav4XG4KGS9KknqsQNCQjl3qQzk7OtmHiEYTQ9pUk,3861
385
387
  firefighter/slack/views/modals/key_event_message.py,sha256=ga3-ITZyzJExwzctX-GfgnDqyQaxTfcqpqnOwY2E38M,5620
386
- firefighter/slack/views/modals/open.py,sha256=mAjOkvejCciUP7-QQmVfPKmljuEowNdGybAhwyKlfUI,21548
388
+ firefighter/slack/views/modals/open.py,sha256=qA8lN8pAAdK7j1qa8zEwe-Fvu5Tu18UG3Bcwxpg6Ymk,23012
387
389
  firefighter/slack/views/modals/postmortem.py,sha256=AeEtmiam_XgCRxDmltKluNT2VN1gcuCB2VbYeeATVcA,2525
388
390
  firefighter/slack/views/modals/select.py,sha256=Y-Ji_ALnzhYkXDBAyi497UL1Xn2vCGqXCtj8eog75Jk,3312
389
391
  firefighter/slack/views/modals/send_sos.py,sha256=bP6HgYyDwPrIcTq7n_sQz6UQsxhYbvBDS4HjM0uRccA,4838
@@ -446,8 +448,8 @@ firefighter_tests/test_slack/views/modals/test_open.py,sha256=Iatphd7vnrEMrv8ysK
446
448
  firefighter_tests/test_slack/views/modals/test_send_sos.py,sha256=_rE6jD-gOzcGyhlY0R9GzlGtPx65oOOguJYdENgxtLc,1289
447
449
  firefighter_tests/test_slack/views/modals/test_status.py,sha256=oQzPfwdg2tkbo9nfkO1GfS3WydxqSC6vy1AZjZDKT30,2226
448
450
  firefighter_tests/test_slack/views/modals/test_update_status.py,sha256=Y8Oa_fraj1vtaGig9Y28_6tOWvMrRPS-wyg3rY-DHBk,39380
449
- firefighter_incident-0.0.9.dist-info/METADATA,sha256=AC3MrJi0Y5Gck0TpVsOIciZCSTtqFB37fecMBDrPFO0,5487
450
- firefighter_incident-0.0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
451
- firefighter_incident-0.0.9.dist-info/entry_points.txt,sha256=c13meJbv7YNmYz7MipMOQwzQ5IeFOPXUBYAJ44XMQsM,61
452
- firefighter_incident-0.0.9.dist-info/licenses/LICENSE,sha256=krRiGp-a9-1nH1bWpBEdxyTKLhjLmn6DMVVoIb0zF90,1087
453
- firefighter_incident-0.0.9.dist-info/RECORD,,
451
+ firefighter_incident-0.0.10.dist-info/METADATA,sha256=hXTBfaxg9pA1hQgk54ZjQnhxRjQm3aZ6zbRiwUu2-pA,5488
452
+ firefighter_incident-0.0.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
453
+ firefighter_incident-0.0.10.dist-info/entry_points.txt,sha256=c13meJbv7YNmYz7MipMOQwzQ5IeFOPXUBYAJ44XMQsM,61
454
+ firefighter_incident-0.0.10.dist-info/licenses/LICENSE,sha256=krRiGp-a9-1nH1bWpBEdxyTKLhjLmn6DMVVoIb0zF90,1087
455
+ firefighter_incident-0.0.10.dist-info/RECORD,,