aa-structures 2.13.0__tar.gz → 2.14.1__tar.gz

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 (229) hide show
  1. {aa_structures-2.13.0 → aa_structures-2.14.1}/PKG-INFO +1 -1
  2. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/__init__.py +1 -1
  3. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/admin.py +1 -1
  4. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/app_settings.py +4 -0
  5. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/constants.py +1 -0
  6. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_timers.py +53 -6
  7. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_types.py +1 -0
  8. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/managers.py +13 -2
  9. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/owners.py +82 -12
  10. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/structures_1.py +5 -0
  11. aa_structures-2.13.0/structures/templates/structures/partials/structures/poco_list.html → aa_structures-2.14.1/structures/templates/structures/partials/structures/orbital_list.html +1 -1
  12. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/starbase_list.html +1 -1
  13. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/public.html +2 -2
  14. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/structures.html +5 -5
  15. aa_structures-2.13.0/structures/tests/core/test_notifications_timerboard.py → aa_structures-2.14.1/structures/tests/core/test_notifications_timers.py +6 -1
  16. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/test_tasks.py +102 -1
  17. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/test_views.py +1 -1
  18. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_2.py +14 -0
  19. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_5.py +135 -1
  20. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_structures.py +49 -42
  21. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_managers_1.py +11 -1
  22. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/factories.py +21 -0
  23. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/helpers.py +6 -0
  24. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_structures.py +12 -4
  25. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/structures.py +6 -6
  26. {aa_structures-2.13.0 → aa_structures-2.14.1}/LICENSE +0 -0
  27. {aa_structures-2.13.0 → aa_structures-2.14.1}/README.md +0 -0
  28. {aa_structures-2.13.0 → aa_structures-2.14.1}/pyproject.toml +0 -0
  29. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/apps.py +0 -0
  30. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/auth_hooks.py +0 -0
  31. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/__init__.py +0 -0
  32. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/__init__.py +0 -0
  33. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/billing_embeds.py +0 -0
  34. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/corporate_embeds.py +0 -0
  35. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/helpers.py +0 -0
  36. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/main.py +0 -0
  37. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/moonmining_embeds.py +0 -0
  38. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/orbital_embeds.py +0 -0
  39. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/skyhook_embeds.py +0 -0
  40. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/sov_embeds.py +0 -0
  41. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/structures_embeds.py +0 -0
  42. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/tower_embeds.py +0 -0
  43. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/notification_embeds/war_embeds.py +0 -0
  44. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/serializers.py +0 -0
  45. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/sovereignty.py +0 -0
  46. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/core/starbases.py +0 -0
  47. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/forms.py +0 -0
  48. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/helpers.py +0 -0
  49. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/de/LC_MESSAGES/django.mo +0 -0
  50. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/de/LC_MESSAGES/django.po +0 -0
  51. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/django.pot +0 -0
  52. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/en/LC_MESSAGES/django.mo +0 -0
  53. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/en/LC_MESSAGES/django.po +0 -0
  54. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/es/LC_MESSAGES/django.mo +0 -0
  55. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/es/LC_MESSAGES/django.po +0 -0
  56. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  57. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/fr_FR/LC_MESSAGES/django.po +0 -0
  58. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/it_IT/LC_MESSAGES/django.mo +0 -0
  59. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/it_IT/LC_MESSAGES/django.po +0 -0
  60. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ja/LC_MESSAGES/django.mo +0 -0
  61. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ja/LC_MESSAGES/django.po +0 -0
  62. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
  63. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ko_KR/LC_MESSAGES/django.po +0 -0
  64. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ru/LC_MESSAGES/django.mo +0 -0
  65. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/ru/LC_MESSAGES/django.po +0 -0
  66. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/uk/LC_MESSAGES/django.mo +0 -0
  67. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/uk/LC_MESSAGES/django.po +0 -0
  68. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  69. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/locale/zh_Hans/LC_MESSAGES/django.po +0 -0
  70. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/__init__.py +0 -0
  71. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_load_eve.py +0 -0
  72. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_preload_eveuniverse.py +0 -0
  73. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/management/commands/structures_update_poco_planets.py +0 -0
  74. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0001_initial_new.py +0 -0
  75. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0002_remove_eveuniverse_relation_names.py +0 -0
  76. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0003_add_localization_and_unique_key.py +0 -0
  77. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0004_improve_localization.py +0 -0
  78. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0005_add_notification_types.py +0 -0
  79. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0006_add_ownercharacter_disabled.py +0 -0
  80. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0007_add_notificationtypes_skyhook_metenox.py +0 -0
  81. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/0008_add_notificationtypes_skyhook_metenox.py +0 -0
  82. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/migrations/__init__.py +0 -0
  83. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/__init__.py +0 -0
  84. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/eveuniverse.py +0 -0
  85. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/notifications.py +0 -0
  86. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/models/structures_2.py +0 -0
  87. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/providers.py +0 -0
  88. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/global.css +0 -0
  89. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/main.css +0 -0
  90. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/public.css +0 -0
  91. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/statistics.css +0 -0
  92. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/css/structures.css +0 -0
  93. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/bars-rotate-fade-black-36.svg +0 -0
  94. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/bars-rotate-fade-white-36.svg +0 -0
  95. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/eve_symbol_128.png +0 -0
  96. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0h.png +0 -0
  97. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0l.png +0 -0
  98. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0m.png +0 -0
  99. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0r.png +0 -0
  100. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/0s.png +0 -0
  101. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1h.png +0 -0
  102. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1l.png +0 -0
  103. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1m.png +0 -0
  104. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/1r.png +0 -0
  105. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2h.png +0 -0
  106. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2l.png +0 -0
  107. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2m.png +0 -0
  108. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/2r.png +0 -0
  109. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3h.png +0 -0
  110. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3l.png +0 -0
  111. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3m.png +0 -0
  112. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/3r.png +0 -0
  113. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4h.png +0 -0
  114. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4l.png +0 -0
  115. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4m.png +0 -0
  116. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/4s.png +0 -0
  117. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5h.png +0 -0
  118. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5l.png +0 -0
  119. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5m.png +0 -0
  120. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/5s.png +0 -0
  121. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6h.png +0 -0
  122. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6l.png +0 -0
  123. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/6m.png +0 -0
  124. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7h.png +0 -0
  125. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7l.png +0 -0
  126. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/7m.png +0 -0
  127. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8h.png +0 -0
  128. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8l.png +0 -0
  129. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/8m.png +0 -0
  130. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/blank.png +0 -0
  131. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/circle.png +0 -0
  132. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/dustwheel.png +0 -0
  133. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/h.png +0 -0
  134. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/l.png +0 -0
  135. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/m.png +0 -0
  136. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/noship.png +0 -0
  137. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/r.png +0 -0
  138. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis.png +0 -0
  139. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_blue.png +0 -0
  140. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_darkred.png +0 -0
  141. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_default.png +0 -0
  142. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/panel/tyrannis_revelations.png +0 -0
  143. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/img/structures_logo.png +0 -0
  144. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/global.js +0 -0
  145. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/public.js +0 -0
  146. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/statistics.js +0 -0
  147. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/js/structures.js +0 -0
  148. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/dataTables.rowGroup.min.js +0 -0
  149. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/datetime.js +0 -0
  150. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/filterDropDown.min.js +0 -0
  151. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/rowGroup.bootstrap.min.css +0 -0
  152. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/static/structures/vendor/datatables/plugins/rowGroup.dataTables.min.css +0 -0
  153. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tasks.py +0 -0
  154. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/base.html +0 -0
  155. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/fitting_assets.html +0 -0
  156. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/fitting_gfx.html +0 -0
  157. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/poco_details.html +0 -0
  158. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/starbase_detail.html +0 -0
  159. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/structure_details.html +0 -0
  160. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/tab_general_detail.html +0 -0
  161. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/modals/tab_services_detail.html +0 -0
  162. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/menu.html +0 -0
  163. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/public/poco_list.html +0 -0
  164. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/statistics/structure_summary.html +0 -0
  165. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/active_tags.html +0 -0
  166. /aa_structures-2.13.0/structures/templates/structures/partials/structures/jump_gates_list.html → /aa_structures-2.14.1/structures/templates/structures/partials/structures/jump_gate_list.html +0 -0
  167. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/partials/structures/structure_list.html +0 -0
  168. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/statistics.html +0 -0
  169. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/detail_title.html +0 -0
  170. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_asset.html +0 -0
  171. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_item.html +0 -0
  172. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_tax_item.html +0 -0
  173. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templates/structures/templatetags/list_title.html +0 -0
  174. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templatetags/__init__.py +0 -0
  175. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/templatetags/structures.py +0 -0
  176. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/__init__.py +0 -0
  177. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/__init__.py +0 -0
  178. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/__init__.py +0 -0
  179. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/test_helpers.py +0 -0
  180. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/notification_embeds/test_main.py +0 -0
  181. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_notification_structuretimers.py +0 -0
  182. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_notification_types.py +0 -0
  183. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_serializers.py +0 -0
  184. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_sovereignty.py +0 -0
  185. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/core/test_starbases.py +0 -0
  186. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/integration/__init__.py +0 -0
  187. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/__init__.py +0 -0
  188. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_eveuniverse.py +0 -0
  189. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_1.py +0 -0
  190. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_2.py +0 -0
  191. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_3.py +0 -0
  192. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_notifications_discord.py +0 -0
  193. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_1.py +0 -0
  194. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_3.py +0 -0
  195. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_4.py +0 -0
  196. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/models/test_owners_6.py +0 -0
  197. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_admin.py +0 -0
  198. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_helpers.py +0 -0
  199. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_managers_2.py +0 -0
  200. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/test_tasks.py +0 -0
  201. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/__init__.py +0 -0
  202. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/create_eveuniverse.py +0 -0
  203. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/entities.json +0 -0
  204. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/esi_data.json +0 -0
  205. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/eveuniverse.json +0 -0
  206. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_notifications.py +0 -0
  207. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_notifications_2.py +0 -0
  208. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/generate_structures.py +0 -0
  209. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/load_eveuniverse.py +0 -0
  210. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/tasks_loadtest.py +0 -0
  211. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/testdata/test_generate_structures.py +0 -0
  212. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/__init__.py +0 -0
  213. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_public.py +0 -0
  214. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_service_status.py +0 -0
  215. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/test_statistics.py +0 -0
  216. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/tests/views/utils.py +0 -0
  217. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/urls.py +0 -0
  218. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/__init__.py +0 -0
  219. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/common.py +0 -0
  220. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/public.py +0 -0
  221. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/statistics.py +0 -0
  222. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/views/status.py +0 -0
  223. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/__init__.py +0 -0
  224. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/core.py +0 -0
  225. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/managers.py +0 -0
  226. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/models.py +0 -0
  227. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/__init__.py +0 -0
  228. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/test_core.py +0 -0
  229. {aa_structures-2.13.0 → aa_structures-2.14.1}/structures/webhooks/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aa-structures
