aa-ledger 1.0.3__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. {aa_ledger-1.0.3.dist-info → aa_ledger-2.0.0.dist-info}/METADATA +6 -6
  2. aa_ledger-2.0.0.dist-info/RECORD +267 -0
  3. {aa_ledger-1.0.3.dist-info → aa_ledger-2.0.0.dist-info}/WHEEL +1 -1
  4. ledger/__init__.py +2 -2
  5. ledger/admin.py +23 -18
  6. ledger/api/__init__.py +23 -7
  7. ledger/api/{ledger/admin.py → admin.py} +25 -31
  8. ledger/api/alliance.py +755 -0
  9. ledger/api/character.py +786 -0
  10. ledger/api/corporation.py +1141 -0
  11. ledger/api/{helpers.py → helpers/core.py} +33 -33
  12. ledger/api/helpers/icons.py +372 -0
  13. ledger/api/helpers/planetary_helper.py +354 -0
  14. ledger/api/planetary.py +354 -0
  15. ledger/api/schema.py +240 -15
  16. ledger/app_settings.py +18 -26
  17. ledger/auth_hooks.py +2 -2
  18. ledger/constants.py +50 -177
  19. ledger/decorators.py +2 -46
  20. ledger/forms.py +133 -39
  21. ledger/helpers/billboard.py +194 -144
  22. ledger/helpers/cache.py +105 -0
  23. ledger/helpers/discord.py +2 -4
  24. ledger/helpers/eveonline.py +160 -0
  25. ledger/helpers/ledger_data.py +23 -0
  26. ledger/helpers/ref_type.py +53 -78
  27. ledger/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  28. ledger/locale/cs_CZ/LC_MESSAGES/django.po +349 -193
  29. ledger/locale/de/LC_MESSAGES/django.mo +0 -0
  30. ledger/locale/de/LC_MESSAGES/django.po +528 -379
  31. ledger/locale/django.pot +717 -553
  32. ledger/locale/es/LC_MESSAGES/django.mo +0 -0
  33. ledger/locale/es/LC_MESSAGES/django.po +349 -194
  34. ledger/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  35. ledger/locale/fr_FR/LC_MESSAGES/django.po +349 -193
  36. ledger/locale/it_IT/LC_MESSAGES/django.mo +0 -0
  37. ledger/locale/it_IT/LC_MESSAGES/django.po +349 -193
  38. ledger/locale/ja/LC_MESSAGES/django.mo +0 -0
  39. ledger/locale/ja/LC_MESSAGES/django.po +348 -193
  40. ledger/locale/ko_KR/LC_MESSAGES/django.mo +0 -0
  41. ledger/locale/ko_KR/LC_MESSAGES/django.po +349 -193
  42. ledger/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
  43. ledger/locale/nl_NL/LC_MESSAGES/django.po +349 -193
  44. ledger/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
  45. ledger/locale/pl_PL/LC_MESSAGES/django.po +350 -193
  46. ledger/locale/ru/LC_MESSAGES/django.mo +0 -0
  47. ledger/locale/ru/LC_MESSAGES/django.po +348 -193
  48. ledger/locale/sk/LC_MESSAGES/django.mo +0 -0
  49. ledger/locale/sk/LC_MESSAGES/django.po +348 -193
  50. ledger/locale/uk/LC_MESSAGES/django.mo +0 -0
  51. ledger/locale/uk/LC_MESSAGES/django.po +348 -193
  52. ledger/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  53. ledger/locale/zh_Hans/LC_MESSAGES/django.po +348 -193
  54. ledger/managers/character_audit_manager.py +28 -20
  55. ledger/managers/character_journal_manager.py +187 -358
  56. ledger/managers/character_mining_manager.py +64 -30
  57. ledger/managers/character_planetary_manager.py +185 -138
  58. ledger/managers/corporation_audit_manager.py +36 -27
  59. ledger/managers/corporation_journal_manager.py +94 -57
  60. ledger/managers/general_manager.py +12 -8
  61. ledger/migrations/0018_remove_characterplanet_ledger_char_planet__58a5b6_idx_and_more.py +44 -0
  62. ledger/migrations/0019_rename_characteraudit_characterowner_and_more.py +48 -0
  63. ledger/models/__init__.py +5 -11
  64. ledger/models/characteraudit.py +101 -109
  65. ledger/models/corporationaudit.py +94 -49
  66. ledger/models/general.py +105 -211
  67. ledger/models/helpers/update_manager.py +302 -0
  68. ledger/models/planetary.py +60 -205
  69. ledger/providers.py +101 -0
  70. ledger/static/ledger/css/{ledger.css → aa-ledger.css} +54 -28
  71. ledger/static/ledger/js/aa-ledger.js +124 -0
  72. ledger/static/ledger/js/charts.js +25 -1
  73. ledger/static/ledger/js/view-alliance-ledger.js +383 -0
  74. ledger/static/ledger/js/view-character-ledger.js +388 -0
  75. ledger/static/ledger/js/view-corporation-ledger.js +402 -0
  76. ledger/static/ledger/js/view-planetary.js +492 -0
  77. ledger/static/ledger/libs/amCharts/5.14.4/js/flow.js +2 -0
  78. ledger/static/ledger/libs/amCharts/5.14.4/js/index.js +2 -0
  79. ledger/static/ledger/libs/amCharts/5.14.4/js/percent.js +2 -0
  80. ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Animated.js +2 -0
  81. ledger/static/ledger/libs/amCharts/5.14.4/js/themes/Dark.js +2 -0
  82. ledger/static/ledger/libs/amCharts/5.14.4/js/xy.js +2 -0
  83. ledger/static/ledger/libs/datatables/2.3.5/css/dataTables.bootstrap5.css +610 -0
  84. ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.bootstrap5.js +122 -0
  85. ledger/static/ledger/libs/datatables/2.3.5/js/dataTables.js +14127 -0
  86. ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.bootstrap5.css +516 -0
  87. ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/css/columnControl.dataTables.css +529 -0
  88. ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/columnControl.bootstrap5.js +73 -0
  89. ledger/static/ledger/libs/datatables/Extensions/ColumnControl/1.1.1/js/dataTables.columnControl.js +3090 -0
  90. ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/css/fixedHeader.bootstrap5.css +20 -0
  91. ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/dataTables.fixedHeader.js +1203 -0
  92. ledger/static/ledger/libs/datatables/Extensions/FixedHeader/4.0.4/js/fixedHeader.bootstrap5.js +59 -0
  93. ledger/tasks.py +157 -146
  94. ledger/templates/ledger/base.html +59 -21
  95. ledger/templates/ledger/bundles/aa-ledger-css.html +3 -0
  96. ledger/templates/ledger/bundles/aa-ledger-js.html +3 -0
  97. ledger/templates/ledger/bundles/view-alliance-ledger-js.html +14 -0
  98. ledger/templates/ledger/bundles/view-character-ledger-js.html +15 -0
  99. ledger/templates/ledger/bundles/view-character-planetary-css.html +3 -0
  100. ledger/templates/ledger/bundles/view-character-planetary-js.html +4 -0
  101. ledger/templates/ledger/bundles/view-corporation-ledger-js.html +15 -0
  102. ledger/templates/ledger/partials/modal/confirm.html +0 -1
  103. ledger/templates/ledger/partials/modal/request-accept-delete-alliance.html +38 -0
  104. ledger/templates/ledger/partials/modal/request-accept-delete-character.html +38 -0
  105. ledger/templates/ledger/partials/modal/request-accept-delete-corporation.html +38 -0
  106. ledger/templates/ledger/partials/modal/request-accept-switch-notification.html +38 -0
  107. ledger/templates/ledger/partials/modal/request-view-alliance-details.html +26 -0
  108. ledger/templates/ledger/partials/modal/request-view-character-details.html +26 -0
  109. ledger/templates/ledger/partials/modal/request-view-corporation-details.html +26 -0
  110. ledger/templates/ledger/partials/modal/request-view-extractor.html +32 -0
  111. ledger/templates/ledger/partials/modal/request-view-factory.html +31 -0
  112. ledger/templates/ledger/partials/{menu → navigation}/administration.html +8 -0
  113. ledger/templates/ledger/partials/{menu → navigation}/navigation.html +2 -2
  114. ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance_corporations.html +3 -3
  115. ledger/templates/ledger/partials/view-alliance-administration/dashboard.html +81 -0
  116. ledger/templates/ledger/partials/view-alliance-ledger/alliance-billboard.html +25 -0
  117. ledger/templates/ledger/partials/view-alliance-ledger/alliance-ledger-details.html +21 -0
  118. ledger/templates/ledger/partials/view-alliance-ledger/alliance-table.html +24 -0
  119. ledger/templates/ledger/partials/view-alliance-ledger/information/daily.html +18 -0
  120. ledger/templates/ledger/partials/view-alliance-ledger/information/hourly.html +18 -0
  121. ledger/templates/ledger/partials/view-alliance-ledger/information/summary.html +19 -0
  122. ledger/templates/ledger/partials/{administration → view-character-administration}/character.html +1 -9
  123. ledger/templates/ledger/partials/{administration → view-character-administration}/dashboard.html +0 -34
  124. ledger/templates/ledger/partials/view-character-ledger/character-billboard.html +25 -0
  125. ledger/templates/ledger/partials/view-character-ledger/character-ledger-details.html +21 -0
  126. ledger/templates/ledger/partials/view-character-ledger/character-table.html +25 -0
  127. ledger/templates/ledger/partials/view-character-ledger/information/daily.html +18 -0
  128. ledger/templates/ledger/partials/view-character-ledger/information/hourly.html +18 -0
  129. ledger/templates/ledger/partials/view-character-ledger/information/summary.html +19 -0
  130. ledger/templates/ledger/partials/view-character-planetary/extractor-table.html +24 -0
  131. ledger/templates/ledger/partials/view-character-planetary/factory-table.html +24 -0
  132. ledger/templates/ledger/partials/view-character-planetary/planetary-table.html +22 -0
  133. ledger/templates/ledger/partials/view-character-planetary/storage-table.html +23 -0
  134. ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation.html +5 -13
  135. ledger/templates/ledger/partials/{administration → view-corporation-administration}/corporation_characters.html +1 -1
  136. ledger/templates/ledger/partials/view-corporation-administration/dashboard.html +81 -0
  137. ledger/templates/ledger/partials/view-corporation-ledger/corporation-billboard.html +25 -0
  138. ledger/templates/ledger/partials/view-corporation-ledger/corporation-ledger-details.html +21 -0
  139. ledger/templates/ledger/partials/view-corporation-ledger/corporation-table.html +26 -0
  140. ledger/templates/ledger/partials/view-corporation-ledger/information/daily.html +18 -0
  141. ledger/templates/ledger/partials/view-corporation-ledger/information/hourly.html +18 -0
  142. ledger/templates/ledger/partials/view-corporation-ledger/information/summary.html +19 -0
  143. ledger/templates/ledger/view-administration.html +62 -0
  144. ledger/templates/ledger/view-alliance-administration.html +49 -0
  145. ledger/templates/ledger/view-alliance-ledger.html +72 -0
  146. ledger/templates/ledger/view-alliance-overview.html +131 -0
  147. ledger/templates/ledger/view-character-administration.html +42 -0
  148. ledger/templates/ledger/view-character-ledger.html +73 -0
  149. ledger/templates/ledger/view-character-overview.html +135 -0
  150. ledger/templates/ledger/view-character-planetary-overview.html +135 -0
  151. ledger/templates/ledger/view-character-planetary.html +73 -0
  152. ledger/templates/ledger/view-corporation-administration.html +42 -0
  153. ledger/templates/ledger/view-corporation-ledger.html +73 -0
  154. ledger/templates/ledger/view-corporation-overview.html +131 -0
  155. ledger/templatetags/ledger.py +3 -5
  156. ledger/tests/__init__.py +187 -0
  157. ledger/tests/test_admin.py +164 -68
  158. ledger/tests/test_auth_hook.py +31 -13
  159. ledger/tests/test_decarators.py +14 -79
  160. ledger/tests/test_discord_installed.py +0 -1
  161. ledger/tests/test_helpers/test_ledger_data.py +19 -0
  162. ledger/tests/test_managers/test_character_audit_manager.py +111 -69
  163. ledger/tests/test_managers/test_character_journal_manager.py +48 -208
  164. ledger/tests/test_managers/test_character_mining_manager.py +37 -16
  165. ledger/tests/test_managers/test_corporation_division_manager.py +66 -28
  166. ledger/tests/test_managers/test_corporation_journal_manager.py +39 -42
  167. ledger/tests/test_managers/test_general_manager.py +78 -18
  168. ledger/tests/test_managers/test_planetary_manager.py +73 -32
  169. ledger/tests/test_models/test_characteraudit.py +58 -74
  170. ledger/tests/test_models/test_characterminingledger.py +20 -26
  171. ledger/tests/test_models/test_characterwalletjournal.py +10 -33
  172. ledger/tests/test_models/test_corporationaudit.py +41 -35
  173. ledger/tests/test_models/test_corporationwalletjournal.py +35 -32
  174. ledger/tests/test_models/test_general.py +44 -11
  175. ledger/tests/test_models/test_planetary.py +14 -80
  176. ledger/tests/test_templatetags.py +2 -7
  177. ledger/tests/test_views/corporation/test_add_corp.py +16 -35
  178. ledger/tests/test_views/corporation/test_delete_corporation.py +66 -42
  179. ledger/tests/test_views/test_access.py +512 -545
  180. ledger/tests/test_views/test_add_ally.py +57 -46
  181. ledger/tests/test_views/test_add_char.py +21 -33
  182. ledger/tests/test_views/test_delete_character.py +24 -21
  183. ledger/tests/testdata/README_ESI_STUB.md +430 -0
  184. ledger/tests/testdata/esi_stub_openapi.py +511 -0
  185. ledger/tests/testdata/integrations/__init__.py +0 -0
  186. ledger/tests/testdata/{load_eveuniverse.py → integrations/eveuniverse.py} +0 -1
  187. ledger/tests/testdata/integrations/planetary.py +13 -0
  188. ledger/tests/testdata/json/factory.json +281 -0
  189. ledger/tests/testdata/json/inactive.json +281 -0
  190. ledger/tests/testdata/json/pins.json +175 -272
  191. ledger/tests/testdata/json/route.json +95 -528
  192. ledger/tests/testdata/test_esi_stub.py +468 -0
  193. ledger/tests/testdata/utils.py +601 -0
  194. ledger/thirdparty/charlink_hook.py +60 -30
  195. ledger/urls.py +0 -135
  196. ledger/views/alliance/add_ally.py +2 -4
  197. ledger/views/alliance/alliance_ledger.py +64 -147
  198. ledger/views/character/add_char.py +8 -10
  199. ledger/views/character/character_ledger.py +60 -126
  200. ledger/views/character/planetary.py +5 -98
  201. ledger/views/corporation/add_corp.py +10 -12
  202. ledger/views/corporation/corporation_ledger.py +65 -327
  203. ledger/views/index.py +92 -30
  204. aa_ledger-1.0.3.dist-info/RECORD +0 -236
  205. ledger/api/api_helper/planetary_helper.py +0 -107
  206. ledger/api/ledger/__init__.py +0 -7
  207. ledger/api/ledger/planetary.py +0 -231
  208. ledger/helpers/alliance.py +0 -317
  209. ledger/helpers/character.py +0 -251
  210. ledger/helpers/core.py +0 -665
  211. ledger/helpers/corporation.py +0 -427
  212. ledger/helpers/data_exporter.py +0 -452
  213. ledger/static/ledger/js/planetary-confirm.js +0 -66
  214. ledger/static/ledger/js/planetary.js +0 -143
  215. ledger/templates/ledger/admin.html +0 -43
  216. ledger/templates/ledger/allyledger/admin/alliance_administration.html +0 -46
  217. ledger/templates/ledger/allyledger/admin/alliance_overview.html +0 -108
  218. ledger/templates/ledger/allyledger/alliance_ledger.html +0 -86
  219. ledger/templates/ledger/bundles/character-ledger-bundles.html +0 -66
  220. ledger/templates/ledger/bundles/corporation-ledger-bundles.html +0 -75
  221. ledger/templates/ledger/bundles/ledger-bundles.html +0 -23
  222. ledger/templates/ledger/bundles/ledger-css.html +0 -3
  223. ledger/templates/ledger/bundles/planetary-bundles.html +0 -50
  224. ledger/templates/ledger/bundles/table-css.html +0 -3
  225. ledger/templates/ledger/charledger/admin/character_administration.html +0 -39
  226. ledger/templates/ledger/charledger/admin/character_overview.html +0 -106
  227. ledger/templates/ledger/charledger/character_ledger.html +0 -94
  228. ledger/templates/ledger/charledger/planetary/admin/planetary_overview.html +0 -123
  229. ledger/templates/ledger/charledger/planetary/planetary_ledger.html +0 -54
  230. ledger/templates/ledger/corpledger/admin/corporation_administration.html +0 -39
  231. ledger/templates/ledger/corpledger/admin/corporation_overview.html +0 -108
  232. ledger/templates/ledger/corpledger/corporation_ledger.html +0 -129
  233. ledger/templates/ledger/data-export.html +0 -78
  234. ledger/templates/ledger/error.html +0 -31
  235. ledger/templates/ledger/partials/form/error-message.html +0 -1
  236. ledger/templates/ledger/partials/information/daily.html +0 -56
  237. ledger/templates/ledger/partials/information/day.html +0 -48
  238. ledger/templates/ledger/partials/information/error.html +0 -8
  239. ledger/templates/ledger/partials/information/hourly.html +0 -53
  240. ledger/templates/ledger/partials/information/summary.html +0 -88
  241. ledger/templates/ledger/partials/information/view_character_content.html +0 -35
  242. ledger/templates/ledger/partials/modal/switchalarm_confirm.html +0 -39
  243. ledger/templates/ledger/partials/modal/view_extractor.html +0 -48
  244. ledger/templates/ledger/partials/modal/view_factory.html +0 -123
  245. ledger/templates/ledger/partials/table/char-ledger.html +0 -85
  246. ledger/templates/ledger/partials/table/corp-ledger.html +0 -66
  247. ledger/templates/ledger/partials/table/planetary.html +0 -18
  248. ledger/templates/ledger/partials/thirdparty/billboard.html +0 -22
  249. ledger/templates/ledger/partials/view/card.html +0 -160
  250. ledger/templates/ledger/permission.html +0 -2
  251. ledger/tests/test_helpers/test_billboard.py +0 -11
  252. ledger/tests/test_helpers/test_data_exporter.py +0 -207
  253. ledger/tests/test_tasks.py +0 -282
  254. ledger/tests/test_view_helpers/test_core.py +0 -47
  255. ledger/tests/test_views/corporation/test_corporation.py +0 -267
  256. ledger/tests/test_views/test_planetary.py +0 -137
  257. ledger/tests/testdata/esi_stub.py +0 -109
  258. ledger/tests/testdata/esi_stub_migration.py +0 -80
  259. ledger/tests/testdata/generate_characteraudit.py +0 -106
  260. ledger/tests/testdata/generate_corporationaudit.py +0 -74
  261. ledger/tests/testdata/generate_events.py +0 -31
  262. ledger/tests/testdata/generate_miningledger.py +0 -13
  263. ledger/tests/testdata/generate_planets.py +0 -48
  264. ledger/tests/testdata/generate_walletjournal.py +0 -42
  265. ledger/tests/testdata/json/czarno-pins.json +0 -240
  266. ledger/tests/testdata/json/czarno-routes.json +0 -165
  267. ledger/tests/testdata/json/pins2.json +0 -538
  268. {aa_ledger-1.0.3.dist-info → aa_ledger-2.0.0.dist-info}/licenses/LICENSE +0 -0
  269. /ledger/{tests/test_view_helpers → api/helpers}/__init__.py +0 -0
  270. /ledger/templates/ledger/bundles/{ally-administration-bundles.html → view-alliance-administration-js.html} +0 -0
  271. /ledger/templates/ledger/bundles/{char-administration-bundles.html → view-character-administration-js.html} +0 -0
  272. /ledger/templates/ledger/bundles/{corp-administration-bundles.html → view-corporation-administration-js.html} +0 -0
  273. /ledger/templates/ledger/partials/{administration → view-alliance-administration}/alliance.html +0 -0
  274. /ledger/tests/testdata/{esi.json → esi_test_data.json} +0 -0
  275. /ledger/tests/testdata/{allianceauth.json → integrations/allianceauth.json} +0 -0
  276. /ledger/tests/testdata/{load_allianceauth.py → integrations/allianceauth.py} +0 -0
  277. /ledger/tests/testdata/{eveentity.json → integrations/eveentity.json} +0 -0
  278. /ledger/tests/testdata/{load_eveentity.py → integrations/eveentity.py} +0 -0
  279. /ledger/tests/testdata/{eveuniverse.json → integrations/eveuniverse.json} +0 -0
  280. /ledger/tests/testdata/{planetary.json → integrations/planetary.json} +0 -0
