aa-ledger 0.9.9__py3-none-any.whl → 0.9.9.1__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.
- {aa_ledger-0.9.9.dist-info → aa_ledger-0.9.9.1.dist-info}/METADATA +1 -1
- {aa_ledger-0.9.9.dist-info → aa_ledger-0.9.9.1.dist-info}/RECORD +77 -77
- ledger/__init__.py +9 -9
- ledger/api/api_helper/billboard_helper.py +277 -277
- ledger/api/ledger/admin.py +289 -289
- ledger/app_settings.py +50 -50
- ledger/constants.py +5 -0
- ledger/decorators.py +92 -11
- ledger/helpers/alliance.py +353 -334
- ledger/helpers/character.py +260 -260
- ledger/helpers/core.py +565 -565
- ledger/helpers/corporation.py +455 -421
- ledger/helpers/etag.py +237 -237
- ledger/helpers/ref_type.py +475 -475
- ledger/locale/cs_CZ/LC_MESSAGES/django.po +942 -942
- ledger/locale/de/LC_MESSAGES/django.po +961 -961
- ledger/locale/django.pot +942 -942
- ledger/locale/es/LC_MESSAGES/django.po +943 -943
- ledger/locale/fr_FR/LC_MESSAGES/django.po +942 -942
- ledger/locale/it_IT/LC_MESSAGES/django.po +942 -942
- ledger/locale/ja/LC_MESSAGES/django.po +943 -943
- ledger/locale/ko_KR/LC_MESSAGES/django.po +942 -942
- ledger/locale/nl_NL/LC_MESSAGES/django.po +942 -942
- ledger/locale/pl_PL/LC_MESSAGES/django.po +942 -942
- ledger/locale/ru/LC_MESSAGES/django.po +945 -945
- ledger/locale/sk/LC_MESSAGES/django.po +944 -944
- ledger/locale/uk/LC_MESSAGES/django.po +946 -946
- ledger/locale/zh_Hans/LC_MESSAGES/django.po +943 -943
- ledger/managers/character_mining_manager.py +239 -239
- ledger/managers/character_planetary_manager.py +1 -1
- ledger/migrations/0016_characterminingledger_price_per_unit.py +21 -21
- ledger/models/characteraudit.py +496 -496
- ledger/static/ledger/css/cards.css +1 -1
- ledger/static/ledger/css/table.css +1 -1
- ledger/static/ledger/js/charts.js +221 -221
- ledger/static/ledger/js/planetary.js +143 -143
- ledger/tasks.py +442 -449
- ledger/templates/ledger/allyledger/admin/alliance_administration.html +46 -46
- ledger/templates/ledger/allyledger/admin/alliance_overview.html +108 -108
- ledger/templates/ledger/allyledger/alliance_ledger.html +86 -86
- ledger/templates/ledger/bundles/ally-administration-bundles.html +59 -59
- ledger/templates/ledger/bundles/char-administration-bundles.html +66 -66
- ledger/templates/ledger/bundles/character-ledger-bundles.html +66 -66
- ledger/templates/ledger/bundles/corp-administration-bundles.html +68 -68
- ledger/templates/ledger/bundles/corporation-ledger-bundles.html +75 -75
- ledger/templates/ledger/charledger/admin/character_administration.html +39 -39
- ledger/templates/ledger/charledger/admin/character_overview.html +106 -106
- ledger/templates/ledger/charledger/character_ledger.html +94 -94
- ledger/templates/ledger/charledger/planetary/planetary_ledger.html +54 -54
- ledger/templates/ledger/corpledger/admin/corporation_administration.html +39 -39
- ledger/templates/ledger/corpledger/admin/corporation_overview.html +108 -108
- ledger/templates/ledger/corpledger/corporation_ledger.html +129 -86
- ledger/templates/ledger/partials/administration/alliance.html +37 -37
- ledger/templates/ledger/partials/administration/alliance_corporations.html +58 -58
- ledger/templates/ledger/partials/administration/corporation_characters.html +34 -34
- ledger/templates/ledger/partials/information/daily.html +56 -56
- ledger/templates/ledger/partials/information/day.html +48 -48
- ledger/templates/ledger/partials/information/hourly.html +53 -53
- ledger/templates/ledger/partials/information/summary.html +88 -88
- ledger/templates/ledger/partials/information/view_character_content.html +35 -35
- ledger/templates/ledger/partials/table/char-ledger.html +85 -85
- ledger/templates/ledger/partials/table/corp-ledger.html +66 -66
- ledger/templates/ledger/partials/view/card.html +160 -160
- ledger/tests/test_decarators.py +102 -17
- ledger/tests/test_helpers/test_etag.py +149 -149
- ledger/tests/test_managers/test_character_mining_manager.py +54 -54
- ledger/tests/test_models/test_characterminingledger.py +107 -106
- ledger/tests/test_tasks.py +282 -282
- ledger/tests/test_templatetags.py +5 -2
- ledger/tests/test_views/test_access.py +852 -852
- ledger/tests/testdata/esi.json +1 -2
- ledger/tests/testdata/eveuniverse.json +391 -391
- ledger/urls.py +66 -21
- ledger/views/alliance/alliance_ledger.py +203 -203
- ledger/views/corporation/corporation_ledger.py +25 -9
- {aa_ledger-0.9.9.dist-info → aa_ledger-0.9.9.1.dist-info}/WHEEL +0 -0
- {aa_ledger-0.9.9.dist-info → aa_ledger-0.9.9.1.dist-info}/licenses/LICENSE +0 -0
ledger/app_settings.py
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
"""
|
|
2
|
-
App Settings
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
# Standard Library
|
|
6
|
-
import sys
|
|
7
|
-
|
|
8
|
-
# Alliance Auth (External Libs)
|
|
9
|
-
from app_utils.app_settings import clean_setting
|
|
10
|
-
|
|
11
|
-
IS_TESTING = sys.argv[1:2] == ["test"]
|
|
12
|
-
|
|
13
|
-
# Set Test Mode True or False
|
|
14
|
-
|
|
15
|
-
# Set Naming on Auth Hook
|
|
16
|
-
LEDGER_APP_NAME = clean_setting("LEDGER_APP_NAME", "Ledger")
|
|
17
|
-
|
|
18
|
-
# zKillboard - https://zkillboard.com/
|
|
19
|
-
EVE_BASE_URL = "https://esi.evetech.net/"
|
|
20
|
-
EVE_API_URL = "https://esi.evetech.net/latest/"
|
|
21
|
-
EVE_BASE_URL_REGEX = r"^http[s]?:\/\/esi.evetech\.net\/"
|
|
22
|
-
|
|
23
|
-
# fuzzwork
|
|
24
|
-
FUZZ_BASE_URL = "https://www.fuzzwork.co.uk/"
|
|
25
|
-
FUZZ_API_URL = "https://www.fuzzwork.co.uk/api/"
|
|
26
|
-
FUZZ_BASE_URL_REGEX = r"^http[s]?:\/\/(www\.)?fuzzwork\.co\.uk\/"
|
|
27
|
-
|
|
28
|
-
# Global timeout for tasks in seconds to reduce task accumulation during outages.
|
|
29
|
-
LEDGER_TASKS_TIME_LIMIT = clean_setting("LEDGER_TASKS_TIME_LIMIT", 600)
|
|
30
|
-
|
|
31
|
-
LEDGER_STALE_TYPES = clean_setting(
|
|
32
|
-
"LEDGER_STALE_TYPES",
|
|
33
|
-
{
|
|
34
|
-
"wallet_journal": 30,
|
|
35
|
-
"wallet_division_names": 30,
|
|
36
|
-
"wallet_division": 30,
|
|
37
|
-
"mining_ledger": 30,
|
|
38
|
-
"planets": 30,
|
|
39
|
-
"planets_details": 30,
|
|
40
|
-
},
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
# Mining Price Calculation
|
|
44
|
-
LEDGER_USE_COMPRESSED = clean_setting("LEDGER_USE_COMPRESSED", True)
|
|
45
|
-
LEDGER_PRICE_PERCENTAGE = clean_setting("LEDGER_PRICE_PERCENTAGE", 0.9)
|
|
46
|
-
|
|
47
|
-
# Ledger Cache System
|
|
48
|
-
LEDGER_CACHE_STALE = 60 * 60 * 168 # 168 hours
|
|
49
|
-
LEDGER_CACHE_KEY = "LEDGER"
|
|
50
|
-
LEDGER_CACHE_ENABLED = True
|
|
1
|
+
"""
|
|
2
|
+
App Settings
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Standard Library
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
# Alliance Auth (External Libs)
|
|
9
|
+
from app_utils.app_settings import clean_setting
|
|
10
|
+
|
|
11
|
+
IS_TESTING = sys.argv[1:2] == ["test"]
|
|
12
|
+
|
|
13
|
+
# Set Test Mode True or False
|
|
14
|
+
|
|
15
|
+
# Set Naming on Auth Hook
|
|
16
|
+
LEDGER_APP_NAME = clean_setting("LEDGER_APP_NAME", "Ledger")
|
|
17
|
+
|
|
18
|
+
# zKillboard - https://zkillboard.com/
|
|
19
|
+
EVE_BASE_URL = "https://esi.evetech.net/"
|
|
20
|
+
EVE_API_URL = "https://esi.evetech.net/latest/"
|
|
21
|
+
EVE_BASE_URL_REGEX = r"^http[s]?:\/\/esi.evetech\.net\/"
|
|
22
|
+
|
|
23
|
+
# fuzzwork
|
|
24
|
+
FUZZ_BASE_URL = "https://www.fuzzwork.co.uk/"
|
|
25
|
+
FUZZ_API_URL = "https://www.fuzzwork.co.uk/api/"
|
|
26
|
+
FUZZ_BASE_URL_REGEX = r"^http[s]?:\/\/(www\.)?fuzzwork\.co\.uk\/"
|
|
27
|
+
|
|
28
|
+
# Global timeout for tasks in seconds to reduce task accumulation during outages.
|
|
29
|
+
LEDGER_TASKS_TIME_LIMIT = clean_setting("LEDGER_TASKS_TIME_LIMIT", 600)
|
|
30
|
+
|
|
31
|
+
LEDGER_STALE_TYPES = clean_setting(
|
|
32
|
+
"LEDGER_STALE_TYPES",
|
|
33
|
+
{
|
|
34
|
+
"wallet_journal": 30,
|
|
35
|
+
"wallet_division_names": 30,
|
|
36
|
+
"wallet_division": 30,
|
|
37
|
+
"mining_ledger": 30,
|
|
38
|
+
"planets": 30,
|
|
39
|
+
"planets_details": 30,
|
|
40
|
+
},
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Mining Price Calculation
|
|
44
|
+
LEDGER_USE_COMPRESSED = clean_setting("LEDGER_USE_COMPRESSED", True)
|
|
45
|
+
LEDGER_PRICE_PERCENTAGE = clean_setting("LEDGER_PRICE_PERCENTAGE", 0.9)
|
|
46
|
+
|
|
47
|
+
# Ledger Cache System
|
|
48
|
+
LEDGER_CACHE_STALE = 60 * 60 * 168 # 168 hours
|
|
49
|
+
LEDGER_CACHE_KEY = "LEDGER"
|
|
50
|
+
LEDGER_CACHE_ENABLED = True
|
ledger/constants.py
CHANGED
|
@@ -139,6 +139,11 @@ P3_PRODUCTS = [
|
|
|
139
139
|
P4_PRODUCTS = [2867, 2868, 2869, 2870, 2871, 2872, 2875, 2876]
|
|
140
140
|
P5_PRODUCTS = []
|
|
141
141
|
|
|
142
|
+
NPC_ENTITIES = [
|
|
143
|
+
1000125, # Concord Bounties (Bounty Prizes, ESS
|
|
144
|
+
1000132, # Secure Commerce Commission (Market Fees)
|
|
145
|
+
1000413, # Air Laboratories (Daily Login Rewards, etc.)
|
|
146
|
+
]
|
|
142
147
|
|
|
143
148
|
BOUNTY_PRIZES = ["bounty_prizes"]
|
|
144
149
|
ESS_TRANSFER = ["ess_escrow_transfer"]
|
ledger/decorators.py
CHANGED
|
@@ -4,13 +4,15 @@ Decorators
|
|
|
4
4
|
|
|
5
5
|
# Standard Library
|
|
6
6
|
import time
|
|
7
|
+
import uuid
|
|
7
8
|
from functools import wraps
|
|
8
9
|
|
|
9
10
|
# Alliance Auth
|
|
10
11
|
from allianceauth.services.hooks import get_extension_logger
|
|
11
12
|
|
|
12
13
|
# Alliance Auth (External Libs)
|
|
13
|
-
from app_utils.
|
|
14
|
+
from app_utils.allianceauth import get_redis_client
|
|
15
|
+
from app_utils.esi import fetch_esi_status
|
|
14
16
|
from app_utils.logging import LoggerAddTag
|
|
15
17
|
|
|
16
18
|
# AA Ledger
|
|
@@ -20,25 +22,104 @@ from ledger.app_settings import IS_TESTING
|
|
|
20
22
|
logger = LoggerAddTag(get_extension_logger(__name__), __title__)
|
|
21
23
|
|
|
22
24
|
|
|
23
|
-
def
|
|
24
|
-
"""
|
|
25
|
+
def _esi_cache_available(redis_client, cache_key):
|
|
26
|
+
"""Return True if ESI availability cache is present. Handles Redis errors."""
|
|
27
|
+
try:
|
|
28
|
+
if redis_client.get(cache_key):
|
|
29
|
+
return True
|
|
30
|
+
except Exception: # pylint: disable=broad-except
|
|
31
|
+
# If Redis is flaky, fall through to live check
|
|
32
|
+
logger.debug("Error reading ESI cache, will attempt live check.")
|
|
33
|
+
return False
|
|
25
34
|
|
|
26
|
-
Raise exception when ESI is offline.
|
|
27
|
-
Complete the task without running it when downtime is detected.
|
|
28
35
|
|
|
36
|
+
def _acquire_lock(redis_client, lock_key, token, lock_ttl):
|
|
37
|
+
"""Try to acquire a short-lived lock in Redis. Returns True on success."""
|
|
38
|
+
try:
|
|
39
|
+
return redis_client.set(lock_key, token, nx=True, ex=lock_ttl)
|
|
40
|
+
except Exception: # pylint: disable=broad-except
|
|
41
|
+
logger.exception("Failed to acquire ESI status lock, will attempt live check.")
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _wait_for_lock_or_cache(redis_client, cache_key, lock_key, token, lock_ttl):
|
|
46
|
+
"""Wait a short time for either the cache to appear or the lock to become available.
|
|
47
|
+
|
|
48
|
+
Returns a tuple (acquired, cache_available).
|
|
49
|
+
"""
|
|
50
|
+
waited = 0.0
|
|
51
|
+
poll_interval = 0.1
|
|
52
|
+
max_wait = float(lock_ttl) - 0.1
|
|
53
|
+
while waited < max_wait:
|
|
54
|
+
try:
|
|
55
|
+
# If cache was set while waiting, proceed.
|
|
56
|
+
if _esi_cache_available(redis_client, cache_key):
|
|
57
|
+
logger.debug("ESI status became available in cache while waiting.")
|
|
58
|
+
return False, True
|
|
59
|
+
|
|
60
|
+
# If the lock expired or was released, try to acquire it.
|
|
61
|
+
if not redis_client.get(lock_key):
|
|
62
|
+
try:
|
|
63
|
+
acquired = redis_client.set(lock_key, token, nx=True, ex=lock_ttl)
|
|
64
|
+
if acquired:
|
|
65
|
+
# We acquired the lock and will perform the check
|
|
66
|
+
return True, False
|
|
67
|
+
except Exception: # pylint: disable=broad-except
|
|
68
|
+
logger.debug("Failed to re-acquire lock while waiting for holder.")
|
|
69
|
+
except Exception: # pylint: disable=broad-except
|
|
70
|
+
logger.debug("Error polling ESI cache while waiting for lock holder.")
|
|
71
|
+
time.sleep(poll_interval)
|
|
72
|
+
waited += poll_interval
|
|
73
|
+
|
|
74
|
+
return False, False
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def when_esi_is_available(func):
|
|
78
|
+
"""
|
|
79
|
+
Make sure the decorated task only runs when esi is available and store the result.
|
|
80
|
+
Complete the task without running it when downtime is detected.
|
|
29
81
|
Automatically disabled during tests.
|
|
30
82
|
"""
|
|
31
83
|
|
|
32
84
|
@wraps(func)
|
|
33
85
|
def outer(*args, **kwargs):
|
|
34
|
-
|
|
86
|
+
# During tests we skip ESI checks
|
|
87
|
+
if IS_TESTING:
|
|
88
|
+
return func(*args, **kwargs)
|
|
89
|
+
|
|
90
|
+
cache_key = "esi_status_is_up"
|
|
91
|
+
redis_client = get_redis_client()
|
|
92
|
+
|
|
93
|
+
# Prevent hammering ESI status endpoint
|
|
94
|
+
if _esi_cache_available(redis_client, cache_key):
|
|
95
|
+
logger.debug("ESI status cached as available.")
|
|
96
|
+
return func(*args, **kwargs)
|
|
97
|
+
|
|
98
|
+
# Try to acquire a short-lived lock so only one process checks ESI
|
|
99
|
+
token = str(uuid.uuid4())
|
|
100
|
+
lock_key = "esi_status_lock"
|
|
101
|
+
lock_ttl = 5
|
|
102
|
+
acquired = _acquire_lock(redis_client, lock_key, token, lock_ttl)
|
|
103
|
+
|
|
104
|
+
# If we didn't get the lock, wait a short time for cache or lock
|
|
105
|
+
if not acquired:
|
|
106
|
+
acquired, cache_available = _wait_for_lock_or_cache(
|
|
107
|
+
redis_client, cache_key, lock_key, token, lock_ttl
|
|
108
|
+
)
|
|
109
|
+
if cache_available:
|
|
110
|
+
return func(*args, **kwargs)
|
|
111
|
+
|
|
112
|
+
# Check ESI status
|
|
113
|
+
if fetch_esi_status().is_ok:
|
|
114
|
+
logger.debug("ESI is available, proceeding.")
|
|
115
|
+
# 5 second TTL
|
|
35
116
|
try:
|
|
36
|
-
|
|
37
|
-
except
|
|
38
|
-
logger.
|
|
39
|
-
|
|
117
|
+
redis_client.setex(cache_key, 5, "1")
|
|
118
|
+
except Exception: # pylint: disable=broad-except
|
|
119
|
+
logger.debug("Failed to set ESI availability cache.")
|
|
120
|
+
return func(*args, **kwargs)
|
|
40
121
|
|
|
41
|
-
return
|
|
122
|
+
return None # function will not run
|
|
42
123
|
|
|
43
124
|
return outer
|
|
44
125
|
|