3
- Version: 2.13.0
3
+ Version: 2.14.1
4
4
  Summary: App for managing Eve Online structures with Alliance Auth.
5
5
  Author-email: Erik Kalkoken <kalkoken87@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -3,5 +3,5 @@
3
3
  # pylint: disable = invalid-name
4
4
  default_app_config = "structures.apps.StructuresConfig"
5
5
 
6
- __version__ = "2.13.0"
6
+ __version__ = "2.14.1"
7
7
  __title__ = "Structures"
@@ -324,7 +324,7 @@ class NotificationBaseAdmin(admin.ModelAdmin):
324
324
  message = format_lazy("{first} {second}", first=first, second=second)
325
325
  else:
326
326
  message = first
327
- message = format_lazy({first})
327
+ message = format_lazy(first)
328
328
  self.message_user(request, message)
329
329
 
330
330
 
@@ -49,6 +49,10 @@ STRUCTURES_FEATURE_REFUELED_NOTIFICATIONS = clean_setting(
49
49
  )
50
50
  """Enable / disable refueled notifications feature."""
51
51
 
52
+ STRUCTURES_FEATURE_SKYHOOKS = clean_setting("STRUCTURES_FEATURE_SKYHOOKS", False)
53
+ """Show skyhooks in structures list."""
54
+
55
+
52
56
  STRUCTURES_FEATURE_STARBASES = clean_setting("STRUCTURES_FEATURE_STARBASES", True)