@@ -0,0 +1,59 @@
1
+ /*!
2
+ * Bootstrap 5 styling wrapper for FixedHeader
3
+ * © SpryMedia Ltd - datatables.net/license
4
+ */
5
+
6
+ (function( factory ){
7
+ if ( typeof define === 'function' && define.amd ) {
8
+ // AMD
9
+ define( ['jquery', 'datatables.net-bs5', 'datatables.net-fixedheader'], function ( $ ) {
10
+ return factory( $, window, document );
11
+ } );
12
+ }
13
+ else if ( typeof exports === 'object' ) {
14
+ // CommonJS
15
+ var jq = require('jquery');
16
+ var cjsRequires = function (root, $) {
17
+ if ( ! $.fn.dataTable ) {
18
+ require('datatables.net-bs5')(root, $);
19
+ }
20
+
21
+ if ( ! $.fn.dataTable.FixedHeader ) {
22
+ require('datatables.net-fixedheader')(root, $);
23
+ }
24
+ };
25
+
26
+ if (typeof window === 'undefined') {
27
+ module.exports = function (root, $) {
28
+ if ( ! root ) {
29
+ // CommonJS environments without a window global must pass a
30
+ // root. This will give an error otherwise
31
+ root = window;
32
+ }
33
+
34
+ if ( ! $ ) {
35
+ $ = jq( root );
36
+ }
37
+
38
+ cjsRequires( root, $ );
39
+ return factory( $, root, root.document );
40
+ };
41
+ }
42
+ else {
43
+ cjsRequires( window, jq );
44
+ module.exports = factory( jq, window, window.document );
45
+ }
46
+ }
47
+ else {
48
+ // Browser
49
+ factory( jQuery, window, document );
50
+ }
51
+ }(function( $, window, document ) {
52
+ 'use strict';
53
+ var DataTable = $.fn.dataTable;
54
+
55
+
56
+
57
+
58
+ return DataTable;
59
+ }));
ledger/tasks.py CHANGED
@@ -5,7 +5,7 @@ import inspect
5
5
  from collections.abc import Callable
