aa-moonregistry 0.1.0__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.
- aa_moonregistry-0.1.0/LICENSE +21 -0
- aa_moonregistry-0.1.0/PKG-INFO +111 -0
- aa_moonregistry-0.1.0/README.md +81 -0
- aa_moonregistry-0.1.0/aa_moonregistry/__init__.py +6 -0
- aa_moonregistry-0.1.0/aa_moonregistry/admin.py +5 -0
- aa_moonregistry-0.1.0/aa_moonregistry/app_settings.py +7 -0
- aa_moonregistry-0.1.0/aa_moonregistry/apps.py +7 -0
- aa_moonregistry-0.1.0/aa_moonregistry/auth_hooks.py +34 -0
- aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_jita_materials_prices.py +144 -0
- aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_metenox_data.py +112 -0
- aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_planets_moons.py +41 -0
- aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_sovereignty.py +10 -0
- aa_moonregistry-0.1.0/aa_moonregistry/migrations/0001_initial.py +118 -0
- aa_moonregistry-0.1.0/aa_moonregistry/migrations/0002_create_moonregistry_view.py +132 -0
- aa_moonregistry-0.1.0/aa_moonregistry/migrations/__init__.py +0 -0
- aa_moonregistry-0.1.0/aa_moonregistry/models.py +101 -0
- aa_moonregistry-0.1.0/aa_moonregistry/static/aa_moonregistry/components/MoonRegistry.js +255 -0
- aa_moonregistry-0.1.0/aa_moonregistry/static/aa_moonregistry/components/MoonScan.js +60 -0
- aa_moonregistry-0.1.0/aa_moonregistry/static/aa_moonregistry/components/vue-autocomplete.js +182 -0
- aa_moonregistry-0.1.0/aa_moonregistry/static/aa_moonregistry/css/main.css +593 -0
- aa_moonregistry-0.1.0/aa_moonregistry/static/aa_moonregistry/scripts/parse.js +50 -0
- aa_moonregistry-0.1.0/aa_moonregistry/tasks.py +25 -0
- aa_moonregistry-0.1.0/aa_moonregistry/templates/aa_moonregistry/base.html +8 -0
- aa_moonregistry-0.1.0/aa_moonregistry/templates/aa_moonregistry/index.html +126 -0
- aa_moonregistry-0.1.0/aa_moonregistry/templates/aa_moonregistry/vue/autocomplete.html +13 -0
- aa_moonregistry-0.1.0/aa_moonregistry/templates/aa_moonregistry/vue/moonlist-component.html +181 -0
- aa_moonregistry-0.1.0/aa_moonregistry/templates/aa_moonregistry/vue/moonscan-component.html +18 -0
- aa_moonregistry-0.1.0/aa_moonregistry/urls.py +16 -0
- aa_moonregistry-0.1.0/aa_moonregistry/utils.py +94 -0
- aa_moonregistry-0.1.0/aa_moonregistry/views.py +296 -0
- aa_moonregistry-0.1.0/pyproject.toml +78 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 cmbrando999@gmail.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aa_moonregistry
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Moon Registry for Alliance Auth.
|
|
5
|
+
Author-email: CMBrando <CMBrando999@gmail.com>
|
|
6
|
+
Requires-Python: >=3.10,<3.15
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Environment :: Web Environment
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 5.2
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: allianceauth>=5.0,<6.0
|
|
25
|
+
Requires-Dist: django>=5.2,<6.0
|
|
26
|
+
Requires-Dist: django-eveuniverse>=2.0,<3.0
|
|
27
|
+
Project-URL: Homepage, https://github.com/CMBrando/aaMoonRegistry
|
|
28
|
+
Project-URL: Issues, https://github.com/CMBrando/aaMoonRegistry/issues
|
|
29
|
+
|
|
30
|
+
# Moon Registry for Alliance Auth
|
|
31
|
+
|
|
32
|
+
This is a Moon Registry app for [Alliance Auth](https://gitlab.com/allianceauth/allianceauth) (AA)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- Search all moons across Eve once imported, by (system, constellation, region), ore, sov. owner, rarity
|
|
38
|
+
- Add moon scans via parsed text
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Once you have cloned the repo or copied all files into place.
|
|
43
|
+
|
|
44
|
+
Make sure you are in your venv. Then install it with pip in editable mode:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install -e {path_to}/aa_moonregistry
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
or via PyPi:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install aa_moonregistry
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add `aa_moonregistry` to `INSTALLED_APPS` in `settings/local.py`. If `eveuniverse` is not already there, add it too; the app depends on it.
|
|
57
|
+
|
|
58
|
+
Next perform migrations to add models to the database:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
python manage.py migrate
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Next load all the planets and moons from via eve universe, if not loaded already. This will take a while!!
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python manage.py aa_moonregistry_load_planets_moons
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Load initial Eve sovereignty
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
python manage.py aa_moonregistry_load_sovereignty
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Load Metenox-specific fuel data
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python manage.py aa_moonregistry_load_metenox_data
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Load initial JITA IV material pricing. Calculates average of top 5 JBV per type
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python manage.py aa_moonregistry_load_jita_materials_prices
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Next copy all the static data to the output folder
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
python manage.py collectstatic --noinput
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Finally restart your AA setup.
|
|
95
|
+
|
|
96
|
+
## Permissions
|
|
97
|
+
|
|
98
|
+
There is only one access level that will give access to the app in menu
|
|
99
|
+
*aa_moonregistry.basic_access*
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
## Alliance Auth Tasks
|
|
103
|
+
|
|
104
|
+
There are several registered tasks that should be run periodically.
|
|
105
|
+
|
|
106
|
+
*aa_moonregistry.tasks.refresh_sovereignty* - Reloads current Eve Sovereignty. Schedule once a week or so.
|
|
107
|
+
|
|
108
|
+
*aa_moonregistry.tasks.refresh_material_prices* - Refreshes pricing for calculations. Schedule once per day.
|
|
109
|
+
|
|
110
|
+
*aa_moonregistry.tasks.refresh_metenox_data* - Refreshes Metenox metadata. Schedule once per month.
|
|
111
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Moon Registry for Alliance Auth
|
|
2
|
+
|
|
3
|
+
This is a Moon Registry app for [Alliance Auth](https://gitlab.com/allianceauth/allianceauth) (AA)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Search all moons across Eve once imported, by (system, constellation, region), ore, sov. owner, rarity
|
|
9
|
+
- Add moon scans via parsed text
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Once you have cloned the repo or copied all files into place.
|
|
14
|
+
|
|
15
|
+
Make sure you are in your venv. Then install it with pip in editable mode:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install -e {path_to}/aa_moonregistry
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
or via PyPi:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install aa_moonregistry
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Add `aa_moonregistry` to `INSTALLED_APPS` in `settings/local.py`. If `eveuniverse` is not already there, add it too; the app depends on it.
|
|
28
|
+
|
|
29
|
+
Next perform migrations to add models to the database:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
python manage.py migrate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Next load all the planets and moons from via eve universe, if not loaded already. This will take a while!!
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
python manage.py aa_moonregistry_load_planets_moons
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Load initial Eve sovereignty
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python manage.py aa_moonregistry_load_sovereignty
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Load Metenox-specific fuel data
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
python manage.py aa_moonregistry_load_metenox_data
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Load initial JITA IV material pricing. Calculates average of top 5 JBV per type
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python manage.py aa_moonregistry_load_jita_materials_prices
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Next copy all the static data to the output folder
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
python manage.py collectstatic --noinput
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Finally restart your AA setup.
|
|
66
|
+
|
|
67
|
+
## Permissions
|
|
68
|
+
|
|
69
|
+
There is only one access level that will give access to the app in menu
|
|
70
|
+
*aa_moonregistry.basic_access*
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## Alliance Auth Tasks
|
|
74
|
+
|
|
75
|
+
There are several registered tasks that should be run periodically.
|
|
76
|
+
|
|
77
|
+
*aa_moonregistry.tasks.refresh_sovereignty* - Reloads current Eve Sovereignty. Schedule once a week or so.
|
|
78
|
+
|
|
79
|
+
*aa_moonregistry.tasks.refresh_material_prices* - Refreshes pricing for calculations. Schedule once per day.
|
|
80
|
+
|
|
81
|
+
*aa_moonregistry.tasks.refresh_metenox_data* - Refreshes Metenox metadata. Schedule once per month.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from django.utils.translation import gettext_lazy as _
|
|
2
|
+
|
|
3
|
+
from allianceauth import hooks
|
|
4
|
+
from allianceauth.services.hooks import MenuItemHook, UrlHook
|
|
5
|
+
|
|
6
|
+
from . import urls
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AAMoonRegistryMenuItem(MenuItemHook):
|
|
10
|
+
"""This class ensures only authorized users will see the menu entry"""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
# setup menu entry for sidebar
|
|
14
|
+
MenuItemHook.__init__(
|
|
15
|
+
self,
|
|
16
|
+
_("Moon Registry"),
|
|
17
|
+
"fas fa-cube fa-fw",
|
|
18
|
+
"aa_moonregistry:index"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def render(self, request):
|
|
22
|
+
if request.user.has_perm("aa_moonregistry.basic_access"):
|
|
23
|
+
return MenuItemHook.render(self, request)
|
|
24
|
+
return ""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@hooks.register("menu_item_hook")
|
|
28
|
+
def register_menu():
|
|
29
|
+
return AAMoonRegistryMenuItem()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@hooks.register("url_hook")
|
|
33
|
+
def register_urls():
|
|
34
|
+
return UrlHook(urls, "aa_moonregistry", r"^aa_moonregistry/")
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# myapp/management/commands/pull_jita_orders.py
|
|
2
|
+
from django.core.management.base import BaseCommand
|
|
3
|
+
from django.utils import timezone
|
|
4
|
+
from django.db.models import Avg, F, Window
|
|
5
|
+
from django.db.models.functions import RowNumber
|
|
6
|
+
from esi.openapi_clients import ESIClientProvider
|
|
7
|
+
from eveuniverse.models import EveType
|
|
8
|
+
from aa_moonregistry.models import MarketOrder, MarketPrice
|
|
9
|
+
|
|
10
|
+
from aa_moonregistry import apps
|
|
11
|
+
from aa_moonregistry import app_settings
|
|
12
|
+
|
|
13
|
+
from collections import defaultdict
|
|
14
|
+
from decimal import Decimal, ROUND_HALF_UP
|
|
15
|
+
|
|
16
|
+
import csv
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
esi = ESIClientProvider(
|
|
20
|
+
compatibility_date="2020-01-01",
|
|
21
|
+
ua_appname=apps.DefaultConfig.verbose_name,
|
|
22
|
+
ua_version=app_settings.MOON_VERSION,
|
|
23
|
+
operations=[
|
|
24
|
+
"GetMarketsRegionIdOrders"
|
|
25
|
+
]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
JITA_STATION_ID = 60003760
|
|
29
|
+
FORGE_REGION_ID = 10000002
|
|
30
|
+
EVE_CATEGORY_MATERIAL = 4
|
|
31
|
+
|
|
32
|
+
MAGMATIC_GAS_ID = 81143
|
|
33
|
+
|
|
34
|
+
FUEL_BLOCK_IDS = [4247, 4246, 4051, 4312]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Command(BaseCommand):
|
|
38
|
+
help = "Pulls Jita IV (Caldari Navy Assembly Plant) market orders for materials and saves them to DB"
|
|
39
|
+
|
|
40
|
+
def handle(self, *args, **options):
|
|
41
|
+
self.stdout.write("Pulling market orders for Jita IV materials...")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
save_type_ids = list(
|
|
45
|
+
EveType.objects
|
|
46
|
+
.filter(eve_group__eve_category_id=EVE_CATEGORY_MATERIAL)
|
|
47
|
+
.values_list("id", flat=True)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Add Magmatic Gas and Fuel Blocks to the list in order to get prices for them as well
|
|
51
|
+
save_type_ids.extend([MAGMATIC_GAS_ID])
|
|
52
|
+
save_type_ids.extend(FUEL_BLOCK_IDS)
|
|
53
|
+
|
|
54
|
+
run_timestamp = timezone.now()
|
|
55
|
+
|
|
56
|
+
all_orders = []
|
|
57
|
+
page = 1
|
|
58
|
+
while True:
|
|
59
|
+
res = esi.client.Market.GetMarketsRegionIdOrders(
|
|
60
|
+
region_id=FORGE_REGION_ID, order_type='all', page=page
|
|
61
|
+
).result(use_etag=False)
|
|
62
|
+
|
|
63
|
+
if not res:
|
|
64
|
+
break
|
|
65
|
+
|
|
66
|
+
for order in res:
|
|
67
|
+
if (
|
|
68
|
+
order.location_id == JITA_STATION_ID
|
|
69
|
+
and order.type_id in save_type_ids
|
|
70
|
+
):
|
|
71
|
+
all_orders.append(order)
|
|
72
|
+
|
|
73
|
+
if len(res) < 1000:
|
|
74
|
+
break
|
|
75
|
+
page += 1
|
|
76
|
+
|
|
77
|
+
self.stdout.write(f"Found {len(all_orders)} Jita material orders. Saving...")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Bulk insert/update
|
|
81
|
+
objs = []
|
|
82
|
+
for order in all_orders:
|
|
83
|
+
objs.append(
|
|
84
|
+
MarketOrder(
|
|
85
|
+
order_id=order.order_id,
|
|
86
|
+
type_id=order.type_id,
|
|
87
|
+
price=order.price,
|
|
88
|
+
volume_remain=order.volume_remain,
|
|
89
|
+
volume_total=order.volume_total,
|
|
90
|
+
min_volume=order.min_volume,
|
|
91
|
+
is_buy_order=order.is_buy_order,
|
|
92
|
+
issued=order.issued,
|
|
93
|
+
duration=order.duration,
|
|
94
|
+
location_id=order.location_id,
|
|
95
|
+
range=order.range,
|
|
96
|
+
system_id=order.system_id,
|
|
97
|
+
region_id=FORGE_REGION_ID,
|
|
98
|
+
pulled_at=run_timestamp,
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# clear existing data
|
|
103
|
+
MarketOrder.objects.all().delete()
|
|
104
|
+
|
|
105
|
+
MarketOrder.objects.bulk_create(objs, ignore_conflicts=True)
|
|
106
|
+
|
|
107
|
+
self.stdout.write(self.style.SUCCESS("Jita material orders saved successfully."))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# 1) Get BUY orders for this run, sorted by type then price DESC
|
|
111
|
+
qs = (
|
|
112
|
+
MarketOrder.objects
|
|
113
|
+
.filter(is_buy_order=True)
|
|
114
|
+
.values("type_id", "price")
|
|
115
|
+
.order_by("type_id", "-price")
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# 2) Average the five highest buy prices per type_id
|
|
119
|
+
counts = defaultdict(int)
|
|
120
|
+
sums = defaultdict(Decimal)
|
|
121
|
+
|
|
122
|
+
for row in qs:
|
|
123
|
+
t = row["type_id"]
|
|
124
|
+
if counts[t] < 5: # only the first five highest bids per type
|
|
125
|
+
price = row["price"]
|
|
126
|
+
# If price is float in the DB, cast to Decimal safely
|
|
127
|
+
if isinstance(price, float):
|
|
128
|
+
price = Decimal(str(price))
|
|
129
|
+
else:
|
|
130
|
+
price = Decimal(price)
|
|
131
|
+
counts[t] += 1
|
|
132
|
+
sums[t] += price
|
|
133
|
+
|
|
134
|
+
# 3) Replace MarketPrice with the new snapshot
|
|
135
|
+
MarketPrice.objects.all().delete()
|
|
136
|
+
|
|
137
|
+
to_create = []
|
|
138
|
+
for t, total in sums.items():
|
|
139
|
+
avg = (total / counts[t]).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
|
|
140
|
+
to_create.append(MarketPrice(type_id=t, price=avg))
|
|
141
|
+
|
|
142
|
+
MarketPrice.objects.bulk_create(to_create, batch_size=1000)
|
|
143
|
+
|
|
144
|
+
self.stdout.write(self.style.SUCCESS("Saved calculated prices successfully."))
|
aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_metenox_data.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
import zipfile
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from urllib.request import urlretrieve
|
|
7
|
+
from django.core.management.base import BaseCommand, CommandError
|
|
8
|
+
from django.db import transaction
|
|
9
|
+
from django.db.models import Exists, OuterRef
|
|
10
|
+
|
|
11
|
+
from aa_moonregistry.models import MetenoxDrillAttribute
|
|
12
|
+
|
|
13
|
+
from eveuniverse.models import EveSolarSystem, EvePlanet
|
|
14
|
+
|
|
15
|
+
STANDUP_METENOX_DRILL_TYPE_ID = 82941
|
|
16
|
+
FUEL_NEED_ATTR = 2109
|
|
17
|
+
|
|
18
|
+
class Command(BaseCommand):
|
|
19
|
+
help = 'Loads Metenox attribute data for moon drilling from SDE'
|
|
20
|
+
|
|
21
|
+
def handle(self, *args, **kwargs):
|
|
22
|
+
|
|
23
|
+
# Step 1: Get the latest build number
|
|
24
|
+
self.stdout.write('Fetching latest build number from ESI...')
|
|
25
|
+
latest_url = 'https://developers.eveonline.com/static-data/tranquility/latest.jsonl'
|
|
26
|
+
|
|
27
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
28
|
+
latest_file = os.path.join(temp_dir, 'latest.jsonl')
|
|
29
|
+
urlretrieve(latest_url, latest_file)
|
|
30
|
+
|
|
31
|
+
with open(latest_file, 'r', encoding='utf-8') as f:
|
|
32
|
+
latest_data = json.loads(f.readline())
|
|
33
|
+
build_number = latest_data['buildNumber']
|
|
34
|
+
|
|
35
|
+
self.stdout.write(f'Latest build number: {build_number}')
|
|
36
|
+
|
|
37
|
+
# Step 2: Download the static data ZIP
|
|
38
|
+
zip_url = f'https://developers.eveonline.com/static-data/tranquility/eve-online-static-data-{build_number}-jsonl.zip'
|
|
39
|
+
self.stdout.write(f'Downloading static data from {zip_url}...')
|
|
40
|
+
|
|
41
|
+
zip_path = os.path.join(temp_dir, 'static-data.zip')
|
|
42
|
+
urlretrieve(zip_url, zip_path)
|
|
43
|
+
|
|
44
|
+
self.stdout.write('Extracting ZIP file...')
|
|
45
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
46
|
+
zip_ref.extractall(temp_dir)
|
|
47
|
+
|
|
48
|
+
# Step 3: Load the JSONL files
|
|
49
|
+
type_dogma_path = os.path.join(temp_dir, 'typeDogma.jsonl')
|
|
50
|
+
|
|
51
|
+
if not os.path.exists(type_dogma_path):
|
|
52
|
+
self.stdout.write(self.style.ERROR(
|
|
53
|
+
'Required JSONL files not found in extracted data.'
|
|
54
|
+
))
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
self.stdout.write('Loading typeDogma.jsonl...')
|
|
58
|
+
fuel_value = None
|
|
59
|
+
with open(type_dogma_path, 'r', encoding='utf-8') as f:
|
|
60
|
+
for line in f:
|
|
61
|
+
item = json.loads(line)
|
|
62
|
+
|
|
63
|
+
if item['_key'] == STANDUP_METENOX_DRILL_TYPE_ID:
|
|
64
|
+
fuel_value = next(
|
|
65
|
+
(
|
|
66
|
+
attribute["value"]
|
|
67
|
+
for attribute in item["dogmaAttributes"]
|
|
68
|
+
if attribute["attributeID"] == FUEL_NEED_ATTR
|
|
69
|
+
),
|
|
70
|
+
None,
|
|
71
|
+
)
|
|
72
|
+
break
|
|
73
|
+
|
|
74
|
+
self.stdout.write('Loading metenoxMoonDrill.jsonl...')
|
|
75
|
+
cycleTime = None
|
|
76
|
+
consumed_per_cycle = None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
type_metenox_path = os.path.join(temp_dir, 'metenoxMoonDrill.jsonl')
|
|
80
|
+
|
|
81
|
+
with open(type_metenox_path, 'r', encoding='utf-8') as f:
|
|
82
|
+
for line in f:
|
|
83
|
+
item = json.loads(line)
|
|
84
|
+
|
|
85
|
+
cycleTime = item["miningCycleTime"]
|
|
86
|
+
consumed_per_cycle = item["reagentsConsumedPerCycle"]
|
|
87
|
+
|
|
88
|
+
attributes = {
|
|
89
|
+
"module_cycle_fuel_need": fuel_value,
|
|
90
|
+
"cycle_time": cycleTime,
|
|
91
|
+
"consumed_per_cycle": consumed_per_cycle,
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
missing_attributes = [
|
|
95
|
+
name for name, value in attributes.items() if value is None
|
|
96
|
+
]
|
|
97
|
+
if missing_attributes:
|
|
98
|
+
raise CommandError(
|
|
99
|
+
"Missing Metenox drill attributes in SDE: "
|
|
100
|
+
+ ", ".join(missing_attributes)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
with transaction.atomic():
|
|
104
|
+
for name, value in attributes.items():
|
|
105
|
+
MetenoxDrillAttribute.objects.update_or_create(
|
|
106
|
+
name=name,
|
|
107
|
+
defaults={"value": value},
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
self.stdout.write(
|
|
111
|
+
self.style.SUCCESS("Metenox drill attributes saved successfully.")
|
|
112
|
+
)
|
aa_moonregistry-0.1.0/aa_moonregistry/management/commands/aa_moonregistry_load_planets_moons.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from django.db.models import Exists, OuterRef
|
|
2
|
+
from django.core.management.base import BaseCommand
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from eveuniverse.models import EveSolarSystem, EvePlanet
|
|
6
|
+
|
|
7
|
+
class Command(BaseCommand):
|
|
8
|
+
help = 'Loads all EveUniverse Planets and Moons for existing Systems'
|
|
9
|
+
|
|
10
|
+
def handle(self, *args, **kwargs):
|
|
11
|
+
|
|
12
|
+
enabled_sections = [
|
|
13
|
+
EveSolarSystem.Section.PLANETS,
|
|
14
|
+
EvePlanet.Section.MOONS,
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
qs = (
|
|
18
|
+
EveSolarSystem.objects
|
|
19
|
+
.annotate(has_planet=Exists(
|
|
20
|
+
EvePlanet.objects.filter(eve_solar_system=OuterRef("pk"))
|
|
21
|
+
))
|
|
22
|
+
.filter(has_planet=False)
|
|
23
|
+
.only("id")
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
count = qs.count()
|
|
27
|
+
print(f"Found {count:,} EveSolarSystem objects missing planets to process")
|
|
28
|
+
|
|
29
|
+
processed = 0
|
|
30
|
+
for system in qs.iterator(chunk_size=500):
|
|
31
|
+
EveSolarSystem.objects.get_or_create_esi(
|
|
32
|
+
id=system.id,
|
|
33
|
+
include_children=True,
|
|
34
|
+
wait_for_children=False,
|
|
35
|
+
enabled_sections=enabled_sections,
|
|
36
|
+
)
|
|
37
|
+
processed += 1
|
|
38
|
+
if processed % 1000 == 0:
|
|
39
|
+
print(f"Queued {processed:,}/{count:,} systems...")
|
|
40
|
+
|
|
41
|
+
print(f"Queued planet + moon loads for {processed:,} solar systems.")
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from aa_moonregistry.utils import refresh_sovereignty
|
|
4
|
+
|
|
5
|
+
class Command(BaseCommand):
|
|
6
|
+
help = 'Does initial load of all system sovereignty'
|
|
7
|
+
|
|
8
|
+
def handle(self, *args, **kwargs):
|
|
9
|
+
|
|
10
|
+
refresh_sovereignty()
|