53
57
  """Enable / disable starbases feature."""
54
58
 
@@ -42,6 +42,7 @@ class EveTypeId(IntEnum):
42
42
  IHUB = 32458
43
43
  JUMP_GATE = 35841
44
44
  LIQUID_OZONE = 16273
45
+ ORBITAL_SKYHOOK = 81080
45
46
  NITROGEN_FUEL_BLOCK = 4051
46
47
  STRONTIUM = 16275
47
48
  TCU = 32226
@@ -53,7 +53,9 @@ def add_or_remove_timer(notif: Notification) -> bool:
53
53
  elif notif.notif_type == NotificationType.SOV_STRUCTURE_REINFORCED:
54
54
  timer_processed = _gen_timer_sov_reinforcements(notif)
55
55
  elif notif.notif_type == NotificationType.ORBITAL_REINFORCED:
56
- timer_processed = _gen_timer_orbital_reinforcements(notif)
56
+ timer_processed = _gen_timer_customs_office_reinforcements(notif)
57
+ elif notif.notif_type == NotificationType.SKYHOOK_LOST_SHIELDS:
58
+ timer_processed = _gen_timer_skyhook_reinforcements(notif)
57
59
  elif notif.notif_type in [
58
60
  NotificationType.MOONMINING_EXTRACTION_STARTED,
59
61
  NotificationType.MOONMINING_EXTRACTION_CANCELLED,
@@ -65,9 +67,7 @@ def add_or_remove_timer(notif: Notification) -> bool:
65
67
  elif notif.notif_type == NotificationType.TOWER_REINFORCED_EXTRA:
66
68
  timer_processed = _gen_timer_tower_reinforcements(notif)
67
69
  else:
68
- raise NotImplementedError(
69
- f"Unsupported notification type for timers: {notif.notif_type}"
70
- )
70
+ raise NotImplementedError(notif.notif_type)
71
71
  if timer_processed:
72
72
  logger.info("%s: Created timer for notification", notif.notification_id)
73
73
  notif.is_timer_added = True
@@ -181,8 +181,8 @@ def _gen_timer_sov_reinforcements(notif: Notification) -> bool:
181
181
  return timer_processed
182
182
 
183
183
 
184
- def _gen_timer_orbital_reinforcements(notif: Notification) -> bool:
185
- """Generate timer for orbital reinforcements."""
184
+ def _gen_timer_customs_office_reinforcements(notif: Notification) -> bool:
185
+ """Generate timer for customs office reinforcements."""
186
186
 
187
187
  solar_system = notif.eve_solar_system()
188
188
  planet = notif.eve_planet()
@@ -231,6 +231,53 @@ def _gen_timer_orbital_reinforcements(notif: Notification) -> bool:
231
231
  return timer_processed
232
232
 
233
233
 
234
+ def _gen_timer_skyhook_reinforcements(notif: Notification) -> bool:
235
+ """Generate timer for skyhook reinforcements."""
236
+
237
+ solar_system = notif.eve_solar_system("solarsystemID")
238
+ structure_type = notif.eve_structure_type("typeID")
239
+ planet = notif.eve_planet()
240
+ eve_time = ldap_time_2_datetime(notif.parsed_text()["timestamp"])
241
+ timer_processed = False
242
+
243
+ if AuthTimer:
244
+ AuthTimer.objects.create(
245
+ details=gettext("Final timer"),
246
+ system=solar_system.name,
247
+ planet_moon=planet.name,
248
+ structure="POCO", # Auth timer does not support the Skyhook type yet
249
+ objective="Friendly",
250
+ eve_time=eve_time,
251
+ eve_corp=notif.owner.corporation,
252
+ corp_timer=STRUCTURES_TIMERS_ARE_CORP_RESTRICTED,
253
+ )
254
+ timer_processed = True
255
+
256
+ if Timer:
257
+ visibility = (
258
+ Timer.Visibility.CORPORATION
259
+ if STRUCTURES_TIMERS_ARE_CORP_RESTRICTED
260
+ else Timer.Visibility.UNRESTRICTED
261
+ )
262
+ Timer.objects.create(
263
+ eve_solar_system=solar_system,
264
+ structure_type=structure_type,
265
+ timer_type=Timer.Type.FINAL,
266
+ objective=Timer.Objective.FRIENDLY,
267
+ date=eve_time,
268
+ location_details=planet.name,
269
+ eve_corporation=notif.owner.corporation,
270
+ eve_alliance=notif.owner.corporation.alliance,
271
+ visibility=visibility,
272
+ structure_name=structure_type.name,
273
+ owner_name=notif.owner.corporation.corporation_name,
274
+ details_notes=_timer_details_notes(notif),
275
+ )
276
+ timer_processed = True
277
+
278
+ return timer_processed
279
+
280
+
234
281
  def _gen_timer_moon_extraction(notif: Notification) -> bool:
235
282
  """Generate timer for moon mining extractions."""
236
283
  solar_system = notif.eve_solar_system()
@@ -221,6 +221,7 @@ class NotificationType(models.TextChoices):
221
221
  cls.STRUCTURE_LOST_ARMOR,
222
222
  cls.STRUCTURE_LOST_SHIELD,
223
223
  cls.TOWER_REINFORCED_EXTRA,
224
+ cls.SKYHOOK_LOST_SHIELDS,
224
225
  }
