Merge branch 'release' into pillow
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Some useful pre-built Conditions for data queries.
|
||||
"""
|
||||
from typing import Optional
|
||||
from typing import Optional, Any
|
||||
from itertools import chain
|
||||
|
||||
from psycopg import sql
|
||||
@@ -11,7 +11,7 @@ from data.base import Expression
|
||||
from constants import MAX_COINS
|
||||
|
||||
|
||||
def MULTIVALUE_IN(columns: tuple[str, ...], *data: tuple[...]) -> Condition:
|
||||
def MULTIVALUE_IN(columns: tuple[str, ...], *data: tuple[Any, ...]) -> Condition:
|
||||
"""
|
||||
Condition constructor for filtering by multiple column equalities.
|
||||
|
||||
@@ -100,7 +100,7 @@ class TemporaryTable(Expression):
|
||||
```
|
||||
"""
|
||||
|
||||
def __init__(self, *columns: str, name: str = '_t', types: Optional[tuple[str]] = None):
|
||||
def __init__(self, *columns: str, name: str = '_t', types: Optional[tuple[str, ...]] = None):
|
||||
self.name = name
|
||||
self.columns = columns
|
||||
self.types = types
|
||||
|
||||
@@ -4,6 +4,7 @@ import datetime
|
||||
import iso8601 # type: ignore
|
||||
import pytz
|
||||
import re
|
||||
import json
|
||||
from contextvars import Context
|
||||
|
||||
import discord
|
||||
@@ -764,7 +765,7 @@ class Timezoned:
|
||||
Return the start of the current month in the object's timezone
|
||||
"""
|
||||
today = self.today
|
||||
return today - datetime.timedelta(days=today.day)
|
||||
return today - datetime.timedelta(days=(today.day - 1))
|
||||
|
||||
|
||||
def replace_multiple(format_string, mapping):
|
||||
@@ -829,3 +830,60 @@ async def check_dm(user: discord.User | discord.Member) -> bool:
|
||||
return False
|
||||
except discord.HTTPException:
|
||||
return True
|
||||
|
||||
|
||||
async def command_lengths(tree) -> dict[str, int]:
|
||||
cmds = tree.get_commands()
|
||||
payloads = [
|
||||
await cmd.get_translated_payload(tree.translator)
|
||||
for cmd in cmds
|
||||
]
|
||||
lens = {}
|
||||
for command in payloads:
|
||||
name = command['name']
|
||||
crumbs = {}
|
||||
cmd_len = lens[name] = _recurse_length(command, crumbs, (name,))
|
||||
if name == 'configure' or cmd_len > 4000:
|
||||
print(f"'{name}' over 4000. Breadcrumb Trail follows:")
|
||||
lines = []
|
||||
for loc, val in crumbs.items():
|
||||
locstr = '.'.join(loc)
|
||||
lines.append(f"{locstr}: {val}")
|
||||
print('\n'.join(lines))
|
||||
print(json.dumps(command, indent=2))
|
||||
return lens
|
||||
|
||||
def _recurse_length(payload, breadcrumbs={}, header=()) -> int:
|
||||
total = 0
|
||||
total_header = (*header, '')
|
||||
breadcrumbs[total_header] = 0
|
||||
|
||||
if isinstance(payload, dict):
|
||||
# Read strings that count towards command length
|
||||
# String length is length of longest localisation, including default.
|
||||
for key in ('name', 'description', 'value'):
|
||||
if key in payload:
|
||||
value = payload[key]
|
||||
if isinstance(value, str):
|
||||
values = (value, *payload.get(key + '_localizations', {}).values())
|
||||
maxlen = max(map(len, values))
|
||||
total += maxlen
|
||||
breadcrumbs[(*header, key)] = maxlen
|
||||
|
||||
for key, value in payload.items():
|
||||
loc = (*header, key)
|
||||
total += _recurse_length(value, breadcrumbs, loc)
|
||||
elif isinstance(payload, list):
|
||||
for i, item in enumerate(payload):
|
||||
if isinstance(item, dict) and 'name' in item:
|
||||
loc = (*header, f"{i}<{item['name']}>")
|
||||
else:
|
||||
loc = (*header, str(i))
|
||||
total += _recurse_length(item, breadcrumbs, loc)
|
||||
|
||||
if total:
|
||||
breadcrumbs[total_header] = total
|
||||
else:
|
||||
breadcrumbs.pop(total_header)
|
||||
|
||||
return total
|
||||
|
||||
@@ -56,7 +56,10 @@ class Bucket:
|
||||
def delay(self):
|
||||
self._leak()
|
||||
if self._level + 1 > self.max_level:
|
||||
return (self._level + 1 - self.max_level) * self.leak_rate
|
||||
delay = (self._level + 1 - self.max_level) * self.leak_rate
|
||||
else:
|
||||
delay = 0
|
||||
return delay
|
||||
|
||||
def _leak(self):
|
||||
if self._level:
|
||||
|
||||
@@ -181,6 +181,31 @@ class MsgEditor(MessageUI):
|
||||
"Add Embed"
|
||||
))
|
||||
|
||||
@button(label="RM_EMBED_BUTTON_PLACEHOLDER", style=ButtonStyle.red)
|
||||
async def rm_embed_button(self, press: discord.Interaction, pressed: Button):
|
||||
"""
|
||||
Remove the existing embed from the message.
|
||||
"""
|
||||
await press.response.defer()
|
||||
t = self.bot.translator.t
|
||||
data = self.copy_data()
|
||||
data.pop('embed', None)
|
||||
data.pop('embeds', None)
|
||||
if not data.get('content', '').strip():
|
||||
data['content'] = t(_p(
|
||||
'ui:msg_editor|button:rm_embed|sample_content',
|
||||
"Content Placeholder"
|
||||
))
|
||||
await self.push_change(data)
|
||||
|
||||
async def rm_embed_button_refresh(self):
|
||||
t = self.bot.translator.t
|
||||
button = self.rm_embed_button
|
||||
button.label = t(_p(
|
||||
'ui:msg_editor|button:rm_embed|label',
|
||||
"Remove Embed"
|
||||
))
|
||||
|
||||
# -- Embed Mode --
|
||||
|
||||
@button(label="BODY_BUTTON_PLACEHOLDER", style=ButtonStyle.blurple)
|
||||
@@ -934,7 +959,7 @@ class MsgEditor(MessageUI):
|
||||
return MessageArgs(**args)
|
||||
|
||||
async def refresh_layout(self):
|
||||
await asyncio.gather(
|
||||
to_refresh = (
|
||||
self.edit_button_refresh(),
|
||||
self.add_embed_button_refresh(),
|
||||
self.body_button_refresh(),
|
||||
@@ -948,12 +973,16 @@ class MsgEditor(MessageUI):
|
||||
self.download_button_refresh(),
|
||||
self.undo_button_refresh(),
|
||||
self.redo_button_refresh(),
|
||||
self.rm_embed_button_refresh(),
|
||||
)
|
||||
await asyncio.gather(*to_refresh)
|
||||
|
||||
if self.history[-1].get('embed', None):
|
||||
self.set_layout(
|
||||
(self.body_button, self.author_button, self.footer_button, self.images_button, self.add_field_button),
|
||||
(self.edit_field_menu,),
|
||||
(self.delete_field_menu,),
|
||||
(self.rm_embed_button,),
|
||||
(self.save_button, self.download_button, self.undo_button, self.redo_button, self.quit_button),
|
||||
)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user