6
6
 
7
7
  # Third Party
8
- from celery import chain, shared_task
8
+ from celery import Task, chain, shared_task
9
9
 
10
10
  # Django
11
11
  from django.db.models import Min
@@ -13,23 +13,23 @@ from django.utils.html import format_html
13
13
  from django.utils.translation import gettext_lazy as _
14
14
 
15
15
  # Alliance Auth
16
- from allianceauth.authentication.models import CharacterOwnership, User
16
+ from allianceauth.authentication.models import CharacterOwnership
17
17
  from allianceauth.services.hooks import get_extension_logger
18
18
  from allianceauth.services.tasks import QueueOnce
19
19
 
20
- # Alliance Auth (External Libs)
21
- from app_utils.logging import LoggerAddTag
22
-
23
20
  # AA Ledger
24
21
  from ledger import __title__, app_settings
25
- from ledger.decorators import when_esi_is_available
26
- from ledger.helpers import data_exporter
27
22
  from ledger.helpers.discord import send_user_notification
28
- from ledger.models.characteraudit import CharacterAudit
29
- from ledger.models.corporationaudit import CorporationAudit
23
+ from ledger.models.characteraudit import CharacterOwner
24
+ from ledger.models.corporationaudit import CorporationOwner
25
+ from ledger.models.helpers.update_manager import (
26
+ CharacterUpdateSection,
27
+ CorporationUpdateSection,
28
+ )
30
29
  from ledger.models.planetary import CharacterPlanetDetails
