mirror of
https://github.com/neoarz/Syntrel.git
synced 2025-12-25 03:40:11 +01:00
chore: ruff formatting
This commit is contained in:
@@ -5,7 +5,13 @@ from .signal import setup_signal_handlers
|
||||
from .contributors import generate_contributors_image
|
||||
|
||||
__all__ = [
|
||||
'ascii', 'ascii_plain', 'gradient_text', 'gradient_text_selective',
|
||||
'LoggingFormatter', 'setup_logger', 'get_uptime', 'setup_signal_handlers',
|
||||
'generate_contributors_image'
|
||||
]
|
||||
"ascii",
|
||||
"ascii_plain",
|
||||
"gradient_text",
|
||||
"gradient_text_selective",
|
||||
"LoggingFormatter",
|
||||
"setup_logger",
|
||||
"get_uptime",
|
||||
"setup_signal_handlers",
|
||||
"generate_contributors_image",
|
||||
]
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
import math
|
||||
|
||||
|
||||
def gradient_text(text, start_color, end_color):
|
||||
def rgb_interp(start, end, t):
|
||||
return tuple(int(start[i] + (end[i] - start[i]) * t) for i in range(3))
|
||||
|
||||
lines = text.splitlines()
|
||||
gradient_lines = []
|
||||
total_chars = sum(len(line) for line in lines if line.strip())
|
||||
@@ -23,24 +25,27 @@ def gradient_text(text, start_color, end_color):
|
||||
gradient_lines.append(colored_line)
|
||||
return "\n".join(gradient_lines)
|
||||
|
||||
def gradient_text_selective(text, start_color, end_color, gradient_word, white_prefix=""):
|
||||
|
||||
def gradient_text_selective(
|
||||
text, start_color, end_color, gradient_word, white_prefix=""
|
||||
):
|
||||
def rgb_interp(start, end, t):
|
||||
return tuple(int(start[i] + (end[i] - start[i]) * t) for i in range(3))
|
||||
|
||||
|
||||
lines = text.splitlines()
|
||||
result_lines = []
|
||||
|
||||
|
||||
for line in lines:
|
||||
if gradient_word in line and white_prefix in line:
|
||||
prefix_start = line.find(white_prefix)
|
||||
word_start = line.find(gradient_word)
|
||||
|
||||
|
||||
if prefix_start != -1 and word_start != -1:
|
||||
before_prefix = line[:prefix_start]
|
||||
prefix_part = line[prefix_start:word_start]
|
||||
word_part = gradient_word
|
||||
after_word = line[word_start + len(gradient_word):]
|
||||
|
||||
after_word = line[word_start + len(gradient_word) :]
|
||||
|
||||
colored_before = ""
|
||||
total_chars = sum(1 for char in before_prefix if char.strip())
|
||||
idx = 0
|
||||
@@ -52,9 +57,9 @@ def gradient_text_selective(text, start_color, end_color, gradient_word, white_p
|
||||
idx += 1
|
||||
else:
|
||||
colored_before += char
|
||||
|
||||
|
||||
white_prefix_colored = f"\033[38;2;255;255;255m{prefix_part}\033[0m"
|
||||
|
||||
|
||||
colored_word = ""
|
||||
word_chars = [char for char in word_part if char.strip()]
|
||||
for i, char in enumerate(word_part):
|
||||
@@ -64,8 +69,10 @@ def gradient_text_selective(text, start_color, end_color, gradient_word, white_p
|
||||
colored_word += f"\033[38;2;{r};{g};{b}m{char}\033[0m"
|
||||
else:
|
||||
colored_word += char
|
||||
|
||||
result_lines.append(colored_before + white_prefix_colored + colored_word + after_word)
|
||||
|
||||
result_lines.append(
|
||||
colored_before + white_prefix_colored + colored_word + after_word
|
||||
)
|
||||
else:
|
||||
colored_line = ""
|
||||
total_chars = sum(1 for char in line if char.strip())
|
||||
@@ -92,7 +99,7 @@ def gradient_text_selective(text, start_color, end_color, gradient_word, white_p
|
||||
else:
|
||||
colored_line += char
|
||||
result_lines.append(colored_line)
|
||||
|
||||
|
||||
return "\n".join(result_lines)
|
||||
|
||||
|
||||
@@ -105,8 +112,8 @@ _ascii_art = """
|
||||
╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝
|
||||
"""
|
||||
|
||||
_start_rgb = (88, 101, 242)
|
||||
_end_rgb = (114, 137, 218)
|
||||
_start_rgb = (88, 101, 242)
|
||||
_end_rgb = (114, 137, 218)
|
||||
|
||||
ascii = gradient_text_selective(_ascii_art, _start_rgb, _end_rgb, "neoarz", "Made by ")
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import os
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
def get_owner_friend_ids():
|
||||
owner_friends = os.getenv("OWNER_FRIENDS", "")
|
||||
if not owner_friends.strip():
|
||||
return []
|
||||
return [int(id.strip()) for id in owner_friends.split(",") if id.strip().isdigit()]
|
||||
|
||||
|
||||
def is_owner_or_friend():
|
||||
async def predicate(ctx):
|
||||
owner_friend_ids = get_owner_friend_ids()
|
||||
return ctx.author.id in owner_friend_ids or await ctx.bot.is_owner(ctx.author)
|
||||
return commands.check(predicate)
|
||||
|
||||
return commands.check(predicate)
|
||||
|
||||
@@ -8,32 +8,32 @@ from PIL import Image
|
||||
def fetch_contributors(owner, repo):
|
||||
contributors = []
|
||||
page = 1
|
||||
|
||||
|
||||
while True:
|
||||
url = f"https://api.github.com/repos/{owner}/{repo}/contributors"
|
||||
params = {"page": page, "per_page": 100}
|
||||
|
||||
|
||||
headers = {
|
||||
"User-Agent": "github-contributors-graph",
|
||||
"Accept": "application/vnd.github.v3+json"
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
|
||||
|
||||
response = requests.get(url, headers=headers, params=params)
|
||||
|
||||
|
||||
if not response.ok:
|
||||
return []
|
||||
|
||||
|
||||
data = response.json()
|
||||
|
||||
|
||||
if not data:
|
||||
break
|
||||
|
||||
|
||||
contributors.extend(data)
|
||||
page += 1
|
||||
|
||||
if response.headers.get('X-RateLimit-Remaining') == '0':
|
||||
|
||||
if response.headers.get("X-RateLimit-Remaining") == "0":
|
||||
break
|
||||
|
||||
|
||||
return contributors
|
||||
|
||||
|
||||
@@ -41,65 +41,66 @@ def download_avatar(avatar_url, size):
|
||||
try:
|
||||
if "avatars.githubusercontent.com" in avatar_url:
|
||||
avatar_url = f"{avatar_url}?s={size}"
|
||||
|
||||
|
||||
response = requests.get(avatar_url, timeout=10)
|
||||
|
||||
|
||||
if not response.ok:
|
||||
return None
|
||||
|
||||
|
||||
img = Image.open(BytesIO(response.content))
|
||||
|
||||
|
||||
if img.size != (size, size):
|
||||
img = img.resize((size, size), Image.Resampling.LANCZOS)
|
||||
|
||||
|
||||
return img
|
||||
|
||||
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def generate_contributors_image(owner="neoarz", repo="syntrel", size=64, images_per_row=20):
|
||||
def generate_contributors_image(
|
||||
owner="neoarz", repo="syntrel", size=64, images_per_row=20
|
||||
):
|
||||
contributors = fetch_contributors(owner, repo)
|
||||
|
||||
|
||||
if not contributors:
|
||||
return None
|
||||
|
||||
|
||||
images = []
|
||||
|
||||
|
||||
for contributor in contributors:
|
||||
avatar_url = contributor.get("avatar_url")
|
||||
|
||||
|
||||
if not avatar_url:
|
||||
continue
|
||||
|
||||
|
||||
img = download_avatar(avatar_url, size)
|
||||
|
||||
|
||||
if img is None:
|
||||
continue
|
||||
|
||||
|
||||
images.append(img)
|
||||
|
||||
|
||||
if not images:
|
||||
return None
|
||||
|
||||
|
||||
actual_images_per_row = min(len(images), images_per_row)
|
||||
width = size * actual_images_per_row
|
||||
row_count = ceil(len(images) / images_per_row)
|
||||
height = size * row_count
|
||||
|
||||
|
||||
canvas = Image.new("RGB", (width, height), color="black")
|
||||
|
||||
|
||||
for idx, img in enumerate(images):
|
||||
col = idx % images_per_row
|
||||
row = idx // images_per_row
|
||||
x = col * size
|
||||
y = row * size
|
||||
|
||||
|
||||
canvas.paste(img, (x, y))
|
||||
|
||||
|
||||
buffer = BytesIO()
|
||||
canvas.save(buffer, "PNG")
|
||||
buffer.seek(0)
|
||||
|
||||
return buffer
|
||||
|
||||
return buffer
|
||||
|
||||
@@ -37,12 +37,14 @@ def setup_logger():
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(LoggingFormatter())
|
||||
|
||||
|
||||
log_file_path = os.getenv("LOG_FILE", "logs/discord.log")
|
||||
log_dir = os.path.dirname(log_file_path)
|
||||
if log_dir:
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
file_handler = logging.FileHandler(filename=log_file_path, encoding="utf-8", mode="w")
|
||||
file_handler = logging.FileHandler(
|
||||
filename=log_file_path, encoding="utf-8", mode="w"
|
||||
)
|
||||
file_handler_formatter = logging.Formatter(
|
||||
"[{asctime}] [{levelname:<8}] {name}: {message}", "%Y-%m-%d %H:%M:%S", style="{"
|
||||
)
|
||||
@@ -50,5 +52,5 @@ def setup_logger():
|
||||
|
||||
logger.addHandler(console_handler)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
|
||||
return logger
|
||||
|
||||
@@ -8,6 +8,6 @@ def setup_signal_handlers(bot):
|
||||
if bot.loop and not bot.loop.is_closed():
|
||||
asyncio.create_task(bot.close())
|
||||
bot.loop.call_soon_threadsafe(bot.loop.stop)
|
||||
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
@@ -7,7 +7,7 @@ def get_uptime(start_time: float) -> str:
|
||||
hours = (uptime_seconds % 86400) // 3600
|
||||
minutes = (uptime_seconds % 3600) // 60
|
||||
seconds = uptime_seconds % 60
|
||||
|
||||
|
||||
if days > 0:
|
||||
return f"{days}d {hours}h {minutes}m {seconds}s"
|
||||
elif hours > 0:
|
||||
|
||||
Reference in New Issue
Block a user