Files
hh_auto/manage_users.py

142 lines
5.0 KiB
Python

#!/usr/bin/env python3
"""Управление пользователями сервиса hh_auto.
Примеры:
python3 manage_users.py add friend1 # спросит пароль
python3 manage_users.py add friend1 --password 123 --limit 50
python3 manage_users.py list
python3 manage_users.py passwd friend1
python3 manage_users.py limit friend1 100
python3 manage_users.py remove friend1
"""
import argparse
import datetime
import getpass
import json
import os
import shutil
import sys
from werkzeug.security import generate_password_hash
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
USERS_FILE = os.path.join(BASE_DIR, "users.json")
def load():
if os.path.exists(USERS_FILE):
with open(USERS_FILE, encoding="utf-8") as f:
return json.load(f)
return {}
def save(users):
tmp = USERS_FILE + ".tmp"
with open(tmp, "w", encoding="utf-8") as f:
json.dump(users, f, ensure_ascii=False, indent=2)
os.replace(tmp, USERS_FILE)
os.chmod(USERS_FILE, 0o600)
def add(username, password, limit):
users = load()
if username in users:
sys.exit(f"Пользователь «{username}» уже существует")
users[username] = {
"password_hash": generate_password_hash(password),
"llm_limit": limit,
"llm_usage": {},
"created": datetime.date.today().isoformat(),
}
save(users)
os.makedirs(os.path.join(BASE_DIR, "users", username, "accounts"), exist_ok=True)
print(f"Пользователь «{username}» создан")
print(f" Данные: {BASE_DIR}/users/{username}/")
print(f" Дневной лимит генераций: {limit or 'без лимита'}")
print(f" Вход: https://ВАШ-ДОМЕН/ (логин: {username})")
def remove(username):
users = load()
if username not in users:
sys.exit(f"Пользователь «{username}» не найден")
del users[username]
save(users)
shutil.rmtree(os.path.join(BASE_DIR, "users", username), ignore_errors=True)
print(f"Пользователь «{username}» удалён вместе с данными")
def set_password(username, password):
users = load()
if username not in users:
sys.exit(f"Пользователь «{username}» не найден")
users[username]["password_hash"] = generate_password_hash(password)
save(users)
print(f"Пароль «{username}» обновлён")
def set_limit(username, limit):
users = load()
if username not in users:
sys.exit(f"Пользователь «{username}» не найден")
users[username]["llm_limit"] = limit
save(users)
print(f"Лимит «{username}»: {limit or 'без лимита'} генераций в день")
def list_users():
users = load()
if not users:
print("Пользователей нет")
return
today = datetime.date.today().isoformat()
print(f"{'Логин':20} {'Генерации сегодня':18} Создан")
for name, u in sorted(users.items()):
used = (u.get("llm_usage") or {}).get(today, 0)
limit = u.get("llm_limit") or 0
lim = f"{used}/{limit}" if limit else f"{used}/∞"
print(f" {name:18} {lim:16} {u.get('created', '?')}")
def main():
ap = argparse.ArgumentParser(description="Управление пользователями hh_auto")
sub = ap.add_subparsers(dest="cmd", required=True)
a = sub.add_parser("add", help="Создать пользователя")
a.add_argument("username")
a.add_argument("--password", help="Пароль (иначе спросит)")
a.add_argument("--limit", type=int, default=50,
help="Дневной лимит генераций (0 = без лимита)")
sub.add_parser("list", help="Список пользователей")
p = sub.add_parser("passwd", help="Сменить пароль")
p.add_argument("username")
l = sub.add_parser("limit", help="Установить дневной лимит генераций")
l.add_argument("username")
l.add_argument("limit", type=int)
r = sub.add_parser("remove", help="Удалить пользователя с данными")
r.add_argument("username")
args = ap.parse_args()
if args.cmd == "add":
password = args.password or getpass.getpass(f"Пароль для «{args.username}»: ")
add(args.username, password, args.limit)
elif args.cmd == "list":
list_users()
elif args.cmd == "passwd":
password = getpass.getpass(f"Новый пароль для «{args.username}»: ")
set_password(args.username, password)
elif args.cmd == "limit":
set_limit(args.username, args.limit)
elif args.cmd == "remove":
if input(f"Удалить «{args.username}» и все его данные? [y/N]: ").strip().lower() \
in ("y", "д", "yes", "да"):
remove(args.username)
if __name__ == "__main__":
main()