From 5742e507d0d6f577b7529f4ba947f2f4c4abbf79 Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 1 Oct 2024 00:15:01 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=B2=D0=B0=D1=80?= =?UTF-8?q?=D0=B8=D0=B0=D0=BD=D1=82=D1=8B=20=D0=BE=D0=BF=D0=BB=D0=B0=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B4=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__pycache__/instructions.cpython-310.pyc | Bin 1651 -> 1651 bytes handlers/__pycache__/keys.cpython-310.pyc | Bin 10254 -> 9405 bytes .../__pycache__/notifications.cpython-310.pyc | Bin 2911 -> 2889 bytes handlers/__pycache__/pay.cpython-310.pyc | Bin 7514 -> 7819 bytes handlers/__pycache__/profile.cpython-310.pyc | Bin 2347 -> 2347 bytes handlers/__pycache__/start.cpython-310.pyc | Bin 4882 -> 4870 bytes handlers/keys.py | 63 +++++------------- handlers/pay.py | 22 ++++-- 8 files changed, 31 insertions(+), 54 deletions(-) diff --git a/handlers/__pycache__/instructions.cpython-310.pyc b/handlers/__pycache__/instructions.cpython-310.pyc index a72d557d86f1c23864343cd37c63d8e2030cf69e..6299e6045377aa9bc06e449d0b74904091812a2c 100644 GIT binary patch delta 30 kcmey&^O=V?pO=@50SI3A{794A$a|lak#+K0)>cMl0Fu=SNB{r; delta 30 kcmey&^O=V?pO=@50SMfJzNg7<O>7%Q6y7(xb~pZ6JNEh~wqtMNIKeH7@`KYtX^DEFX&`~7O(9YRrIVy_S|@B= z6taAMqF)@g`3mZb_%=eR8!m>@Jv zo0gR&7>iim$Rpk;jal9(ZKm;MX)H#`h?GuL9i$&1Rvnay4PrQ?egcElKh!1}3RSP` zV;KhVGtaAV9`7gGi1{)u`dY}Mg#CtIJ?A|OFoNGU&ch-;=ZnI`cF?dDv|=(h#osGs*8kDmpvx^|zpa>w4$>p^UM)u(?!Q z>r5Bi=6G)W%4@S1&*fMzyPV{w_TUCyHTsO&*R@-li<{Rr->KcI-87!aJk_=Lwmx<_ zRo~X#^Vq)buCD)V)XZ_`Zo%#ze5ii`FXGL>^O=)8M>=e#`C#rB;1w_;;DCT91-Jy9 z5JQRiL?bD{#X>aVF zcC{fkMm)a@+16HTpVz+RwvHF#qYa-DvsDyG;&<^tV9$Q=xA+gRfz`xeFnRi6a!2HC zAsd7%D1t@92(CcEm$#Me`F*=OvK9WuHA7cc!1Us6qXSOkedEad6m=GzIh_&enkMEf zb#vzCOyled^>AkA%*$DkszqmBW3W`0ri;0lb6PUL%6qaxV?OFHk)qpTIt^G%MUU2>8HGR8YYSsvLs|QDr-4byN6Htz8E@UTrsE0iOxQU=GiO+8k*zWafCX zw1S(BI;61@YV)-4*PBzU5^*py_@MoR$azl92?5grOaTi5GFa|tKX#N)y^_jXaS<19 cLg!{DUh?RQOZI`QlUs(H#;t=}ircY&0J0L2W&i*H delta 2051 zcmbVNU2GIp6rOWucbV>Xe>(fyo!xeJy9LTmOKFM;mh#{aRJ0QQ6nIeZmda8Wyvz#J zS-aSVgv7;=8%+=!cN2~F#ej>|1mVR8jqzdD2NR1A@}v->A;g$8BAz?2wPH2Kot$s) zz2BL8&fatGx0eP^ZT21XdfgI!-n4$*_ufONeF>O3zx*JK(I|~gNW0=g!E%T;Q}={a z0qPlYX2bgkjnl}4V;puh+pKmEo1jUX)oixq9=4V0Hk+WSI}s?^Ds`l)-Mf|`ayysWkaUosqJr{Su=fJCK@Qb8U)z-ww4j`8o+ zZJTLBi44QAOnoIND2C63@w#IJ^_vZ6B^of4vfp%3mxf1E4$!6woRuaW1-H?ZRZX`E zrj!k4L#9Gi8sybrZ|Z%J3LcO~qr!uROb_~#x*vLlc|)iNB79xwD9rNdP-k=RD!o>$ zja%nCJ7&FXC^vNEsY4@sa%Ks1Z)$qT)+wejRLj{ zAOfD?l}MXwhZyeWUqlwe6u%M4yGpolxQ~xSTi5$Qx#e>aAmF&I64&o74pPj>KGF$F zk=#~g_B{GNBO}y5V(diw6zwMOYRmNC!A}vE#yM+4m~ya1V%#lY_1vn=?i1sPy~?jf zgTY=Let>qKj{U8QBX$)>MHRRF-zrjd(z!q#gEWM7>{^m` zNJivXy_ylbn&Eq@87ax!6Y5?Y9b|Fw%QgzwFCZ#llYmDN@~aT6w`xV}vUS0_XnkCJ zx%P@~U9!&cH$oa^S>dP&M{!~cI_f>T^@;Ui?Rf3g+6n8NzI64xwqXbGwO_;)wD-Segks#_Ur4~+wbN-gxACc#RkO& zj|tEPq!98e`DH!EACE-6Iy1!Th=81^s9QA4G}@i!(*N3A%3O1;xZ7O(sy_`wcCoLB zVpp};F5+ZIaR)vT-?75pza#pedY*f=&*2LHTDu<#*hLw>Cb3)rz|`>f@oyB3yh3Cp{xZ_)*`l#W(MbE&EAFkT6_8v^RK}G z*72HXzlAPD2e6$;%|Q1xD*R><_^H-)aFl=9`ZUV(O8qmJ=&!uS`{GF+O>OECVmBl2 z&l&%sc<92O6CiYoJ;`57Jp!ZryVL+24v!EdDX&Xf4|KguOz zBJ5!Sc>yojmqy57zi8AW{GGPfNjh$${XkHbROrrxw8MJn^zCQq*KKN1q diff --git a/handlers/__pycache__/notifications.cpython-310.pyc b/handlers/__pycache__/notifications.cpython-310.pyc index b0a30e754e84f05b2b974a072b0664731d2a949b..e4475773e42721e784a90fe08ac29cf0eee1503b 100644 GIT binary patch delta 707 zcmb7Czl#$=6rP#={bP1FxtMr}Sb7U8SSmKTM2~=%;-bwoVb7U_z|8J3yMenZ$Xz8i zvVVoOgjtElG;+C+9Ega$qm$;^8b5HohH@U+D5t7j4E{{Y^Vu1-Z+~bKz zNh&gu8Se9*=#ieu1Kt;VWKZk{WMG7lUlT(zgn&7hfQ*g+jc9xYXw2}XMXvwni2t(2 z%G$VUryUv5gxM=ZQ<`1bWS^o1$a~-Qj&jubv}jnf5v&U|QpTHNo?D%DST&t{Qf(V1 zJEyrgV|5NYZ&C?SlvJhRlg06*DjRm*s5Z``QGL3|g!)KU+cTvOW+iW5!TSgPczQgW zFK5#(o{pc5566qg%jYLgRU5o!&9dNpxviP3+de8`(7r^g8$C5&Z7c9W2&HB@l&K05 zzeCo02d3=@f9}RwiP|K%3vv4>cnfc}--6QzNXwRn+X_0b*i>s-2&o%NM}w>N^pAdT zwc+YRYw5M0!+q$tAH&fk(AV_8)ZxF^%pPQ<3&t4hs{5iUSDUp=w5%sIOD#@|nzcW} fhj$K?lmQpicqoY?j5r+0M5QcMlu^gA zY^jW84#%>sI;`XHhRCk!v7XvuTTV#i1=VML2t;rK*u_1-Q%+9-r=oY_u}lBE)hDK4 z>#W!FD|sgTIpS^JIrZ6P4yRzy{c7KAGC&RHc_pf)5>0F)7qZF+u<=GkW!&(vSXV+f zLG}Dtl=W+P=W#k7J{*pQ(|fZ=hYuP&93SjYX8U7vCfY5O%2(V#x)9YYmvXi)g)U8@ zWLlYf$~|4IkDI^|lSb}O4|a=HC7xBU&7%Q6rMM`-v3=Y{*5WXB2j({O;8a~DgsnJkTzjbQ@2gfW*(?${-@W881#lJTw(ep8cc**s566^ z%&JnfZ01O-AZ?d<&D}Ulw01jKGP0qduv8VwDknvwXtFd{S*A)~A&i_PKsXdFjFGKE zd#7fHPSIVGJK_yHnagotF{V}3Ef+>c$UvvKYX8!Iba1fu&9`4#v&ODW%}j>pa9uKv z3^sS|=I)U}amM)zM#ZrEvNkNs>ldH8DL)HYaKQLS(Rj^3ghBd zI^#L$FZ&&}<(@d~4OdE9sBvWht2#p_b1Dh-x#t0^0TL=$r&^3LeRtAlvEmUjixt<5 zC9+vcImTl(li@td8rOoEk{4P@7MmjY#JoVLX>ky{q8$VM0Cq!;U4)XR3LggI_=3pWd*f~T19Q4j-igB)^0)RVCkDs=PKe&N3EeYcA&`QCJxxf0ZT49 z$k#tYOR}i4g@LkN3PYFc+*oK)FZ8&+(4<}23F8rw<5gOA!vuE=Pym*|QF^WPJEB1* zxr2yMad@firGy>DB-fGN5;d7cg?mWqin2x7Z5diYqvW7_3e&Mzt_{H^#?y0k#CSY{ zc!qWIIEJGO0OSmj94f~@iciKi^(@TdF1KshEk*&E+}mDPq?X53rTLYU%*V^pc-iaC z+Im{a?Afev_oYa-=E<(wvpZ^kSlCw7p^^W~tmQKD@XVX%vt-~AaUpk+{uvWL=S~A# z>FGQHP!MDJ)u)ai-XBKQ#*O;j-ul<|Wn}GYwAkWp@djL3=Is-sOq0AUKKkKtinheS1cw%alCRXQn5Da~E0Artz$JwClWf8&9XX z_@pbZ8K6-E#1~!99`zy?ds-3__j{4W#ys6XcE^%HA9zXTJ%Y3vQk bqN97=mS2M)km9;fdyWAW$9rf delta 1617 zcmZ8gOK)366rMBp?fdZS`WdH+3NcE{Bccitv{Y3Sq88c;@leGhq^6Tvalj2X)26ZJ zl1Rx8SyYTFKvg8?4@FF>|nuy6%tg1Gqz(VwdFHsW{%H%=X~G!?B%_e zg6qDYAo$su{`;C>tlSBQYI-s zw0EE?b!P?6$Xm`Ww0}7QW@Ixl;@TMUBmPz%5P30}xgs=XEzzjPO>QxpIV{npbwJ-` z-oW=+Fz}Ns)${8*OSd7`1!>p~hh>D$vTb^vFmjFn5zt6r?ogg_Cki-pDB%84M$bc8(;=$KNhg$lglS2GD%9jyE+&YX@Ren9+N!fIA4DH1vicOlA*@x=flSop5*UT_CXqq~&vuIkJ>|V%^8`6K&Wp z5c3B-*+}gSPt+SOzF{*jb})Ookr56f%pd0GSsr4mlfAd^5(dKVTKz8BHd(4mO~}&N z>@K=t#QWkvNSz`R5GPpJ4a;FzuA3;YqF7q_NuqQ$u{EMaaAbk74}ZT3mWE+=t{aC+J__IOHob*KYNA~*g3dP5~433 zM&D8BM|K9?K`_T~fWq6bHr|IbI{1I32kLPud5-mO4!|uay!k_TK?zs>n=IQ1ey|zq zxd-H399FeTCPw9KaZ!F(ya-o!X=xhZnw%~FAYU9gT`dhI9VzwoWd4}+m*n=yxEZKx zPyRIWOt5EM{b->UMd$EnA}Q_4cxg`Es#(~xZmcXs^NXxE6kNVmxnkbIi3lZn3wWWp_ul*E$6q{QOX$=f;7_;{EE7}=Nvm_%53 HjHDO=*TWgB delta 107 zcmZ22v|5NepO=@50SIPGzMIHh#LpYWo68r)$Hy-pl45C?FNy}P&PTkm=A_71oYKop>)NEIn{D1vBc=%%0=uf)mb;{YkCDDH%W zgoKiPfuu;4^7=eTloyEd0x9D)Nr9W0zkXwlWPjSd+g0aEN#@V*hdV~D4U7>Z zune2ZEjW(c2^7#|VIvn~9Qw#6u7$18$2N6sY&(fEI5=R`Cb?uJja&#EQpc=SoHA0&2-nTv^M;8jU%(fjuF+mJ z70YM=IPx~89`%>ZTWOTH0S$vqf~`HXb=n9v4K`|Q|LG!)O{3_aSTfw&pj@gUtU(HJ%)tB(LjDHmSH&tckh7QjzZm!>*T2rs!V5RwoDCzjQxvU?P zF{G<+iHefu6Xu=OcX=iL_iysABA)MgsDBps^{n^))k_~zrg;V#XqZ4IG$dT}Tx2^s Nq-@}8T7vA4;4jyQXHftE delta 485 zcmY+Ay-EW?5XX1!)=Ta)clk1EV$>oc=o{E*p`@{~8w8u#L&I(oqOlTEBnXyzFJKCv zAof0nkkU?DU%<_xhzmRX=l`1zn7h_vE9`}#$Mkz|f2B7MVPmupj1eP{OaX$j(1Jy7 zNn3H`M%!{pIp`S8WlrTWuUvFZz9c>6qpt!CREVL9FfzWQ{Q?$@&dC^KJu@#8m0)5# zR~A(XOKMccGB5#ShLvMR9{CeSzHrAjRw)q6sYM}06OJ`ed0G*i3S*c8#Uj!qq2h#( z0arC!qY{-TOtXscHLKFHVRgf5|JVwx8rBe%wr*VegH#tz%Bex?reNJHt#+DbrPYak zc#}2^-=N$n+u8hBTr}&z0r2b5TfVh8{lHy>f(~=u z>x=H(yAoYG?_cz;dxKy$bwci#5^wh6UD>~SFM77Kx8xqSv$NuDc~|$xEPw!Fs6k-m J_0K+w^=~>kZsPy| diff --git a/handlers/keys.py b/handlers/keys.py index 0061644d..b3a5b6b4 100644 --- a/handlers/keys.py +++ b/handlers/keys.py @@ -139,6 +139,7 @@ async def process_callback_delete_key(callback_query: types.CallbackQuery): await bot.edit_message_text("Вы уверены, что хотите удалить ключ?", chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=confirmation_keyboard, parse_mode="HTML") await callback_query.answer() + # Обработка выбора плана продления @router.callback_query(lambda c: c.data.startswith('renew_key|')) async def process_callback_renew_key(callback_query: types.CallbackQuery): @@ -155,10 +156,12 @@ async def process_callback_renew_key(callback_query: types.CallbackQuery): expiry_time = record['expiry_time'] current_time = datetime.utcnow().timestamp() * 1000 # Получаем текущее время в миллисекундах - # Убираем проверку на истекший ключ + # Добавляем новые планы продления (6 месяцев и год) keyboard = types.InlineKeyboardMarkup(inline_keyboard=[ [types.InlineKeyboardButton(text='📅 1 месяц (100 руб.)', callback_data=f'renew_plan|1|{client_id}')], - [types.InlineKeyboardButton(text='📅 3 месяца (250 руб.)', callback_data=f'renew_plan|3|{client_id}')], + [types.InlineKeyboardButton(text='📅 3 месяца (285 руб.)', callback_data=f'renew_plan|3|{client_id}')], + [types.InlineKeyboardButton(text='📅 6 месяцев (540 руб.)', callback_data=f'renew_plan|6|{client_id}')], + [types.InlineKeyboardButton(text='📅 12 месяцев (1000 руб.)', callback_data=f'renew_plan|12|{client_id}')], [types.InlineKeyboardButton(text='🔙 Назад', callback_data='view_profile')] ]) @@ -177,46 +180,6 @@ async def process_callback_renew_key(callback_query: types.CallbackQuery): await callback_query.answer() -async def handle_error(tg_id, callback_query, message): - await bot.edit_message_text(message, chat_id=tg_id, message_id=callback_query.message.message_id) - -# Подтверждение удаления -@router.callback_query(lambda c: c.data.startswith('renew_key|')) -async def process_callback_renew_key(callback_query: types.CallbackQuery): - tg_id = callback_query.from_user.id - client_id = callback_query.data.split('|')[1] # Используем разделитель вертикальная черта - - try: - conn = await asyncpg.connect(DATABASE_URL) - try: - record = await conn.fetchrow('SELECT email, expiry_time FROM keys WHERE client_id = $1', client_id) - - if record: - email = record['email'] - expiry_time = record['expiry_time'] - current_time = datetime.utcnow().timestamp() * 1000 # Получаем текущее время в миллисекундах - - # Убираем проверку на истекший ключ - keyboard = types.InlineKeyboardMarkup(inline_keyboard=[ - [types.InlineKeyboardButton(text='Продлить на 1 месяц (100 руб.)', callback_data=f'renew_plan|1|{client_id}')], - [types.InlineKeyboardButton(text='Продлить на 3 месяца (250 руб.)', callback_data=f'renew_plan|3|{client_id}')], - [types.InlineKeyboardButton(text='Назад', callback_data='view_profile')] - ]) - - balance = await get_balance(tg_id) - response_message = (f"Выберите план продления:\n" - f"Баланс: {balance} руб.\n" - f"Текущая дата истечения ключа: {datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S')}") - - await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard, parse_mode="HTML") - - finally: - await conn.close() - - except Exception as e: - await bot.edit_message_text(f"Ошибка при выборе плана: {e}", chat_id=tg_id, message_id=callback_query.message.message_id) - - await callback_query.answer() @router.callback_query(lambda c: c.data.startswith('confirm_delete|')) async def process_callback_confirm_delete(callback_query: types.CallbackQuery): @@ -259,8 +222,8 @@ async def process_callback_confirm_delete(callback_query: types.CallbackQuery): @router.callback_query(lambda c: c.data.startswith('renew_plan|')) async def process_callback_renew_plan(callback_query: types.CallbackQuery): tg_id = callback_query.from_user.id - plan, client_id = callback_query.data.split('|')[1], callback_query.data.split('|')[2] # '1' или '3' и client_id - days_to_extend = 30 * int(plan) + plan, client_id = callback_query.data.split('|')[1], callback_query.data.split('|')[2] # '1', '3', '6' или '12' и client_id + days_to_extend = 30 * int(plan) # Умножаем на количество месяцев (1 месяц = 30 дней) try: conn = await asyncpg.connect(DATABASE_URL) @@ -274,14 +237,19 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery): # Проверяем, если ключ истек, то продлеваем от текущей даты, иначе продлеваем от текущей даты истечения if expiry_time <= current_time: - # Ключ истек, начинаем отсчет от текущего времени new_expiry_time = int(current_time + timedelta(days=days_to_extend).total_seconds() * 1000) else: - # Ключ активен, продлеваем от текущей даты истечения new_expiry_time = int(expiry_time + timedelta(days=days_to_extend).total_seconds() * 1000) # Стоимость продления в зависимости от выбранного плана - cost = 100 if plan == '1' else 250 + if plan == '1': + cost = 100 + elif plan == '3': + cost = 285 + elif plan == '6': + cost = 540 # Стоимость для 6 месяцев + elif plan == '12': + cost = 1000 # Стоимость для 12 месяцев balance = await get_balance(tg_id) if balance < cost: @@ -317,5 +285,6 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery): await callback_query.answer() + async def handle_error(tg_id, callback_query, message): await bot.edit_message_text(message, chat_id=tg_id, message_id=callback_query.message.message_id) \ No newline at end of file diff --git a/handlers/pay.py b/handlers/pay.py index af8c9c5d..7f42f840 100644 --- a/handlers/pay.py +++ b/handlers/pay.py @@ -49,7 +49,7 @@ async def process_callback_replenish_balance(callback_query: types.CallbackQuery # Если записи нет, создаем нового клиента в базе данных if not exists: await add_connection(tg_id, balance=0.0, trial=0) - + await state.set_state(ReplenishBalanceState.choosing_transfer_method) keyboard = InlineKeyboardMarkup(inline_keyboard=[ [InlineKeyboardButton(text='По реквизитам', callback_data='transfer_method_requisites')], @@ -78,9 +78,8 @@ async def process_transfer_method_selection(callback_query: types.CallbackQuery, if transfer_method == 'requisites': amount_keyboard = InlineKeyboardMarkup(inline_keyboard=[ - [InlineKeyboardButton(text='100 RUB', callback_data='amount_100')], - [InlineKeyboardButton(text='300 RUB', callback_data='amount_300')], - [InlineKeyboardButton(text='500 RUB', callback_data='amount_500')], + [InlineKeyboardButton(text='100 RUB', callback_data='amount_100'), InlineKeyboardButton(text='300 RUB', callback_data='amount_300')], + [InlineKeyboardButton(text='600 RUB', callback_data='amount_600'), InlineKeyboardButton(text='1000 RUB', callback_data='amount_1000')], [InlineKeyboardButton(text='⬅️ Назад', callback_data='back_to_profile')] ]) @@ -95,6 +94,7 @@ async def process_transfer_method_selection(callback_query: types.CallbackQuery, await send_message_with_deletion(callback_query.from_user.id, "Неверный метод перевода.", state=state, message_key='transfer_method_error_message_id') return + @router.callback_query(lambda c: c.data.startswith('amount_')) async def process_amount_selection(callback_query: types.CallbackQuery, state: FSMContext): data = callback_query.data.split('_', 1) @@ -104,7 +104,11 @@ async def process_amount_selection(callback_query: types.CallbackQuery, state: F return amount_str = data[1] - amount = int(amount_str) + try: + amount = int(amount_str) + except ValueError: + await send_message_with_deletion(callback_query.from_user.id, "Некорректная сумма.", state=state, message_key='amount_error_message_id') + return state_data = await state.get_data() amount_selection_message_id = state_data.get('amount_selection_message_id') @@ -155,17 +159,18 @@ async def process_admin_confirmation(callback_query: types.CallbackQuery, state: data = callback_query.data.split('_', 4) - if len(data) < 4: + if len(data) < 5: await send_message_with_deletion(callback_query.from_user.id, "Неверные данные для обработки запроса.", state=state, message_key='admin_error_message_id') return action = data[1] user_id_str = data[2] transfer_method = data[3] - amount = int(data[4]) + amount_str = data[4] try: user_id = int(user_id_str) + amount = int(amount_str) state_data = await state.get_data() requisites_message_id = state_data.get('requisites_message_id') @@ -201,6 +206,9 @@ async def process_admin_confirmation(callback_query: types.CallbackQuery, state: await send_message_with_deletion(callback_query.from_user.id, "Пополнение баланса отклонено.", state=state, message_key='admin_decline_message_id') await bot.send_message(user_id, "Ваш запрос на пополнение баланса был отклонен.") + except ValueError: + await send_message_with_deletion(callback_query.from_user.id, "Некорректные данные суммы.", state=state, message_key='admin_error_message_id') + return except Exception as e: await send_message_with_deletion(callback_query.from_user.id, f"Ошибка при пополнении баланса: {e}", state=state, message_key='admin_error_message_id') print(f"Ошибка при пополнении баланса: {e}")