30
+ from ledger.providers import AppLogger, retry_task_on_esi_error
31
31
 
32
- logger = LoggerAddTag(get_extension_logger(__name__), __title__)
32
+ logger = AppLogger(get_extension_logger(__name__), __title__)
33
33
 
34
34
  MAX_RETRIES_DEFAULT = 3
35
35
 
@@ -39,17 +39,23 @@ TASK_DEFAULTS = {
39
39
  "max_retries": MAX_RETRIES_DEFAULT,
40
40
  }
41
41
 
42
+ # Default params for tasks that need bind=True.
43
+ TASK_DEFAULTS_BIND = {**TASK_DEFAULTS, **{"bind": True}}
44
+
45
+ # Default params for tasks that need bind=True and run once only.
46
+ TASK_DEFAULTS_BIND_ONCE = {**TASK_DEFAULTS, **{"bind": True, "base": QueueOnce}}
47
+
42
48
  # Default params for tasks that need run once only.
43
49
  TASK_DEFAULTS_ONCE = {**TASK_DEFAULTS, **{"base": QueueOnce}}
44
50
 
45
- _update_ledger_char_params = {
46
- **TASK_DEFAULTS_ONCE,
47
- **{"once": {"keys": ["character_pk", "force_refresh"], "graceful": True}},
51
+ TASK_DEFAULTS_BIND_ONCE_CHARACTER = {
52
+ **TASK_DEFAULTS_BIND_ONCE,
53
+ **{"once": {"keys": ["character_pk"], "graceful": True}},
48
54
  }
49
55
 
50
- _update_ledger_corp_params = {
51
- **TASK_DEFAULTS_ONCE,
52
- **{"once": {"keys": ["corporation_pk", "force_refresh"], "graceful": True}},
56
+ TASK_DEFAULTS_BIND_ONCE_CORPORATION = {
57
+ **TASK_DEFAULTS_BIND_ONCE,
58
+ **{"once": {"keys": ["corporation_pk"], "graceful": True}},
53
59
  }
54
60
 
55
61
 
@@ -60,9 +66,13 @@ def check_planetary_alarms(runs: int = 0):
60
66
  owner_ids = {}
61
67
  warnings = {}
62
68
 
63
- for planet in all_planets:
64
- if planet.is_expired and not planet.notification_sent and planet.notification:
65
- character_id = planet.planet.character.eve_character.character_id
69
+ for planet_details in all_planets:
70
+ if (
71
+ planet_details.is_expired
72
+ and not planet_details.notification_sent
73
+ and planet_details.notification
74
+ ):
75
+ character_id = planet_details.planet.character.eve_character.character_id
66
76
 
67
77
  try:
68
78
  owner = CharacterOwnership.objects.get(
@@ -82,16 +92,16 @@ def check_planetary_alarms(runs: int = 0):
82
92
  continue
83
93
 
84
94
  msg = _("%(charname)s on %(planetname)s") % {
85
- "charname": planet.planet.character.eve_character.character_name,
86
- "planetname": planet.planet.planet.name,
95
+ "charname": planet_details.planet.character.eve_character.character_name,
96
+ "planetname": planet_details.planet.eve_planet.name,
87
97
  }
88
98
 
89
99
  if main_id not in warnings:
90
100
  warnings[main_id] = []
91
101
 
92
102
  warnings[main_id].append(msg)
93
- planet.notification_sent = True
94
- planet.save()
103
+ planet_details.notification_sent = True
104
+ planet_details.save()
95
105
 
96
106
  if warnings:
97
107
  for main_id, messages in warnings.items():
@@ -117,12 +127,12 @@ def check_planetary_alarms(runs: int = 0):
117
127
 
118
128
 
119
129
  @shared_task(**TASK_DEFAULTS_ONCE)
120
- @when_esi_is_available
121
130
  def update_all_characters(runs: int = 0, force_refresh=False):
122
131
  """Update all characters"""
123
132
  # Disable characters with no owner
124
- CharacterAudit.objects.disable_characters_with_no_owner()
125
- characters = CharacterAudit.objects.select_related("eve_character").filter(active=1)
133
+ CharacterOwner.objects.disable_characters_with_no_owner()
134
+
135
+ characters = CharacterOwner.objects.select_related("eve_character").filter(active=1)
126
136
  for char in characters:
127
137
  update_character.apply_async(
128
138
  args=[char.pk], kwargs={"force_refresh": force_refresh}
@@ -132,12 +142,13 @@ def update_all_characters(runs: int = 0, force_refresh=False):
132
142
 
133
143
 
134
144
  @shared_task(**TASK_DEFAULTS_ONCE)
135
- @when_esi_is_available
136
145
  def update_subset_characters(subset=2, min_runs=50, max_runs=500, force_refresh=False):
137
146
  """Update a batch of characters to prevent overload ESI"""
138
147
  # Disable characters with no owner
139
- CharacterAudit.objects.disable_characters_with_no_owner()
140
- total_characters = CharacterAudit.objects.filter(active=1).count()
148
+ CharacterOwner.objects.disable_characters_with_no_owner()
149
+
150
+ # Calculate number of characters to update
151
+ total_characters = CharacterOwner.objects.filter(active=1).count()
141
152
  characters_count = min(max(total_characters // subset, min_runs), total_characters)
142
153
 
143
154
  # Limit the number of characters to update to prevent overload ESI
@@ -145,7 +156,7 @@ def update_subset_characters(subset=2, min_runs=50, max_runs=500, force_refresh=
145
156
 
146
157
  # Annotate characters with the oldest `last_run_finished` across all update sections
147
158
  characters = (
148
- CharacterAudit.objects.filter(active=1)
159
+ CharacterOwner.objects.filter(active=1)
149
160
  .annotate(oldest_update=Min("ledger_update_status__last_run_finished_at"))
150
161
  .order_by("oldest_update")
151
162
  .distinct()[:characters_count]
@@ -158,13 +169,30 @@ def update_subset_characters(subset=2, min_runs=50, max_runs=500, force_refresh=
158
169
  logger.debug("Queued %s Character Audit Tasks", len(characters))
159
170
 
160
171
 
161
- @shared_task(**TASK_DEFAULTS_ONCE)
162
- @when_esi_is_available
163
- def update_character(character_pk: int, force_refresh=False):
164
- character = CharacterAudit.objects.prefetch_related("ledger_update_status").get(
172
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CHARACTER)
173
+ def update_character(
174
+ self: Task, character_pk: int, force_refresh=False
175
+ ) -> bool: # pylint: disable=unused-argument
176
+ """Update a character owner
177
+
178
+ Args:
179
+ character_pk (int): Primary key of the CharacterOwner to update
180
+ force_refresh (bool): Whether to force a refresh of all sections
181
+
182
+ Returns:
183
+ True if the task was successful, False otherwise
184
+ """
185
+ character = CharacterOwner.objects.prefetch_related("ledger_update_status").get(
165
186
  pk=character_pk
166
187
  )
167
188
 
189
+ if character.is_orphan:
190
+ logger.info(
191
+ "Character %s is an orphan. Skipping update.",
192
+ character,
193
+ )
194
+ return False
195
+
168
196
  que = []
169
197
  priority = 7
170
198
 
@@ -175,15 +203,15 @@ def update_character(character_pk: int, force_refresh=False):
175
203
 
176
204
  if force_refresh:
177
205
  # Reset Token Error if we are forcing a refresh
178
- character.reset_has_token_error()
206
+ character.update_manager.reset_has_token_error()
179
207
 
180
- needs_update = character.calc_update_needed()
208
+ needs_update = character.update_manager.calc_update_needed()
181
209
 
182
210
  if not needs_update and not force_refresh:
183
211
  logger.info("No updates needed for %s", character.eve_character.character_name)
184
- return
212
+ return False
185
213
 
186
- sections = character.UpdateSection.get_sections()
214
+ sections = CharacterUpdateSection.get_sections()
187
215
 
188
216
  for section in sections:
189
217
  # Skip sections that are not in the needs_update list
@@ -207,59 +235,62 @@ def update_character(character_pk: int, force_refresh=False):
207
235
  len(que),
208
236
  character.eve_character.character_name,
209
237
  )
238
+ return True
210
239
 
211
240
 
212
- @shared_task(**_update_ledger_char_params)
213
- @when_esi_is_available
214
- def update_char_wallet_journal(character_pk: int, force_refresh: bool):
241
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CHARACTER)
242
+ def update_char_wallet_journal(self: Task, character_pk: int, force_refresh: bool):
215
243
  return _update_character_section(
216
- character_pk,
217
- section=CharacterAudit.UpdateSection.WALLET_JOURNAL,
244
+ task=self,
245
+ character_pk=character_pk,
246
+ section=CharacterUpdateSection.WALLET_JOURNAL,
218
247
  force_refresh=force_refresh,
219
248
  )
220
249
 
221
250
 
222
- @shared_task(**_update_ledger_char_params)
223
- @when_esi_is_available
224
- def update_char_mining_ledger(character_pk: int, force_refresh: bool):
251
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CHARACTER)
252
+ def update_char_mining_ledger(self: Task, character_pk: int, force_refresh: bool):
225
253
  return _update_character_section(
226
- character_pk,
227
- section=CharacterAudit.UpdateSection.MINING_LEDGER,
254
+ task=self,
255
+ character_pk=character_pk,
256
+ section=CharacterUpdateSection.MINING_LEDGER,
228
257
  force_refresh=force_refresh,
229
258
  )
230
259
 
231
260
 
232
- @shared_task(**_update_ledger_char_params)
233
- @when_esi_is_available
234
- def update_char_planets(character_pk: int, force_refresh: bool):
261
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CHARACTER)
262
+ def update_char_planets(self: Task, character_pk: int, force_refresh: bool):
235
263
  logger.debug("Updating Planet Data for %s", character_pk)
236
264
  return _update_character_section(
237
- character_pk,
238
- section=CharacterAudit.UpdateSection.PLANETS,
265
+ task=self,
266
+ character_pk=character_pk,
267
+ section=CharacterUpdateSection.PLANETS,
239
268
  force_refresh=force_refresh,
240
269
  )
241
270
 
242
271
 
243
- @shared_task(**_update_ledger_char_params)
244
- @when_esi_is_available
245
- def update_char_planets_details(character_pk: int, force_refresh: bool):
272
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CHARACTER)
273
+ def update_char_planets_details(self: Task, character_pk: int, force_refresh: bool):
246
274
  logger.debug("Updating Planet Details for %s", character_pk)
247
275
  return _update_character_section(
248
- character_pk,
249
- section=CharacterAudit.UpdateSection.PLANETS_DETAILS,
276
+ task=self,
277
+ character_pk=character_pk,
278
+ section=CharacterUpdateSection.PLANETS_DETAILS,
250
279
  force_refresh=force_refresh,
251
280
  )
252
281
 
253
282
 
254
- def _update_character_section(character_pk: int, section: str, force_refresh: bool):
283
+ def _update_character_section(
284
+ task: Task, character_pk: int, section: str, force_refresh: bool
285
+ ):
255
286
  """Update a specific section of the character audit."""
256
- section = CharacterAudit.UpdateSection(section)
257
- character = CharacterAudit.objects.get(pk=character_pk)
287
+ section = CharacterUpdateSection(section)
288
+ character = CharacterOwner.objects.get(pk=character_pk)
258
289
  logger.debug(
259
290
  "Updating %s for %s", section.label, character.eve_character.character_name
260
291
  )
261
292
 
262
- character.reset_update_status(section)
293
+ character.update_manager.reset_update_status(section)
263
294
 
264
295
  method: Callable = getattr(character, section.method_name)
265
296
  method_signature = inspect.signature(method)
@@ -268,15 +299,18 @@ def _update_character_section(character_pk: int, section: str, force_refresh: bo
268
299
  kwargs = {"force_refresh": force_refresh}
269
300
  else:
270
301
  kwargs = {}
271
- result = character.perform_update_status(section, method, **kwargs)
272
- character.update_section_log(section, result)
302
+
303
+ with retry_task_on_esi_error(task):
304
+ result = character.update_manager.perform_update_status(
305
+ section, method, **kwargs
306
+ )
307
+ character.update_manager.update_section_log(section, result)
273
308
 
274
309
 
275
310
  # Corporation Audit - Tasks
276
311
  @shared_task(**TASK_DEFAULTS_ONCE)
277
- @when_esi_is_available
278
312
  def update_all_corporations(runs: int = 0, force_refresh=False):
279
- corps = CorporationAudit.objects.select_related("corporation").filter(active=1)
313
+ corps = CorporationOwner.objects.filter(active=1)
280
314
  for corp in corps:
281
315
  update_corporation.apply_async(
282
316
  args=[corp.pk], kwargs={"force_refresh": force_refresh}
@@ -286,12 +320,11 @@ def update_all_corporations(runs: int = 0, force_refresh=False):
286
320
 
287
321
 
288
322
  @shared_task(**TASK_DEFAULTS_ONCE)
289
- @when_esi_is_available
290
323
  def update_subset_corporations(
291
324
  subset=5, min_runs=20, max_runs=200, force_refresh=False
292
325
  ):
293
326
  """Update a batch of corporations to prevent overload ESI"""
294
- total_corporations = CorporationAudit.objects.filter(active=1).count()
327
+ total_corporations = CorporationOwner.objects.filter(active=1).count()
295
328
  corporations_count = min(
296
329
  max(total_corporations // subset, min_runs), total_corporations
297
330
  )
@@ -301,7 +334,7 @@ def update_subset_corporations(
301
334
 
302
335
  # Annotate corporations with the oldest `last_run_finished` across all update sections
303
336
  corporations = (
304
- CorporationAudit.objects.filter(active=1)
337
+ CorporationOwner.objects.filter(active=1)
305
338
  .annotate(
306
339
  oldest_update=Min("ledger_corporation_update_status__last_run_finished_at")
307
340
  )
@@ -316,12 +349,20 @@ def update_subset_corporations(
316
349
  logger.debug("Queued %s Corporation Audit Tasks", len(corporations))
317
350
 
318
351
 
319
- @shared_task(**TASK_DEFAULTS_ONCE)
320
- @when_esi_is_available
352
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CORPORATION)
321
353
  def update_corporation(
322
- corporation_pk, force_refresh=False
323
- ): # pylint: disable=unused-argument
324
- corporation = CorporationAudit.objects.prefetch_related(
354
+ self: Task, corporation_pk, force_refresh=False
355
+ ) -> bool: # pylint: disable=unused-argument
356
+ """Update a corporation owner
357
+
358
+ Args:
359
+ corporation_pk (int): Primary key of the CorporationOwner to update
360
+ force_refresh (bool): Whether to force a refresh of all sections
361
+
362
+ Returns:
363
+ True if the task was successful, False otherwise
364
+ """
365
+ corporation = CorporationOwner.objects.prefetch_related(
325
366
  "ledger_corporation_update_status"
326
367
  ).get(pk=corporation_pk)
327
368
 
@@ -330,29 +371,29 @@ def update_corporation(
330
371
 
331
372
  logger.debug(
332
373
  "Processing Audit Updates for %s",
333
- format(corporation.corporation.corporation_name),
374
+ format(corporation.eve_corporation.corporation_name),
334
375
  )
335
376
 
336
377
  if force_refresh:
337
378
  # Reset Token Error if we are forcing a refresh
338
- corporation.reset_has_token_error()
379
+ corporation.update_manager.reset_has_token_error()
339
380
 
340
- needs_update = corporation.calc_update_needed()
381
+ needs_update = corporation.update_manager.calc_update_needed()
341
382
 
342
383
  if not needs_update and not force_refresh:
343
384
  logger.info(
344
- "No updates needed for %s", corporation.corporation.corporation_name
385
+ "No updates needed for %s", corporation.eve_corporation.corporation_name
345
386
  )
346
- return
387
+ return False
347
388
 
348
- sections = corporation.UpdateSection.get_sections()
389
+ sections = CorporationUpdateSection.get_sections()
349
390
 
350
391
  for section in sections:
351
392
  # Skip sections that are not in the needs_update list
352
393
  if not force_refresh and not needs_update.for_section(section):
353
394
  logger.debug(
354
395
  "No updates needed for %s (%s)",
355
- corporation.corporation.corporation_name,
396
+ corporation.eve_corporation.corporation_name,
356
397
  section,
357
398
  )
358
399
  continue
@@ -367,49 +408,56 @@ def update_corporation(
367
408
  logger.debug(
368
409
  "Queued %s Audit Updates for %s",
369
410
  len(que),
370
- corporation.corporation.corporation_name,
411
+ corporation.eve_corporation.corporation_name,
371
412
  )
413
+ return True
372
414
 
373
415
 
374
- @shared_task(**_update_ledger_corp_params)
375
- @when_esi_is_available
376
- def update_corp_wallet_division_names(corporation_pk: int, force_refresh: bool):
416
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CORPORATION)
417
+ def update_corp_wallet_division_names(
418
+ self: Task, corporation_pk: int, force_refresh: bool
419
+ ):
377
420
  return _update_corporation_section(
378
- corporation_pk,
379
- section=CorporationAudit.UpdateSection.WALLET_DIVISION_NAMES,
421
+ task=self,
422
+ corporation_pk=corporation_pk,
423
+ section=CorporationUpdateSection.WALLET_DIVISION_NAMES,
380
424
  force_refresh=force_refresh,
381
425
  )
382
426
 
383
427
 
384
- @shared_task(**_update_ledger_corp_params)
385
- @when_esi_is_available
386
- def update_corp_wallet_division(corporation_pk: int, force_refresh: bool):
428
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CORPORATION)
429
+ def update_corp_wallet_division(self: Task, corporation_pk: int, force_refresh: bool):
387
430
  return _update_corporation_section(
388
- corporation_pk,
389
- section=CorporationAudit.UpdateSection.WALLET_DIVISION,
431
+ task=self,
432
+ corporation_pk=corporation_pk,
433
+ section=CorporationUpdateSection.WALLET_DIVISION,
390
434
  force_refresh=force_refresh,
391
435
  )
392
436
 
393
437
 
394
- @shared_task(**_update_ledger_corp_params)
395
- @when_esi_is_available
396
- def update_corp_wallet_journal(corporation_pk: int, force_refresh: bool):
438
+ @shared_task(**TASK_DEFAULTS_BIND_ONCE_CORPORATION)
439
+ def update_corp_wallet_journal(self: Task, corporation_pk: int, force_refresh: bool):
397
440
  return _update_corporation_section(
398
- corporation_pk,
399
- section=CorporationAudit.UpdateSection.WALLET_JOURNAL,
441
+ task=self,
442
+ corporation_pk=corporation_pk,
443
+ section=CorporationUpdateSection.WALLET_JOURNAL,
400
444
  force_refresh=force_refresh,
401
445
  )
402
446
 
403
447
 
404
- def _update_corporation_section(corporation_pk: int, section: str, force_refresh: bool):
448
+ def _update_corporation_section(
449
+ task: Task, corporation_pk: int, section: str, force_refresh: bool
450
+ ):
405
451
  """Update a specific section of the character audit."""
406
- section = CorporationAudit.UpdateSection(section)
407
- corporation = CorporationAudit.objects.get(pk=corporation_pk)
452
+ section = CorporationUpdateSection(section)
453
+ corporation = CorporationOwner.objects.get(pk=corporation_pk)
408
454
  logger.debug(
409
- "Updating %s for %s", section.label, corporation.corporation.corporation_name
455
+ "Updating %s for %s",
456
+ section.label,
457
+ corporation.eve_corporation.corporation_name,
410
458
  )
411
459
 
412
- corporation.reset_update_status(section)
460
+ corporation.update_manager.reset_update_status(section)
413
461
 
414
462
  method: Callable = getattr(corporation, section.method_name)
415
463
  method_signature = inspect.signature(method)
@@ -419,12 +467,16 @@ def _update_corporation_section(corporation_pk: int, section: str, force_refresh
419
467
  else:
420
468
  kwargs = {}
421
469
 
422
- result = corporation.perform_update_status(section, method, **kwargs)
423
- corporation.update_section_log(section, result)
470
+ with retry_task_on_esi_error(task):
471
+ result = corporation.update_manager.perform_update_status(
472
+ section, method, **kwargs
473
+ )
474
+
475
+ corporation.update_manager.update_section_log(section, result)
424
476
 
425
477
 
426
478
  @shared_task(**TASK_DEFAULTS_ONCE)
427
- def clear_all_etags():
479
+ def clear_all_cache():
428
480
  logger.debug("Clearing all etags")
429
481
  try:
430
482
  # Third Party
@@ -446,44 +498,3 @@ def clear_all_etags():
446
498
  logger.info("Deleted %s etag keys", deleted)
447
499
  else:
448
500
  logger.info("No etag keys to delete")
449
-
450
-
451
- @shared_task(**TASK_DEFAULTS_ONCE)
452
- # pylint: disable=too-many-positional-arguments
453
- def export_data_ledger(
454
- user_pk: int,
455
- ledger_type: str,
456
- entity_id: int,
457
- division_id: int = None,
458
- year: int = None,
459
- month: int = None,
460
- ):
461
- """Export data for a ledger."""
462
- msg = data_exporter.export_ledger_to_archive(
463
- ledger_type, entity_id, division_id, year, month
464
- )
465
-
466
- try:
467
- user = User.objects.get(pk=user_pk)
468
- except User.DoesNotExist:
469
- logger.debug("User with pk %s does not exist", user_pk)
470
- return
471
-
472
- if not msg:
473
- title = _(f"{ledger_type.capitalize()} Data Export Ready")
474
- message = _(
475
- f"Your data export for topic {ledger_type} is ready. You can download it from the Data Export page.",
476
- )
477
- else:
478
- title = _(f"{ledger_type.capitalize()} Data Export Failed")
479
- message = _(
480
- f"Your data export for topic {ledger_type} has failed with following error: {msg}",
481
- )
482
-
483
- send_user_notification.delay(
484
- user_id=user.pk,
485
- title=title,
486
- message=message,
487
- embed_message=True,
488
- level="info",
489
- )