Skip to content

Commit a6d21c5

Browse files
Merge remote-tracking branch 'upstream/smell/too-many-instance-attributes' into smell/too-many-branches_and_too-many-statements
2 parents c4619de + 635a014 commit a6d21c5

9 files changed

Lines changed: 244 additions & 150 deletions

File tree

bot/exts/filtering/_filters/filter.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Filter(FieldRequiring):
3131
# If a subclass uses extra fields, it should assign the pydantic model type to this variable.
3232
extra_fields_type = None
3333

34-
def __init__(self, filter_data: dict, defaults: Defaults | None = None):
34+
def __init__(self, filter_data: dict, defaults: Defaults | None=None):
3535
self.id = filter_data["id"]
3636
self.content = filter_data["content"]
3737
self.description = filter_data["description"]
@@ -90,6 +90,15 @@ async def process_input(cls, content: str, description: str) -> tuple[str, str]:
9090
A BadArgument should be raised if the content can't be used.
9191
"""
9292
return content, description
93+
94+
95+
@property
96+
def created_at(self) -> arrow.Arrow:
97+
return self.timestamps.created_at
98+
99+
@property
100+
def updated_at(self) -> arrow.Arrow:
101+
return self.timestamps.updated_at
93102

94103
def __str__(self) -> str:
95104
"""A string representation of the filter."""

bot/exts/filtering/_ui/filter.py

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections.abc import Callable
2+
from dataclasses import dataclass
23
from typing import Any
34

45
import discord
@@ -110,6 +111,35 @@ async def on_submit(self, interaction: Interaction) -> None:
110111
await self.embed_view.apply_template(self.template.value, self.message, interaction)
111112

112113

114+
@dataclass
115+
class FilterTarget:
116+
"""The filter being edited and its context."""
117+
filter_list: FilterList
118+
list_type: ListType
119+
filter_type: type[Filter]
120+
121+
122+
@dataclass
123+
class FilterContent:
124+
"""Content and description of the filter being edited."""
125+
content: str | None
126+
description: str | None
127+
128+
129+
def build_type_per_setting_name(
130+
filter_type: type[Filter],
131+
loaded_settings: dict,
132+
loaded_filter_settings: dict,
133+
) -> dict:
134+
"""Build the type_per_setting_name dict from the loaded settings."""
135+
type_per_setting_name = {setting: info[2] for setting, info in loaded_settings.items()}
136+
type_per_setting_name.update({
137+
f"{filter_type.name}/{name}": type_
138+
for name, (_, _, type_) in loaded_filter_settings.get(filter_type.name, {}).items()
139+
})
140+
return type_per_setting_name
141+
142+
113143
class FilterEditView(EditBaseView):
114144
"""A view used to edit a filter's settings before updating the database."""
115145

@@ -118,11 +148,8 @@ class _REMOVE:
118148

