aa-fitting-mastery 0.1.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.
- aa_fitting_mastery-0.1.0.dist-info/METADATA +304 -0
- aa_fitting_mastery-0.1.0.dist-info/RECORD +80 -0
- aa_fitting_mastery-0.1.0.dist-info/WHEEL +4 -0
- aa_fitting_mastery-0.1.0.dist-info/licenses/LICENSE +21 -0
- mastery/__init__.py +7 -0
- mastery/app_settings.py +8 -0
- mastery/apps.py +7 -0
- mastery/auth_hooks.py +29 -0
- mastery/management/commands/__init__.py +0 -0
- mastery/management/commands/import_sde_masteries.py +69 -0
- mastery/migrations/0001_initial.py +133 -0
- mastery/migrations/0002_doctrineskillsetgroupmap_default_mastery_level_and_more.py +23 -0
- mastery/migrations/0003_make_fitting_mastery_override_nullable.py +25 -0
- mastery/migrations/0004_fittingskillcontrol_recommended_level_override.py +20 -0
- mastery/migrations/0005_fittingskillsetmap_last_synced_at.py +17 -0
- mastery/migrations/0006_fittingskillcontrol_is_manual.py +17 -0
- mastery/migrations/0007_general.py +26 -0
- mastery/migrations/0008_summary_audience_groups.py +56 -0
- mastery/migrations/__init__.py +0 -0
- mastery/models/__init__.py +11 -0
- mastery/models/certificate_skill.py +20 -0
- mastery/models/doctrine_skill_snapshot.py +68 -0
- mastery/models/doctrine_skillsetgroup_map.py +29 -0
- mastery/models/fitting_skill_control.py +58 -0
- mastery/models/fitting_skill_override.py +27 -0
- mastery/models/fitting_skillset_map.py +47 -0
- mastery/models/general.py +20 -0
- mastery/models/sde_version.py +11 -0
- mastery/models/ship_mastery.py +11 -0
- mastery/models/ship_mastery_certificate.py +16 -0
- mastery/models/summary_group.py +51 -0
- mastery/services/__init__.py +0 -0
- mastery/services/doctrine/__init__.py +1 -0
- mastery/services/doctrine/doctrine_map_service.py +47 -0
- mastery/services/doctrine/doctrine_skill_service.py +164 -0
- mastery/services/fittings/__init__.py +2 -0
- mastery/services/fittings/fitting_map_service.py +33 -0
- mastery/services/fittings/skill_extractor.py +135 -0
- mastery/services/pilots/__init__.py +5 -0
- mastery/services/pilots/pilot_access_service.py +58 -0
- mastery/services/pilots/pilot_progress_service.py +1025 -0
- mastery/services/sde/__init__.py +3 -0
- mastery/services/sde/importer.py +105 -0
- mastery/services/sde/mastery_service.py +47 -0
- mastery/services/sde/version_service.py +37 -0
- mastery/services/skills/__init__.py +3 -0
- mastery/services/skills/skill_control_service.py +114 -0
- mastery/services/skills/skillcheck_service.py +58 -0
- mastery/services/skills/suggestion_service.py +165 -0
- mastery/tasks.py +29 -0
- mastery/templates/mastery/base.html +48 -0
- mastery/templates/mastery/doctrine_detail.html +172 -0
- mastery/templates/mastery/doctrine_list.html +116 -0
- mastery/templates/mastery/fitting_skills.html +315 -0
- mastery/templates/mastery/index.html +313 -0
- mastery/templates/mastery/partials/ajax_messages.html +7 -0
- mastery/templates/mastery/partials/fitting_skill_preview.html +101 -0
- mastery/templates/mastery/partials/fitting_skills_editor.html +356 -0
- mastery/templates/mastery/pilot_fitting_detail.html +747 -0
- mastery/templates/mastery/summary_doctrine_detail.html +92 -0
- mastery/templates/mastery/summary_fitting_detail.html +199 -0
- mastery/templates/mastery/summary_list_view.html +126 -0
- mastery/templates/mastery/summary_settings.html +200 -0
- mastery/templatetags/__init__.py +0 -0
- mastery/templatetags/skill_render.py +63 -0
- mastery/tests/__init__.py +0 -0
- mastery/tests/test_auth_hooks.py +27 -0
- mastery/tests/test_pilot_progress_service.py +167 -0
- mastery/tests/test_services.py +616 -0
- mastery/tests/test_tasks.py +55 -0
- mastery/tests/test_views.py +1334 -0
- mastery/urls.py +67 -0
- mastery/views/__init__.py +72 -0
- mastery/views/common.py +569 -0
- mastery/views/deps.py +34 -0
- mastery/views/doctrine.py +150 -0
- mastery/views/fitting.py +499 -0
- mastery/views/pilot.py +319 -0
- mastery/views/summary.py +277 -0
- mastery/views/summary_helpers.py +526 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aa-fitting-mastery
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Fitting Mastery and Skill Plan generator.
|
|
5
|
+
Author-email: Jay <jays.gaming.contact@gmail.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Environment :: Web Environment
|
|
9
|
+
Classifier: Framework :: Django
|
|
10
|
+
Classifier: Framework :: Django :: 4.0
|
|
11
|
+
Classifier: Framework :: Django :: 4.2
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: aa-memberaudit>=4.3.1
|
|
25
|
+
Requires-Dist: fittings>=2.3.0
|
|
26
|
+
Requires-Dist: allianceauth-app-utils>=1.18
|
|
27
|
+
Requires-Dist: allianceauth>=4,<5
|
|
28
|
+
Requires-Dist: django-esi>=8.3.1
|
|
29
|
+
Requires-Dist: django-eveonline-sde>=0.0.1b2
|
|
30
|
+
Project-URL: Changelog, https://github.com/hermesdj/aa-fitting-mastery/-/blob/master/CHANGELOG.md
|
|
31
|
+
Project-URL: Homepage, https://github.com/hermesdj/aa-fitting-mastery
|
|
32
|
+
Project-URL: Source, https://github.com/hermesdj/aa-fitting-mastery
|
|
33
|
+
Project-URL: Tracker, https://github.com/hermesdj/aa-fitting-mastery/-/issues
|
|
34
|
+
|
|
35
|
+
# Fitting Mastery Plugin for Alliance Auth
|
|
36
|
+
|
|
37
|
+
`aa-fitting-mastery` is an [Alliance Auth](https://allianceauth.readthedocs.io/) plugin that turns doctrine fittings into actionable skill plans.
|
|
38
|
+
|
|
39
|
+
It connects your configured doctrines and fittings from the `fittings` plugin with character and skill data from `aa-memberaudit`, then provides:
|
|
40
|
+
|
|
41
|
+
- pilot readiness views for accessible doctrine fittings,
|
|
42
|
+
- missing required and recommended skills,
|
|
43
|
+
- exportable in-game skill plans,
|
|
44
|
+
- configurable required and recommended skill plans per fitting,
|
|
45
|
+
- leadership summary views for doctrine coverage.
|
|
46
|
+
|
|
47
|
+
[](https://pypi.org/project/aa-fitting-mastery/)
|
|
48
|
+
[](https://pypi.org/project/aa-fitting-mastery/)
|
|
49
|
+
[](https://pypi.org/project/aa-fitting-mastery/)
|
|
50
|
+
[](LICENSE)
|
|
51
|
+
[](https://github.com/pre-commit/pre-commit)
|
|
52
|
+
[](https://github.com/psf/black)
|
|
53
|
+
|
|
54
|
+
## Contents
|
|
55
|
+
|
|
56
|
+
- [Overview](#overview)
|
|
57
|
+
- [Requirements](#requirements)
|
|
58
|
+
- [Main features](#main-features)
|
|
59
|
+
- [Screenshots](#screenshots)
|
|
60
|
+
- [Installation](#installation)
|
|
61
|
+
- [Updating](#updating)
|
|
62
|
+
- [Configuration](#configuration)
|
|
63
|
+
- [Permissions](#permissions)
|
|
64
|
+
- [How it works](#how-it-works)
|
|
65
|
+
- [Settings](#settings)
|
|
66
|
+
|
|
67
|
+
## Overview
|
|
68
|
+
|
|
69
|
+
Fitting Mastery is designed for organizations that already manage doctrine ships in `fittings` and track character skills in `aa-memberaudit`.
|
|
70
|
+
|
|
71
|
+
The plugin adds two complementary workflows:
|
|
72
|
+
|
|
73
|
+
1. **Pilot workflow**
|
|
74
|
+
- members can see which of their characters can fly a doctrine fitting,
|
|
75
|
+
- inspect missing required / recommended skills,
|
|
76
|
+
- export missing skills in a format suitable for EVE skill plan import.
|
|
77
|
+
|
|
78
|
+
2. **Leadership workflow**
|
|
79
|
+
- doctrine managers can configure fitting skill plans,
|
|
80
|
+
- review suggestions to blacklist or restore skills,
|
|
81
|
+
- define summary groups across corporations and alliances,
|
|
82
|
+
- view doctrine coverage for a selected audience.
|
|
83
|
+
|
|
84
|
+
Access to doctrines and fittings follows the visibility rules from the `fittings` plugin so that category restrictions are respected consistently.
|
|
85
|
+
|
|
86
|
+
## Requirements
|
|
87
|
+
|
|
88
|
+
This plugin depends on the following components:
|
|
89
|
+
|
|
90
|
+
- `fittings` — required
|
|
91
|
+
- `aa-memberaudit` — required
|
|
92
|
+
- `django-eveonline-sde` / `eve_sde` — required for ship mastery and dogma data
|
|
93
|
+
- Alliance Auth 4.x
|
|
94
|
+
|
|
95
|
+
> **Important**
|
|
96
|
+
> This plugin does **not** replace `fittings` or `aa-memberaudit`.
|
|
97
|
+
> It builds on top of both. You need both plugins installed and working before enabling `mastery`.
|
|
98
|
+
|
|
99
|
+
## Main features
|
|
100
|
+
|
|
101
|
+
- Generate fitting skill plans from doctrine ships and their modules
|
|
102
|
+
- Merge **required** fitting skills with **recommended** ship mastery skills
|
|
103
|
+
- Add manual skills, blacklist skills, or override recommended levels per fitting
|
|
104
|
+
- Detect and suggest skills that can be removed from a plan
|
|
105
|
+
- Export missing skills in dependency-safe order for in-game EVE import
|
|
106
|
+
- Support multiple export languages for skill names
|
|
107
|
+
- Show member-facing doctrine readiness based on accessible fittings only
|
|
108
|
+
- Show leadership doctrine coverage across configurable corp/alliance audience groups
|
|
109
|
+
- Keep fitting access aligned with the access rules configured in the `fittings` plugin
|
|
110
|
+
|
|
111
|
+
## Screenshots
|
|
112
|
+
|
|
113
|
+
### Character progress
|
|
114
|
+
|
|
115
|
+

|
|
116
|
+
|
|
117
|
+
### Fitting skill plan management
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
## Installation
|
|
122
|
+
|
|
123
|
+
### 1 - Install prerequisites
|
|
124
|
+
|
|
125
|
+
Make sure your Alliance Auth installation already has these apps installed and configured:
|
|
126
|
+
|
|
127
|
+
- `fittings`
|
|
128
|
+
- `memberaudit`
|
|
129
|
+
- `eve_sde`
|
|
130
|
+
|
|
131
|
+
### 2 - Install the package
|
|
132
|
+
|
|
133
|
+
Install the plugin into your Alliance Auth virtual environment:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
pip install aa-fitting-mastery
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3 - Add the app to Alliance Auth
|
|
140
|
+
|
|
141
|
+
Add `mastery` to `INSTALLED_APPS` in your `local.py`:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
INSTALLED_APPS += [
|
|
145
|
+
"mastery",
|
|
146
|
+
]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 4 - Configure the scheduled SDE mastery update task
|
|
150
|
+
|
|
151
|
+
Add the periodic task to your `CELERYBEAT_SCHEDULE` (every day at midnight):
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from celery.schedules import crontab
|
|
155
|
+
|
|
156
|
+
CELERYBEAT_SCHEDULE["update_sde_masteries"] = {
|
|
157
|
+
"task": "mastery.tasks.update_sde_masteries",
|
|
158
|
+
"schedule": crontab(minute="0", hour="0"),
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 5 - Run migrations and collect static files
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
python manage.py migrate
|
|
166
|
+
python manage.py collectstatic
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 6 - Import mastery data
|
|
170
|
+
|
|
171
|
+
Import ship mastery and certificate data from the EVE SDE:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
python manage.py import_sde_masteries
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
For a test run without writing to the database:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
python manage.py import_sde_masteries --dry-run
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 7 - Restart your services
|
|
184
|
+
|
|
185
|
+
Restart your web and Celery services so the plugin and beat task are loaded.
|
|
186
|
+
|
|
187
|
+
## Updating
|
|
188
|
+
|
|
189
|
+
To update an existing installation:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
pip install -U aa-fitting-mastery
|
|
193
|
+
python manage.py migrate
|
|
194
|
+
python manage.py collectstatic
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Then restart your web and Celery services.
|
|
198
|
+
|
|
199
|
+
## Configuration
|
|
200
|
+
|
|
201
|
+
After installation, the usual setup flow is:
|
|
202
|
+
|
|
203
|
+
1. **Ensure your doctrines and fittings already exist in the `fittings` plugin**
|
|
204
|
+
2. Open **Manage Skill Plans** in Fitting Mastery
|
|
205
|
+
3. Generate or sync doctrine skill plans
|
|
206
|
+
4. Review each fitting and adjust:
|
|
207
|
+
- mastery level,
|
|
208
|
+
- manual skills,
|
|
209
|
+
- blacklisted skills,
|
|
210
|
+
- recommended level overrides,
|
|
211
|
+
- skill suggestions
|
|
212
|
+
5. If you want doctrine leadership views, create audience groups in **Summary Group Settings**
|
|
213
|
+
6. Assign the appropriate permissions to members, doctrine managers and leadership roles
|
|
214
|
+
|
|
215
|
+
### Access model
|
|
216
|
+
|
|
217
|
+
For pilot-facing views, Fitting Mastery uses the same fittings visibility rules as the `fittings` plugin.
|
|
218
|
+
|
|
219
|
+
That means:
|
|
220
|
+
|
|
221
|
+
- users must have access to `fittings` itself,
|
|
222
|
+
- category restrictions remain effective,
|
|
223
|
+
- doctrines and fittings that are hidden in `fittings` will not be exposed by Fitting Mastery.
|
|
224
|
+
|
|
225
|
+
## Permissions
|
|
226
|
+
|
|
227
|
+
The plugin defines the following permissions:
|
|
228
|
+
|
|
229
|
+
| Code | Description |
|
|
230
|
+
| --- | --- |
|
|
231
|
+
| `basic_access` | Can access the pilot-facing Fitting Mastery pages |
|
|
232
|
+
| `manage_fittings` | Can manage doctrine/fitting skill plans |
|
|
233
|
+
| `doctrine_summary` | Can view leadership doctrine summary pages |
|
|
234
|
+
| `manage_summary_groups` | Can create and manage summary audience groups |
|
|
235
|
+
|
|
236
|
+
### Recommended usage
|
|
237
|
+
|
|
238
|
+
- **Members**: `basic_access`
|
|
239
|
+
- **Doctrine / fitting managers**: `basic_access`, `manage_fittings`
|
|
240
|
+
- **Leadership / FC / HR reviewers**: `basic_access`, `doctrine_summary`
|
|
241
|
+
- **Admins managing summary scopes**: `manage_summary_groups`
|
|
242
|
+
|
|
243
|
+
In practice, pilot-facing access is usually granted together with fitting visibility from the `fittings` plugin.
|
|
244
|
+
|
|
245
|
+
You will typically also want matching access in the `fittings` plugin, especially `fittings.access_fittings` or `fittings.manage`.
|
|
246
|
+
|
|
247
|
+
## How it works
|
|
248
|
+
|
|
249
|
+
At a high level the plugin works like this:
|
|
250
|
+
|
|
251
|
+
1. It reads the ship and module requirements from fitting dogma data
|
|
252
|
+
2. It reads ship mastery recommendations from imported SDE mastery data
|
|
253
|
+
3. It combines both into a per-fitting skill plan
|
|
254
|
+
4. It lets managers refine that plan with blacklists, manual additions and level overrides
|
|
255
|
+
5. It compares those plans against character skills from `aa-memberaudit`
|
|
256
|
+
6. It presents the result in pilot and leadership views
|
|
257
|
+
|
|
258
|
+
### Required vs Recommended
|
|
259
|
+
|
|
260
|
+
- **Required** skills come from fitting / module requirements and their recursive prerequisites
|
|
261
|
+
- **Recommended** skills come from ship mastery data, plus any manual adjustments you configure
|
|
262
|
+
|
|
263
|
+
### Summary groups
|
|
264
|
+
|
|
265
|
+
Doctrine summary views can be scoped to configurable audience groups.
|
|
266
|
+
|
|
267
|
+
Each summary group can combine:
|
|
268
|
+
|
|
269
|
+
- corporations,
|
|
270
|
+
- alliances,
|
|
271
|
+
- mixed corporation/alliance audiences.
|
|
272
|
+
|
|
273
|
+
This makes it possible to review doctrine coverage for a coalition, SIG, alliance wing or any other relevant operational scope.
|
|
274
|
+
|
|
275
|
+
### Exported skill plans
|
|
276
|
+
|
|
277
|
+
When exporting missing skills for a pilot, the plugin:
|
|
278
|
+
|
|
279
|
+
- includes all missing intermediate levels,
|
|
280
|
+
- adds missing prerequisites recursively,
|
|
281
|
+
- orders skills so prerequisites appear first,
|
|
282
|
+
- supports multiple languages for skill labels.
|
|
283
|
+
|
|
284
|
+
## Settings
|
|
285
|
+
|
|
286
|
+
The following setting can be added to your Alliance Auth `local.py`:
|
|
287
|
+
|
|
288
|
+
| Name | Description | Default |
|
|
289
|
+
| --- | --- | --- |
|
|
290
|
+
| `MASTERY_PLAN_ESTIMATE_SP_PER_HOUR` | Training speed used to estimate plan duration in fitting previews | `1800` |
|
|
291
|
+
|
|
292
|
+
Example:
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
MASTERY_PLAN_ESTIMATE_SP_PER_HOUR = 1800
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Notes
|
|
299
|
+
|
|
300
|
+
- If you change doctrine skill plan configuration, regenerate or sync the affected doctrine/fitting so changes are reflected in the active skill set.
|
|
301
|
+
- If leadership summaries are enabled, remember to configure at least one summary audience group.
|
|
302
|
+
- If no mastery data has been imported yet, recommended ship skills will be incomplete until `import_sde_masteries` has been run.
|
|
303
|
+
- Fitting Mastery respects fitting visibility from the `fittings` plugin and will not intentionally expose restricted doctrines or fittings outside that access model.
|
|
304
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
mastery/__init__.py,sha256=zoqT0a5XHAA49Ejh87JnO4zuDvKp6z6jAqfKnMwRPaA,208
|
|
2
|
+
mastery/app_settings.py,sha256=efQlmIlVIXHXChICmwDl71mKr8Q5WREVPZjq24T06CA,272
|
|
3
|
+
mastery/apps.py,sha256=eWzHG0Eyb3lIpvcstAXZkyvgO-g3wXjQ2azpl2nhV9U,155
|
|
4
|
+
mastery/auth_hooks.py,sha256=cs_uYeDHYzEwjqZOfRMZGYZz9SIvd9QjhU9l4Vs1TfE,723
|
|
5
|
+
mastery/tasks.py,sha256=AmzcqPUvNwQ4XmSyti5xox1lbrPvG2cWQA0VRi4vG6U,1041
|
|
6
|
+
mastery/urls.py,sha256=WXNmUZ0f529aR9-UJI4YisnBv8NEO-NIYf8pDO_gNuQ,2973
|
|
7
|
+
mastery/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
mastery/management/commands/import_sde_masteries.py,sha256=5cnpspLhXagnypJeGfAZZYskq1FX8e8-cNVQioWVSec,2267
|
|
9
|
+
mastery/migrations/0001_initial.py,sha256=TjWdErcIuHX7m8QZPwxNnigbUKYVZsSF65yXi_VFj8g,7727
|
|
10
|
+
mastery/migrations/0002_doctrineskillsetgroupmap_default_mastery_level_and_more.py,sha256=f0g6ZFFYN2iGgiyLnI9_XyN-0Cq8YC4VSXY0bLz9oPw,659
|
|
11
|
+
mastery/migrations/0003_make_fitting_mastery_override_nullable.py,sha256=8pat3ZSgWUjCvlHle42PLfk7nLTIBSZqhgm9OLpRTJc,794
|
|
12
|
+
mastery/migrations/0004_fittingskillcontrol_recommended_level_override.py,sha256=j8P3VjkBJje9q4BCPAznObB5kyRzC8ZzMsOQZSuh5pE,513
|
|
13
|
+
mastery/migrations/0005_fittingskillsetmap_last_synced_at.py,sha256=7L0dpxfl0giFH5EG5HoQo6DmZWbfGtuGbXL_shJ_Ej0,427
|
|
14
|
+
mastery/migrations/0006_fittingskillcontrol_is_manual.py,sha256=2ZX5fJg0E3s7UxPnDcuDNETX1XVDJk1SBu-AY4ctawo,396
|
|
15
|
+
mastery/migrations/0007_general.py,sha256=uQAP8fWM3GWl1sFuCYaVVfc3UyC_dsTuABB7t2gHNBg,685
|
|
16
|
+
mastery/migrations/0008_summary_audience_groups.py,sha256=cJLPcEpHwOIwRVcAPHRRFmgemPmAIYBsO7v0voKdOB4,2375
|
|
17
|
+
mastery/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
mastery/models/__init__.py,sha256=iAp0RCWO3yEzIbeQp8tO_bXcoq_kPI-J2mamkHiNGLI,372
|
|
19
|
+
mastery/models/certificate_skill.py,sha256=iuMnXcM2UMP3QtLC0_Jpf53dY77ott6srtu0BI1wMhU,744
|
|
20
|
+
mastery/models/doctrine_skill_snapshot.py,sha256=8GdjltTYeK66PrscvgPSM4WjXTDIvoYfF_tLFcdDGgg,1728
|
|
21
|
+
mastery/models/doctrine_skillsetgroup_map.py,sha256=hVVcNXUSMmT9oYIlAV6LzEJW5_uoSdd2bm1pd0c9Bjk,824
|
|
22
|
+
mastery/models/fitting_skill_control.py,sha256=HRxzxCTHZijbWH2J88k3IccDJZmiNUxw4iFHDAIf8cQ,1446
|
|
23
|
+
mastery/models/fitting_skill_override.py,sha256=_kl3Owce3-e_nKmSLjlRQf9ROUdswqhWv1mfKdvBEHc,766
|
|
24
|
+
mastery/models/fitting_skillset_map.py,sha256=qahUrh0F0CeTcwmOxmhG6XENgQ8Cv2YsKLuB3T8o-x4,1186
|
|
25
|
+
mastery/models/general.py,sha256=GaCZjR-ZYy5IBTQaJQuLJGlfXetDBmm2Rdqz0s5TjNo,681
|
|
26
|
+
mastery/models/sde_version.py,sha256=osK4dD_qHNucKhSDN-Jagan8k3kjhKARkPUZqBdNzc8,327
|
|
27
|
+
mastery/models/ship_mastery.py,sha256=qwTXkJhVzrkoeUBw-M4x7DiTgD6HDMALKd5QXGMnba4,312
|
|
28
|
+
mastery/models/ship_mastery_certificate.py,sha256=8nrnMO6BbWUmxe5Pqx1CPZXWxdMFoDIlwA-9KNOeNtw,478
|
|
29
|
+
mastery/models/summary_group.py,sha256=5Fr8T9UOEEHnbADn0d467PBgs6G47HQ-6rQz336fjEk,1702
|
|
30
|
+
mastery/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
mastery/services/doctrine/__init__.py,sha256=42XnJ10t_7RS_a5SPYS7VJGdOyPFrshRTHXaxulxG7k,36
|
|
32
|
+
mastery/services/doctrine/doctrine_map_service.py,sha256=AtJBurZJSR74_jtXxy-kAbrmFfJACLJVCKYL0pFRRXg,1658
|
|
33
|
+
mastery/services/doctrine/doctrine_skill_service.py,sha256=cjLk-HWO0qy10ZoLMy2WCSTE-O1G1qKCXShFFV1pcbI,7114
|
|
34
|
+
mastery/services/fittings/__init__.py,sha256=MjN6sOywL_infwb2_6tuPgCky5U6azWaRzJ3epW6Z0s,65
|
|
35
|
+
mastery/services/fittings/fitting_map_service.py,sha256=uSPO1HQhEzxuJh6-6TGIK1_Fx1NW0pWSWlBC8QUi2bE,1109
|
|
36
|
+
mastery/services/fittings/skill_extractor.py,sha256=bNlbt8p7D-QMoVY1DWJ-IwROhqrQHplwEW-ktp_2-B8,4355
|
|
37
|
+
mastery/services/pilots/__init__.py,sha256=Z81y83hee4RxB9qyQD2lVYZA9bX37NvjYdfJyZH3_eY,169
|
|
38
|
+
mastery/services/pilots/pilot_access_service.py,sha256=FdbVFSzWkl9onZbixfxnsEOwRd2fuzV-B4pVZp79s0c,2322
|
|
39
|
+
mastery/services/pilots/pilot_progress_service.py,sha256=SQ0ARoOxiI1D75Y2hB2HRzjYuQQEByQ8g_3G9eXgE1I,42169
|
|
40
|
+
mastery/services/sde/__init__.py,sha256=aBKB0gE6lnU6m3D6w0bGmBQ9u6q_ZGr7rw51P-ytAY0,85
|
|
41
|
+
mastery/services/sde/importer.py,sha256=MO6asR41SMpqy_bRjHcze5vw19ACa1NtFOpLD9NrHCs,3830
|
|
42
|
+
mastery/services/sde/mastery_service.py,sha256=IZ0j-S2pnj-Kmm50p-EkvUXSkFDnH6ONy3yvtd8hJMY,1388
|
|
43
|
+
mastery/services/sde/version_service.py,sha256=gUpqwhNgx1WV3YKAUpjV63_TGxKxJF2pCc_PLFc6rMg,1187
|
|
44
|
+
mastery/services/skills/__init__.py,sha256=If6nCdT4B3qG-yYx1_OBUSAJ8f8xYgHRQMypwoDC8DQ,104
|
|
45
|
+
mastery/services/skills/skill_control_service.py,sha256=quKIO0qnucDeIJxBt39J651zs-vMn1A-92htGccHvOU,4397
|
|
46
|
+
mastery/services/skills/skillcheck_service.py,sha256=kYux3_holCDqCYmtoGy5Si65ubmGFGH9hrZXOmq166A,1848
|
|
47
|
+
mastery/services/skills/suggestion_service.py,sha256=sVdKzBX-g43H97qU5aagJwjI0cPAkUhxB4mChhRNqfI,5221
|
|
48
|
+
mastery/templates/mastery/base.html,sha256=vKK4VawAzknAFtcgLCtR6ZRVbObCvqkXylrBskcuSOg,1530
|
|
49
|
+
mastery/templates/mastery/doctrine_detail.html,sha256=dFzMOHAeVK07KwYQYYK-qw8m8AcESXqboTBS2g3JENM,8664
|
|
50
|
+
mastery/templates/mastery/doctrine_list.html,sha256=XyfrV6a2zqlWVJ8Ea8XRAffwKA71onizS___KUseh78,5474
|
|
51
|
+
mastery/templates/mastery/fitting_skills.html,sha256=7WGX7whtD5UeZfH7jYcjHky9dKRGpYz362bvyPJzAWs,9438
|
|
52
|
+
mastery/templates/mastery/index.html,sha256=ZVpjyEuoh30dOgDktUMP-jGsvScrCMkiYvmoNug1roU,14969
|
|
53
|
+
mastery/templates/mastery/pilot_fitting_detail.html,sha256=SsaodqvhM-cPDm8xoBEZXjw4qtfAtVbL6SpKK9eX6Dk,42810
|
|
54
|
+
mastery/templates/mastery/summary_doctrine_detail.html,sha256=Gp5bFiNnsbFu45S4OVQXQBZA_coEG8dx40iH9QFtbyk,5827
|
|
55
|
+
mastery/templates/mastery/summary_fitting_detail.html,sha256=YsqxIUF238XLLK2Xx9z_MzPlVYFhlLGmHUfpHtw1tMI,12821
|
|
56
|
+
mastery/templates/mastery/summary_list_view.html,sha256=JP3koYysmiiAw0PdNm7IIT2BrJH-1nS9tAJYmG7xIps,6934
|
|
57
|
+
mastery/templates/mastery/summary_settings.html,sha256=D-Tm7NPjbQEEeNcNl8hemshTSdSi02jf4Ptl4yRx8Xg,10392
|
|
58
|
+
mastery/templates/mastery/partials/ajax_messages.html,sha256=hQUl2VDCnjeHQ88s3a8fxoEhnX6Myjgstin1q8Eaz1Y,291
|
|
59
|
+
mastery/templates/mastery/partials/fitting_skill_preview.html,sha256=S4-xA8ZV48JVi_FRPcs_flyDHhYhsJFD_XCTNgZpXiQ,4171
|
|
60
|
+
mastery/templates/mastery/partials/fitting_skills_editor.html,sha256=YHJrxIv1uhfOErLqiS2Hv2iFneJh3kd6TJHMJZhCV14,21766
|
|
61
|
+
mastery/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
62
|
+
mastery/templatetags/skill_render.py,sha256=zw2uWmwyg_DmIgbSsK0jFyFcZAreLkSph9SoMZIqd94,1809
|
|
63
|
+
mastery/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
|
+
mastery/tests/test_auth_hooks.py,sha256=mLzlV0rWW17mseOLY-TsoQwUJa4BQLlATsYMXEnTEI0,777
|
|
65
|
+
mastery/tests/test_pilot_progress_service.py,sha256=Msmo8uOV_L8kn3u8q1vDH_8ObZefUmLWzTvwYjzClrg,6535
|
|
66
|
+
mastery/tests/test_services.py,sha256=M6DUvGf7i_d87rPiCg4EpHTYh5spytEsasqyEEBmPcw,27692
|
|
67
|
+
mastery/tests/test_tasks.py,sha256=bsB_BgbnsWB2sqts3Fdx3KrrUVsNNxtr4-Owz68MOE4,2444
|
|
68
|
+
mastery/tests/test_views.py,sha256=yvKjAfzCW1Pq-08YyOsTJK98V73cwzaRJpABHqgNS4w,56487
|
|
69
|
+
mastery/views/__init__.py,sha256=YDZVj0sXxtmkhG4iSwQfoxVJAJfuWR4X-CFGYAH9ejM,1932
|
|
70
|
+
mastery/views/common.py,sha256=1YOytDT6OQ3NPeOcRflLK1qUCnYIZV77wojeoSOpojc,19696
|
|
71
|
+
mastery/views/deps.py,sha256=9wfa7tUSSqjCAnEwaKTkfM7AEYaMBCdNyUyLV6u78Ls,1390
|
|
72
|
+
mastery/views/doctrine.py,sha256=_-EzmEH_VXdMUzGczyn7XWzm-QsHj2nzJUUpdYRnh3A,5554
|
|
73
|
+
mastery/views/fitting.py,sha256=9eSGu5AhFrkVb4T_aYjPEYSYKaI2zXo-e4gKkXnf5tQ,17414
|
|
74
|
+
mastery/views/pilot.py,sha256=I5A_WEeFGdfAmGlZSAwU8BIekSAoubwpHrgRt15F3iI,12982
|
|
75
|
+
mastery/views/summary.py,sha256=ae0dkzvHgdsVsAR8n_-Bliso2_ANkLdpUdtSRxo5CHM,11470
|
|
76
|
+
mastery/views/summary_helpers.py,sha256=LsI-hvVa5V_EB-yP2dYjabOMF4O-t_AugK5WdwObcvs,18684
|
|
77
|
+
aa_fitting_mastery-0.1.0.dist-info/licenses/LICENSE,sha256=kM9zGC-yCxQyVxHjoM3Pu_Yb8mSa1fa-Kx0ZgL13CKY,1062
|
|
78
|
+
aa_fitting_mastery-0.1.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
79
|
+
aa_fitting_mastery-0.1.0.dist-info/METADATA,sha256=lNFH3wGfnpG1KQE1BiB12kGxGaMXwFNvoi8gpV43raY,10786
|
|
80
|
+
aa_fitting_mastery-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jay's
|
|
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.
|
mastery/__init__.py
ADDED
mastery/app_settings.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Settings for Fitting Mastery."""
|
|
2
|
+
|
|
3
|
+
from app_utils.app_settings import clean_setting
|
|
4
|
+
|
|
5
|
+
MASTERY_PLAN_ESTIMATE_SP_PER_HOUR = clean_setting(
|
|
6
|
+
"MASTERY_PLAN_ESTIMATE_SP_PER_HOUR", 1800, min_value=1
|
|
7
|
+
)
|
|
8
|
+
"""Training speed used to estimate plan duration in fitting previews."""
|
mastery/apps.py
ADDED
mastery/auth_hooks.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from allianceauth import hooks
|
|
2
|
+
from allianceauth.services.hooks import UrlHook, MenuItemHook
|
|
3
|
+
|
|
4
|
+
from . import urls
|
|
5
|
+
|
|
6
|
+
class MasteryMenu(MenuItemHook):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
MenuItemHook.__init__(
|
|
9
|
+
self,
|
|
10
|
+
"Skill Planner",
|
|
11
|
+
"fas fa-chart-bar",
|
|
12
|
+
"mastery:pilot_index",
|
|
13
|
+
navactive=["mastery:"],
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def render(self, request):
|
|
17
|
+
if request.user.has_perm("mastery.basic_access"):
|
|
18
|
+
return MenuItemHook.render(self, request)
|
|
19
|
+
return ""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@hooks.register("menu_item_hook")
|
|
23
|
+
def register_menu():
|
|
24
|
+
return MasteryMenu()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@hooks.register("url_hook")
|
|
28
|
+
def register_urls():
|
|
29
|
+
return UrlHook(urls, "fitting-mastery", r"^fitting-mastery/")
|
|
File without changes
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Management command to import SDE masteries and certificates."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from django.core.management import BaseCommand
|
|
6
|
+
|
|
7
|
+
from mastery.services.sde.importer import SdeMasteryImporter
|
|
8
|
+
from mastery.services.sde.version_service import SdeVersionService
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Command(BaseCommand):
|
|
12
|
+
"""Import SDE mastery data into local mastery models."""
|
|
13
|
+
|
|
14
|
+
def add_arguments(self, parser):
|
|
15
|
+
parser.add_argument(
|
|
16
|
+
"--force",
|
|
17
|
+
action="store_true",
|
|
18
|
+
help="Force import even if SDE version is up to date",
|
|
19
|
+
)
|
|
20
|
+
parser.add_argument(
|
|
21
|
+
"--dry-run",
|
|
22
|
+
action="store_true",
|
|
23
|
+
help="Perform a dry run without making any changes",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def handle(self, *args, **options):
|
|
27
|
+
start = time.time()
|
|
28
|
+
version_service = SdeVersionService()
|
|
29
|
+
|
|
30
|
+
latest = version_service.fetch_latest()
|
|
31
|
+
current = version_service.get_current()
|
|
32
|
+
|
|
33
|
+
if current:
|
|
34
|
+
self.stdout.write(f"Current SDE version: {current.build_number}")
|
|
35
|
+
else:
|
|
36
|
+
self.stdout.write("No SDE imported yet")
|
|
37
|
+
|
|
38
|
+
self.stdout.write(f"Latest SDE version: {latest['build_number']}")
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
current
|
|
42
|
+
and current.build_number == latest["build_number"]
|
|
43
|
+
and not options["force"]
|
|
44
|
+
):
|
|
45
|
+
self.stdout.write(self.style.SUCCESS("SDE is up to date, skipping import"))
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
dry_run = options["dry_run"]
|
|
49
|
+
|
|
50
|
+
if dry_run:
|
|
51
|
+
self.stdout.write(self.style.WARNING("Running in DRY-RUN mode"))
|
|
52
|
+
|
|
53
|
+
# IMPORT
|
|
54
|
+
importer = SdeMasteryImporter()
|
|
55
|
+
zip_file = importer.download()
|
|
56
|
+
|
|
57
|
+
masteries = importer.extract_yaml(zip_file, "masteries.yaml")
|
|
58
|
+
self.stdout.write(f"Masteries loaded: {len(masteries)} ships")
|
|
59
|
+
|
|
60
|
+
certificates = importer.extract_yaml(zip_file, "certificates.yaml")
|
|
61
|
+
self.stdout.write(f"Certificates loaded: {len(certificates)} entries")
|
|
62
|
+
|
|
63
|
+
if dry_run:
|
|
64
|
+
self.stdout.write(self.style.WARNING("Dry-run: skipping DB import"))
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
importer.exec_import(latest, masteries, certificates, dry_run=dry_run)
|
|
68
|
+
|
|
69
|
+
self.stdout.write(self.style.SUCCESS(f"SDE import complete, done in {time.time() - start:.2f}s"))
|