Files
Solo_bot/utils/csv_export.py
T
2025-05-09 01:34:11 +03:00

199 lines
6.5 KiB
Python

import csv
from datetime import datetime
from io import StringIO
from typing import Any
from aiogram.types import BufferedInputFile
async def export_users_csv(session: Any) -> BufferedInputFile:
"""
Экспорт пользователей в CSV с сортировкой от самого старого к новому.
"""
query = """
SELECT
tg_id,
username,
first_name,
last_name,
language_code,
is_bot,
balance,
trial,
created_at
FROM users
ORDER BY created_at ASC
"""
users = await session.fetch(query)
buffer = StringIO()
buffer.write("tg_id,username,first_name,last_name,language_code,is_bot,balance,trial,created_at\n")
for user in users:
buffer.write(
f"{user['tg_id']},{user['username']},{user['first_name']},{user['last_name']},"
f"{user['language_code']},{user['is_bot']},{user['balance']},{user['trial']},"
f"{user['created_at']}\n"
)
buffer.seek(0)
return BufferedInputFile(file=buffer.getvalue().encode("utf-8-sig"), filename="users_export.csv")
async def export_payments_csv(session: Any) -> BufferedInputFile:
"""
Экспорт платежей в CSV с сортировкой от самого старого к новому.
"""
query = """
SELECT
u.tg_id,
u.username,
u.first_name,
u.last_name,
p.amount,
p.payment_system,
p.status,
p.created_at
FROM users u
JOIN payments p ON u.tg_id = p.tg_id
ORDER BY p.created_at ASC -- Сортировка по дате от старых к новым
"""
payments = await session.fetch(query)
return _export_payments_csv(payments, "payments_export.csv")
async def export_user_payments_csv(tg_id: int, session: Any) -> BufferedInputFile:
query = """
SELECT
u.tg_id,
u.username,
u.first_name,
u.last_name,
p.amount,
p.payment_system,
p.status,
p.created_at
FROM users u
JOIN payments p ON u.tg_id = p.tg_id
WHERE u.tg_id = $1
"""
payments = await session.fetch(query, tg_id)
return _export_payments_csv(payments, f"payments_export_{tg_id}.csv")
def _export_payments_csv(payments: list, filename: str) -> BufferedInputFile:
buffer = StringIO()
buffer.write("tg_id,username,first_name,last_name,amount,payment_system,status,created_at\n")
for payment in payments:
buffer.write(
f"{payment['tg_id']},{payment['username']},{payment['first_name']},{payment['last_name']},"
f"{payment['amount']},{payment['payment_system']},{payment['status']},{payment['created_at']}\n"
)
buffer.seek(0)
return BufferedInputFile(file=buffer.getvalue().encode("utf-8-sig"), filename=filename)
async def export_referrals_csv(referrer_tg_id: int, session: Any) -> BufferedInputFile | None:
"""
Формирует CSV-файл со списком рефералов и возвращает его как BufferedInputFile.
Если у пользователя нет рефералов, возвращает None.
"""
rows = await session.fetch(
"""
SELECT
r.referred_tg_id,
COALESCE(u.first_name, '') AS first_name,
COALESCE(u.last_name, '') AS last_name,
COALESCE(u.username, '') AS username
FROM referrals r
JOIN users u ON u.tg_id = r.referred_tg_id
WHERE r.referrer_tg_id = $1
ORDER BY r.referred_tg_id
""",
referrer_tg_id,
)
if not rows:
return None
output = StringIO()
writer = csv.writer(output, delimiter=";")
writer.writerow(["Приглашённый (tg_id)", "Имя"])
for row in rows:
invited_id = row["referred_tg_id"]
full_name = row["first_name"].strip() or row["username"] or str(invited_id)
if row["last_name"]:
full_name = f"{full_name} {row['last_name']}"
writer.writerow([invited_id, full_name.strip()])
output.seek(0)
csv_data = output.getvalue().encode("utf-8")
filename = f"referrals_{referrer_tg_id}.csv"
return BufferedInputFile(file=csv_data, filename=filename)
async def export_hot_leads_csv(session: Any) -> BufferedInputFile:
"""
Экспорт пользователей, которые делали платежи, но сейчас не имеют ключей.
Возвращает: tg_id, username, first_name, last_name, updated_at
"""
query = """
SELECT DISTINCT u.tg_id, u.username, u.first_name, u.last_name, u.updated_at
FROM users u
JOIN payments p ON u.tg_id = p.tg_id
LEFT JOIN keys k ON u.tg_id = k.tg_id
WHERE p.status = 'success'
AND k.tg_id IS NULL
ORDER BY u.updated_at DESC
"""
users = await session.fetch(query)
buffer = StringIO()
buffer.write("tg_id,username,first_name,last_name,updated_at\n")
for user in users:
buffer.write(
f"{user['tg_id']},{user['username'] or ''},"
f"{user['first_name'] or ''},{user['last_name'] or ''},"
f"{user['updated_at']}\n"
)
buffer.seek(0)
return BufferedInputFile(file=buffer.getvalue().encode("utf-8-sig"), filename="hot_leads_export.csv")
async def export_keys_csv(session) -> BufferedInputFile:
"""
Экспорт подписок в CSV с нормальными датами.
"""
keys = await session.fetch("""
SELECT tg_id, client_id, email, created_at, expiry_time, key, server_id, is_frozen, alias
FROM keys
ORDER BY created_at ASC
""")
buffer = StringIO()
buffer.write("tg_id,client_id,email,created_at,expiry_time,key,server_id,is_frozen,alias\n")
for row in keys:
created_at = datetime.utcfromtimestamp(row["created_at"] / 1000).strftime("%Y-%m-%d %H:%M:%S")
expiry_time = datetime.utcfromtimestamp(row["expiry_time"] / 1000).strftime("%Y-%m-%d %H:%M:%S")
buffer.write(
f"{row['tg_id']},{row['client_id']},{row['email']},"
f"{created_at},{expiry_time},{row['key']},"
f"{row['server_id']},{row['is_frozen']},{row['alias'] or ''}\n"
)
buffer.seek(0)
return BufferedInputFile(file=buffer.getvalue().encode("utf-8-sig"), filename="keys_export.csv")