225
226
 
226
227
  @classmethod
@@ -2,9 +2,11 @@
2
2
 
3
3
  # pylint: disable=missing-class-docstring
4
4
 
5
+ from __future__ import annotations
6
+
5
7
  import datetime as dt
6
8
  import itertools
7
- from typing import Any, Iterable, Optional, Set, Tuple
9
+ from typing import TYPE_CHECKING, Any, Iterable, Optional, Set, Tuple
8
10
 
9
11
  from django.contrib.auth.models import User
10
12
  from django.db import models, transaction
@@ -24,6 +26,9 @@ from .core.notification_types import NotificationType
24
26
  from .providers import esi
25
27
  from .webhooks.managers import WebhookBaseManager
26
28
 
29
+ if TYPE_CHECKING:
30
+ from .models import Owner
31
+
27
32
  logger = LoggerAddTag(get_extension_logger(__name__), __title__)
28
33
 
29
34
 
@@ -231,6 +236,10 @@ class StructureQuerySet(models.QuerySet):
231
236
  """Filter for starbases."""
232
237
  return self.filter(eve_type__eve_group__eve_category=EveCategoryId.STARBASE)
233
238
 
239
+ def filter_skyhooks(self) -> models.QuerySet:
240
+ """Filter for skyhooks."""
241
+ return self.filter(eve_type=EveTypeId.ORBITAL_SKYHOOK)
242
+
234
243
  def ids(self) -> Set[int]:
235
244
  """Return ids as set."""
236
245
  return set(self.values_list("id", flat=True))
@@ -380,7 +389,9 @@ class StructureManagerBase(models.Manager):
380
389
  obj, created = self.update_or_create_from_dict(structure=structure, owner=owner)
381
390
  return obj, created
382
391
 
