aa-bb 3.2.7b4__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_bb/__init__.py +4 -0
- aa_bb/admin.py +627 -0
- aa_bb/app_settings.py +2375 -0
- aa_bb/apps.py +68 -0
- aa_bb/auth_hooks.py +227 -0
- aa_bb/celery.py +63 -0
- aa_bb/checks/__init__.py +8 -0
- aa_bb/checks/add_to_blacklist.py +190 -0
- aa_bb/checks/alliance_blacklist.py +21 -0
- aa_bb/checks/alpha_skills.json +757 -0
- aa_bb/checks/awox.py +383 -0
- aa_bb/checks/clone_state.py +305 -0
- aa_bb/checks/coalition_blacklist.py +19 -0
- aa_bb/checks/corp_changes.py +257 -0
- aa_bb/checks/cyno.py +387 -0
- aa_bb/checks/hostile_assets.py +311 -0
- aa_bb/checks/hostile_clones.py +298 -0
- aa_bb/checks/roles_and_tokens.py +219 -0
- aa_bb/checks/skills.json +659 -0
- aa_bb/checks/skills.py +303 -0
- aa_bb/checks/sus_contacts.py +301 -0
- aa_bb/checks/sus_contracts.py +290 -0
- aa_bb/checks/sus_mails.py +295 -0
- aa_bb/checks/sus_trans.py +420 -0
- aa_bb/checks_cb/__init__.py +7 -0
- aa_bb/checks_cb/hostile_assets.py +143 -0
- aa_bb/checks_cb/sus_contracts.py +322 -0
- aa_bb/checks_cb/sus_trans.py +388 -0
- aa_bb/esi_cache.py +39 -0
- aa_bb/esi_client.py +75 -0
- aa_bb/forms.py +52 -0
- aa_bb/locale/.gitkeep +0 -0
- aa_bb/management/__init__.py +0 -0
- aa_bb/management/commands/__init__.py +0 -0
- aa_bb/migrations/0001_initial.py +25 -0
- aa_bb/migrations/0002_bigbrotherconfig_userstatus.py +58 -0
- aa_bb/migrations/0003_alter_bigbrotherconfig_pingroleid.py +18 -0
- aa_bb/migrations/0004_alter_bigbrotherconfig_is_active_and_more.py +23 -0
- aa_bb/migrations/0005_alter_bigbrotherconfig_hostile_alliances.py +18 -0
- aa_bb/migrations/0006_alter_bigbrotherconfig_pingroleid.py +18 -0
- aa_bb/migrations/0007_alter_general_options.py +17 -0
- aa_bb/migrations/0008_alliance_names_corporation_names.py +41 -0
- aa_bb/migrations/0009_userstatus_sus_contacts_userstatus_sus_contracts_and_more.py +38 -0
- aa_bb/migrations/0010_alter_userstatus_awox_kill_links_and_more.py +48 -0
- aa_bb/migrations/0011_character_names.py +27 -0
- aa_bb/migrations/0012_id_types.py +27 -0
- aa_bb/migrations/0013_bigbrotherconfig_mail_keywords.py +18 -0
- aa_bb/migrations/0014_processedcontract_processedmail_and_more.py +74 -0
- aa_bb/migrations/0015_processedtransaction_sustransactionnote.py +42 -0
- aa_bb/migrations/0016_warmprogress.py +23 -0
- aa_bb/migrations/0017_entityinfocache.py +27 -0
- aa_bb/migrations/0018_userstatus_cyno_userstatus_has_skills_and_more.py +28 -0
- aa_bb/migrations/0019_bigbrotherconfig_whitelist_alliances_and_more.py +23 -0
- aa_bb/migrations/0020_messages_bigbrotherconfig_are_daily_messages_active_and_more.py +35 -0
- aa_bb/migrations/0021_alter_messages_id_alter_messages_text.py +23 -0
- aa_bb/migrations/0022_messages_sent_in_cycle.py +18 -0
- aa_bb/migrations/0023_optmessages1_optmessages2_optmessages3_optmessages4_and_more.py +103 -0
- aa_bb/migrations/0024_bigbrotherconfig_dailyschedule_and_more.py +45 -0
- aa_bb/migrations/0025_alter_messages_options_alter_optmessages1_options_and_more.py +37 -0
- aa_bb/migrations/0026_alter_general_options_alter_bigbrotherconfig_id_and_more.py +97 -0
- aa_bb/migrations/0027_alter_general_options_bigbrotherconfig_is_loa_active_and_more.py +27 -0
- aa_bb/migrations/0028_alter_bigbrotherconfig_is_loa_active.py +18 -0
- aa_bb/migrations/0029_leaverequest_main_character.py +18 -0
- aa_bb/migrations/0030_alter_general_options.py +17 -0
- aa_bb/migrations/0031_bigbrotherconfig_loa_max_logoff_days_and_more.py +88 -0
- aa_bb/migrations/0032_alter_leaverequest_status.py +18 -0
- aa_bb/migrations/0033_messagetype_bigbrotherconfig_pingroleid2_and_more.py +45 -0
- aa_bb/migrations/0034_rename_last_updated_userstatus_updated.py +18 -0
- aa_bb/migrations/0035_alter_userstatus_options.py +17 -0
- aa_bb/migrations/0036_alter_general_options.py +17 -0
- aa_bb/migrations/0037_corpstatus.py +32 -0
- aa_bb/migrations/0038_bigbrotherconfig_ignored_corporations.py +18 -0
- aa_bb/migrations/0039_alter_bigbrotherconfig_ignored_corporations.py +18 -0
- aa_bb/migrations/0040_sovereigntymapcache_corporationinfocache_and_more.py +49 -0
- aa_bb/migrations/0041_bigbrotherconfig_is_warmer_active.py +18 -0
- aa_bb/migrations/0042_alter_general_options_and_more.py +23 -0
- aa_bb/migrations/0043_bigbrotherconfig_bb_member_states_and_more.py +24 -0
- aa_bb/migrations/0044_bigbrotherconfig_character_scopes_and_more.py +23 -0
- aa_bb/migrations/0045_userstatus_sp_age_ratio_result.py +18 -0
- aa_bb/migrations/0046_bigbrotherconfig_member_corporations.py +18 -0
- aa_bb/migrations/0047_bigbrotherconfig_member_alliances.py +18 -0
- aa_bb/migrations/0048_characteraccountstate.py +21 -0
- aa_bb/migrations/0049_userstatus_clone_status.py +18 -0
- aa_bb/migrations/0050_alter_general_options_and_more.py +22 -0
- aa_bb/migrations/0051_monthlypapstats.py +34 -0
- aa_bb/migrations/0052_papsconfig_delete_monthlypapstats.py +30 -0
- aa_bb/migrations/0053_alter_papsconfig_corp_modifier_and_more.py +38 -0
- aa_bb/migrations/0054_alter_general_options.py +17 -0
- aa_bb/migrations/0055_papsconfig_group_paps_papsconfig_group_paps_modifier.py +24 -0
- aa_bb/migrations/0056_alter_papsconfig_group_paps.py +19 -0
- aa_bb/migrations/0057_papsconfig_excluded_groups_papsconfig_excluded_users_and_more.py +31 -0
- aa_bb/migrations/0058_papsconfig_excluded_groups_get_paps_and_more.py +30 -0
- aa_bb/migrations/0059_alter_papsconfig_excluded_groups_get_paps.py +18 -0
- aa_bb/migrations/0060_papsconfig_cap_group_papsconfig_cap_group_paps_and_more.py +49 -0
- aa_bb/migrations/0061_remove_papsconfig_cap_group_and_more.py +42 -0
- aa_bb/migrations/0062_complianceticket.py +28 -0
- aa_bb/migrations/0063_alter_complianceticket_user.py +21 -0
- aa_bb/migrations/0064_alter_complianceticket_reason.py +18 -0
- aa_bb/migrations/0065_alter_complianceticket_reason_and_more.py +26 -0
- aa_bb/migrations/0066_tickettoolconfig_papcompliance.py +52 -0
- aa_bb/migrations/0067_remove_tickettoolconfig_category_id_and_more.py +21 -0
- aa_bb/migrations/0068_tickettoolconfig_category_id_and_more.py +23 -0
- aa_bb/migrations/0069_tickettoolconfig_ticket_counter.py +18 -0
- aa_bb/migrations/0070_remove_tickettoolconfig_role_id_and_more.py +54 -0
- aa_bb/migrations/0071_tickettoolconfig_role_id.py +18 -0
- aa_bb/migrations/0072_alter_complianceticket_reason.py +18 -0
- aa_bb/migrations/0073_tickettoolconfig_starting_pap_compliance.py +18 -0
- aa_bb/migrations/0074_alter_bigbrotherconfig_hostile_alliances.py +18 -0
- aa_bb/migrations/0075_bbupdatestate_tickettoolconfig_afk_check_frequency_and_more.py +49 -0
- aa_bb/migrations/0076_id_types_last_accessed_frequentcorpchangescache_and_more.py +74 -0
- aa_bb/migrations/0077_complianceticket_ticket_id_and_more.py +28 -0
- aa_bb/migrations/0078_tickettoolconfig_awox_monitor_enabled.py +18 -0
- aa_bb/migrations/0079_helptext_guidance.py +57 -0
- aa_bb/migrations/0080_bigbrotherconfig_dlc_flags.py +65 -0
- aa_bb/migrations/0081_remove_papsconfig_imp_modifier_and_more.py +56 -0
- aa_bb/migrations/0082_remove_bigbrotherconfig_token_and_more.py +82 -0
- aa_bb/migrations/0083_alter_bigbrotherredditmessage_options_and_more.py +71 -0
- aa_bb/migrations/0084_bigbrotherconfig_consider_all_structures_hostile_and_more.py +43 -0
- aa_bb/migrations/0085_bigbrotherconfig_awox_notify_and_more.py +33 -0
- aa_bb/migrations/0086_bigbrotherconfig_are_recurring_stats_active_and_more.py +54 -0
- aa_bb/migrations/0087_bigbrotherconfig_dlc_are_recurring_stats_active.py +18 -0
- aa_bb/migrations/0088_bigbrotherconfig_cyno_notify.py +18 -0
- aa_bb/migrations/0089_bigbrotherconfig_asset_notify_and_more.py +58 -0
- aa_bb/migrations/0090_alter_papsconfig_options_and_more.py +488 -0
- aa_bb/migrations/0091_remove_bigbrotherconfig_dlc_are_recurring_stats_active_and_more.py +62 -0
- aa_bb/migrations/0092_userstatus_baseline_initialized.py +28 -0
- aa_bb/migrations/0093_eveitemprice_delete_bigbrotherredditmessage_and_more.py +154 -0
- aa_bb/migrations/0094_bigbrotherconfig_corp_compliance_webhook_and_more.py +28 -0
- aa_bb/migrations/0095_alter_bigbrotherconfig_limit_to_main_corp.py +18 -0
- aa_bb/migrations/0096_bigbrotherconfig_clone_state_notify_and_more.py +23 -0
- aa_bb/migrations/0097_bigbrotherconfig_hostile_everyone_else.py +18 -0
- aa_bb/migrations/0098_bigbrotherconfig_exclude_high_sec_and_more.py +28 -0
- aa_bb/migrations/0099_tickettoolconfig_hr_forum_webhook.py +18 -0
- aa_bb/migrations/0100_tickettoolconfig_use_forum_threads.py +18 -0
- aa_bb/migrations/0101_userstatus_compliance_forum_thread_id.py +114 -0
- aa_bb/migrations/0102_remove_tickettoolconfig_use_forum_threads_and_more.py +67 -0
- aa_bb/migrations/0103_tickettoolconfig_afk_check_include_user_and_more.py +58 -0
- aa_bb/migrations/0104_alter_bigbrotherconfig_is_active.py +24 -0
- aa_bb/migrations/0105_remove_tickettoolconfig_compliance_filter.py +52 -0
- aa_bb/migrations/0106_bigbrotherconfig_consider_lowsec_hostile.py +18 -0
- aa_bb/migrations/0107_remove_tickettoolconfig_role_id_and_more.py +36 -0
- aa_bb/migrations/__init__.py +0 -0
- aa_bb/models.py +2191 -0
- aa_bb/signals.py +64 -0
- aa_bb/static/aa_bb/.gitkeep +0 -0
- aa_bb/static/aa_bb/js/admin_market_toggle.js +21 -0
- aa_bb/static/aa_bb/js/admin_ticket_type_toggle.js +44 -0
- aa_bb/tasks.py +1467 -0
- aa_bb/tasks_bot.py +880 -0
- aa_bb/tasks_cb.py +950 -0
- aa_bb/tasks_ct.py +372 -0
- aa_bb/tasks_other.py +255 -0
- aa_bb/tasks_tickets.py +662 -0
- aa_bb/tasks_utils.py +342 -0
- aa_bb/templates/aa_bb/base.html +25 -0
- aa_bb/templates/aa_bb/disabled.html +20 -0
- aa_bb/templates/aa_bb/index.html +555 -0
- aa_bb/templates/aa_bb/ticket_list.html +73 -0
- aa_bb/templates/aa_bb/ticket_view.html +117 -0
- aa_bb/templates/aa_cb/base.html +26 -0
- aa_bb/templates/aa_cb/disabled.html +20 -0
- aa_bb/templates/aa_cb/index.html +398 -0
- aa_bb/templates/faq/base.html +19 -0
- aa_bb/templates/faq/cards.html +115 -0
- aa_bb/templates/faq/faq.html +531 -0
- aa_bb/templates/faq/menu.html +30 -0
- aa_bb/templates/faq/modules.html +66 -0
- aa_bb/templates/faq/settings_bigbrother.html +355 -0
- aa_bb/templates/faq/settings_nav.html +49 -0
- aa_bb/templates/faq/settings_paps.html +132 -0
- aa_bb/templates/faq/settings_stats.html +116 -0
- aa_bb/templates/faq/settings_tickets.html +332 -0
- aa_bb/templates/loa/_loa_subtabs.html +17 -0
- aa_bb/templates/loa/admin.html +113 -0
- aa_bb/templates/loa/base.html +22 -0
- aa_bb/templates/loa/disabled.html +19 -0
- aa_bb/templates/loa/index.html +62 -0
- aa_bb/templates/loa/menu.html +27 -0
- aa_bb/templates/loa/request.html +81 -0
- aa_bb/templates/paps/base.html +21 -0
- aa_bb/templates/paps/disabled.html +19 -0
- aa_bb/templates/paps/history.html +25 -0
- aa_bb/templates/paps/index.html +86 -0
- aa_bb/templates/paps/menu.html +20 -0
- aa_bb/tests/__init__.py +1 -0
- aa_bb/tests/test_clone_state_logic.py +75 -0
- aa_bb/tests/test_performance.py +129 -0
- aa_bb/tests/test_price_timer.py +62 -0
- aa_bb/tests/test_sus_contacts.py +79 -0
- aa_bb/tests/test_sus_trans.py +224 -0
- aa_bb/tests/test_task_setup.py +83 -0
- aa_bb/tests/test_tasks_notifications.py +70 -0
- aa_bb/tests/test_tasks_recurring_stats.py +92 -0
- aa_bb/tests/test_views.py +203 -0
- aa_bb/urls.py +65 -0
- aa_bb/urls_cb.py +27 -0
- aa_bb/urls_loa.py +14 -0
- aa_bb/urls_paps.py +10 -0
- aa_bb/views.py +1423 -0
- aa_bb/views_cb.py +776 -0
- aa_bb/views_faq.py +581 -0
- aa_bb/views_paps.py +342 -0
- aa_bb-3.2.7b4.dist-info/METADATA +445 -0
- aa_bb-3.2.7b4.dist-info/RECORD +206 -0
- aa_bb-3.2.7b4.dist-info/WHEEL +4 -0
- aa_bb-3.2.7b4.dist-info/licenses/LICENSE +7 -0
aa_bb/__init__.py
ADDED
aa_bb/admin.py
ADDED
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Admin registrations for every BigBrother-related model.
|
|
3
|
+
|
|
4
|
+
Most models are singletons that gate optional modules. The helpers below
|
|
5
|
+
ensure their admin entries only appear when the relevant feature is enabled
|
|
6
|
+
and prevent accidental multi-row creation of what should be one-off configs.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from solo.admin import SingletonModelAdmin
|
|
10
|
+
|
|
11
|
+
from django.contrib import admin
|
|
12
|
+
from .app_settings import afat_active, discordbot_active, charlink_active
|
|
13
|
+
from django.contrib.admin.sites import NotRegistered
|
|
14
|
+
|
|
15
|
+
from .models import (
|
|
16
|
+
BigBrotherConfig,
|
|
17
|
+
Messages,
|
|
18
|
+
OptMessages1,
|
|
19
|
+
OptMessages2,
|
|
20
|
+
OptMessages3,
|
|
21
|
+
OptMessages4,
|
|
22
|
+
OptMessages5,
|
|
23
|
+
UserStatus,
|
|
24
|
+
WarmProgress,
|
|
25
|
+
PapsConfig,
|
|
26
|
+
RecurringStatsConfig,
|
|
27
|
+
AA_CONTACTS_INSTALLED,
|
|
28
|
+
TicketToolConfig,
|
|
29
|
+
PapCompliance,
|
|
30
|
+
LeaveRequest,
|
|
31
|
+
ComplianceTicket,
|
|
32
|
+
ComplianceThread,
|
|
33
|
+
EveItemPrice,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@admin.register(BigBrotherConfig)
|
|
37
|
+
class BB_ConfigAdmin(SingletonModelAdmin):
|
|
38
|
+
fieldsets = (
|
|
39
|
+
(
|
|
40
|
+
"Core Activation",
|
|
41
|
+
{
|
|
42
|
+
"fields": (
|
|
43
|
+
"is_active",
|
|
44
|
+
"is_warmer_active",
|
|
45
|
+
"is_loa_active",
|
|
46
|
+
"is_paps_active",
|
|
47
|
+
"are_daily_messages_active",
|
|
48
|
+
"are_recurring_stats_active",
|
|
49
|
+
"are_opt_messages1_active",
|
|
50
|
+
"are_opt_messages2_active",
|
|
51
|
+
"are_opt_messages3_active",
|
|
52
|
+
"are_opt_messages4_active",
|
|
53
|
+
"are_opt_messages5_active",
|
|
54
|
+
"loa_max_logoff_days",
|
|
55
|
+
)
|
|
56
|
+
},
|
|
57
|
+
),
|
|
58
|
+
(
|
|
59
|
+
"Notifications",
|
|
60
|
+
{
|
|
61
|
+
"fields": (
|
|
62
|
+
"ct_notify",
|
|
63
|
+
"awox_notify",
|
|
64
|
+
"cyno_notify",
|
|
65
|
+
"sp_inject_notify",
|
|
66
|
+
"clone_notify",
|
|
67
|
+
"clone_state_notify",
|
|
68
|
+
"asset_notify",
|
|
69
|
+
"contact_notify",
|
|
70
|
+
"contract_notify",
|
|
71
|
+
"mail_notify",
|
|
72
|
+
"transaction_notify",
|
|
73
|
+
"show_market_transactions",
|
|
74
|
+
"new_user_notify",
|
|
75
|
+
),
|
|
76
|
+
},
|
|
77
|
+
),
|
|
78
|
+
(
|
|
79
|
+
"Update Performance",
|
|
80
|
+
{
|
|
81
|
+
"fields": (
|
|
82
|
+
"clone_state_always_recheck",
|
|
83
|
+
"update_stagger_seconds",
|
|
84
|
+
"update_cache_ttl_hours",
|
|
85
|
+
"update_maintenance_window_start",
|
|
86
|
+
"update_maintenance_window_end",
|
|
87
|
+
"update_backlog_threshold",
|
|
88
|
+
"update_backlog_notify",
|
|
89
|
+
),
|
|
90
|
+
},
|
|
91
|
+
),
|
|
92
|
+
(
|
|
93
|
+
"Market Transaction Settings",
|
|
94
|
+
{
|
|
95
|
+
"classes": ("market-transaction-settings-fieldset",),
|
|
96
|
+
"fields": (
|
|
97
|
+
"market_transactions_show_major_hubs",
|
|
98
|
+
"market_transactions_show_secondary_hubs",
|
|
99
|
+
"market_transactions_excluded_systems",
|
|
100
|
+
"market_transactions_threshold_alert",
|
|
101
|
+
"market_transactions_threshold_percent",
|
|
102
|
+
"market_transactions_price_method",
|
|
103
|
+
"market_transactions_janice_api_key",
|
|
104
|
+
"market_transactions_fuzzwork_station_id",
|
|
105
|
+
"market_transactions_price_instant",
|
|
106
|
+
"market_transactions_price_max_age",
|
|
107
|
+
)
|
|
108
|
+
},
|
|
109
|
+
),
|
|
110
|
+
(
|
|
111
|
+
"Blacklist Settings",
|
|
112
|
+
{
|
|
113
|
+
"fields": (
|
|
114
|
+
"alliance_blacklist_url",
|
|
115
|
+
"external_blacklist_url",
|
|
116
|
+
)
|
|
117
|
+
},
|
|
118
|
+
),
|
|
119
|
+
(
|
|
120
|
+
"Ping / Messaging Roles",
|
|
121
|
+
{
|
|
122
|
+
"fields": (
|
|
123
|
+
"pingroleID",
|
|
124
|
+
"pingroleID2",
|
|
125
|
+
"pingrole1_messages",
|
|
126
|
+
"pingrole2_messages",
|
|
127
|
+
"here_messages",
|
|
128
|
+
"everyone_messages",
|
|
129
|
+
)
|
|
130
|
+
},
|
|
131
|
+
),
|
|
132
|
+
(
|
|
133
|
+
"Webhooks",
|
|
134
|
+
{
|
|
135
|
+
"fields": (
|
|
136
|
+
"webhook",
|
|
137
|
+
"loawebhook",
|
|
138
|
+
"dailywebhook",
|
|
139
|
+
"optwebhook1",
|
|
140
|
+
"optwebhook2",
|
|
141
|
+
"optwebhook3",
|
|
142
|
+
"optwebhook4",
|
|
143
|
+
"optwebhook5",
|
|
144
|
+
"user_compliance_webhook",
|
|
145
|
+
"corp_compliance_webhook",
|
|
146
|
+
"stats_webhook",
|
|
147
|
+
)
|
|
148
|
+
},
|
|
149
|
+
),
|
|
150
|
+
(
|
|
151
|
+
"Schedules",
|
|
152
|
+
{
|
|
153
|
+
"fields": (
|
|
154
|
+
"dailyschedule",
|
|
155
|
+
"optschedule1",
|
|
156
|
+
"optschedule2",
|
|
157
|
+
"optschedule3",
|
|
158
|
+
"optschedule4",
|
|
159
|
+
"optschedule5",
|
|
160
|
+
"stats_schedule",
|
|
161
|
+
),
|
|
162
|
+
},
|
|
163
|
+
),
|
|
164
|
+
(
|
|
165
|
+
"User State & Membership",
|
|
166
|
+
{
|
|
167
|
+
"fields": (
|
|
168
|
+
"limit_to_main_corp",
|
|
169
|
+
"bb_guest_states",
|
|
170
|
+
"bb_member_states",
|
|
171
|
+
"member_corporations",
|
|
172
|
+
"member_alliances",
|
|
173
|
+
)
|
|
174
|
+
},
|
|
175
|
+
),
|
|
176
|
+
(
|
|
177
|
+
"Hostile / Whitelist Rules",
|
|
178
|
+
{
|
|
179
|
+
"fields": (
|
|
180
|
+
"hostile_alliances",
|
|
181
|
+
"hostile_corporations",
|
|
182
|
+
"hostile_everyone_else",
|
|
183
|
+
"whitelist_alliances",
|
|
184
|
+
"whitelist_corporations",
|
|
185
|
+
"ignored_corporations",
|
|
186
|
+
"consider_nullsec_hostile",
|
|
187
|
+
"consider_lowsec_hostile",
|
|
188
|
+
"consider_all_structures_hostile",
|
|
189
|
+
"consider_npc_stations_hostile",
|
|
190
|
+
"excluded_systems",
|
|
191
|
+
"excluded_stations",
|
|
192
|
+
"exclude_high_sec",
|
|
193
|
+
"exclude_low_sec",
|
|
194
|
+
"hostile_assets_ships_only",
|
|
195
|
+
# aa-contacts import (conditionally add fields)
|
|
196
|
+
*(
|
|
197
|
+
(
|
|
198
|
+
"auto_import_contacts_enabled",
|
|
199
|
+
"contacts_source_alliances",
|
|
200
|
+
"contacts_source_corporations",
|
|
201
|
+
"contacts_handle_neutrals",
|
|
202
|
+
)
|
|
203
|
+
if AA_CONTACTS_INSTALLED
|
|
204
|
+
else ()
|
|
205
|
+
),
|
|
206
|
+
)
|
|
207
|
+
},
|
|
208
|
+
),
|
|
209
|
+
(
|
|
210
|
+
"Scopes",
|
|
211
|
+
{
|
|
212
|
+
"classes": ("collapse",),
|
|
213
|
+
"fields": (
|
|
214
|
+
"character_scopes",
|
|
215
|
+
"corporation_scopes",
|
|
216
|
+
),
|
|
217
|
+
},
|
|
218
|
+
),
|
|
219
|
+
(
|
|
220
|
+
"Main Corp / Alliance",
|
|
221
|
+
{
|
|
222
|
+
"fields": (
|
|
223
|
+
"main_corporation_id",
|
|
224
|
+
"main_corporation",
|
|
225
|
+
"main_alliance_id",
|
|
226
|
+
"main_alliance",
|
|
227
|
+
),
|
|
228
|
+
},
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
"""Singleton config for the core BigBrother module."""
|
|
232
|
+
readonly_fields = (
|
|
233
|
+
"main_corporation",
|
|
234
|
+
"main_alliance",
|
|
235
|
+
"main_corporation_id",
|
|
236
|
+
"main_alliance_id",
|
|
237
|
+
"update_last_dispatch_count",
|
|
238
|
+
)
|
|
239
|
+
filter_horizontal = (
|
|
240
|
+
"pingrole1_messages",
|
|
241
|
+
"pingrole2_messages",
|
|
242
|
+
"here_messages",
|
|
243
|
+
"everyone_messages",
|
|
244
|
+
"bb_guest_states",
|
|
245
|
+
"bb_member_states",
|
|
246
|
+
# aa-contacts M2M (only if installed)
|
|
247
|
+
*(
|
|
248
|
+
("contacts_source_alliances", "contacts_source_corporations")
|
|
249
|
+
if AA_CONTACTS_INSTALLED
|
|
250
|
+
else ()
|
|
251
|
+
),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
class Media:
|
|
255
|
+
js = ("aa_bb/js/admin_market_toggle.js",)
|
|
256
|
+
|
|
257
|
+
def has_add_permission(self, request):
|
|
258
|
+
"""Prevent duplicate singleton rows."""
|
|
259
|
+
if BigBrotherConfig.objects.exists(): # Disallow when a config already exists.
|
|
260
|
+
return False
|
|
261
|
+
return super().has_add_permission(request)
|
|
262
|
+
|
|
263
|
+
def has_delete_permission(self, request, obj=None):
|
|
264
|
+
"""Always allow deleting to keep parity with default behavior."""
|
|
265
|
+
return True
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@admin.register(PapsConfig)
|
|
269
|
+
class PapsConfigAdmin(SingletonModelAdmin):
|
|
270
|
+
"""Controls PAP multipliers/thresholds; singleton per installation."""
|
|
271
|
+
filter_horizontal = (
|
|
272
|
+
"group_paps",
|
|
273
|
+
"excluded_groups",
|
|
274
|
+
"excluded_users",
|
|
275
|
+
"excluded_users_paps",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def has_add_permission(self, request):
|
|
279
|
+
"""Prevent duplicate PAP config entries."""
|
|
280
|
+
if PapsConfig.objects.exists(): # Disallow singleton duplication.
|
|
281
|
+
return False
|
|
282
|
+
return super().has_add_permission(request)
|
|
283
|
+
|
|
284
|
+
def has_delete_permission(self, request, obj=None):
|
|
285
|
+
"""Allow deletes so admins can rebuild the configuration."""
|
|
286
|
+
return True
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@admin.register(TicketToolConfig)
|
|
290
|
+
class TicketToolConfigAdmin(SingletonModelAdmin):
|
|
291
|
+
"""Ticket automation thresholds + templates."""
|
|
292
|
+
readonly_fields = ("ticket_counter",)
|
|
293
|
+
filter_horizontal = (
|
|
294
|
+
"excluded_users",
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def get_fieldsets(self, request, obj=None):
|
|
298
|
+
fieldsets = [
|
|
299
|
+
(None, {
|
|
300
|
+
'fields': ('ticket_type', 'role_id', 'hr_forum_webhook', 'Forum_Channel_ID', 'ticket_counter', 'excluded_users')
|
|
301
|
+
}),
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
# Corp Compliance Check - only show compliance_filter if charlink is installed
|
|
305
|
+
corp_check_fields = []
|
|
306
|
+
if charlink_active():
|
|
307
|
+
corp_check_fields.append('compliance_filter')
|
|
308
|
+
corp_check_fields.extend(['corp_check_enabled', 'corp_check_include_user', 'corp_check', 'corp_check_frequency', 'corp_check_reason', 'corp_check_reminder'])
|
|
309
|
+
|
|
310
|
+
fieldsets.append(('Corp Compliance Check', {
|
|
311
|
+
'fields': tuple(corp_check_fields)
|
|
312
|
+
}))
|
|
313
|
+
|
|
314
|
+
fieldsets.extend([
|
|
315
|
+
('Inactivity Check', {
|
|
316
|
+
'fields': ('afk_check_enabled', 'afk_check_include_user', 'Max_Afk_Days', 'afk_check', 'afk_check_frequency', 'afk_check_reason', 'afk_check_reminder')
|
|
317
|
+
}),
|
|
318
|
+
('Discord Inactivity Check', {
|
|
319
|
+
'fields': ('discord_inactivity_enabled', 'discord_inactivity_include_user', 'discord_inactivity_days', 'discord_inactivity_reason')
|
|
320
|
+
}),
|
|
321
|
+
('Character Removal Check', {
|
|
322
|
+
'fields': ('char_removed_enabled', 'char_removed_include_user', 'char_removed_reason')
|
|
323
|
+
}),
|
|
324
|
+
('AWOX Check', {
|
|
325
|
+
'fields': ('awox_monitor_enabled', 'awox_kill_include_user', 'awox_kill_reason')
|
|
326
|
+
}),
|
|
327
|
+
])
|
|
328
|
+
|
|
329
|
+
if discordbot_active():
|
|
330
|
+
fieldsets.insert(1, ('Private Channel Settings (Bot)', {
|
|
331
|
+
'fields': ('Category_ID', 'role_id')
|
|
332
|
+
}))
|
|
333
|
+
|
|
334
|
+
# Find the index of Inactivity Check to insert Discord Link Check after it
|
|
335
|
+
idx = 0
|
|
336
|
+
for i, (name, _) in enumerate(fieldsets):
|
|
337
|
+
if name == 'Inactivity Check':
|
|
338
|
+
idx = i + 1
|
|
339
|
+
break
|
|
340
|
+
|
|
341
|
+
fieldsets.insert(idx, ('Discord Link Check', {
|
|
342
|
+
'fields': ('discord_check_enabled', 'discord_check', 'discord_check_frequency', 'discord_check_reason', 'discord_check_reminder')
|
|
343
|
+
}))
|
|
344
|
+
|
|
345
|
+
if afat_active():
|
|
346
|
+
fieldsets.append(('PAP Compliance Check', {
|
|
347
|
+
'fields': ('paps_check_enabled', 'paps_check_include_user', 'max_months_without_pap_compliance', 'starting_pap_compliance', 'paps_check', 'paps_check_frequency', 'paps_check_reason', 'paps_check_reminder')
|
|
348
|
+
}))
|
|
349
|
+
|
|
350
|
+
return fieldsets
|
|
351
|
+
|
|
352
|
+
class Media:
|
|
353
|
+
js = ("aa_bb/js/admin_ticket_type_toggle.js",)
|
|
354
|
+
|
|
355
|
+
def get_form(self, request, obj=None, **kwargs):
|
|
356
|
+
from django import forms
|
|
357
|
+
form = super().get_form(request, obj, **kwargs)
|
|
358
|
+
|
|
359
|
+
# Make role_id a textarea
|
|
360
|
+
if 'role_id' in form.base_fields:
|
|
361
|
+
form.base_fields['role_id'].widget = forms.Textarea(attrs={'rows': 3, 'cols': 40})
|
|
362
|
+
|
|
363
|
+
if not discordbot_active():
|
|
364
|
+
from .models import TicketToolConfig
|
|
365
|
+
# Restrict choices if bot is not active
|
|
366
|
+
allowed_choices = [
|
|
367
|
+
(TicketToolConfig.TICKET_TYPE_FORUM_THREAD, 'Public Forum Threads (Webhook)'),
|
|
368
|
+
(TicketToolConfig.TICKET_TYPE_AUTH_ONLY, 'Auth Only (No Discord)'),
|
|
369
|
+
]
|
|
370
|
+
form.base_fields['ticket_type'].choices = allowed_choices
|
|
371
|
+
return form
|
|
372
|
+
|
|
373
|
+
def has_add_permission(self, request):
|
|
374
|
+
"""Prevent duplicate ticket config entries."""
|
|
375
|
+
if TicketToolConfig.objects.exists(): # Ticket config should remain singleton.
|
|
376
|
+
return False
|
|
377
|
+
return super().has_add_permission(request)
|
|
378
|
+
|
|
379
|
+
def has_delete_permission(self, request, obj=None):
|
|
380
|
+
"""Allow deletes when operators need to reset settings."""
|
|
381
|
+
return True
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
@admin.register(EveItemPrice)
|
|
387
|
+
class EveItemPriceAdmin(admin.ModelAdmin):
|
|
388
|
+
list_display = ("eve_type_id", "buy", "sell", "updated")
|
|
389
|
+
search_fields = ("eve_type_id",)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@admin.register(Messages)
|
|
393
|
+
class DailyMessageConfig(admin.ModelAdmin):
|
|
394
|
+
"""Standard daily webhook messages rotated each cycle."""
|
|
395
|
+
search_fields = ["text"]
|
|
396
|
+
list_display = ["text", "sent_in_cycle"]
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
@admin.register(OptMessages1)
|
|
400
|
+
class OptMessage1Config(admin.ModelAdmin):
|
|
401
|
+
"""Optional webhook stream #1."""
|
|
402
|
+
search_fields = ["text"]
|
|
403
|
+
list_display = ["text", "sent_in_cycle"]
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
@admin.register(OptMessages2)
|
|
407
|
+
class OptMessage2Config(admin.ModelAdmin):
|
|
408
|
+
"""Optional webhook stream #2."""
|
|
409
|
+
search_fields = ["text"]
|
|
410
|
+
list_display = ["text", "sent_in_cycle"]
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@admin.register(OptMessages3)
|
|
414
|
+
class OptMessage3Config(admin.ModelAdmin):
|
|
415
|
+
"""Optional webhook stream #3."""
|
|
416
|
+
search_fields = ["text"]
|
|
417
|
+
list_display = ["text", "sent_in_cycle"]
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
@admin.register(OptMessages4)
|
|
421
|
+
class OptMessage4Config(admin.ModelAdmin):
|
|
422
|
+
"""Optional webhook stream #4."""
|
|
423
|
+
search_fields = ["text"]
|
|
424
|
+
list_display = ["text", "sent_in_cycle"]
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
@admin.register(OptMessages5)
|
|
428
|
+
class OptMessage5Config(admin.ModelAdmin):
|
|
429
|
+
"""Optional webhook stream #5."""
|
|
430
|
+
search_fields = ["text"]
|
|
431
|
+
list_display = ["text", "sent_in_cycle"]
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@admin.register(WarmProgress)
|
|
435
|
+
class WarmProgressConfig(admin.ModelAdmin):
|
|
436
|
+
"""Shows which users the cache warmer has processed recently."""
|
|
437
|
+
list_display = ["user_main", "updated"]
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
@admin.register(UserStatus)
|
|
441
|
+
class UserStatusConfig(admin.ModelAdmin):
|
|
442
|
+
"""Simple heartbeat for per-user card status."""
|
|
443
|
+
list_display = ["user", "updated"]
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
class ReasonFilter(admin.SimpleListFilter):
|
|
447
|
+
title = 'reason'
|
|
448
|
+
parameter_name = 'reason'
|
|
449
|
+
|
|
450
|
+
def lookups(self, request, model_admin):
|
|
451
|
+
from .models import ComplianceTicket
|
|
452
|
+
reasons = list(ComplianceTicket.REASONS)
|
|
453
|
+
if not afat_active():
|
|
454
|
+
reasons = [r for r in reasons if r[0] != "paps_check"]
|
|
455
|
+
if not discordbot_active():
|
|
456
|
+
reasons = [r for r in reasons if r[0] != "discord_check"]
|
|
457
|
+
return reasons
|
|
458
|
+
|
|
459
|
+
def queryset(self, request, queryset):
|
|
460
|
+
if self.value():
|
|
461
|
+
return queryset.filter(reason=self.value())
|
|
462
|
+
return queryset
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
@admin.register(ComplianceTicket)
|
|
466
|
+
class ComplianceTicketConfig(admin.ModelAdmin):
|
|
467
|
+
"""History of tickets issued by the automation layer."""
|
|
468
|
+
list_display = ["user", "ticket_id", "reason", "is_resolved", "is_exception"]
|
|
469
|
+
list_filter = ["is_resolved", "is_exception", ReasonFilter]
|
|
470
|
+
readonly_fields = ["created_at"]
|
|
471
|
+
|
|
472
|
+
actions = ["mark_as_exception", "clear_exception", "mark_as_resolved", "mark_as_open"]
|
|
473
|
+
|
|
474
|
+
def mark_as_exception(self, request, queryset):
|
|
475
|
+
"""Mark selected tickets as exceptions."""
|
|
476
|
+
count = queryset.update(is_exception=True, exception_reason=f"Marked as exception by {request.user.username}")
|
|
477
|
+
self.message_user(request, f"{count} ticket(s) marked as exception.")
|
|
478
|
+
mark_as_exception.short_description = "Mark selected tickets as exception"
|
|
479
|
+
|
|
480
|
+
def clear_exception(self, request, queryset):
|
|
481
|
+
"""Clear exception status from selected tickets."""
|
|
482
|
+
count = queryset.update(is_exception=False, exception_reason=None)
|
|
483
|
+
self.message_user(request, f"{count} ticket(s) exception status cleared.")
|
|
484
|
+
clear_exception.short_description = "Clear exception status"
|
|
485
|
+
|
|
486
|
+
def mark_as_resolved(self, request, queryset):
|
|
487
|
+
"""Mark selected tickets as resolved."""
|
|
488
|
+
count = queryset.update(is_resolved=True)
|
|
489
|
+
self.message_user(request, f"{count} ticket(s) marked as resolved.")
|
|
490
|
+
mark_as_resolved.short_description = "Mark selected tickets as resolved"
|
|
491
|
+
|
|
492
|
+
def mark_as_open(self, request, queryset):
|
|
493
|
+
"""Mark selected tickets as open."""
|
|
494
|
+
count = queryset.update(is_resolved=False, is_exception=False)
|
|
495
|
+
self.message_user(request, f"{count} ticket(s) marked as open.")
|
|
496
|
+
mark_as_open.short_description = "Mark selected tickets as open"
|
|
497
|
+
|
|
498
|
+
def get_queryset(self, request):
|
|
499
|
+
qs = super().get_queryset(request)
|
|
500
|
+
if not afat_active():
|
|
501
|
+
qs = qs.exclude(reason="paps_check")
|
|
502
|
+
if not discordbot_active():
|
|
503
|
+
qs = qs.exclude(reason="discord_check")
|
|
504
|
+
return qs
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
@admin.register(ComplianceThread)
|
|
508
|
+
class ComplianceThreadAdmin(admin.ModelAdmin):
|
|
509
|
+
"""Mapping of user/reason to Discord thread IDs."""
|
|
510
|
+
list_display = ["user", "reason", "thread_id"]
|
|
511
|
+
list_filter = [ReasonFilter]
|
|
512
|
+
|
|
513
|
+
def get_queryset(self, request):
|
|
514
|
+
qs = super().get_queryset(request)
|
|
515
|
+
if not afat_active():
|
|
516
|
+
qs = qs.exclude(reason="paps_check")
|
|
517
|
+
if not discordbot_active():
|
|
518
|
+
qs = qs.exclude(reason="discord_check")
|
|
519
|
+
return qs
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
@admin.register(LeaveRequest)
|
|
523
|
+
class LeaveRequestConfig(admin.ModelAdmin):
|
|
524
|
+
"""Expose LeaveRequest records to staff when LoA is enabled."""
|
|
525
|
+
list_display = ["main_character", "start_date", "end_date", "reason", "status"]
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
@admin.register(PapCompliance)
|
|
529
|
+
class PapComplianceConfig(admin.ModelAdmin):
|
|
530
|
+
"""Shows the most recent PAP compliance calculation per user."""
|
|
531
|
+
search_fields = ["user_profile"]
|
|
532
|
+
list_display = ["user_profile", "pap_compliant"]
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
@admin.register(RecurringStatsConfig)
|
|
536
|
+
class RecurringStatsConfigAdmin(SingletonModelAdmin):
|
|
537
|
+
fieldsets = (
|
|
538
|
+
(
|
|
539
|
+
"General",
|
|
540
|
+
{
|
|
541
|
+
"fields": ("enabled",),
|
|
542
|
+
},
|
|
543
|
+
),
|
|
544
|
+
(
|
|
545
|
+
"States",
|
|
546
|
+
{
|
|
547
|
+
"fields": ("states",),
|
|
548
|
+
"description": "Select which states you want broken out (Member, Blue, Alumni, etc.).",
|
|
549
|
+
},
|
|
550
|
+
),
|
|
551
|
+
(
|
|
552
|
+
"Included Stats",
|
|
553
|
+
{
|
|
554
|
+
"fields": (
|
|
555
|
+
"include_auth_users",
|
|
556
|
+
"include_discord_users",
|
|
557
|
+
"include_mumble_users",
|
|
558
|
+
"include_characters",
|
|
559
|
+
"include_corporations",
|
|
560
|
+
"include_alliances",
|
|
561
|
+
"include_tokens",
|
|
562
|
+
"include_unique_tokens",
|
|
563
|
+
"include_character_audits",
|
|
564
|
+
"include_corporation_audits",
|
|
565
|
+
),
|
|
566
|
+
},
|
|
567
|
+
),
|
|
568
|
+
(
|
|
569
|
+
"Internal",
|
|
570
|
+
{
|
|
571
|
+
"fields": ("last_run_at", "last_snapshot"),
|
|
572
|
+
"classes": ("collapse",),
|
|
573
|
+
},
|
|
574
|
+
),
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
filter_horizontal = ("states",)
|
|
578
|
+
readonly_fields = ("last_run_at", "last_snapshot")
|
|
579
|
+
|
|
580
|
+
if not afat_active():
|
|
581
|
+
for _m in (PapsConfig, PapCompliance):
|
|
582
|
+
try:
|
|
583
|
+
admin.site.unregister(_m)
|
|
584
|
+
except NotRegistered:
|
|
585
|
+
pass
|
|
586
|
+
|
|
587
|
+
_PAP_OBJECT_NAMES = {"PapsConfig", "PapCompliance"}
|
|
588
|
+
_MARKET_OBJECT_NAMES = {"EveItemPrice", "ProcessedTransaction", "SusTransactionNote"}
|
|
589
|
+
_ORIG_GET_APP_LIST = admin.site.get_app_list
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
def _filtered_get_app_list(request, app_label=None):
|
|
593
|
+
app_list = _ORIG_GET_APP_LIST(request, app_label)
|
|
594
|
+
|
|
595
|
+
is_afat = afat_active()
|
|
596
|
+
config = BigBrotherConfig.get_solo()
|
|
597
|
+
show_market = getattr(config, "show_market_transactions", False)
|
|
598
|
+
|
|
599
|
+
filtered = []
|
|
600
|
+
for app in app_list:
|
|
601
|
+
label = app.get("app_label")
|
|
602
|
+
|
|
603
|
+
# Exclude AFAT's own admin section if present.
|
|
604
|
+
if not is_afat and label == "afat":
|
|
605
|
+
continue
|
|
606
|
+
|
|
607
|
+
# Filter models within our app
|
|
608
|
+
if label == "aa_bb":
|
|
609
|
+
models = app.get("models", [])
|
|
610
|
+
if not is_afat:
|
|
611
|
+
models = [
|
|
612
|
+
m for m in models if m.get("object_name") not in _PAP_OBJECT_NAMES
|
|
613
|
+
]
|
|
614
|
+
if not show_market:
|
|
615
|
+
models = [
|
|
616
|
+
m for m in models if m.get("object_name") not in _MARKET_OBJECT_NAMES
|
|
617
|
+
]
|
|
618
|
+
app = {**app, "models": models}
|
|
619
|
+
|
|
620
|
+
# Drop empty app groups
|
|
621
|
+
if app.get("models"):
|
|
622
|
+
filtered.append(app)
|
|
623
|
+
|
|
624
|
+
return filtered
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
admin.site.get_app_list = _filtered_get_app_list
|