119149
def __init__(
120150
self,
121-
filter_list: FilterList,
122-
list_type: ListType,
123-
filter_type: type[Filter],
124-
content: str | None,
125-
description: str | None,
151+
filter_target: FilterTarget,
152+
filter_content: FilterContent,
126153
settings_overrides: dict,
127154
filter_settings_overrides: dict,
128155
loaded: LoadedTypes,
@@ -131,19 +158,17 @@ def __init__(
131158
confirm_callback: Callable
132159
):
133160
super().__init__(author)
134-
self.filter_list = filter_list
135-
self.list_type = list_type
136-
self.filter_type = filter_type
137-
self.content = content
138-
self.description = description
161+
self.filter_target = filter_target
162+
self.filter_content = filter_content
139163
self.settings_overrides = settings_overrides
140164
self.filter_settings_overrides = filter_settings_overrides
141165
self.loaded = loaded
142166
self.embed = embed
143167
self.confirm_callback = confirm_callback
144168

145169
all_settings_repr_dict = build_filter_repr_dict(
146-
filter_list, list_type, filter_type, settings_overrides, filter_settings_overrides
170+
filter_target.filter_list, filter_target.list_type, filter_target.filter_type,
171+
settings_overrides, filter_settings_overrides
147172
)
148173
populate_embed_from_dict(embed, all_settings_repr_dict)
149174

@@ -156,14 +181,15 @@ def __init__(
156181
add_select = CustomCallbackSelect(
157182
self._prompt_new_value,
158183
placeholder="Select a setting to edit",
159-
options=[SelectOption(label=name) for name in sorted(self.type_per_setting_name)],
184+
options=[SelectOption(label=name) for name in sorted(type_per_setting_name)],
160185
row=1
161186
)
162187
self.add_item(add_select)
163188

164189
if settings_overrides or filter_settings_overrides:
165190
override_names = (
166-
list(settings_overrides) + [f"{filter_list.name}/{setting}" for setting in filter_settings_overrides]
191+
list(settings_overrides)
192+
+ [f"{filter_target.filter_list.name}/{setting}" for setting in filter_settings_overrides]
167193
)
168194
remove_select = CustomCallbackSelect(
169195
self._remove_override,
@@ -199,21 +225,21 @@ async def enter_template(self, interaction: Interaction, button: discord.ui.Butt
199225
@discord.ui.button(label="✅ Confirm", style=discord.ButtonStyle.green, row=4)
200226
async def confirm(self, interaction: Interaction, button: discord.ui.Button) -> None:
201227
"""Confirm the content, description, and settings, and update the filters database."""
202-
if self.content is None:
228+
if self.filter_content.content is None:
203229
await interaction.response.send_message(
204230
":x: Cannot add a filter with no content.", ephemeral=True, reference=interaction.message
205231
)
206-
if self.description is None:
207-
self.description = ""
232+
if self.filter_content.description is None:
233+
self.filter_content.description = ""
208234
await interaction.response.edit_message(view=None) # Make sure the interaction succeeds first.
209235
try:
210236
await self.confirm_callback(
211237
interaction.message,
212-
self.filter_list,
213-
self.list_type,
214-
self.filter_type,
215-
self.content,
216-
self.description,
238+
self.filter_target.filter_list,
239+
self.filter_target.list_type,
240+
self.filter_target.filter_type,
241+
self.filter_content.content,
242+
self.filter_content.description,
217243
self.settings_overrides,
218244
self.filter_settings_overrides
219245
)
@@ -348,7 +374,7 @@ async def apply_template(self, template_id: str, embed_message: discord.Message,
348374
"""Replace any non-overridden settings with overrides from the given filter."""
349375
try:
350376
settings, filter_settings = template_settings(
351-
template_id, self.filter_list, self.list_type, self.filter_type
377+
template_id, self.filter_target.filter_list, self.filter_target.list_type, self.filter_target.filter_type
352378
)
353379
except BadArgument as e: # The interaction object is necessary to send an ephemeral message.
354380
await interaction.response.send_message(f":x: {e}", ephemeral=True)
@@ -373,11 +399,15 @@ async def _remove_override(self, interaction: Interaction, select: discord.ui.Se
373399
def copy(self) -> FilterEditView:
374400
"""Create a copy of this view."""
375401
return FilterEditView(
376-
self.filter_list,
377-
self.list_type,
378-
self.filter_type,
379-
self.content,
380-
self.description,
402+
FilterTarget(
403+
self.filter_target.filter_list,
404+
self.filter_target.list_type,
405+
self.filter_target.filter_type,
406+
),
407+
FilterContent(
408+
self.filter_content.content,
409+
self.filter_content.description,
410+
),
381411
self.settings_overrides,
382412
self.filter_settings_overrides,
383413
self.loaded,

bot/exts/filtering/_ui/filter_list.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def __init__(
8888
self.embed = embed
8989
self.confirm_callback = confirm_callback
9090

91-
self.settings_repr_dict = {name: to_serializable(value) for name, value in settings.items()}
92-
populate_embed_from_dict(embed, self.settings_repr_dict)
91+
settings_repr_dict = {name: to_serializable(value) for name, value in settings.items()}
92+
populate_embed_from_dict(embed, settings_repr_dict)
9393

9494
self.type_per_setting_name = {setting: info[2] for setting, info in loaded.settings.items()}
9595

@@ -189,8 +189,8 @@ def __init__(
189189
self.embed = embed
190190
self.confirm_callback = confirm_callback
191191

192-
self.settings_repr_dict = build_filterlist_repr_dict(filter_list, list_type, new_settings)
193-
populate_embed_from_dict(embed, self.settings_repr_dict)
192+
settings_repr_dict = build_filterlist_repr_dict(filter_list, list_type, new_settings)
193+
populate_embed_from_dict(embed, settings_repr_dict)
194194

195195
self.type_per_setting_name = {setting: info[2] for setting, info in loaded.settings.items()}
196196

@@ -221,11 +221,11 @@ async def cancel(self, interaction: Interaction, button: discord.ui.Button) -> N
221221
self.stop()
222222

223223
def current_value(self, setting_name: str) -> Any:
224-
"""Get the current value stored for the setting or MISSING if none found."""
225224
if setting_name in self.settings:
226225
return self.settings[setting_name]
227-
if setting_name in self.settings_repr_dict:
228-
return self.settings_repr_dict[setting_name]
226+
settings_repr_dict = build_filterlist_repr_dict(self.filter_list, self.list_type, self.settings)
227+
if setting_name in settings_repr_dict:
228+
return settings_repr_dict[setting_name]
229229
return MISSING
230230

231231
async def update_embed(

bot/exts/filtering/_ui/search.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections.abc import Callable
2+
from dataclasses import dataclass
23
from typing import Any
34

45
import discord
@@ -298,7 +299,7 @@ async def apply_template(self, template_id: str, embed_message: discord.Message,
298299
"""Set any unset criteria with settings values from the given filter."""
299300
try:
300301
settings, filter_settings, self.filter_type = template_settings(
301-
template_id, self.loaded_filter_lists, self.filter_type
302+
template_id, self.filter_resources.filter_lists, self.filter_type
302303
)
303304
except BadArgument as e: # The interaction object is necessary to send an ephemeral message.
304305
await interaction.response.send_message(f":x: {e}", ephemeral=True)

0 commit comments

Comments
 (0)