From 0b0d56c045419d1d47b6722a397a115d258bc99d Mon Sep 17 00:00:00 2001 From: Disledg Date: Sun, 6 Oct 2024 19:15:37 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=BE:=20?= =?UTF-8?q?=20-=20=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D1=83=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B0=D0=BD?= =?UTF-8?q?=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- __pycache__/db.cpython-312.pyc | Bin 0 -> 6224 bytes __pycache__/logger_config.cpython-312.pyc | Bin 0 -> 940 bytes bot.py | 102 +++++++++++++++++----- db.py | 43 ++++++++- service.py | 2 +- 6 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 __pycache__/db.cpython-312.pyc create mode 100644 __pycache__/logger_config.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 15897e4..155e758 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ bin/ include/ lib/ lib64/ -lib64 \ No newline at end of file +lib64 +*.log \ No newline at end of file diff --git a/__pycache__/db.cpython-312.pyc b/__pycache__/db.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab0cbcab1503d208e19dd0f15e83227475f499a6 GIT binary patch literal 6224 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 G>irLC_7kK4 literal 0 HcmV?d00001 diff --git a/__pycache__/logger_config.cpython-312.pyc b/__pycache__/logger_config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37397db0aa5602943cdf763281416a1596dcfba4 GIT binary patch literal 940 zcmZ8fPiqrF6rb5llTFfXv!$geNJy1R_t4~`;6Xenq!wx_T10yZYi6?9xPQX#B-)Zf z1jVa@P!E0qso%j5;Kk5FmQkUgm)wN()Pp#aWRu{7egF3Ne(%k^`Kl-hz~%LqlgeKR zz%LPmB8{AWhC4?90}L&&C#+;aTiTN#z>!yAFR~9c)Dz&M23dO7vQyz+={U}9WH_}53g>k*(_52Y4%4HMi_6b8p5+#zUzn&9|P=s2#)V|VO?)ez8R zn8XlEID!$L`5Zl-8D(DN#Bm~1+fcun16$)|exS)+c(Z8((4 z#3{R&U;M$fwRPPuQ@#w%&u(Pb)*XH9TBJ#=sn{mIuNxew#aWCGU~mE!HwfM4KJl1b zDhYI{#AKf*MKwcP#lns!cF5ud*RyrX=V7z_|0GK27>~BEMOaiYb4;u{d=M;N3F~~p zlg(x?a`~!jlYG~^vLs{%9nU0eA_~JxaZx;fTc(e0z=l$l<_PgyPx# literal 0 HcmV?d00001 diff --git a/bot.py b/bot.py index 08afe72..6ba257b 100644 --- a/bot.py +++ b/bot.py @@ -1,12 +1,12 @@ from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes -from db import User -from db import Subscription -from db import Transaction -from db import VPNServer +from db import User, VPNServer, Transaction, Subscription +from db import last_subscription, create_user , get_sub_list +import db from sqlalchemy import desc import json +import string from datetime import datetime from db import get_db_session from db import init_db, SessionLocal @@ -14,15 +14,9 @@ from logger_config import setup_logger with open('config.json', 'r') as file: config = json.load(file) -def last_subscription(session,user): - last_subscription = ( - session.query(Subscription) - .filter(Subscription.user_id == user.id) - .order_by(desc(Subscription.created_at)) - .first() - ) - return last_subscription - + +logger = setup_logger() + async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: keyboard = [ @@ -47,16 +41,20 @@ async def personal_account(update: Update, context: ContextTypes.DEFAULT_TYPE) - reply_markup = InlineKeyboardMarkup(keyboard) session = next(get_db_session()) - user = session.query(User).filter(User.telegram_id == update.chat_member.from_user.id).first() - check = last_subscription(session=session,user=user) - if not check: + if session.query(User).filter(User.telegram_id == str(update.effective_user.id)).first() == None: + create_user(str(update.effective_user.id),update.effective_user.username) + user = session.query(User).filter(User.telegram_id == str(update.effective_user.id)).first() + + subscription = last_subscription(session=session,user=user) + + if not subscription: await update.message.reply_text(f'Профиль {user.username}\nВы не приобретали ещё у нас подписку, но это явно стоит сделать:)',reply_markup=reply_markup) # проверяем, истекла ли подписка - if check.expiry_date < datetime.now(): - await update.message.reply_text(f'Ваш профиль {user.username},Ваша подписка действует до - {check.expiry_date}',reply_markup=reply_markup) + elif subscription.expiry_date < datetime.now(): + await update.message.reply_text(f'Ваш профиль {user.username},Ваша подписка действует до - {subscription.expiry_date}',reply_markup=reply_markup) else: - await update.message.reply_text(f'Ваш профиль {user.username},\nВаша подписка истекла - {check.expiry_date}',reply_markup=reply_markup) + await update.message.reply_text(f'Ваш профиль {user.username},\nВаша подписка истекла - {subscription.expiry_date}',reply_markup=reply_markup) async def about(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: keyboard = [ @@ -83,11 +81,68 @@ async def pop_up(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: reply_markup = InlineKeyboardMarkup(keyboard) await update.message.reply_text(f'Когда нибудь эта штука заработает',reply_markup=reply_markup) -#async def buy_subscription(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: +async def buy_subscription(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + keyboard = [ + [ + InlineKeyboardButton("Главное меню", callback_data="account"), + ]] + reply_markup = InlineKeyboardMarkup(keyboard) + session = next(get_db_session()) + user = session.query(User).filter(User.telegram_id == str(update.effective_user.id)).first() + check = last_subscription(session=session,user=user) + if not check: + keyboard = [ + [ + InlineKeyboardButton("Тариф 1 \"Бимжик\"", callback_data="bimzhik"), + ], + [ + InlineKeyboardButton("Тариф 2 \"Бизнес хомячёк\"", callback_data="homyachok"), + ], + [ + InlineKeyboardButton("Тариф 2 \"Продвинутый Акулёнок\"", callback_data="akulenok"), + ]] + reply_markup = InlineKeyboardMarkup(keyboard) + await update.message.reply_text(f'Какую подписку вы хотели бы приобрести\nТариф 1 "Бимжик" - 200 рубликов - 1 месяцок\nТариф 2 "Бизнес хомячёк" - 500 рубликов - 3 месяцка\nТариф 3 "Продвинутый Акулёнок" - 888 рубликов - 888 рубликов\n',reply_markup=reply_markup) + # проверяем, истекла ли подписка + else: + keyboard = [ + [ + InlineKeyboardButton("Главное меню", callback_data="account"), + ]] + reply_markup = InlineKeyboardMarkup(keyboard) + await update.message.reply_text(f'У вас уже приобретена подписка',reply_markup=reply_markup) + + +async def faq(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + keyboard = [ + [ + InlineKeyboardButton("Главное меню", callback_data="account"), + ]] + reply_markup = InlineKeyboardMarkup(keyboard) + await update.message.reply_text(f'Когда нибудь что нибудь здесь будет написано!!;)',reply_markup=reply_markup) +async def active_sub(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + keyboard = [ + [ + InlineKeyboardButton("Главное меню", callback_data="account"), + ]] + reply_markup = InlineKeyboardMarkup(keyboard) + session = next(get_db_session()) + list_sub = get_sub_list(session, 10, update.effective_user.id) + + if list_sub: + message = "Ваши подписки:\n" + for cur_sub in list_sub: + if cur_sub.expiry_date > datetime.now(): + message += f" Активная: {cur_sub.plan}, Дата покупки: {cur_sub.created_at}\n" + else: + message += f" Устаревшая: {cur_sub.plan}, Дата покупки: {cur_sub.created_at}\n" + else: + message = "Ты пидор, не приобрел у нас подписку?!" + await update.message.reply_text(message,reply_markup=reply_markup) def main() -> None: - logger = setup_logger() + init_db() db = SessionLocal() application = Application.builder().token(config['token']).build() @@ -97,7 +152,10 @@ def main() -> None: application.add_handler(CommandHandler("about", about)) application.add_handler(CommandHandler("support", support)) application.add_handler(CommandHandler("popup", pop_up)) - #application.add_handler(CommandHandler("buy_subscription", buy_subscription)) + application.add_handler(CommandHandler("buy_subscription", buy_subscription)) + application.add_handler(CommandHandler("faq", faq)) + application.add_handler(CommandHandler("active_sub", active_sub)) + application.run_polling(allowed_updates=Update.ALL_TYPES) db.close() diff --git a/db.py b/db.py index 1721acc..7156134 100644 --- a/db.py +++ b/db.py @@ -1,14 +1,55 @@ from sqlalchemy import create_engine, Column, String, Integer, Numeric, DateTime, ForeignKey, Text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship +from sqlalchemy import desc from datetime import datetime +import json import uuid +with open('config.json', 'r') as file : config = json.load(file) Base = declarative_base() def generate_uuid(): return str(uuid.uuid4()) + +def last_subscription(session,user): + last_subscription = ( + session.query(Subscription) + .filter(Subscription.user_id == user.id) + .order_by(desc(Subscription.created_at)) + .first() + ) + return last_subscription +def get_sub_list(session,count,user_id): + subscriptions = ( + session.query(Subscription) + .filter(Subscription.user_id == str(user_id)) + .order_by(desc(Subscription.created_at)) + .limit(count) # Ограничиваем результат 10 записями + .all() # Получаем все записи + ) + return subscriptions + +def create_user(telegram_id: str, username: str = None, balance: float = 0.0): + db = next(get_db_session()) + try: + new_user = User( + telegram_id=telegram_id, + username=username, + balance=balance + ) + db.add(new_user) + db.commit() + db.refresh(new_user) + return new_user + except Exception as e: + db.rollback() + raise e + finally: + db.close() + + #Пользователи class User(Base): __tablename__ = 'users' @@ -67,7 +108,7 @@ class VPNServer(Base): subscriptions = relationship("Subscription", back_populates="vpn_server") # Настройка подключения к базе данных -DATABASE_URL = "postgresql://vpn_bot_user:yourpassword@localhost/vpn_bot_db" +DATABASE_URL = f"postgresql://{config['username']}:{config['password_DB']}@localhost/bot_db" engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) diff --git a/service.py b/service.py index cd57c73..6d1f010 100644 --- a/service.py +++ b/service.py @@ -12,7 +12,7 @@ with open('config.json', 'r') as file : config = json.load(file) class UserService: def __init__(self,logger): self.logger = logger - + def add_user(self,telegram_id: int, username: str): session = next(get_db_session()) try: