feat: full feature suite — welcome, modmail, security, staff, avis, rules, links, shop, custom
All checks were successful
ci / ci (push) Successful in 1m1s
All checks were successful
ci / ci (push) Successful in 1m1s
features/shared.py: per-guild JSON config store features/welcome.py: on_member_join message + invite tracking + /invites features/modmail.py: DM-based tickets with staff relay features/security.py: antiraid (join rate detection), ban protection, join/leave log features/staff.py: staff ranks, promote/demote, /staff_list features/avis.py: /avis modal -> embed in configured channel features/rules.py: /rules_setup with accept button + role assignment features/links.py: /links panel, /links_setup, /links_remove features/shop.py: /shop_announce new product embeds features/custom.py: /botstatus, /custom_send, /embed
This commit is contained in:
parent
33b9303948
commit
5d9baee102
12 changed files with 911 additions and 2 deletions
58
features/shared.py
Normal file
58
features/shared.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
from config import DATA_DIR
|
||||
|
||||
FEATURES_DIR = DATA_DIR / "features"
|
||||
_LOCK = threading.Lock()
|
||||
_cache: dict = {}
|
||||
|
||||
|
||||
def _ensure():
|
||||
FEATURES_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def _path(guild_id: int) -> Path:
|
||||
return FEATURES_DIR / f"{guild_id}.json"
|
||||
|
||||
|
||||
def get(guild_id: int, key: str = "") -> dict:
|
||||
with _LOCK:
|
||||
_ensure()
|
||||
if guild_id not in _cache:
|
||||
f = _path(guild_id)
|
||||
if f.exists():
|
||||
with open(f, "r", encoding="utf-8") as fh:
|
||||
_cache[guild_id] = json.load(fh)
|
||||
else:
|
||||
_cache[guild_id] = {}
|
||||
data = _cache[guild_id]
|
||||
return data.get(key, {}) if key else data
|
||||
|
||||
|
||||
def set(guild_id: int, key: str, value) -> None:
|
||||
with _LOCK:
|
||||
_ensure()
|
||||
if guild_id not in _cache:
|
||||
f = _path(guild_id)
|
||||
if f.exists():
|
||||
with open(f, "r", encoding="utf-8") as fh:
|
||||
_cache[guild_id] = json.load(fh)
|
||||
else:
|
||||
_cache[guild_id] = {}
|
||||
_cache[guild_id][key] = value
|
||||
_save(guild_id)
|
||||
|
||||
|
||||
def _save(guild_id: int) -> None:
|
||||
_ensure()
|
||||
with open(_path(guild_id), "w", encoding="utf-8") as fh:
|
||||
json.dump(_cache[guild_id], fh, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
def section(guild_id: int, name: str) -> dict:
|
||||
data = get(guild_id)
|
||||
return data.get(name, {})
|
||||
Loading…
Add table
Add a link
Reference in a new issue