383
- def update_or_create_from_dict(self, structure: dict, owner) -> Tuple[Any, bool]:
392
+ def update_or_create_from_dict(
393
+ self, structure: dict, owner: Owner
394
+ ) -> Tuple[Any, bool]:
384
395
  """update or create structure from given dict"""
385
396
 
386
397
  eve_type: EveType = EveType.objects.get_or_create_esi(id=structure["type_id"])[
@@ -37,6 +37,7 @@ from structures.app_settings import (
37
37
  STRUCTURES_DEVELOPER_MODE,
38
38
  STRUCTURES_ESI_DIRECTOR_ERROR_MAX_RETRIES,
39
39
  STRUCTURES_FEATURE_CUSTOMS_OFFICES,
40
+ STRUCTURES_FEATURE_SKYHOOKS,
40
41
  STRUCTURES_FEATURE_STARBASES,
41
42
  STRUCTURES_HOURS_UNTIL_STALE_NOTIFICATION,
42
43
  STRUCTURES_NOTIFICATION_SYNC_GRACE_MINUTES,
@@ -545,14 +546,14 @@ class Owner(models.Model):
545
546
  )
546
547
 
547
548
  def _remove_structures_not_returned_from_esi(
548
- self, structures_qs: models.QuerySet, new_structures: Iterable
549
+ self, existing_structures: models.QuerySet, new_structures: Iterable[dict]
549
550
  ):
550
551
  """Remove structures no longer returned from ESI."""
551
- ids_local = {x.id for x in structures_qs}
552
+ ids_local = {x.id for x in existing_structures}
552
553
  ids_from_esi = {x["structure_id"] for x in new_structures}
553
554
  ids_to_remove = ids_local - ids_from_esi
554
555
  if len(ids_to_remove) > 0:
555
- structures_qs.filter(id__in=ids_to_remove).delete()
556
+ existing_structures.filter(id__in=ids_to_remove).delete()
556
557
  logger.info(
557
558
  "Removed %d structures which apparently no longer exist.",
558
559
  len(ids_to_remove),
@@ -591,7 +592,7 @@ class Owner(models.Model):
591
592
  is_ok = True
592
593
  # fetch main list of structure for this corporation
593
594
  try:
594
- structures = (
595
+ structures: List[dict] = (
595
596
  esi.client.Corporation.get_corporations_corporation_id_structures(
596
597
  corporation_id=self.corporation.corporation_id,
597
598
  token=token.valid_access_token(),
@@ -619,9 +620,19 @@ class Owner(models.Model):
619
620
  )
620
621
  ).results()
621
622
  except OSError as ex:
622
- self._report_esi_issue(
623
- f"fetch structure #{structure['structure_id']}", ex, token
624
- )
623
+ if isinstance(ex, HTTPForbidden):
624
+ logger.error(
625
+ "Failed to fetch structure with ID #%d belonging to %s, "
626
+ "because the character '%s' is missing "
627
+ "docking rights for it.",
628
+ structure["structure_id"],
629
+ self,
630
+ token.character_name,
631
+ )
632
+ else:
633
+ self._report_esi_issue(
634
+ f"fetch structure #{structure['structure_id']}", ex, token
635
+ )
625
636
  structure["name"] = "(no data)"
626
637
  is_ok = False
627
638
  else:
@@ -650,7 +661,7 @@ class Owner(models.Model):
650
661
  self._store_raw_data("structures", structures)
651
662
 
652
663
  self._remove_structures_not_returned_from_esi(
653
- structures_qs=self.structures.filter_upwell_structures(),
664
+ existing_structures=self.structures.filter_upwell_structures(),
654
665
  new_structures=structures,
655
666
  )
656
667
  return is_ok
@@ -701,7 +712,7 @@ class Owner(models.Model):
701
712
  return False
702
713
 
703
714
  self._remove_structures_not_returned_from_esi(
704
- structures_qs=self.structures.filter_customs_offices(),
715
+ existing_structures=self.structures.filter_customs_offices(),
705
716
  new_structures=structures.values(),
706
717
  )
707
718
  return True
@@ -868,7 +879,7 @@ class Owner(models.Model):
868
879
  return False
869
880
 
870
881
  self._remove_structures_not_returned_from_esi(
871
- structures_qs=self.structures.filter_starbases(),
882
+ existing_structures=self.structures.filter_starbases(),
872
883
  new_structures=structures,
873
884
  )
874
885
  character.reset_error_counter()
@@ -1214,15 +1225,18 @@ class Owner(models.Model):
1214
1225
  def update_asset_esi(self, user: Optional[User] = None):
1215
1226
  """Update assets from ESI."""
1216
1227
  token = self.fetch_token()
1217
- assets_data = self._fetch_structure_assets_from_esi(token)
1228
+ assets_data = self._fetch_owner_assets_from_esi(token)
1218
1229
  self._store_items_for_upwell_structures(assets_data)
1219
1230
  self._store_items_for_starbases(assets_data)
1231
+ if STRUCTURES_FEATURE_SKYHOOKS:
1232
+ self._update_skyhooks_from_assets(assets_data)
1233
+ self._resolve_skyhook_planets()
1220
1234
  if user:
1221
1235
  self._send_report_to_user(
1222
1236
  topic="assets", topic_count=self.structures.count(), user=user
1223
1237
  )
1224
1238
 
1225
- def _fetch_structure_assets_from_esi(self, token: Token) -> dict:
1239
+ def _fetch_owner_assets_from_esi(self, token: Token) -> dict:
1226
1240
  assets_raw = esi.client.Assets.get_corporations_corporation_id_assets(
1227
1241
  corporation_id=self.corporation.corporation_id,
1228
1242
  token=token.valid_access_token(),
@@ -1306,6 +1320,62 @@ class Owner(models.Model):
1306
1320
  )
1307
1321
  structure.update_items(structure_items)
1308
1322
 
1323
+ def _update_skyhooks_from_assets(self, assets_data: dict):
1324
+ skyhooks = {
1325
+ item_id: item
1326
+ for item_id, item in assets_data.items()
1327
+ if item["type_id"] == EveTypeId.ORBITAL_SKYHOOK
1328
+ and item["location_type"] == "solar_system"
1329
+ and item["location_flag"] == "AutoFit"
1330
+ and item["is_singleton"]
1331
+ and item["position"]
1332
+ }
1333
+ structures = []
1334
+ for item in skyhooks.values():
1335
+ structures.append(
1336
+ {
1337
+ "corporation_id": self.corporation.corporation_id,
1338
+ "type_id": item["type_id"],
1339
+ "position": item["position"],
1340
+ "structure_id": item["item_id"],
1341
+ "system_id": item["location_id"],
1342
+ }
1343
+ )
1344
+
1345
+ for s in structures:
1346
+ Structure.objects.update_or_create_from_dict(s, self)
1347
+
1348
+ self._remove_structures_not_returned_from_esi(
1349
+ existing_structures=self.structures.filter_skyhooks(),
1350
+ new_structures=structures,
1351
+ )
1352
+
1353
+ def _resolve_skyhook_planets(self):
1354
+ """Add planets to all unresolved Skyhooks."""
1355
+ s: Structure
1356
+ for s in self.structures.filter_skyhooks().filter(
1357
+ eve_planet__isnull=True,
1358
+ position_x__isnull=False,
1359
+ position_y__isnull=False,
1360
+ position_z__isnull=False,
1361
+ ):
1362
+ try:
1363
+ celestial = s.eve_solar_system.nearest_celestial(
1364
+ x=s.position_x,
1365
+ y=s.position_y,
1366
+ z=s.position_z,
1367
+ group_id=EveGroupId.PLANET,
1368
+ )
1369
+ except OSError:
1370
+ continue
1371
+
1372
+ if not celestial or not isinstance(celestial.eve_object, EvePlanet):
1373
+ continue
1374
+
1375
+ s.eve_planet = celestial.eve_object
1376
+ s.name = celestial.eve_type.name
1377
+ s.save()
1378
+
1309
1379
  @staticmethod
1310
1380
  def get_esi_scopes() -> List[str]:
1311
1381
  """Return all required ESI scopes."""
@@ -464,6 +464,11 @@ class Structure(models.Model): # pylint: disable = too-many-public-methods
464
464
  """Return True if this structure is a starbase, else False."""
465
465
  return starbases.is_starbase(self.eve_type)
466
466
 
467
+ @property
468
+ def is_skyhook(self) -> bool:
469
+ """Return True if this structure is a skyhook, else False."""
470
+ return self.eve_type_id == EveTypeId.ORBITAL_SKYHOOK
471
+
467
472
  @cached_property
468
473
  def is_upwell_structure(self) -> bool:
469
474
  """Return True if this structure is an upwell structure, else False."""
@@ -5,7 +5,7 @@
5
5
  <!-- structure list -->
6
6
 
7
7
  <h3>
8
- {% translate 'Customs Offices' %}
8
+ {% translate 'Orbitals' %}
9
9
  {% include "structures/partials/structures/active_tags.html" %}
10
10
  </h3>
11
11
 
@@ -5,7 +5,7 @@
5
5
  <!-- structure list -->
6
6
 
7
7
  <h3>
8
- {% translate 'All Structures' %}
8
+ {% translate 'Starbases' %}
9
9
  {% include "structures/partials/structures/active_tags.html" %}
10
10
  </h3>
11
11
 
@@ -28,7 +28,7 @@
28
28
  <ul id="public-tabs" class="nav nav-tabs" role="tablist">
29
29
 
30
30
  <li role="presentation" class="active">
31
- <a href="#pocos" aria-controls="pocos" role="tab" data-toggle="tab">
31
+ <a href="#pocos" aria-controls="orbitals" role="tab" data-toggle="tab">
32
32
  {% translate "Customs Offices" %} <small>({{ pocos_count|default:"-" }})</small>
33
33
  </a>
34
34
  </li>
@@ -39,7 +39,7 @@
39
39
  <div class="panel-body">
40
40
  <div class="tab-content">
41
41
 
42
- <div role="tabpanel" class="tab-pane active" id="pocos">
42
+ <div role="tabpanel" class="tab-pane active" id="orbitals">
43
43
  {% include "structures/partials/public/poco_list.html" %}
44
44
  </div>
45
45
 
@@ -48,8 +48,8 @@
48
48
  </li>
49
49
 
50
50
  <li role="presentation">
51
- <a href="#pocos" aria-controls="pocos" role="tab" data-toggle="tab">
52
- {% trans "Customs Offices" %} <small>({{ pocos_count|default:"-" }})</small>
51
+ <a href="#orbitals" aria-controls="orbitals" role="tab" data-toggle="tab">
52
+ {% trans "Orbitals" %} <small>({{ orbitals_count|default:"-" }})</small>
53
53
  </a>
54
54
  </li>
55
55
 
@@ -77,8 +77,8 @@
77
77
  {% include "structures/partials/structures/structure_list.html" %}
78
78
  </div>
79
79
 
80
- <div role="tabpanel" class="tab-pane" id="pocos">
81
- {% include "structures/partials/structures/poco_list.html" %}
80
+ <div role="tabpanel" class="tab-pane" id="orbitals">
81
+ {% include "structures/partials/structures/orbital_list.html" %}
82
82
  </div>
83
83
 
84
84
  <div role="tabpanel" class="tab-pane" id="starbases">
@@ -87,7 +87,7 @@
87
87
 
88
88
  {% if show_jump_gates_tab %}
89
89
  <div role="tabpanel" class="tab-pane" id="jump-gates">
90
- {% include "structures/partials/structures/jump_gates_list.html" %}
90
+ {% include "structures/partials/structures/jump_gate_list.html" %}
91
91
  </div>
92
92
  {% endif %}
93
93
 
@@ -4,6 +4,7 @@ from app_utils.django import app_labels
4
4
  from app_utils.testing import NoSocketsTestCase
5
5
 
6
6
  from structures.core import notification_timers
7
+ from structures.core.notification_types import NotificationType
7
8
  from structures.models import Notification
8
9
  from structures.tests.testdata.factories import (
9
10
  GeneratedNotificationFactory,
@@ -107,7 +108,11 @@ if "timerboard" in app_labels():
107
108
  @patch(MODULE_PATH + ".STRUCTURES_MOON_EXTRACTION_TIMERS_ENABLED", True)
108
109
  def test_run_all(self):
109
110
  for obj in Notification.objects.all():
110
- obj.add_or_remove_timer()
111
+ timer_types = NotificationType.relevant_for_timerboard()
112
+ with self.subTest(notif_type=obj.notif_type):
113
+ is_timer = obj.notif_type in timer_types
114
+ is_added = obj.add_or_remove_timer()
115
+ self.assertEqual(is_timer, is_added)
111
116
 
112
117
  @patch(MODULE_PATH + ".STRUCTURES_TIMERS_ARE_CORP_RESTRICTED", False)
113
118
  def test_corp_restriction_1(self):
@@ -7,7 +7,7 @@ import yaml
7
7
 
8
8
  from django.test import TestCase, override_settings
9
9
  from django.utils.timezone import now
10
- from eveuniverse.models import EveSolarSystem
10
+ from eveuniverse.models import EvePlanet, EveSolarSystem
11
11
 
12
12
  from app_utils.django import app_labels
13
13
  from app_utils.esi import EsiStatus
@@ -22,11 +22,13 @@ from structures.tests.testdata.factories import (
22
22
  NotificationFactory,
23
23
  OwnerFactory,
24
24
  RawNotificationFactory,
25
+ SkyhookFactory,
25
26
  StarbaseFactory,
26
27
  StructureFactory,
27
28
  WebhookFactory,
28
29
  datetime_to_esi,
29
30
  )
31
+ from structures.tests.testdata.helpers import NearestCelestial
30
32
  from structures.tests.testdata.load_eveuniverse import load_eveuniverse
31
33
 
32
34
  if "structuretimers" in app_labels():
@@ -613,3 +615,102 @@ class TestTasks(TestCase):
613
615
  self.assertEqual(len(embeds), 1)
614
616
  embed = embeds[0]
615
617
  self.assertIn("Territorial Claim Unit", embed.title)
618
+
619
+ @patch(OWNERS_PATH + ".STRUCTURES_FEATURE_SKYHOOKS", True)
620
+ def test_should_fetch_new_skyhooks_from_esi(
621
+ self, mock_esi_2, mock_esi, mock_execute
622
+ ):
623
+ # given
624
+ owner = OwnerFactory()
625
+ structure = SkyhookFactory(owner=owner)
626
+ eve_planet = EvePlanet.objects.get(id=40161469)
627
+ corporation_id = owner.corporation.corporation_id
628
+ endpoints = [
629
+ EsiEndpoint(
630
+ "Assets",
631
+ "get_corporations_corporation_id_assets",
632
+ "corporation_id",
633
+ needs_token=True,
634
+ data={
635
+ str(corporation_id): [
636
+ {
637
+ "is_singleton": True,
638
+ "item_id": structure.id,
639
+ "location_flag": "AutoFit",
640
+ "location_id": 30002537,
641
+ "location_type": "solar_system",
642
+ "quantity": 1,
643
+ "type_id": 81080,
644
+ },
645
+ ]
646
+ },
647
+ ),
648
+ EsiEndpoint(
649
+ "Assets",
650
+ "post_corporations_corporation_id_assets_names",
651
+ "corporation_id",
652
+ needs_token=True,
653
+ data={str(corporation_id): []},
654
+ ),
655
+ EsiEndpoint(
656
+ "Assets",
657
+ "post_corporations_corporation_id_assets_locations",
658
+ "corporation_id",
659
+ needs_token=True,
660
+ data={
661
+ str(corporation_id): [
662
+ {"item_id": structure.id, "position": {"x": 1, "y": 2, "z": 3}}
663
+ ]
664
+ },
665
+ ),
666
+ EsiEndpoint(
667
+ "Corporation",
668
+ "get_corporations_corporation_id_starbases",
669
+ "corporation_id",
670
+ needs_token=True,
671
+ data={str(corporation_id): []},
672
+ ),
673
+ EsiEndpoint(
674
+ "Corporation",
675
+ "get_corporations_corporation_id_structures",
676
+ "corporation_id",
677
+ needs_token=True,
678
+ data={str(corporation_id): []},
679
+ ),
680
+ EsiEndpoint(
681
+ "Planetary_Interaction",
682
+ "get_corporations_corporation_id_customs_offices",
683
+ "corporation_id",
684
+ needs_token=True,
685
+ data={str(corporation_id): []},
686
+ ),
687
+ EsiEndpoint(
688
+ "Sovereignty",
689
+ "get_sovereignty_map",
690
+ needs_token=False,
691
+ data=[],
692
+ ),
693
+ EsiEndpoint(
694
+ "Universe",
695
+ "get_universe_structures_structure_id",
696
+ "structure_id",
697
+ needs_token=True,
698
+ data={},
699
+ ),
700
+ ]
701
+ mock_esi.client = mock_esi_2.client = EsiClientStub.create_from_endpoints(
702
+ endpoints
703
+ )
704
+ structure_id = structure.id
705
+ structure.delete()
706
+ # when
707
+
708
+ with patch(OWNERS_PATH + ".EveSolarSystem.nearest_celestial") as m:
709
+ m.return_value = NearestCelestial(
710
+ eve_object=eve_planet,
711
+ distance=35_000_000,
712
+ eve_type=eve_planet.eve_type,
713
+ )
714
+ tasks.update_all_structures.delay()
715
+ # then
716
+ self.assertTrue(owner.structures.filter(id=structure_id).exists())
@@ -46,7 +46,7 @@ class TestStructureListView(TestCase):
46
46
  # then
47
47
  self.assertEqual(response.status_code, 200)
48
48
  self.assertEqual(response.context["structures_count"], 2)
49
- self.assertEqual(response.context["pocos_count"], 1)
49
+ self.assertEqual(response.context["orbitals_count"], 1)
50
50
  self.assertEqual(response.context["starbases_count"], 1)
51
51
  self.assertEqual(response.context["jump_gates_count"], 1)
52
52
  self.assertIn("data_export", response.context)
@@ -376,6 +376,20 @@ class TestUpdateStructuresEsi(NoSocketsTestCase):
376
376
  structure = Structure.objects.get(id=1000000000002)
377
377
  self.assertEqual(structure.name, "(no data)")
378
378
 
379
+ def test_update_will_not_break_on_403_error_from_structure_info(self, mock_esi):
380
+ # given
381
+ new_endpoint = EsiEndpoint(
382
+ "Universe", "get_universe_structures_structure_id", http_error_code=403
383
+ )
384
+ mock_esi.client = self.esi_client_stub.replace_endpoints([new_endpoint])
385
+ owner = OwnerFactory(user=self.user, structures_last_update_at=None)
386
+ # when
387
+ owner.update_structures_esi()
388
+ # then
389
+ self.assertFalse(owner.is_structure_sync_fresh)
390
+ structure = Structure.objects.get(id=1000000000002)
391
+ self.assertEqual(structure.name, "(no data)")
392
+
379
393
  @patch(MODULE_PATH + ".Structure.objects.update_or_create_from_dict")
380
394
  def test_update_will_not_break_on_http_error_when_creating_structures(
381
395
  self, mock_create_structure, mock_esi