Skip to content

Commit

Permalink
Mute HTTP logging unless warning or higher (#71)
Browse files Browse the repository at this point in the history
* update pyproject for new ruff config and no-package setting

* update deps

* ruff updates

* ignore ruff in blame

* update action to use newest 1st party ruff action

* enable preview rules

* update ruff dep

* update latest ruff ruling

* add ruff related commits to blame

* mute logging info on http requests
  • Loading branch information
AbstractUmbra authored Dec 27, 2024
1 parent fc313aa commit 46d73f0
Show file tree
Hide file tree
Showing 26 changed files with 1,157 additions and 794 deletions.
4 changes: 4 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# run ruff
174ab9e3d7bc643805ac97acf71a225dd9523977

# update ruff config
e359280f0eb1ddcde18f35c21dedb429b6e0f28d
48e8c3d2ea7d88ac9049d9be53086a9e77926686
3 changes: 1 addition & 2 deletions .github/workflows/coverage_and_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,4 @@ jobs:
no-comments: ${{ matrix.python-version != '3.x' }}

- name: Lint
if: ${{ always() && steps.install-deps.outcome == 'success' }}
uses: chartboost/ruff-action@v1
uses: astral-sh/ruff-action@v3
6 changes: 4 additions & 2 deletions constants/_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ def __new__(mcs, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> t
return super().__new__(mcs, name, bases, attrs)

def __setattr__(self, attr: str, nv: Any) -> NoReturn:
raise RuntimeError(f"Constant <{attr}> cannot be assigned to.")
msg = f"Constant <{attr}> cannot be assigned to."
raise RuntimeError(msg)

def __delattr__(self, attr: str) -> NoReturn:
raise RuntimeError(f"Constant <{attr}> cannot be deleted.")
msg = f"Constant <{attr}> cannot be deleted."
raise RuntimeError(msg)


class CONSTANTS(metaclass=ConstantsMeta):
Expand Down
4 changes: 2 additions & 2 deletions constants/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
from ._meta import CONSTANTS

__all__ = (
"Roles",
"Colours",
"Channels",
"Colours",
"ForumTags",
"Roles",
)


Expand Down
31 changes: 17 additions & 14 deletions core/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
import aiohttp
import asyncpg
import mystbin
from discord.ext.commands.cog import Cog # type: ignore # stubs
from discord.ext.commands.cog import Cog # pyright: ignore[reportMissingTypeStubs] # stubs

from .utils import LogHandler

Expand All @@ -60,12 +60,12 @@ class Bot(commands.Bot):
logging_queue: Queue[LogRecord]

__slots__ = (
"session",
"pool",
"_previous_websocket_events",
"log_handler",
"mb_client",
"logging_queue",
"_previous_websocket_events",
"mb_client",
"pool",
"session",
)

def __init__(self) -> None:
Expand All @@ -77,11 +77,15 @@ def __init__(self) -> None:
self._previous_websocket_events: deque[Any] = deque(maxlen=10)

async def get_context(
self, message: discord.Message | discord.Interaction, /, *, cls: type[commands.Context[commands.Bot]] | None = None
self,
message: discord.Message | discord.Interaction,
/,
*,
cls: type[commands.Context[commands.Bot]] | None = None,
) -> Context:
return await super().get_context(message, cls=Context)

async def add_cog(self, cog: Cog, /, *, override: bool = False) -> None: # type: ignore
async def add_cog(self, cog: Cog, /, *, override: bool = False) -> None: # pyright: ignore[reportIncompatibleMethodOverride] # weird narrowing on Context generic
# we patch this since we're a single guild bot.
# it allows for guild syncing only.
return await super().add_cog(cog, override=override, guild=discord.Object(id=GUILD_ID))
Expand Down Expand Up @@ -111,13 +115,12 @@ async def on_error(self, event_name: str, /, *args: Any, **kwargs: Any) -> None:

args_str = ["```py"]
for index, arg in enumerate(args):
args_str.append(f"[{index}]: {arg!r}")
args_str.append("```")
args_str.extend((f"[{index}]: {arg!r}", "```"))
embed.add_field(name="Args", value="\n".join(args_str), inline=False)

self.log_handler.error("Event Error", extra={"embed": embed})

async def on_command_error(self, ctx: Context, error: commands.CommandError) -> None: # type: ignore # weird narrowing
async def on_command_error(self, ctx: Context, error: commands.CommandError) -> None: # pyright: ignore[reportIncompatibleMethodOverride] # weird narrowing on Context generic
assert ctx.command # wouldn't be here otherwise

if not isinstance(error, (commands.CommandInvokeError, commands.ConversionError)):
Expand Down Expand Up @@ -158,7 +161,7 @@ async def get_or_fetch_user(
try:
user = await guild.fetch_member(target_id)
except discord.HTTPException:
return
return None

if cache:
cache[target_id] = user
Expand All @@ -169,7 +172,7 @@ async def get_or_fetch_user(
try:
user = await self.fetch_user(target_id)
except discord.HTTPException:
return
return None

if cache:
cache[target_id] = user
Expand All @@ -182,11 +185,11 @@ async def start(self, token: str, *, reconnect: bool = True) -> None:
finally:
path = pathlib.Path("logs/prev_events.log")

with path.open("w+", encoding="utf-8") as f:
with path.open("w+", encoding="utf-8") as f: # noqa: ASYNC230 # this is okay as we're in cleanup phase
for event in self._previous_websocket_events:
try:
last_log = json.dumps(event, ensure_ascii=True, indent=2)
except Exception:
except (ValueError, TypeError):
f.write(f"{event}\n")
else:
f.write(f"{last_log}\n")
Expand Down
8 changes: 5 additions & 3 deletions core/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import constants

if TYPE_CHECKING:
from discord.ext.commands._types import Check # type: ignore # why would this need stubs
from discord.ext.commands._types import Check # pyright: ignore[reportMissingTypeStubs] # why would this need stubs

from core.context import GuildContext

Expand All @@ -42,7 +42,8 @@ def predicate(ctx: GuildContext) -> bool:
# This should never be a problem, but just in case...
if not role:
# TODO: Change this to a custom exception.
raise commands.CheckFailure(f"Role with ID <{role_id}> does not exist.")
msg = f"Role with ID <{role_id}> does not exist."
raise commands.CheckFailure(msg)

ignored = (constants.Roles.NITRO_BOOSTER, constants.Roles.MUTED)
roles = [r for r in ctx.author.roles if r.id not in ignored and ctx.author.top_role >= r]
Expand All @@ -51,6 +52,7 @@ def predicate(ctx: GuildContext) -> bool:
return True

# TODO: Change this to a custom exception.
raise commands.CheckFailure(f"{ctx.author} is not in or higher than role <{role.name}(ID: {role.id})>.")
msg = f"{ctx.author} is not in or higher than role <{role.name}(ID: {role.id})>."
raise commands.CheckFailure(msg)

return commands.check(predicate)
19 changes: 8 additions & 11 deletions core/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,32 @@ def replied_reference(self) -> discord.MessageReference | discord.Message:
return self.message

@discord.utils.cached_property
def replied_message(self) -> discord.Message | discord.Message:
def replied_message(self) -> discord.Message:
ref = self.message.reference
if ref and isinstance(ref.resolved, discord.Message):
return ref.resolved
return self.message

def author_is_mod(self) -> bool:
member: discord.Member
member: discord.Member | None

if self.guild is None: # dms
guild = self.bot.get_guild(GUILD_ID)

if not guild:
return False

_member = guild.get_member(self.author.id)
if _member is not None:
member = _member

else:
member = guild.get_member(self.author.id)
if member is None:
return False

else:
member = self.author # type: ignore
member = self.author # pyright: ignore[reportAssignmentType] # type lie for a shortcut

roles = member._roles # type: ignore # we know this won't change for a while
roles = member._roles # pyright: ignore[reportPrivateUsage,reportOptionalMemberAccess] # we know this won't change for a while
return roles.has(Roles.ADMIN) or roles.has(Roles.MODERATOR)


class GuildContext(Context):
guild: discord.Guild # type: ignore # type lie due to narrowing
author: discord.Member # type: ignore # type lie due to narrowing
guild: discord.Guild # pyright: ignore[reportIncompatibleVariableOverride] # type lie due to narrowing
author: discord.Member # pyright: ignore[reportIncompatibleVariableOverride] # type lie due to narrowing
10 changes: 3 additions & 7 deletions core/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CodeblockConverter(commands.Converter[Codeblock]):
:attr:`Codeblock.language` will be ``None`` if the input was not a complete codeblock.
"""

async def convert(self, ctx: Context, argument: str) -> Codeblock: # type: ignore # this is something to do with the typevar
async def convert(self, ctx: Context, argument: str) -> Codeblock: # pyright: ignore[reportIncompatibleMethodOverride] # generic narrowing on Context
if not argument.startswith("`"):
return Codeblock(None, argument)

Expand All @@ -58,12 +58,8 @@ async def convert(self, ctx: Context, argument: str) -> Codeblock: # type: igno
for character in argument:
if character == "`" and not within_code and not within_language:
backticks += 1
if (
previous_characters
and previous_characters[-1] == "`"
and character != "`"
or within_code
and "".join(previous_characters) != "`" * backticks
if (previous_characters and previous_characters[-1] == "`" and character != "`") or (
within_code and "".join(previous_characters) != "`" * backticks
):
within_code = True
code.append(character)
Expand Down
2 changes: 1 addition & 1 deletion core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
)


CONFIG: Config = toml.load("config.toml") # type: ignore # weird non-assertion
CONFIG: Config = toml.load("config.toml") # pyright: ignore[reportAssignmentType] # weirdly narrow library type


class Cog(commands.Cog):
Expand Down
5 changes: 3 additions & 2 deletions core/utils/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@
from discord.utils import escape_markdown

__all__ = (
"to_codeblock",
"random_pastel_colour",
"to_codeblock",
)


def to_codeblock(
content: str,
language: str = "py",
*,
replace_existing: bool = True,
escape_md: bool = True,
new: str = "'''",
Expand All @@ -50,4 +51,4 @@ def to_codeblock(


def random_pastel_colour() -> Colour:
return Colour.from_hsv(random.random(), 0.28, 0.97)
return Colour.from_hsv(random.random(), 0.28, 0.97) # noqa: S311 # not for crypto usage
14 changes: 9 additions & 5 deletions core/utils/logging.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from __future__ import annotations
from __future__ import annotations # noqa: A005 # we access this as a namespace

import logging
import pathlib
from logging.handlers import RotatingFileHandler
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING

from discord.utils import _ColourFormatter as ColourFormatter, stream_supports_colour # type: ignore # shh, I need it
from discord.utils import (
_ColourFormatter as ColourFormatter, # pyright: ignore[reportPrivateUsage] # shh, I need it # noqa: PLC2701
stream_supports_colour,
)

import core

Expand Down Expand Up @@ -46,6 +49,7 @@ def __enter__(self: Self) -> Self:
logging.getLogger("discord.http").setLevel(logging.INFO)
logging.getLogger("discord.state").setLevel(logging.WARNING)
logging.getLogger("discord.gateway").setLevel(logging.WARNING)
logging.getLogger("starlette_plus.core").setLevel(logging.WARNING)

self.log.setLevel(logging.INFO)
handler = RotatingFileHandler(
Expand All @@ -70,10 +74,10 @@ def __enter__(self: Self) -> Self:

return self

async def __aexit__(self, *args: Any) -> None:
async def __aexit__(self, *args: object) -> None:
return self.__exit__(*args)

def __exit__(self, *args: Any) -> None:
def __exit__(self, *args: object) -> None:
handlers = self.log.handlers[:]
for hdlr in handlers:
hdlr.close()
Expand Down
Loading

0 comments on commit 46d73f0

Please sign in to comment.