Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d30e932f94 | |||
| 87a3e124f4 | |||
| 579a8ca7e4 | |||
| b1276c42a4 | |||
| 0996f15c30 | |||
| b2fb41edc3 | |||
| 10ce155b8c | |||
| 0ca647fd64 | |||
| 33d4fd2e2e | |||
| 7a2f5cd899 | |||
| 6fbe1632bc | |||
| 36baacc0e1 | |||
| eb7effed4c | |||
| f27b62f8e7 | |||
| 4aa9be2408 | |||
| 4fca2cad95 | |||
| b41314af76 | |||
| ce3985ff96 | |||
| 9b9a72ef04 |
+3
-1
@@ -53,4 +53,6 @@ nginx.conf
|
||||
scripts
|
||||
models.py
|
||||
Dockerfile
|
||||
.csv
|
||||
.csv
|
||||
|
||||
setup.py
|
||||
@@ -0,0 +1,330 @@
|
||||
Creative Commons Attribution-NonCommercial 4.0 International Public
|
||||
License © Vladless, 2024.
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-NonCommercial 4.0 International Public License ("Public
|
||||
License"). To the extent this Public License may be interpreted as a
|
||||
contract, You are granted the Licensed Rights in consideration of Your
|
||||
acceptance of these terms and conditions, and the Licensor grants You
|
||||
such rights in consideration of benefits the Licensor receives from
|
||||
making the Licensed Material available under these terms and
|
||||
conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
d. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
f. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
g. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
i. NonCommercial means not primarily intended for or directed towards
|
||||
commercial advantage or monetary compensation. For purposes of
|
||||
this Public License, the exchange of the Licensed Material for
|
||||
other material subject to Copyright and Similar Rights by digital
|
||||
file-sharing or similar means is NonCommercial provided there is
|
||||
no payment of monetary compensation in connection with the
|
||||
exchange.
|
||||
|
||||
j. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
k. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
l. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part, for NonCommercial purposes only; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material for
|
||||
NonCommercial purposes only.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties, including when
|
||||
the Licensed Material is used other than for NonCommercial
|
||||
purposes.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
4. If You Share Adapted Material You produce, the Adapter's
|
||||
License You apply must not prevent recipients of the Adapted
|
||||
Material from complying with this Public License.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database for NonCommercial purposes
|
||||
only;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material; and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
@@ -1,27 +1,31 @@
|
||||
# 🚀 SoloBot
|
||||
|
||||
**SoloBot** — ваш идеальный помощник для управления API 3x-UI VPN на протоколе VLESS.
|
||||
**SoloBot** — ваш идеальный помощник для управления API 3x-UI VPN на протоколе VLESS.
|
||||
|
||||
Три версии — море возможностей:
|
||||
- v1.4 — бот для продажи ключей vless:
|
||||
|
||||

|
||||
- v2.3.1 — стабильная версия подписок вместо ключей с кнопками автодобавления в приложение:
|
||||
- [v1.4](https://github.com/Vladless/Solo_bot/releases/tag/v1.4) — бот для продажи ключей VLESS:
|
||||
|
||||

|
||||
- v3.1 — настолько большая, что смотрите в [релизе](https://github.com/Vladless/Solo_bot/releases/tag/v3.1):
|
||||

|
||||
|
||||
- [v2.3.1](https://github.com/Vladless/Solo_bot/releases/tag/v2.3.1) — стабильная версия подписок вместо ключей с
|
||||
кнопками автодобавления в приложение:
|
||||
|
||||

|
||||
|
||||
Если вам не хватает функций — направьте их в issue, мы реализуем
|
||||
- [v3.1](https://github.com/Vladless/Solo_bot/releases/tag/v3.1) — версия бота со значительным расширением возможностей.
|
||||
|
||||
[Последние актуальные релизы.](https://github.com/Vladless/Solo_bot/releases)
|
||||
Если вам не хватает функций — направьте их в [issue](https://github.com/Vladless/Solo_bot/issues), мы реализуем.
|
||||
|
||||
## 📋 Оглавление
|
||||
1. [Описание](#описание)
|
||||
2. [Стек технологий](#стек-технологий)
|
||||
3. [Установка](#установка)
|
||||
4. [Конфигурация](#конфигурация)
|
||||
5. [Запуск](#запуск)
|
||||
6. [Контакты](#контакты)
|
||||
|
||||
1. [Описание](#-описание)
|
||||
2. [Стек технологий](#-стек-технологий)
|
||||
3. [Установка](#-установка)
|
||||
4. [Конфигурация](#-конфигурация)
|
||||
5. [Запуск](#-запуск)
|
||||
6. [Контакты](#-solobot-в-telegram-и-полная-версия)
|
||||
|
||||
---
|
||||
|
||||
@@ -29,50 +33,47 @@
|
||||
|
||||
SoloBot реализует множество функций, включая:
|
||||
|
||||
- **Выдача подписок на пробный и длительные периоды** (1 месяц, 3 месяца, полгода, год).
|
||||
- **Выдача подписок на различные периоды** (1 месяц, 3 месяца, полгода, год).
|
||||
- **Использование тестового периода подписки.**
|
||||
- **Продление ключей** на указанные периоды.
|
||||
- Полный контроль клиента над своими ключами:
|
||||
- Удаление ключей.
|
||||
- Продление ключей.
|
||||
- Просмотр информации о ключе (сервер, оставшееся время, сам ключ).
|
||||
- **Полный контроль** клиента над своими ключами:
|
||||
- **Просмотр** информации о ключе (сервер, оставшееся время, сам ключ).
|
||||
- **Продление** ключей.
|
||||
- **Удаление** ключей.
|
||||
- **Смена локации** (перемещение ключа между серверами).
|
||||
- Поддержка нескольких ключей для одного клиента (несколько устройств).
|
||||
- **Реферальная программа** с пригласительной ссылкой.
|
||||
- Доступ к **инструкциям**.
|
||||
- **Пополнение баланса**:
|
||||
* через Юкасса (самозанятость и ИП)
|
||||
* через freekassa (Физические Лица)
|
||||
* Криптовалюта (Thanks [izzzzzi](https://github.com/izzzzzi))
|
||||
* Звезды Telegram
|
||||
* Юмани (физические лица) (Thanks [TrackLine](https://github.com/TrackLine))
|
||||
- **Поддержка нескольких ключей и устройств** для одного клиента.
|
||||
- **Реферальная программа** с уникальной ссылкой для приглашений.
|
||||
- Доступ к **инструкциям** для подключения к сервису.
|
||||
- Пополнение баланса:
|
||||
* **Юкасса** (Самозанятость и ИП)
|
||||
* **Юмани** (Физические Лица) ([TrackLine](https://github.com/TrackLine))
|
||||
* **FreeKassa** (Физические Лица)
|
||||
* **Robokassa** (Физические Лица)
|
||||
* **Cryptobot** (Криптовалюта) ([izzzzzi](https://github.com/izzzzzi))
|
||||
* **Звезды Telegram**
|
||||
- Периодические **бэкапы базы данных клиентов**.
|
||||
- Уведомления:
|
||||
- Произвольные сообщения через админку.
|
||||
- Уведомления о неиспользованных пробниках.
|
||||
- Уведомления о истекающих ключах (за сутки, за 6 часов и в момент истечения).
|
||||
- Произвольные сообщения через панель администратора.
|
||||
- Уведомления о неиспользованных пробниках.
|
||||
- Уведомления об истекающих ключах (за сутки, за 6 часов и в момент истечения).
|
||||
- **Чат поддержки** и канал для связи.
|
||||
- **Автоматическое продление ключа** при наличии достаточного баланса.
|
||||
- **Удобная админка прямо в боте**
|
||||
- **Удобная панель администратора прямо в боте**
|
||||
- Серверы:
|
||||
- **мультисерверность**- добавление сервера прямо в админке
|
||||
- **Проверка на доступность** - бот следит за серверами и их откликом
|
||||
- **Балансировка** - бот выдает подписку на наименее загруженный сервер
|
||||
|
||||
- **Мультисерверность** — добавление сервера прямо в админке
|
||||
- **Проверка на доступность** — бот следит за серверами и их откликом
|
||||
- **Балансировка** — бот выдает подписку на наименее загруженный сервер
|
||||
|
||||
---
|
||||
|
||||
## 💻 Стек технологий
|
||||
|
||||
Проект использует следующие технологии:
|
||||
Основные технологии, используемые в проекте:
|
||||
|
||||
- **Python** версии 3.10 или выше.
|
||||
- **Git** для клонирования репозитория.
|
||||
- **Virtualenv** для создания виртуального окружения (рекомендуется).
|
||||
- **PostgreSQL** для хранения данных.
|
||||
- **Nginx** для работы с вебхуками.
|
||||
- **aiogram** (версия 3.13) для взаимодействия с Telegram API.
|
||||
- **youkassa** для обработки платежей.
|
||||
- **aiohttp** для API запросов к панелям.
|
||||
- **Python** версии 3.10 (3.12, для последних версий).
|
||||
- **PostgreSQL** — для хранения данных.
|
||||
- **aiogram** — для взаимодействия с Telegram API.
|
||||
- **aiohttp** — для API запросов к панелям.
|
||||
|
||||
Проект полностью асинхронный, что обеспечивает высокую скорость работы.
|
||||
|
||||
@@ -89,7 +90,9 @@ git clone https://github.com/Vladless/Solo_bot.git
|
||||
cd solo_bot
|
||||
```
|
||||
|
||||
### 2️⃣ Шаг 2: Создание и активация виртуального окружения
|
||||
### 2️⃣ Шаг 2: Создание и подключение виртуального окружения
|
||||
|
||||
Создайте виртуальное окружение **Python** и перейдите в сессию:
|
||||
|
||||
```
|
||||
python3 -m venv venv
|
||||
@@ -98,6 +101,8 @@ source venv/bin/activate
|
||||
|
||||
### 3️⃣ Шаг 3: Установка зависимостей
|
||||
|
||||
Установите зависимости:
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
@@ -106,33 +111,32 @@ pip install -r requirements.txt
|
||||
|
||||
Для правильной работы вам нужно:
|
||||
|
||||
* установить и запустить postgresql, создать пользователя для работы с базой данных и выдать ему права
|
||||
* Настроить ваш сервер на работу с ботом, выпустить SSL сертификат для домена
|
||||
* Настроить вебхуки и пути до них в NGINX
|
||||
* Установить и запустить **PostgreSQL**, создать пользователя для работы с базой данных и выдать ему права
|
||||
* Настроить ваш сервер для работы с ботом, выпустить SSL сертификат для домена
|
||||
* Настроить вебхуки и указать пути до них через любой веб-сервер, например **nginx**
|
||||
|
||||
* Создать файл config.py в корневой папке проекта с вашими данными:
|
||||
|
||||
```
|
||||
API_TOKEN = "токен вашего бота телеграм"
|
||||
|
||||
API_TOKEN = токен вашего бота телеграм
|
||||
|
||||
ADMIN_USERNAME = логин от вашей панели x-ray
|
||||
ADMIN_PASSWORD = пароль от вашей панели x-ray
|
||||
ADMIN_USERNAME = "логин от вашей панели x-ray"
|
||||
ADMIN_PASSWORD = "пароль от вашей панели x-ray"
|
||||
ADD_CLIENT_URL = f"{API_URL}/panel/api/inbounds/addClient"
|
||||
GET_INBOUNDS_URL = f"{API_URL}/panel/api/inbounds/list/"
|
||||
AUTH_URL = f"{API_URL}/login/"
|
||||
|
||||
```
|
||||
**Мы высылаем детальный гайд и недостающие файлы в поддержке бота**
|
||||
|
||||
**Мы высылаем детальный гайд и недостающие файлы в поддержке бота!**
|
||||
|
||||
### 🚀 Запуск
|
||||
|
||||
введите команду из виртуального окружения
|
||||
Введите команду из виртуального окружения `venv/bin/activate`
|
||||
|
||||
```
|
||||
python main.py
|
||||
python3 main.py
|
||||
```
|
||||
|
||||
### 🔗 SoloBot в Telegram и Полная версия
|
||||
|
||||
#### Наш [**➡ сайт**](https://pocomacho.ru/solonetbot/):
|
||||
@@ -140,7 +144,11 @@ python main.py
|
||||
Всегда актуальные гайды по установке, файлы для запуска и ссылка на общий чат:
|
||||

|
||||
|
||||
|
||||
Попробовать SoloBot прямо сейчас в Telegram [**➡ Попробовать**](https://t.me/SoloNetVPN_bot).
|
||||
|
||||
Связаться с нами через [**➡ поддержку**](https://t.me/solonet_sup). Там вы сможете купить полную версию и получить логин и пароль от сайта, а также задать необходимые вопросы!
|
||||
Связаться с нами через [**➡ поддержку**](https://t.me/solonet_sup). Там вы сможете купить полную версию и получить логин
|
||||
и пароль от сайта, а также задать необходимые вопросы!
|
||||
|
||||
## Права на использование
|
||||
|
||||
[Этот проект использует лицензию CC BY-NC 4.0](LICENSE)
|
||||
+14
-13
@@ -594,14 +594,11 @@ async def handle_referral_on_balance_update(tg_id: int, amount: float):
|
||||
Обработка многоуровневой реферальной системы при обновлении баланса пользователя.
|
||||
|
||||
Метод анализирует цепочку рефералов для указанного пользователя и начисляет
|
||||
бонусы рефереерам на разных уровнях согласно настроенным процентам.
|
||||
бонусы реферерам на разных уровнях согласно настроенным процентам.
|
||||
|
||||
Args:
|
||||
tg_id (int): Идентификатор Telegram пользователя, пополнившего баланс
|
||||
amount (float): Сумма пополнения баланса
|
||||
|
||||
Raises:
|
||||
Exception: В случае ошибки при работе с базой данных
|
||||
"""
|
||||
conn = None
|
||||
try:
|
||||
@@ -609,8 +606,11 @@ async def handle_referral_on_balance_update(tg_id: int, amount: float):
|
||||
logger.info(f"Начало обработки реферальной системы для пользователя {tg_id}")
|
||||
|
||||
MAX_REFERRAL_LEVELS = len(REFERRAL_BONUS_PERCENTAGES.keys())
|
||||
visited_tg_ids = set()
|
||||
if MAX_REFERRAL_LEVELS == 0:
|
||||
logger.warning("Реферальные бонусы отключены.")
|
||||
return
|
||||
|
||||
visited_tg_ids = set()
|
||||
current_tg_id = tg_id
|
||||
referral_chain = []
|
||||
|
||||
@@ -695,8 +695,10 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
)
|
||||
logger.debug(f"Получено количество активных рефералов: {active_referrals}")
|
||||
|
||||
MAX_REFERRAL_LEVELS = len(REFERRAL_BONUS_PERCENTAGES.keys())
|
||||
|
||||
referrals_by_level_records = await conn.fetch(
|
||||
"""
|
||||
f"""
|
||||
WITH RECURSIVE referral_levels AS (
|
||||
SELECT referred_tg_id, referrer_tg_id, 1 AS level
|
||||
FROM referrals
|
||||
@@ -707,7 +709,7 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
SELECT r.referred_tg_id, r.referrer_tg_id, rl.level + 1
|
||||
FROM referrals r
|
||||
JOIN referral_levels rl ON r.referrer_tg_id = rl.referred_tg_id
|
||||
WHERE rl.level < 5
|
||||
WHERE rl.level < {MAX_REFERRAL_LEVELS}
|
||||
)
|
||||
SELECT level,
|
||||
COUNT(*) AS level_count,
|
||||
@@ -730,7 +732,7 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
logger.debug(f"Получена статистика рефералов по уровням: {referrals_by_level}")
|
||||
|
||||
total_referral_bonus = await conn.fetchval(
|
||||
"""
|
||||
f"""
|
||||
WITH RECURSIVE referral_levels AS (
|
||||
SELECT
|
||||
referred_tg_id,
|
||||
@@ -747,13 +749,11 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
rl.level + 1
|
||||
FROM referrals r
|
||||
JOIN referral_levels rl ON r.referrer_tg_id = rl.referred_tg_id
|
||||
WHERE rl.level < 5
|
||||
WHERE rl.level < {MAX_REFERRAL_LEVELS}
|
||||
)
|
||||
SELECT
|
||||
SUM(p.amount * CASE
|
||||
WHEN rl.level = 1 THEN 0.25
|
||||
WHEN rl.level = 2 THEN 0.10
|
||||
WHEN rl.level = 3 THEN 0.05
|
||||
{" ".join([f"WHEN rl.level = {level} THEN {REFERRAL_BONUS_PERCENTAGES[level]}" for level in REFERRAL_BONUS_PERCENTAGES])}
|
||||
ELSE 0
|
||||
END) AS total_bonus
|
||||
FROM referral_levels rl
|
||||
@@ -762,6 +762,8 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
""",
|
||||
referrer_tg_id,
|
||||
)
|
||||
|
||||
total_referral_bonus = total_referral_bonus or 0
|
||||
logger.debug(
|
||||
f"Получена общая сумма бонусов от рефералов: {total_referral_bonus}"
|
||||
)
|
||||
@@ -784,7 +786,6 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
logger.info("Закрытие подключения к базе данных")
|
||||
|
||||
|
||||
|
||||
async def update_key_expiry(client_id: str, new_expiry_time: int):
|
||||
"""
|
||||
Обновление времени истечения ключа для указанного клиента.
|
||||
|
||||
@@ -21,7 +21,6 @@ router.include_routers(
|
||||
pay_router,
|
||||
donate_router,
|
||||
coupons_router,
|
||||
|
||||
notifications_router,
|
||||
payments_router,
|
||||
keys_router,
|
||||
|
||||
@@ -34,6 +34,8 @@ async def handle_admin_callback_query(callback_query: CallbackQuery, state: FSMC
|
||||
async def handle_admin_message(message: types.Message, state: FSMContext):
|
||||
await state.clear()
|
||||
|
||||
BOT_VERSION = "3.2.4-beta" # Укажите текущую версию бота
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
@@ -58,14 +60,37 @@ async def handle_admin_message(message: types.Message, state: FSMContext):
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="📢 Массовая рассылка", callback_data="send_to_alls")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="🤖 Управление Ботом", callback_data="bot_management"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
await message.answer(
|
||||
f"🤖 Панель администратора\n\nВерсия бота: <b>{BOT_VERSION}</b>",
|
||||
reply_markup=builder.as_markup(),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "bot_management")
|
||||
async def handle_bot_management(callback_query: types.CallbackQuery):
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="💾 Создать резервную копию", callback_data="backups")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="🔄 Перезагрузить бота", callback_data="restart_bot")
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
|
||||
await message.answer("🤖 Панель администратора", reply_markup=builder.as_markup())
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⬅️ Назад", callback_data="admin")
|
||||
)
|
||||
await callback_query.message.answer(
|
||||
"🤖 Управление ботом",
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "user_stats", IsAdminFilter())
|
||||
@@ -81,6 +106,9 @@ async def user_stats_menu(callback_query: CallbackQuery, session: Any):
|
||||
total_payments_week = await session.fetchval(
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM payments WHERE created_at >= date_trunc('week', CURRENT_DATE)"
|
||||
)
|
||||
total_payments_month = await session.fetchval(
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM payments WHERE created_at >= date_trunc('month', CURRENT_DATE)"
|
||||
)
|
||||
total_payments_all_time = await session.fetchval(
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM payments"
|
||||
)
|
||||
@@ -103,6 +131,7 @@ async def user_stats_menu(callback_query: CallbackQuery, session: Any):
|
||||
f"💰 Финансовая статистика:\n"
|
||||
f" 📅 За день: <b>{total_payments_today} ₽</b>\n"
|
||||
f" 📆 За неделю: <b>{total_payments_week} ₽</b>\n"
|
||||
f" 📆 За месяц: <b>{total_payments_month} ₽</b>\n"
|
||||
f" 🏦 За все время: <b>{total_payments_all_time} ₽</b>\n"
|
||||
)
|
||||
|
||||
@@ -159,7 +188,7 @@ async def export_users_csv(callback_query: CallbackQuery, session: Any):
|
||||
)
|
||||
return
|
||||
|
||||
csv_data = "tg_id,username,first_name,last_name,language_code,is_bot,balance,trial\n" # Заголовки CSV
|
||||
csv_data = "tg_id,username,first_name,last_name,language_code,is_bot,balance,trial\n"
|
||||
for user in users:
|
||||
csv_data += f"{user['tg_id']},{user['username']},{user['first_name']},{user['last_name']},{user['language_code']},{user['is_bot']},{user['balance']},{user['trial']}\n"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import asyncio
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from aiogram import F, Router, types
|
||||
from aiogram import Bot, F, Router, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
@@ -29,6 +29,7 @@ class UserEditorState(StatesGroup):
|
||||
waiting_for_new_balance = State()
|
||||
waiting_for_key_name = State()
|
||||
waiting_for_expiry_time = State()
|
||||
waiting_for_message_text = State()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "search_by_tg_id", IsAdminFilter())
|
||||
@@ -55,7 +56,8 @@ async def prompt_username(callback_query: CallbackQuery, state: FSMContext):
|
||||
async def handle_username_input(
|
||||
message: types.Message, state: FSMContext, session: Any
|
||||
):
|
||||
username = message.text.strip().lstrip("@")
|
||||
# Extract the username from a message text by removing leading '@' and the Telegram URL prefix
|
||||
username = message.text.strip().lstrip('@').replace('https://t.me/', '')
|
||||
user_record = await session.fetchrow(
|
||||
"SELECT tg_id FROM users WHERE username = $1", username
|
||||
)
|
||||
@@ -113,6 +115,12 @@ async def handle_username_input(
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="❌ Удалить клиента", callback_data=f"confirm_delete_user_{tg_id}"))
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="✉️ Отправить сообщение",
|
||||
callback_data=f"send_message_{tg_id}"
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_editor"))
|
||||
|
||||
user_info = (
|
||||
@@ -127,6 +135,35 @@ async def handle_username_input(
|
||||
await state.set_state(UserEditorState.displaying_user_info)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("send_message_"))
|
||||
async def handle_send_message(callback_query: types.CallbackQuery, state: FSMContext):
|
||||
tg_id = callback_query.data.split("_")[2]
|
||||
await state.update_data(target_tg_id=tg_id)
|
||||
await callback_query.message.answer(
|
||||
"✉️ Введите текст сообщения, которое вы хотите отправить пользователю."
|
||||
)
|
||||
await state.set_state(UserEditorState.waiting_for_message_text)
|
||||
|
||||
|
||||
@router.message(UserEditorState.waiting_for_message_text, IsAdminFilter())
|
||||
async def process_send_message(message: types.Message, state: FSMContext, bot: Bot):
|
||||
data = await state.get_data()
|
||||
target_tg_id = data.get("target_tg_id")
|
||||
|
||||
if not target_tg_id:
|
||||
await message.answer("🚫 Ошибка: ID пользователя не найден.")
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
try:
|
||||
await bot.send_message(chat_id=target_tg_id, text=message.text)
|
||||
await message.answer("✅ Сообщение успешно отправлено.")
|
||||
except Exception as e:
|
||||
await message.answer(f"❌ Не удалось отправить сообщение: {e}")
|
||||
|
||||
await state.clear()
|
||||
|
||||
|
||||
@router.message(UserEditorState.waiting_for_tg_id, F.text.isdigit(), IsAdminFilter())
|
||||
async def handle_tg_id_input(message: types.Message, state: FSMContext, session: Any):
|
||||
tg_id = int(message.text)
|
||||
@@ -171,6 +208,12 @@ async def handle_tg_id_input(message: types.Message, state: FSMContext, session:
|
||||
callback_data=f"restore_trial_{tg_id}",
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="✉️ Отправить сообщение",
|
||||
callback_data=f"send_message_{tg_id}"
|
||||
)
|
||||
)
|
||||
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_editor"))
|
||||
|
||||
@@ -338,7 +381,7 @@ async def process_key_edit(callback_query: CallbackQuery, session: Any):
|
||||
callback_data=f"delete_key_admin|{email}",
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="admin"))
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_editor"))
|
||||
|
||||
await callback_query.message.answer(
|
||||
response_message, reply_markup=builder.as_markup()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
GIFT = "🎁 Подарить подписку"
|
||||
MY_GIFTS = "🎁 Мои подарки"
|
||||
PROFILE = "👤 Личный кабинет"
|
||||
BACK = "🔙 Назад"
|
||||
GIFTS_ABOUT = "<b>Дарите подарки и следите, чтобы они дошли до адресата! 🎄</b>"
|
||||
@@ -0,0 +1,8 @@
|
||||
ADD_SUB = "➕ Устройство"
|
||||
MY_SUBS = "📱 Мои устройства"
|
||||
PAYMENT = "💳 Пополнить баланс"
|
||||
INVITE = "👥 Пригласить"
|
||||
GIFTS = "🎁 Подарить"
|
||||
TARRIFS = "💡 Тарифы"
|
||||
INSTRUCTIONS = "📘 Инструкции"
|
||||
MAIN_MENU = "⬅️ Главное меню"
|
||||
@@ -0,0 +1,3 @@
|
||||
PAY = "Пополнить"
|
||||
BACK = "⬅️ Назад"
|
||||
CUSTOM_SUM = "💰 Ввести свою сумму"
|
||||
@@ -1,22 +1,28 @@
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
import asyncpg
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.types import BufferedInputFile, InlineKeyboardButton
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
from config import CONNECT_IOS, CONNECT_WINDOWS, SUPPORT_CHAT_URL
|
||||
from handlers.texts import INSTRUCTION_PC, INSTRUCTIONS, KEY_MESSAGE
|
||||
from config import CONNECT_MACOS, CONNECT_WINDOWS, DATABASE_URL, SUPPORT_CHAT_URL
|
||||
from handlers.texts import CONNECT_TV_TEXT, INSTRUCTION_PC, INSTRUCTIONS, KEY_MESSAGE, SUBSCRIPTION_DETAILS_TEXT
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "instructions")
|
||||
async def send_instructions(callback_query: types.CallbackQuery):
|
||||
@router.message(F.text == "/instructions")
|
||||
async def send_instructions(callback_query_or_message: types.CallbackQuery | types.Message):
|
||||
instructions_message = INSTRUCTIONS
|
||||
image_path = os.path.join("img", "instructions.jpg")
|
||||
|
||||
if not os.path.isfile(image_path):
|
||||
await callback_query.message.answer("Файл изображения не найден.")
|
||||
if isinstance(callback_query_or_message, types.CallbackQuery):
|
||||
await callback_query_or_message.message.answer("Файл изображения не найден.")
|
||||
else:
|
||||
await callback_query_or_message.answer("Файл изображения не найден.")
|
||||
return
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
@@ -25,14 +31,20 @@ async def send_instructions(callback_query: types.CallbackQuery):
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"),
|
||||
)
|
||||
|
||||
if isinstance(callback_query_or_message, types.CallbackQuery):
|
||||
send_photo = callback_query_or_message.message.answer_photo
|
||||
else:
|
||||
send_photo = callback_query_or_message.answer_photo
|
||||
|
||||
with open(image_path, "rb") as image_from_buffer:
|
||||
await callback_query.message.answer_photo(
|
||||
await send_photo(
|
||||
BufferedInputFile(image_from_buffer.read(), filename="instructions.jpg"),
|
||||
caption=instructions_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("connect_pc|"))
|
||||
async def process_connect_pc(callback_query: types.CallbackQuery, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
@@ -65,7 +77,7 @@ async def process_connect_pc(callback_query: types.CallbackQuery, session: Any):
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="💻 Подключить MacOS", url=f"{CONNECT_IOS}{key}")
|
||||
InlineKeyboardButton(text="💻 Подключить MacOS", url=f"{CONNECT_MACOS}{key}")
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="🆘 Поддержка", url=f"{SUPPORT_CHAT_URL}"))
|
||||
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
|
||||
@@ -76,3 +88,70 @@ async def process_connect_pc(callback_query: types.CallbackQuery, session: Any):
|
||||
parse_mode="HTML",
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("connect_tv|"))
|
||||
async def process_connect_tv(callback_query: types.CallbackQuery):
|
||||
key_name = callback_query.data.split("|")[1]
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="▶ Продолжить", callback_data=f"continue_tv|{key_name}"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
|
||||
await callback_query.message.answer(
|
||||
text=CONNECT_TV_TEXT,
|
||||
reply_markup=builder.as_markup(),
|
||||
parse_mode="HTML",
|
||||
disable_web_page_preview=True
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("continue_tv|"))
|
||||
async def process_continue_tv(callback_query: types.CallbackQuery):
|
||||
key_name = callback_query.data.split("|")[1]
|
||||
tg_id = callback_query.from_user.id
|
||||
|
||||
print(f"tg_id: {tg_id}, key_name: {key_name}") # Отладочный вывод
|
||||
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
try:
|
||||
record = await conn.fetchrow(
|
||||
"""
|
||||
SELECT k.key
|
||||
FROM keys k
|
||||
WHERE k.tg_id = $1 AND k.email = $2
|
||||
""",
|
||||
tg_id,
|
||||
key_name,
|
||||
)
|
||||
|
||||
print(f"Query result: {record}") # Отладочный вывод результата
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
|
||||
subscription_link = record['key']
|
||||
|
||||
message_text = SUBSCRIPTION_DETAILS_TEXT.format(subscription_link=subscription_link)
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="📖 Полная инструкция", url="https://vpn4tv.com/quick-guide.html"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
|
||||
await callback_query.message.answer(
|
||||
text=message_text,
|
||||
reply_markup=builder.as_markup(),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ from config import (
|
||||
)
|
||||
from database import get_balance, get_trial, store_key, update_balance
|
||||
from handlers.keys.key_utils import create_key_on_cluster
|
||||
from handlers.texts import DISCOUNTS, KEY, key_message_success
|
||||
from handlers.texts import DISCOUNTS, key_message_success
|
||||
from handlers.utils import generate_random_email, get_least_loaded_cluster
|
||||
from logger import logger
|
||||
|
||||
@@ -36,31 +36,6 @@ class Form(StatesGroup):
|
||||
|
||||
|
||||
@router.callback_query(F.data == "create_key")
|
||||
async def process_callback_create_key(callback_query: CallbackQuery, state: FSMContext, session: Any):
|
||||
server_id = "все сервера"
|
||||
await state.update_data(selected_server_id=server_id)
|
||||
await select_server(callback_query, state, session)
|
||||
|
||||
|
||||
async def select_server(callback_query: CallbackQuery, state: FSMContext, session: Any):
|
||||
trial_status = await get_trial(callback_query.message.chat.id, session)
|
||||
if trial_status == 1:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="✅ Да, подключить новое устройство", callback_data="confirm_create_new_key")
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
|
||||
|
||||
await callback_query.message.answer(
|
||||
text=KEY,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
await state.update_data(creating_new_key=True)
|
||||
else:
|
||||
await handle_key_creation(callback_query.message.chat.id, state, session, callback_query)
|
||||
|
||||
|
||||
@router.callback_query(F.data == "confirm_create_new_key")
|
||||
async def confirm_create_new_key(callback_query: CallbackQuery, state: FSMContext, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
|
||||
@@ -206,7 +181,7 @@ async def create_key(
|
||||
InlineKeyboardButton(text="🍏 Подключить на iOS", url=f"{CONNECT_IOS}{public_link}"),
|
||||
InlineKeyboardButton(text="🤖 Подключить на Android", url=f"{CONNECT_ANDROID}{public_link}"),
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="💻 Windows/Linux", callback_data=f"connect_pc|{email}"))
|
||||
builder.row(InlineKeyboardButton(text="💻 Windows/Linux/MacOS", callback_data=f"connect_pc|{email}"))
|
||||
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
|
||||
|
||||
remaining_time = expiry_time - datetime.utcnow()
|
||||
|
||||
+94
-70
@@ -35,7 +35,6 @@ from handlers.texts import (
|
||||
DISCOUNTS,
|
||||
INSUFFICIENT_FUNDS_MSG,
|
||||
KEY_NOT_FOUND_MSG,
|
||||
NO_KEYS,
|
||||
PLAN_SELECTION_MSG,
|
||||
SUCCESS_RENEWAL_MSG,
|
||||
key_message,
|
||||
@@ -49,84 +48,106 @@ router = Router()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "view_keys")
|
||||
async def process_callback_view_keys(callback_query: types.CallbackQuery, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
@router.message(F.text == "/subs")
|
||||
async def process_callback_or_message_view_keys(
|
||||
callback_query_or_message: types.Message | types.CallbackQuery, session: Any
|
||||
):
|
||||
if isinstance(callback_query_or_message, types.CallbackQuery):
|
||||
chat_id = callback_query_or_message.message.chat.id
|
||||
send_message = callback_query_or_message.message.answer
|
||||
send_photo = callback_query_or_message.message.answer_photo
|
||||
else:
|
||||
chat_id = callback_query_or_message.chat.id
|
||||
send_message = callback_query_or_message.answer
|
||||
send_photo = callback_query_or_message.answer_photo
|
||||
|
||||
try:
|
||||
records = await session.fetch(
|
||||
"""
|
||||
SELECT email, client_id FROM keys WHERE tg_id = $1
|
||||
""",
|
||||
tg_id,
|
||||
""",
|
||||
chat_id,
|
||||
)
|
||||
|
||||
if records:
|
||||
builder = InlineKeyboardBuilder()
|
||||
for record in records:
|
||||
key_name = record["email"]
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"🔑 {key_name}", callback_data=f"view_key|{key_name}"
|
||||
)
|
||||
)
|
||||
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
|
||||
inline_keyboard = builder.as_markup()
|
||||
response_message = (
|
||||
"<b>🔑 Список ваших устройств</b>\n\n"
|
||||
"<i>👇 Выберите устройство для управления подпиской:</i>"
|
||||
)
|
||||
|
||||
image_path = os.path.join("img", "pic_keys.jpg")
|
||||
if os.path.isfile(image_path):
|
||||
with open(image_path, "rb") as image_file:
|
||||
await callback_query.message.answer_photo(
|
||||
photo=BufferedInputFile(
|
||||
image_file.read(), filename="pic_keys.jpg"
|
||||
),
|
||||
caption=response_message,
|
||||
reply_markup=inline_keyboard,
|
||||
)
|
||||
else:
|
||||
await callback_query.message.answer(
|
||||
text=response_message,
|
||||
reply_markup=inline_keyboard,
|
||||
)
|
||||
|
||||
inline_keyboard, response_message = build_keys_response(records)
|
||||
else:
|
||||
response_message = NO_KEYS
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="➕ Создать подписку", callback_data="create_key"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
inline_keyboard, response_message = build_no_keys_response()
|
||||
|
||||
keyboard = builder.as_markup()
|
||||
|
||||
image_path = os.path.join("img", "pic_keys.jpg")
|
||||
|
||||
if os.path.isfile(image_path):
|
||||
with open(image_path, "rb") as image_file:
|
||||
await callback_query.message.answer_photo(
|
||||
photo=BufferedInputFile(
|
||||
image_file.read(), filename="pic_keys.jpg"
|
||||
),
|
||||
caption=response_message,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
else:
|
||||
await callback_query.message.answer(
|
||||
text=response_message,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
image_path = os.path.join("img", "pic_keys.jpg")
|
||||
await send_with_optional_image(
|
||||
send_message, send_photo, image_path, response_message, inline_keyboard
|
||||
)
|
||||
except Exception as e:
|
||||
await handle_error(tg_id, callback_query, f"Ошибка при получении ключей: {e}")
|
||||
error_message = f"Ошибка при получении ключей: {e}"
|
||||
await send_message(text=error_message)
|
||||
|
||||
|
||||
def build_keys_response(records):
|
||||
"""
|
||||
Формирует сообщение и клавиатуру, если у пользователя есть устройства.
|
||||
"""
|
||||
builder = InlineKeyboardBuilder()
|
||||
for record in records:
|
||||
key_name = record["email"]
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"🔑 {key_name}", callback_data=f"view_key|{key_name}"
|
||||
)
|
||||
)
|
||||
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
|
||||
inline_keyboard = builder.as_markup()
|
||||
response_message = (
|
||||
"<b>🔑 Список ваших устройств</b>\n\n"
|
||||
"<i>👇 Выберите устройство для управления подпиской:</i>"
|
||||
)
|
||||
return inline_keyboard, response_message
|
||||
|
||||
|
||||
def build_no_keys_response():
|
||||
"""
|
||||
Формирует сообщение и клавиатуру, если у пользователя нет устройств.
|
||||
"""
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="➕ Создать подписку", callback_data="create_key"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile")
|
||||
)
|
||||
|
||||
inline_keyboard = builder.as_markup()
|
||||
response_message = (
|
||||
"<b>❌ У вас пока нет активных устройств</b>\n\n"
|
||||
"<i>Нажмите кнопку ниже, чтобы создать устройство:</i>"
|
||||
)
|
||||
return inline_keyboard, response_message
|
||||
|
||||
|
||||
async def send_with_optional_image(send_message, send_photo, image_path, text, keyboard):
|
||||
"""
|
||||
Отправляет сообщение с изображением, если файл существует. В противном случае отправляет только текст.
|
||||
"""
|
||||
if os.path.isfile(image_path):
|
||||
with open(image_path, "rb") as image_file:
|
||||
await send_photo(
|
||||
photo=BufferedInputFile(image_file.read(), filename=os.path.basename(image_path)),
|
||||
caption=text,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
else:
|
||||
await send_message(
|
||||
text=text,
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("view_key|"))
|
||||
@@ -187,7 +208,10 @@ async def process_callback_view_key(callback_query: types.CallbackQuery, session
|
||||
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="💻 Windows/Linux", callback_data=f"connect_pc|{key_name}"
|
||||
text="💻 Компьютеры", callback_data=f"connect_pc|{key_name}"
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text="📺 Андроид TV", callback_data=f"connect_tv|{key_name}"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+990
-937
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+4142
-2367
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,277 @@
|
||||
import hashlib
|
||||
from typing import Any
|
||||
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
from aiohttp import web
|
||||
from robokassa import HashAlgorithm, Robokassa
|
||||
|
||||
from config import (
|
||||
ROBOKASSA_ENABLE,
|
||||
ROBOKASSA_LOGIN,
|
||||
ROBOKASSA_PASSWORD1,
|
||||
ROBOKASSA_PASSWORD2,
|
||||
ROBOKASSA_TEST_MODE,
|
||||
)
|
||||
from database import (
|
||||
add_connection,
|
||||
add_payment,
|
||||
check_connection_exists,
|
||||
get_key_count,
|
||||
update_balance,
|
||||
)
|
||||
from handlers.payments.utils import send_payment_success_notification
|
||||
from handlers.texts import PAYMENT_OPTIONS
|
||||
from logger import logger
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
class ReplenishBalanceState(StatesGroup):
|
||||
choosing_amount_robokassa = State()
|
||||
waiting_for_payment_confirmation_robokassa = State()
|
||||
|
||||
|
||||
if ROBOKASSA_ENABLE:
|
||||
robokassa = Robokassa(
|
||||
merchant_login=ROBOKASSA_LOGIN,
|
||||
password1=ROBOKASSA_PASSWORD1,
|
||||
password2=ROBOKASSA_PASSWORD2,
|
||||
algorithm=HashAlgorithm.md5,
|
||||
is_test=ROBOKASSA_TEST_MODE,
|
||||
)
|
||||
|
||||
logger.info("Robokassa initialized with login: {}", ROBOKASSA_LOGIN)
|
||||
|
||||
|
||||
def generate_payment_link(amount, inv_id, description, tg_id):
|
||||
"""Генерация ссылки на оплату."""
|
||||
logger.debug(
|
||||
f"Generating payment link for amount: {amount}, inv_id: {inv_id}, description: {description}"
|
||||
)
|
||||
payment_link = robokassa._payment.link.generate_by_script(
|
||||
out_sum=amount,
|
||||
inv_id=inv_id,
|
||||
description="пополнение баланса",
|
||||
id=f"{tg_id}",
|
||||
)
|
||||
logger.info(f"Generated payment link: {payment_link}")
|
||||
return payment_link
|
||||
|
||||
|
||||
@router.callback_query(F.data == "pay_robokassa")
|
||||
async def process_callback_pay_robokassa(
|
||||
callback_query: types.CallbackQuery, state: FSMContext, session: Any
|
||||
):
|
||||
tg_id = callback_query.message.chat.id
|
||||
logger.info(f"User {tg_id} initiated Robokassa payment.")
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
for i in range(0, len(PAYMENT_OPTIONS), 2):
|
||||
if i + 1 < len(PAYMENT_OPTIONS):
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=PAYMENT_OPTIONS[i]["text"],
|
||||
callback_data=f'robokassa_amount|{PAYMENT_OPTIONS[i]["callback_data"]}',
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text=PAYMENT_OPTIONS[i + 1]["text"],
|
||||
callback_data=f'robokassa_amount|{PAYMENT_OPTIONS[i + 1]["callback_data"]}',
|
||||
),
|
||||
)
|
||||
else:
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=PAYMENT_OPTIONS[i]["text"],
|
||||
callback_data=f'robokassa_amount|{PAYMENT_OPTIONS[i]["callback_data"]}',
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="💰 Ввести свою сумму",
|
||||
callback_data="enter_custom_amount_robokassa",
|
||||
)
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="⬅️ Назад", callback_data="pay"))
|
||||
|
||||
key_count = await get_key_count(tg_id)
|
||||
|
||||
if key_count == 0:
|
||||
exists = await check_connection_exists(tg_id)
|
||||
if not exists:
|
||||
await add_connection(tg_id, balance=0.0, trial=0, session=session)
|
||||
logger.info(f"Created new connection for user {tg_id} with balance 0.0.")
|
||||
|
||||
await callback_query.message.answer(
|
||||
text="Выберите сумму пополнения:",
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
await state.set_state(ReplenishBalanceState.choosing_amount_robokassa)
|
||||
logger.info(f"Displayed amount selection for user {tg_id}.")
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("robokassa_amount|"))
|
||||
async def process_amount_selection(
|
||||
callback_query: types.CallbackQuery, state: FSMContext
|
||||
):
|
||||
logger.info(f"Получены данные callback_data: {callback_query.data}")
|
||||
|
||||
data = callback_query.data.split("|")
|
||||
if len(data) != 3 or data[1] != "amount":
|
||||
logger.error("Ошибка: callback_data не соответствует формату.")
|
||||
await callback_query.message.answer("Ошибка: данные повреждены.")
|
||||
return
|
||||
|
||||
amount_str = data[2]
|
||||
try:
|
||||
amount = int(amount_str)
|
||||
if amount <= 0:
|
||||
raise ValueError("Сумма должна быть положительным числом.")
|
||||
except ValueError as e:
|
||||
logger.error(f"Некорректное значение суммы: {amount_str}. Ошибка: {e}")
|
||||
await callback_query.message.answer("Некорректная сумма.")
|
||||
return
|
||||
|
||||
await state.update_data(amount=amount)
|
||||
logger.info(f"User {callback_query.message.chat.id} selected amount: {amount}.")
|
||||
inv_id = 0
|
||||
|
||||
tg_id = callback_query.message.chat.id
|
||||
payment_url = generate_payment_link(amount, inv_id, "Пополнение баланса", tg_id)
|
||||
|
||||
logger.info(f"Payment URL for user {callback_query.message.chat.id}: {payment_url}")
|
||||
|
||||
confirm_keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(text="Оплатить", url=payment_url)],
|
||||
[InlineKeyboardButton(text="⬅️ Назад", callback_data="pay_robokassa")],
|
||||
]
|
||||
)
|
||||
|
||||
await callback_query.message.answer(
|
||||
text=f"Вы выбрали пополнение на {amount} рублей. Для оплаты перейдите по ссылке ниже:",
|
||||
reply_markup=confirm_keyboard,
|
||||
)
|
||||
logger.info(f"Payment link sent to user {callback_query.message.chat.id}.")
|
||||
|
||||
|
||||
async def robokassa_webhook(request):
|
||||
"""Обработка webhook-уведомлений от Robokassa с учетом shp_id."""
|
||||
try:
|
||||
params = await request.post()
|
||||
|
||||
logger.info(f"Received webhook params: {params}")
|
||||
|
||||
amount = params.get("OutSum")
|
||||
inv_id = params.get("InvId")
|
||||
shp_id = params.get("shp_id")
|
||||
signature_value = params.get("SignatureValue")
|
||||
|
||||
logger.info(
|
||||
f"OutSum: {amount}, InvId: {inv_id}, shp_id: {shp_id}, SignatureValue: {signature_value}"
|
||||
)
|
||||
|
||||
if not check_payment_signature(params):
|
||||
logger.error("Неверная подпись или данные запроса.")
|
||||
return web.Response(status=400)
|
||||
|
||||
if not amount or not inv_id or not shp_id:
|
||||
logger.error("Отсутствуют обязательные параметры.")
|
||||
return web.Response(status=400)
|
||||
|
||||
tg_id = shp_id
|
||||
|
||||
logger.info(f"Processing payment for user {tg_id} with amount {amount}.")
|
||||
|
||||
await update_balance(int(tg_id), float(amount))
|
||||
await send_payment_success_notification(tg_id, float(amount))
|
||||
|
||||
await add_payment(int(tg_id), float(amount), "robokassa")
|
||||
|
||||
logger.info(f"Payment successful. Balance updated for user {tg_id}.")
|
||||
|
||||
return web.Response(text=f"OK{inv_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing webhook: {e}")
|
||||
return web.Response(status=500)
|
||||
|
||||
|
||||
def check_payment_signature(params):
|
||||
"""Проверка подписи запроса от Robokassa с учетом shp_id."""
|
||||
out_sum = params.get("OutSum")
|
||||
inv_id = params.get("InvId")
|
||||
signature_value = params.get("SignatureValue")
|
||||
shp_id = params.get("shp_id")
|
||||
|
||||
signature_string = f"{out_sum}:{inv_id}:{ROBOKASSA_PASSWORD2}:shp_id={shp_id}"
|
||||
|
||||
logger.info(f"Signature string before hashing: {signature_string}")
|
||||
|
||||
expected_signature = (
|
||||
hashlib.md5(signature_string.encode("utf-8")).hexdigest().upper()
|
||||
)
|
||||
|
||||
logger.info(f"Expected signature: {expected_signature}")
|
||||
logger.info(f"Received signature: {signature_value}")
|
||||
|
||||
return signature_value.upper() == expected_signature.upper()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "enter_custom_amount_robokassa")
|
||||
async def process_custom_amount_selection(
|
||||
callback_query: types.CallbackQuery, state: FSMContext
|
||||
):
|
||||
tg_id = callback_query.message.chat.id
|
||||
logger.info(f"User {tg_id} chose to enter a custom amount.")
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="pay_robokassa"))
|
||||
|
||||
await callback_query.message.answer(
|
||||
"Пожалуйста, введите сумму пополнения.",
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
|
||||
await state.set_state(
|
||||
ReplenishBalanceState.waiting_for_payment_confirmation_robokassa
|
||||
)
|
||||
|
||||
|
||||
@router.message(ReplenishBalanceState.waiting_for_payment_confirmation_robokassa)
|
||||
async def handle_custom_amount_input(message: types.Message, state: FSMContext):
|
||||
tg_id = message.chat.id
|
||||
logger.info(f"User {tg_id} entered custom amount: {message.text}")
|
||||
inv_id = 0
|
||||
|
||||
try:
|
||||
amount = int(message.text)
|
||||
if amount <= 0:
|
||||
raise ValueError("Сумма должна быть положительным числом.")
|
||||
|
||||
await state.update_data(amount=amount)
|
||||
|
||||
payment_url = generate_payment_link(amount, inv_id, "Пополнение баланса", tg_id)
|
||||
|
||||
logger.info(f"Generated payment link for user {tg_id}: {payment_url}")
|
||||
|
||||
confirm_keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(text="Оплатить", url=payment_url)],
|
||||
[InlineKeyboardButton(text="⬅️ Назад", callback_data="pay_robokassa")],
|
||||
]
|
||||
)
|
||||
|
||||
await message.answer(
|
||||
text=f"Вы выбрали пополнение на {amount} рублей. Для оплаты перейдите по ссылке ниже:",
|
||||
reply_markup=confirm_keyboard,
|
||||
)
|
||||
await state.clear()
|
||||
except ValueError as e:
|
||||
logger.error(f"Некорректная сумма от пользователя {tg_id}: {e}")
|
||||
await message.answer(
|
||||
text="Введите корректную сумму в рублях (целое положительное число)."
|
||||
)
|
||||
+211
-208
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -3,6 +3,9 @@
|
||||
/* BEGIN: Cython Metadata
|
||||
{
|
||||
"distutils": {
|
||||
"extra_compile_args": [
|
||||
"-O2"
|
||||
],
|
||||
"name": "handlers.payments.utils",
|
||||
"sources": [
|
||||
"handlers/payments/utils.py"
|
||||
|
||||
Binary file not shown.
+1556
-1435
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+194
-191
@@ -3,6 +3,9 @@
|
||||
/* BEGIN: Cython Metadata
|
||||
{
|
||||
"distutils": {
|
||||
"extra_compile_args": [
|
||||
"-O2"
|
||||
],
|
||||
"name": "handlers.payments.yoomoney_pay",
|
||||
"sources": [
|
||||
"handlers/payments/yoomoney_pay.py"
|
||||
@@ -2621,25 +2624,26 @@ static PyObject *__pyx_builtin_ValueError;
|
||||
static const char __pyx_k_F[] = "F";
|
||||
static const char __pyx_k_e[] = "e";
|
||||
static const char __pyx_k_i[] = "i";
|
||||
static const char __pyx_k__2[] = "\360\237\222\260 \320\222\320\262\320\265\321\201\321\202\320\270 \321\201\320\262\320\276\321\216 \321\201\321\203\320\274\320\274\321\203";
|
||||
static const char __pyx_k__3[] = "\342\254\205\357\270\217 \320\235\320\260\320\267\320\260\320\264";
|
||||
static const char __pyx_k__4[] = "\320\222\321\213\320\261\320\265\321\200\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\321\217:";
|
||||
static const char __pyx_k__6[] = "|";
|
||||
static const char __pyx_k__8[] = "\320\237\320\276\320\277\320\276\320\273\320\275\320\270\321\202\321\214";
|
||||
static const char __pyx_k__9[] = "\320\222\321\213 \320\262\321\213\320\261\321\200\320\260\320\273\320\270 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265 \320\275\320\260 ";
|
||||
static const char __pyx_k__2[] = "\320\235\320\260\321\200\321\203\321\210\320\265\320\275\320\260 \321\206\320\265\320\273\320\276\321\201\321\202\320\275\320\276\321\201\321\202\321\214 \321\204\320\260\320\271\320\273\320\276\320\262! \320\236\320\261\320\275\320\276\320\262\320\270\321\202\320\265\321\201\321\214 \321\201 \320\277\320\276\320\273\320\275\320\276\320\271 \320\267\320\260\320\274\320\265\320\275\320\276\320\271 \320\277\320\260\320\277\320\272\320\270!";
|
||||
static const char __pyx_k__3[] = "\360\237\222\260 \320\222\320\262\320\265\321\201\321\202\320\270 \321\201\320\262\320\276\321\216 \321\201\321\203\320\274\320\274\321\203";
|
||||
static const char __pyx_k__4[] = "\342\254\205\357\270\217 \320\235\320\260\320\267\320\260\320\264";
|
||||
static const char __pyx_k__5[] = "\320\222\321\213\320\261\320\265\321\200\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\321\217:";
|
||||
static const char __pyx_k__7[] = "|";
|
||||
static const char __pyx_k__9[] = "\320\237\320\276\320\277\320\276\320\273\320\275\320\270\321\202\321\214";
|
||||
static const char __pyx_k_gc[] = "gc";
|
||||
static const char __pyx_k_id[] = "id";
|
||||
static const char __pyx_k_Any[] = "Any";
|
||||
static const char __pyx_k__10[] = " \321\200\321\203\320\261\320\273\320\265\320\271.";
|
||||
static const char __pyx_k__12[] = "&";
|
||||
static const char __pyx_k__13[] = "\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260 \321\205\321\215\321\210\320\260 \320\275\320\265 \320\277\321\200\320\276\320\271\320\264\320\265\320\275\320\260";
|
||||
static const char __pyx_k__15[] = "\360\237\224\231 \320\235\320\260\320\267\320\260\320\264";
|
||||
static const char __pyx_k__16[] = "\320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\321\217.";
|
||||
static const char __pyx_k__19[] = "\320\241\321\203\320\274\320\274\320\260 \320\264\320\276\320\273\320\266\320\275\320\260 \320\261\321\213\321\202\321\214 \320\261\320\276\320\273\321\214\321\210\320\265 \320\275\321\203\320\273\321\217. \320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\265\321\211\320\265 \321\200\320\260\320\267:";
|
||||
static const char __pyx_k__20[] = "\320\235\320\265\320\272\320\276\321\200\321\200\320\265\320\272\321\202\320\275\320\260\321\217 \321\201\321\203\320\274\320\274\320\260. \320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\265\321\211\320\265 \321\200\320\260\320\267:";
|
||||
static const char __pyx_k__21[] = "*";
|
||||
static const char __pyx_k__22[] = ".";
|
||||
static const char __pyx_k__29[] = "?";
|
||||
static const char __pyx_k__10[] = "\320\222\321\213 \320\262\321\213\320\261\321\200\320\260\320\273\320\270 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265 \320\275\320\260 ";
|
||||
static const char __pyx_k__11[] = " \321\200\321\203\320\261\320\273\320\265\320\271.";
|
||||
static const char __pyx_k__13[] = "&";
|
||||
static const char __pyx_k__14[] = "\320\237\321\200\320\276\320\262\320\265\321\200\320\272\320\260 \321\205\321\215\321\210\320\260 \320\275\320\265 \320\277\321\200\320\276\320\271\320\264\320\265\320\275\320\260";
|
||||
static const char __pyx_k__16[] = "\360\237\224\231 \320\235\320\260\320\267\320\260\320\264";
|
||||
static const char __pyx_k__17[] = "\320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\277\320\276\320\277\320\276\320\273\320\275\320\265\320\275\320\270\321\217.";
|
||||
static const char __pyx_k__20[] = "\320\241\321\203\320\274\320\274\320\260 \320\264\320\276\320\273\320\266\320\275\320\260 \320\261\321\213\321\202\321\214 \320\261\320\276\320\273\321\214\321\210\320\265 \320\275\321\203\320\273\321\217. \320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\265\321\211\320\265 \321\200\320\260\320\267:";
|
||||
static const char __pyx_k__21[] = "\320\235\320\265\320\272\320\276\321\200\321\200\320\265\320\272\321\202\320\275\320\260\321\217 \321\201\321\203\320\274\320\274\320\260. \320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260, \320\262\320\262\320\265\320\264\320\270\321\202\320\265 \321\201\321\203\320\274\320\274\321\203 \320\265\321\211\320\265 \321\200\320\260\320\267:";
|
||||
static const char __pyx_k__22[] = "*";
|
||||
static const char __pyx_k__23[] = ".";
|
||||
static const char __pyx_k__30[] = "?";
|
||||
static const char __pyx_k_doc[] = "__doc__";
|
||||
static const char __pyx_k_get[] = "get";
|
||||
static const char __pyx_k_pay[] = "pay";
|
||||
@@ -2750,7 +2754,6 @@ static const char __pyx_k_string_to_hash[] = "string_to_hash";
|
||||
static const char __pyx_k_update_balance[] = "update_balance";
|
||||
static const char __pyx_k_user_id_amount[] = "\320\236\321\210\320\270\320\261\320\272\320\260 \320\272\320\276\320\275\320\262\320\265\321\200\321\202\320\260\321\206\320\270\320\270 user_id \320\270\320\273\320\270 amount: ";
|
||||
static const char __pyx_k_PAYMENT_OPTIONS[] = "PAYMENT_OPTIONS";
|
||||
static const char __pyx_k_YOOKASSA_HASH_2[] = "\320\235\320\265\320\262\320\265\321\200\320\275\320\276\320\265 \320\267\320\275\320\260\321\207\320\265\320\275\320\270\320\265 YOOKASSA_HASH. \320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265 \320\277\321\200\320\265\321\200\320\262\320\260\320\275\320\276.";
|
||||
static const char __pyx_k_YOOMONEY_ENABLE[] = "YOOMONEY_ENABLE";
|
||||
static const char __pyx_k_calculated_hash[] = "calculated_hash";
|
||||
static const char __pyx_k_inline_keyboard[] = "inline_keyboard";
|
||||
@@ -2859,26 +2862,26 @@ typedef struct {
|
||||
PyObject *__pyx_n_s_ValueError;
|
||||
PyObject *__pyx_kp_u_Webhook_event_received;
|
||||
PyObject *__pyx_n_s_YOOKASSA_HASH;
|
||||
PyObject *__pyx_kp_u_YOOKASSA_HASH_2;
|
||||
PyObject *__pyx_n_s_YOOMONEY_ENABLE;
|
||||
PyObject *__pyx_n_s_YOOMONEY_ID;
|
||||
PyObject *__pyx_n_s_YOOMONEY_SECRET_KEY;
|
||||
PyObject *__pyx_kp_u__10;
|
||||
PyObject *__pyx_kp_u__12;
|
||||
PyObject *__pyx_kp_u__11;
|
||||
PyObject *__pyx_kp_u__13;
|
||||
PyObject *__pyx_kp_u__15;
|
||||
PyObject *__pyx_kp_u__14;
|
||||
PyObject *__pyx_kp_u__16;
|
||||
PyObject *__pyx_kp_u__19;
|
||||
PyObject *__pyx_kp_u__17;
|
||||
PyObject *__pyx_kp_u__2;
|
||||
PyObject *__pyx_kp_u__20;
|
||||
PyObject *__pyx_n_s__21;
|
||||
PyObject *__pyx_kp_u__22;
|
||||
PyObject *__pyx_n_s__29;
|
||||
PyObject *__pyx_kp_u__21;
|
||||
PyObject *__pyx_n_s__22;
|
||||
PyObject *__pyx_kp_u__23;
|
||||
PyObject *__pyx_kp_u__3;
|
||||
PyObject *__pyx_n_s__30;
|
||||
PyObject *__pyx_kp_u__4;
|
||||
PyObject *__pyx_kp_u__6;
|
||||
PyObject *__pyx_n_u__8;
|
||||
PyObject *__pyx_kp_u__9;
|
||||
PyObject *__pyx_kp_u__5;
|
||||
PyObject *__pyx_kp_u__7;
|
||||
PyObject *__pyx_n_u__9;
|
||||
PyObject *__pyx_n_s_account_id;
|
||||
PyObject *__pyx_n_s_add_connection;
|
||||
PyObject *__pyx_n_s_add_payment;
|
||||
@@ -3025,18 +3028,18 @@ typedef struct {
|
||||
PyObject *__pyx_int_200;
|
||||
PyObject *__pyx_int_400;
|
||||
PyObject *__pyx_codeobj_;
|
||||
PyObject *__pyx_tuple__7;
|
||||
PyObject *__pyx_tuple__17;
|
||||
PyObject *__pyx_tuple__23;
|
||||
PyObject *__pyx_tuple__8;
|
||||
PyObject *__pyx_tuple__18;
|
||||
PyObject *__pyx_tuple__24;
|
||||
PyObject *__pyx_tuple__25;
|
||||
PyObject *__pyx_tuple__26;
|
||||
PyObject *__pyx_tuple__27;
|
||||
PyObject *__pyx_tuple__28;
|
||||
PyObject *__pyx_codeobj__5;
|
||||
PyObject *__pyx_codeobj__11;
|
||||
PyObject *__pyx_codeobj__14;
|
||||
PyObject *__pyx_codeobj__18;
|
||||
PyObject *__pyx_tuple__29;
|
||||
PyObject *__pyx_codeobj__6;
|
||||
PyObject *__pyx_codeobj__12;
|
||||
PyObject *__pyx_codeobj__15;
|
||||
PyObject *__pyx_codeobj__19;
|
||||
} __pyx_mstate;
|
||||
|
||||
#if CYTHON_USE_MODULE_STATE
|
||||
@@ -3107,26 +3110,26 @@ static int __pyx_m_clear(PyObject *m) {
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_ValueError);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u_Webhook_event_received);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_YOOKASSA_HASH);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u_YOOKASSA_HASH_2);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_YOOMONEY_ENABLE);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_YOOMONEY_ID);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_YOOMONEY_SECRET_KEY);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__10);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__12);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__11);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__13);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__15);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__14);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__16);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__19);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__17);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__2);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__20);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s__21);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__22);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s__29);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__21);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s__22);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__23);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__3);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s__30);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__4);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__6);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_u__8);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__9);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__5);
|
||||
Py_CLEAR(clear_module_state->__pyx_kp_u__7);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_u__9);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_account_id);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_add_connection);
|
||||
Py_CLEAR(clear_module_state->__pyx_n_s_add_payment);
|
||||
@@ -3273,18 +3276,18 @@ static int __pyx_m_clear(PyObject *m) {
|
||||
Py_CLEAR(clear_module_state->__pyx_int_200);
|
||||
Py_CLEAR(clear_module_state->__pyx_int_400);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj_);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__7);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__17);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__23);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__8);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__18);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__24);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__25);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__26);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__27);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__28);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__5);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__11);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__14);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__18);
|
||||
Py_CLEAR(clear_module_state->__pyx_tuple__29);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__6);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__12);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__15);
|
||||
Py_CLEAR(clear_module_state->__pyx_codeobj__19);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3333,26 +3336,26 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_ValueError);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u_Webhook_event_received);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_YOOKASSA_HASH);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u_YOOKASSA_HASH_2);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_YOOMONEY_ENABLE);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_YOOMONEY_ID);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_YOOMONEY_SECRET_KEY);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__10);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__12);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__11);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__13);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__15);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__14);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__16);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__19);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__17);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__2);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__20);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s__21);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__22);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s__29);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__21);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s__22);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__23);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__3);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s__30);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__4);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__6);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_u__8);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__9);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__5);
|
||||
Py_VISIT(traverse_module_state->__pyx_kp_u__7);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_u__9);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_account_id);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_add_connection);
|
||||
Py_VISIT(traverse_module_state->__pyx_n_s_add_payment);
|
||||
@@ -3499,18 +3502,18 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(traverse_module_state->__pyx_int_200);
|
||||
Py_VISIT(traverse_module_state->__pyx_int_400);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj_);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__7);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__17);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__23);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__8);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__18);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__24);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__25);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__26);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__27);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__28);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__5);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__11);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__14);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__18);
|
||||
Py_VISIT(traverse_module_state->__pyx_tuple__29);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__6);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__12);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__15);
|
||||
Py_VISIT(traverse_module_state->__pyx_codeobj__19);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -3569,26 +3572,26 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
#define __pyx_n_s_ValueError __pyx_mstate_global->__pyx_n_s_ValueError
|
||||
#define __pyx_kp_u_Webhook_event_received __pyx_mstate_global->__pyx_kp_u_Webhook_event_received
|
||||
#define __pyx_n_s_YOOKASSA_HASH __pyx_mstate_global->__pyx_n_s_YOOKASSA_HASH
|
||||
#define __pyx_kp_u_YOOKASSA_HASH_2 __pyx_mstate_global->__pyx_kp_u_YOOKASSA_HASH_2
|
||||
#define __pyx_n_s_YOOMONEY_ENABLE __pyx_mstate_global->__pyx_n_s_YOOMONEY_ENABLE
|
||||
#define __pyx_n_s_YOOMONEY_ID __pyx_mstate_global->__pyx_n_s_YOOMONEY_ID
|
||||
#define __pyx_n_s_YOOMONEY_SECRET_KEY __pyx_mstate_global->__pyx_n_s_YOOMONEY_SECRET_KEY
|
||||
#define __pyx_kp_u__10 __pyx_mstate_global->__pyx_kp_u__10
|
||||
#define __pyx_kp_u__12 __pyx_mstate_global->__pyx_kp_u__12
|
||||
#define __pyx_kp_u__11 __pyx_mstate_global->__pyx_kp_u__11
|
||||
#define __pyx_kp_u__13 __pyx_mstate_global->__pyx_kp_u__13
|
||||
#define __pyx_kp_u__15 __pyx_mstate_global->__pyx_kp_u__15
|
||||
#define __pyx_kp_u__14 __pyx_mstate_global->__pyx_kp_u__14
|
||||
#define __pyx_kp_u__16 __pyx_mstate_global->__pyx_kp_u__16
|
||||
#define __pyx_kp_u__19 __pyx_mstate_global->__pyx_kp_u__19
|
||||
#define __pyx_kp_u__17 __pyx_mstate_global->__pyx_kp_u__17
|
||||
#define __pyx_kp_u__2 __pyx_mstate_global->__pyx_kp_u__2
|
||||
#define __pyx_kp_u__20 __pyx_mstate_global->__pyx_kp_u__20
|
||||
#define __pyx_n_s__21 __pyx_mstate_global->__pyx_n_s__21
|
||||
#define __pyx_kp_u__22 __pyx_mstate_global->__pyx_kp_u__22
|
||||
#define __pyx_n_s__29 __pyx_mstate_global->__pyx_n_s__29
|
||||
#define __pyx_kp_u__21 __pyx_mstate_global->__pyx_kp_u__21
|
||||
#define __pyx_n_s__22 __pyx_mstate_global->__pyx_n_s__22
|
||||
#define __pyx_kp_u__23 __pyx_mstate_global->__pyx_kp_u__23
|
||||
#define __pyx_kp_u__3 __pyx_mstate_global->__pyx_kp_u__3
|
||||
#define __pyx_n_s__30 __pyx_mstate_global->__pyx_n_s__30
|
||||
#define __pyx_kp_u__4 __pyx_mstate_global->__pyx_kp_u__4
|
||||
#define __pyx_kp_u__6 __pyx_mstate_global->__pyx_kp_u__6
|
||||
#define __pyx_n_u__8 __pyx_mstate_global->__pyx_n_u__8
|
||||
#define __pyx_kp_u__9 __pyx_mstate_global->__pyx_kp_u__9
|
||||
#define __pyx_kp_u__5 __pyx_mstate_global->__pyx_kp_u__5
|
||||
#define __pyx_kp_u__7 __pyx_mstate_global->__pyx_kp_u__7
|
||||
#define __pyx_n_u__9 __pyx_mstate_global->__pyx_n_u__9
|
||||
#define __pyx_n_s_account_id __pyx_mstate_global->__pyx_n_s_account_id
|
||||
#define __pyx_n_s_add_connection __pyx_mstate_global->__pyx_n_s_add_connection
|
||||
#define __pyx_n_s_add_payment __pyx_mstate_global->__pyx_n_s_add_payment
|
||||
@@ -3735,18 +3738,18 @@ static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
#define __pyx_int_200 __pyx_mstate_global->__pyx_int_200
|
||||
#define __pyx_int_400 __pyx_mstate_global->__pyx_int_400
|
||||
#define __pyx_codeobj_ __pyx_mstate_global->__pyx_codeobj_
|
||||
#define __pyx_tuple__7 __pyx_mstate_global->__pyx_tuple__7
|
||||
#define __pyx_tuple__17 __pyx_mstate_global->__pyx_tuple__17
|
||||
#define __pyx_tuple__23 __pyx_mstate_global->__pyx_tuple__23
|
||||
#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8
|
||||
#define __pyx_tuple__18 __pyx_mstate_global->__pyx_tuple__18
|
||||
#define __pyx_tuple__24 __pyx_mstate_global->__pyx_tuple__24
|
||||
#define __pyx_tuple__25 __pyx_mstate_global->__pyx_tuple__25
|
||||
#define __pyx_tuple__26 __pyx_mstate_global->__pyx_tuple__26
|
||||
#define __pyx_tuple__27 __pyx_mstate_global->__pyx_tuple__27
|
||||
#define __pyx_tuple__28 __pyx_mstate_global->__pyx_tuple__28
|
||||
#define __pyx_codeobj__5 __pyx_mstate_global->__pyx_codeobj__5
|
||||
#define __pyx_codeobj__11 __pyx_mstate_global->__pyx_codeobj__11
|
||||
#define __pyx_codeobj__14 __pyx_mstate_global->__pyx_codeobj__14
|
||||
#define __pyx_codeobj__18 __pyx_mstate_global->__pyx_codeobj__18
|
||||
#define __pyx_tuple__29 __pyx_mstate_global->__pyx_tuple__29
|
||||
#define __pyx_codeobj__6 __pyx_mstate_global->__pyx_codeobj__6
|
||||
#define __pyx_codeobj__12 __pyx_mstate_global->__pyx_codeobj__12
|
||||
#define __pyx_codeobj__15 __pyx_mstate_global->__pyx_codeobj__15
|
||||
#define __pyx_codeobj__19 __pyx_mstate_global->__pyx_codeobj__19
|
||||
/* #### Code section: module_code ### */
|
||||
static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
|
||||
|
||||
@@ -3970,7 +3973,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
*
|
||||
* expected_hash = "HASHHASHYOOKASSA" # <<<<<<<<<<<<<<
|
||||
* if YOOKASSA_HASH != expected_hash:
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
*/
|
||||
__Pyx_INCREF(__pyx_n_u_HASHHASHYOOKASSA);
|
||||
__Pyx_GIVEREF(__pyx_n_u_HASHHASHYOOKASSA);
|
||||
@@ -3980,7 +3983,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
*
|
||||
* expected_hash = "HASHHASHYOOKASSA"
|
||||
* if YOOKASSA_HASH != expected_hash: # <<<<<<<<<<<<<<
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
* await callback_query.message.answer(
|
||||
*/
|
||||
__Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_YOOKASSA_HASH); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
|
||||
@@ -3992,7 +3995,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
/* "handlers/payments/yoomoney_pay.py":45
|
||||
* expected_hash = "HASHHASHYOOKASSA"
|
||||
* if YOOKASSA_HASH != expected_hash:
|
||||
* logger.error(" YOOKASSA_HASH. .") # <<<<<<<<<<<<<<
|
||||
* logger.error(" ! !") # <<<<<<<<<<<<<<
|
||||
* await callback_query.message.answer(
|
||||
* text=" , @solonet_sup."
|
||||
*/
|
||||
@@ -4016,7 +4019,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
}
|
||||
#endif
|
||||
{
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_kp_u_YOOKASSA_HASH_2};
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_kp_u__2};
|
||||
__pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5);
|
||||
__Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
|
||||
if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error)
|
||||
@@ -4027,7 +4030,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":46
|
||||
* if YOOKASSA_HASH != expected_hash:
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
* await callback_query.message.answer( # <<<<<<<<<<<<<<
|
||||
* text=" , @solonet_sup."
|
||||
* )
|
||||
@@ -4039,7 +4042,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":47
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
* await callback_query.message.answer(
|
||||
* text=" , @solonet_sup." # <<<<<<<<<<<<<<
|
||||
* )
|
||||
@@ -4051,7 +4054,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":46
|
||||
* if YOOKASSA_HASH != expected_hash:
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
* await callback_query.message.answer( # <<<<<<<<<<<<<<
|
||||
* text=" , @solonet_sup."
|
||||
* )
|
||||
@@ -4095,7 +4098,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
*
|
||||
* expected_hash = "HASHHASHYOOKASSA"
|
||||
* if YOOKASSA_HASH != expected_hash: # <<<<<<<<<<<<<<
|
||||
* logger.error(" YOOKASSA_HASH. .")
|
||||
* logger.error(" ! !")
|
||||
* await callback_query.message.answer(
|
||||
*/
|
||||
}
|
||||
@@ -4586,7 +4589,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
*/
|
||||
__pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 76, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__2) < 0) __PYX_ERR(0, 76, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__3) < 0) __PYX_ERR(0, 76, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_callback_data, __pyx_n_u_enter_custom_amount_yoomoney) < 0) __PYX_ERR(0, 76, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":75
|
||||
@@ -4638,7 +4641,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
__Pyx_GOTREF(__pyx_t_11);
|
||||
__pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__3) < 0) __PYX_ERR(0, 80, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__4) < 0) __PYX_ERR(0, 80, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_callback_data, __pyx_n_u_pay) < 0) __PYX_ERR(0, 80, __pyx_L1_error)
|
||||
__pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_4);
|
||||
@@ -4880,7 +4883,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_2generator(__pyx_Co
|
||||
*/
|
||||
__pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 90, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__4) < 0) __PYX_ERR(0, 90, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_kp_u__5) < 0) __PYX_ERR(0, 90, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":91
|
||||
* await callback_query.message.answer(
|
||||
@@ -5182,7 +5185,7 @@ static PyObject *__pyx_pf_8handlers_8payments_12yoomoney_pay_3process_amount_sel
|
||||
__Pyx_INCREF(__pyx_cur_scope->__pyx_v_state);
|
||||
__Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_state);
|
||||
{
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1, __pyx_codeobj__5, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_amount_selection, __pyx_n_s_process_amount_selection, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1, __pyx_codeobj__6, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_amount_selection, __pyx_n_s_process_amount_selection, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_DECREF(__pyx_cur_scope);
|
||||
__Pyx_RefNannyFinishContext();
|
||||
return (PyObject *) gen;
|
||||
@@ -5245,7 +5248,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1(__pyx_C
|
||||
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_split); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_2);
|
||||
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
|
||||
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_1);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
__Pyx_GIVEREF(__pyx_t_1);
|
||||
@@ -5608,7 +5611,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1(__pyx_C
|
||||
__Pyx_GOTREF(__pyx_t_10);
|
||||
__pyx_t_9 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 126, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_9);
|
||||
if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_text, __pyx_n_u__8) < 0) __PYX_ERR(0, 126, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_text, __pyx_n_u__9) < 0) __PYX_ERR(0, 126, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_url, __pyx_cur_scope->__pyx_v_payment_url) < 0) __PYX_ERR(0, 126, __pyx_L1_error)
|
||||
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_empty_tuple, __pyx_t_9); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 126, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_13);
|
||||
@@ -5631,7 +5634,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1(__pyx_C
|
||||
__Pyx_GOTREF(__pyx_t_13);
|
||||
__pyx_t_10 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 127, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_10);
|
||||
if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_text, __pyx_kp_u__3) < 0) __PYX_ERR(0, 127, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_text, __pyx_kp_u__4) < 0) __PYX_ERR(0, 127, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_callback_data, __pyx_n_u_pay) < 0) __PYX_ERR(0, 127, __pyx_L1_error)
|
||||
__pyx_t_14 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_empty_tuple, __pyx_t_10); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 127, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_14);
|
||||
@@ -5702,11 +5705,11 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1(__pyx_C
|
||||
__Pyx_GOTREF(__pyx_t_2);
|
||||
__pyx_t_3 = 0;
|
||||
__pyx_t_12 = 127;
|
||||
__Pyx_INCREF(__pyx_kp_u__9);
|
||||
__Pyx_INCREF(__pyx_kp_u__10);
|
||||
__pyx_t_12 = (65535 > __pyx_t_12) ? 65535 : __pyx_t_12;
|
||||
__pyx_t_3 += 25;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__9);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__9);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__10);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__10);
|
||||
__pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_cur_scope->__pyx_v_amount, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 132, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_10);
|
||||
__pyx_t_12 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_12) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_12;
|
||||
@@ -5714,11 +5717,11 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_5generator1(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_10);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_10);
|
||||
__pyx_t_10 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__10);
|
||||
__Pyx_INCREF(__pyx_kp_u__11);
|
||||
__pyx_t_12 = (65535 > __pyx_t_12) ? 65535 : __pyx_t_12;
|
||||
__pyx_t_3 += 8;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__10);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__10);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__11);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__11);
|
||||
__pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_3, __pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 132, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_10);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
@@ -5922,7 +5925,7 @@ static PyObject *__pyx_pf_8handlers_8payments_12yoomoney_pay_6yoomoney_webhook(C
|
||||
__Pyx_INCREF(__pyx_cur_scope->__pyx_v_request);
|
||||
__Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_request);
|
||||
{
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2, __pyx_codeobj__11, (PyObject *) __pyx_cur_scope, __pyx_n_s_yoomoney_webhook, __pyx_n_s_yoomoney_webhook, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2, __pyx_codeobj__12, (PyObject *) __pyx_cur_scope, __pyx_n_s_yoomoney_webhook, __pyx_n_s_yoomoney_webhook, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__Pyx_DECREF(__pyx_cur_scope);
|
||||
__Pyx_RefNannyFinishContext();
|
||||
return (PyObject *) gen;
|
||||
@@ -6241,10 +6244,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_5);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
|
||||
__pyx_t_5 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u__13);
|
||||
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6277,10 +6280,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_3);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_3);
|
||||
__pyx_t_3 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u__13);
|
||||
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6313,10 +6316,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_5);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_t_5);
|
||||
__pyx_t_5 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_kp_u__13);
|
||||
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6349,10 +6352,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_3);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_t_3);
|
||||
__pyx_t_3 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_kp_u__13);
|
||||
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6385,10 +6388,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_5);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_t_5);
|
||||
__pyx_t_5 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_kp_u__13);
|
||||
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6421,10 +6424,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_3);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 10, __pyx_t_3);
|
||||
__pyx_t_3 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_kp_u__13);
|
||||
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__pyx_t_2 = NULL;
|
||||
@@ -6457,10 +6460,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_5);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 12, __pyx_t_5);
|
||||
__pyx_t_5 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 13, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 13, __pyx_kp_u__13);
|
||||
__pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_cur_scope->__pyx_v_notification_secret, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_7;
|
||||
@@ -6468,10 +6471,10 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
__Pyx_GIVEREF(__pyx_t_5);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 14, __pyx_t_5);
|
||||
__pyx_t_5 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__12);
|
||||
__Pyx_INCREF(__pyx_kp_u__13);
|
||||
__pyx_t_6 += 1;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__12);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 15, __pyx_kp_u__12);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__13);
|
||||
PyTuple_SET_ITEM(__pyx_t_1, 15, __pyx_kp_u__13);
|
||||
__pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_cur_scope->__pyx_v_user_id_str, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_7;
|
||||
@@ -6591,7 +6594,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_8generator2(__pyx_C
|
||||
}
|
||||
#endif
|
||||
{
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_kp_u__13};
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_kp_u__14};
|
||||
__pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4);
|
||||
__Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 154, __pyx_L1_error)
|
||||
@@ -7351,7 +7354,7 @@ static PyObject *__pyx_pf_8handlers_8payments_12yoomoney_pay_9process_enter_cust
|
||||
__Pyx_INCREF(__pyx_cur_scope->__pyx_v_state);
|
||||
__Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_state);
|
||||
{
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_11generator3, __pyx_codeobj__14, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_enter_custom_amount, __pyx_n_s_process_enter_custom_amount, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_11generator3, __pyx_codeobj__15, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_enter_custom_amount, __pyx_n_s_process_enter_custom_amount, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__Pyx_DECREF(__pyx_cur_scope);
|
||||
__Pyx_RefNannyFinishContext();
|
||||
return (PyObject *) gen;
|
||||
@@ -7441,7 +7444,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_11generator3(__pyx_
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__pyx_t_5 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 176, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_text, __pyx_kp_u__15) < 0) __PYX_ERR(0, 176, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_text, __pyx_kp_u__16) < 0) __PYX_ERR(0, 176, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_callback_data, __pyx_n_u_pay_yoomoney) < 0) __PYX_ERR(0, 176, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 176, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
@@ -7528,7 +7531,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_11generator3(__pyx_
|
||||
* ", .",
|
||||
* reply_markup=builder.as_markup(),
|
||||
*/
|
||||
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__17, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 178, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__18, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 178, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
|
||||
@@ -7783,7 +7786,7 @@ static PyObject *__pyx_pf_8handlers_8payments_12yoomoney_pay_12process_custom_am
|
||||
__Pyx_INCREF(__pyx_cur_scope->__pyx_v_state);
|
||||
__Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_state);
|
||||
{
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4, __pyx_codeobj__18, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_custom_amount_input, __pyx_n_s_process_custom_amount_input, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__pyx_CoroutineObject *gen = __Pyx_Coroutine_New((__pyx_coroutine_body_t) __pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4, __pyx_codeobj__19, (PyObject *) __pyx_cur_scope, __pyx_n_s_process_custom_amount_input, __pyx_n_s_process_custom_amount_input, __pyx_n_s_handlers_payments_yoomoney_pay); if (unlikely(!gen)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__Pyx_DECREF(__pyx_cur_scope);
|
||||
__Pyx_RefNannyFinishContext();
|
||||
return (PyObject *) gen;
|
||||
@@ -7922,7 +7925,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
}
|
||||
#endif
|
||||
{
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_kp_u__19};
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_kp_u__20};
|
||||
__pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4);
|
||||
__Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 191, __pyx_L1_error)
|
||||
@@ -8182,7 +8185,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_n_u__8) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_text, __pyx_n_u__9) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_url, __pyx_cur_scope->__pyx_v_payment_url) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
|
||||
__pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 207, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_9);
|
||||
@@ -8205,7 +8208,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
__Pyx_GOTREF(__pyx_t_9);
|
||||
__pyx_t_6 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 208, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_text, __pyx_kp_u__3) < 0) __PYX_ERR(0, 208, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_text, __pyx_kp_u__4) < 0) __PYX_ERR(0, 208, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_callback_data, __pyx_n_u_pay) < 0) __PYX_ERR(0, 208, __pyx_L1_error)
|
||||
__pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 208, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_10);
|
||||
@@ -8273,11 +8276,11 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
__Pyx_GOTREF(__pyx_t_2);
|
||||
__pyx_t_7 = 0;
|
||||
__pyx_t_8 = 127;
|
||||
__Pyx_INCREF(__pyx_kp_u__9);
|
||||
__Pyx_INCREF(__pyx_kp_u__10);
|
||||
__pyx_t_8 = (65535 > __pyx_t_8) ? 65535 : __pyx_t_8;
|
||||
__pyx_t_7 += 25;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__9);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__9);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__10);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__10);
|
||||
__pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_cur_scope->__pyx_v_amount, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 213, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_8;
|
||||
@@ -8285,11 +8288,11 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
__Pyx_GIVEREF(__pyx_t_6);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6);
|
||||
__pyx_t_6 = 0;
|
||||
__Pyx_INCREF(__pyx_kp_u__10);
|
||||
__Pyx_INCREF(__pyx_kp_u__11);
|
||||
__pyx_t_8 = (65535 > __pyx_t_8) ? 65535 : __pyx_t_8;
|
||||
__pyx_t_7 += 8;
|
||||
__Pyx_GIVEREF(__pyx_kp_u__10);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__10);
|
||||
__Pyx_GIVEREF(__pyx_kp_u__11);
|
||||
PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__11);
|
||||
__pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 213, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
|
||||
@@ -8369,7 +8372,7 @@ static PyObject *__pyx_gb_8handlers_8payments_12yoomoney_pay_14generator4(__pyx_
|
||||
}
|
||||
#endif
|
||||
{
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_kp_u__20};
|
||||
PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_kp_u__21};
|
||||
__pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4);
|
||||
__Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
|
||||
if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 218, __pyx_L1_error)
|
||||
@@ -9416,26 +9419,26 @@ static int __Pyx_CreateStringTabAndInitStrings(void) {
|
||||
{&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u_Webhook_event_received, __pyx_k_Webhook_event_received, sizeof(__pyx_k_Webhook_event_received), 0, 1, 0, 0},
|
||||
{&__pyx_n_s_YOOKASSA_HASH, __pyx_k_YOOKASSA_HASH, sizeof(__pyx_k_YOOKASSA_HASH), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u_YOOKASSA_HASH_2, __pyx_k_YOOKASSA_HASH_2, sizeof(__pyx_k_YOOKASSA_HASH_2), 0, 1, 0, 0},
|
||||
{&__pyx_n_s_YOOMONEY_ENABLE, __pyx_k_YOOMONEY_ENABLE, sizeof(__pyx_k_YOOMONEY_ENABLE), 0, 0, 1, 1},
|
||||
{&__pyx_n_s_YOOMONEY_ID, __pyx_k_YOOMONEY_ID, sizeof(__pyx_k_YOOMONEY_ID), 0, 0, 1, 1},
|
||||
{&__pyx_n_s_YOOMONEY_SECRET_KEY, __pyx_k_YOOMONEY_SECRET_KEY, sizeof(__pyx_k_YOOMONEY_SECRET_KEY), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__12, __pyx_k__12, sizeof(__pyx_k__12), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__13, __pyx_k__13, sizeof(__pyx_k__13), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__16, __pyx_k__16, sizeof(__pyx_k__16), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__19, __pyx_k__19, sizeof(__pyx_k__19), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__17, __pyx_k__17, sizeof(__pyx_k__17), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__20, __pyx_k__20, sizeof(__pyx_k__20), 0, 1, 0, 0},
|
||||
{&__pyx_n_s__21, __pyx_k__21, sizeof(__pyx_k__21), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u__22, __pyx_k__22, sizeof(__pyx_k__22), 0, 1, 0, 0},
|
||||
{&__pyx_n_s__29, __pyx_k__29, sizeof(__pyx_k__29), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u__21, __pyx_k__21, sizeof(__pyx_k__21), 0, 1, 0, 0},
|
||||
{&__pyx_n_s__22, __pyx_k__22, sizeof(__pyx_k__22), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u__23, __pyx_k__23, sizeof(__pyx_k__23), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0},
|
||||
{&__pyx_n_s__30, __pyx_k__30, sizeof(__pyx_k__30), 0, 0, 1, 1},
|
||||
{&__pyx_kp_u__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0},
|
||||
{&__pyx_n_u__8, __pyx_k__8, sizeof(__pyx_k__8), 0, 1, 0, 1},
|
||||
{&__pyx_kp_u__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 1, 0, 0},
|
||||
{&__pyx_kp_u__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 1, 0, 0},
|
||||
{&__pyx_n_u__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 1, 0, 1},
|
||||
{&__pyx_n_s_account_id, __pyx_k_account_id, sizeof(__pyx_k_account_id), 0, 0, 1, 1},
|
||||
{&__pyx_n_s_add_connection, __pyx_k_add_connection, sizeof(__pyx_k_add_connection), 0, 0, 1, 1},
|
||||
{&__pyx_n_s_add_payment, __pyx_k_add_payment, sizeof(__pyx_k_add_payment), 0, 0, 1, 1},
|
||||
@@ -9600,9 +9603,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
*
|
||||
* if len(data) != 2:
|
||||
*/
|
||||
__pyx_tuple__7 = PyTuple_Pack(2, __pyx_kp_u__6, __pyx_int_1); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 102, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__7);
|
||||
__Pyx_GIVEREF(__pyx_tuple__7);
|
||||
__pyx_tuple__8 = PyTuple_Pack(2, __pyx_kp_u__7, __pyx_int_1); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 102, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__8);
|
||||
__Pyx_GIVEREF(__pyx_tuple__8);
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":178
|
||||
* builder.row(InlineKeyboardButton(text=" ", callback_data="pay_yoomoney"))
|
||||
@@ -9611,9 +9614,9 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* ", .",
|
||||
* reply_markup=builder.as_markup(),
|
||||
*/
|
||||
__pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_u__16); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 178, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__17);
|
||||
__Pyx_GIVEREF(__pyx_tuple__17);
|
||||
__pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_u__17); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 178, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__18);
|
||||
__Pyx_GIVEREF(__pyx_tuple__18);
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":38
|
||||
*
|
||||
@@ -9622,10 +9625,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* async def process_callback_pay_yoomoney(
|
||||
* callback_query: types.CallbackQuery, state: FSMContext, session: Any
|
||||
*/
|
||||
__pyx_tuple__23 = PyTuple_Pack(9, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_session, __pyx_n_s_expected_hash, __pyx_n_s_tg_id, __pyx_n_s_builder, __pyx_n_s_i, __pyx_n_s_key_count, __pyx_n_s_exists); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 38, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__23);
|
||||
__Pyx_GIVEREF(__pyx_tuple__23);
|
||||
__pyx_codeobj_ = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_callback_pay_yoomoney, 38, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj_)) __PYX_ERR(0, 38, __pyx_L1_error)
|
||||
__pyx_tuple__24 = PyTuple_Pack(9, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_session, __pyx_n_s_expected_hash, __pyx_n_s_tg_id, __pyx_n_s_builder, __pyx_n_s_i, __pyx_n_s_key_count, __pyx_n_s_exists); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(0, 38, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__24);
|
||||
__Pyx_GIVEREF(__pyx_tuple__24);
|
||||
__pyx_codeobj_ = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_callback_pay_yoomoney, 38, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj_)) __PYX_ERR(0, 38, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":98
|
||||
*
|
||||
@@ -9634,13 +9637,13 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* async def process_amount_selection(
|
||||
* callback_query: types.CallbackQuery, state: FSMContext
|
||||
*/
|
||||
__pyx_tuple__24 = PyTuple_Pack(1, __pyx_n_u_yoomoney_amount); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__24);
|
||||
__Pyx_GIVEREF(__pyx_tuple__24);
|
||||
__pyx_tuple__25 = PyTuple_Pack(9, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_data, __pyx_n_s_amount_str, __pyx_n_s_amount, __pyx_n_s_customer_id, __pyx_n_s_account_id, __pyx_n_s_payment_url, __pyx_n_s_confirm_keyboard); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_tuple__25 = PyTuple_Pack(1, __pyx_n_u_yoomoney_amount); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__25);
|
||||
__Pyx_GIVEREF(__pyx_tuple__25);
|
||||
__pyx_codeobj__5 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_amount_selection, 98, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__5)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_tuple__26 = PyTuple_Pack(9, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_data, __pyx_n_s_amount_str, __pyx_n_s_amount, __pyx_n_s_customer_id, __pyx_n_s_account_id, __pyx_n_s_payment_url, __pyx_n_s_confirm_keyboard); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__26);
|
||||
__Pyx_GIVEREF(__pyx_tuple__26);
|
||||
__pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_amount_selection, 98, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":137
|
||||
*
|
||||
@@ -9649,10 +9652,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* data = await request.post()
|
||||
* logger.debug(f"Webhook event received: {data}")
|
||||
*/
|
||||
__pyx_tuple__26 = PyTuple_Pack(11, __pyx_n_s_request, __pyx_n_s_data, __pyx_n_s_user_id_str, __pyx_n_s_amount_str, __pyx_n_s_notification_secret, __pyx_n_s_sha1_hash, __pyx_n_s_string_to_hash, __pyx_n_s_calculated_hash, __pyx_n_s_user_id, __pyx_n_s_amount, __pyx_n_s_e); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__26);
|
||||
__Pyx_GIVEREF(__pyx_tuple__26);
|
||||
__pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_yoomoney_webhook, 137, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__pyx_tuple__27 = PyTuple_Pack(11, __pyx_n_s_request, __pyx_n_s_data, __pyx_n_s_user_id_str, __pyx_n_s_amount_str, __pyx_n_s_notification_secret, __pyx_n_s_sha1_hash, __pyx_n_s_string_to_hash, __pyx_n_s_calculated_hash, __pyx_n_s_user_id, __pyx_n_s_amount, __pyx_n_s_e); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__27);
|
||||
__Pyx_GIVEREF(__pyx_tuple__27);
|
||||
__pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_yoomoney_webhook, 137, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":171
|
||||
*
|
||||
@@ -9661,10 +9664,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* async def process_enter_custom_amount(
|
||||
* callback_query: types.CallbackQuery, state: FSMContext
|
||||
*/
|
||||
__pyx_tuple__27 = PyTuple_Pack(3, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_builder); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__27);
|
||||
__Pyx_GIVEREF(__pyx_tuple__27);
|
||||
__pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_enter_custom_amount, 171, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__pyx_tuple__28 = PyTuple_Pack(3, __pyx_n_s_callback_query, __pyx_n_s_state, __pyx_n_s_builder); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__28);
|
||||
__Pyx_GIVEREF(__pyx_tuple__28);
|
||||
__pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_enter_custom_amount, 171, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
|
||||
/* "handlers/payments/yoomoney_pay.py":186
|
||||
*
|
||||
@@ -9673,10 +9676,10 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
|
||||
* async def process_custom_amount_input(message: types.Message, state: FSMContext):
|
||||
* if message.text.isdigit():
|
||||
*/
|
||||
__pyx_tuple__28 = PyTuple_Pack(7, __pyx_n_s_message, __pyx_n_s_state, __pyx_n_s_amount, __pyx_n_s_customer_id, __pyx_n_s_account_id, __pyx_n_s_payment_url, __pyx_n_s_confirm_keyboard); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__28);
|
||||
__Pyx_GIVEREF(__pyx_tuple__28);
|
||||
__pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_custom_amount_input, 186, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__pyx_tuple__29 = PyTuple_Pack(7, __pyx_n_s_message, __pyx_n_s_state, __pyx_n_s_amount, __pyx_n_s_customer_id, __pyx_n_s_account_id, __pyx_n_s_payment_url, __pyx_n_s_confirm_keyboard); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_tuple__29);
|
||||
__Pyx_GIVEREF(__pyx_tuple__29);
|
||||
__pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_COROUTINE, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_handlers_payments_yoomoney_pay_p, __pyx_n_s_process_custom_amount_input, 186, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__Pyx_RefNannyFinishContext();
|
||||
return 0;
|
||||
__pyx_L1_error:;
|
||||
@@ -10778,7 +10781,7 @@ if (!__Pyx_RefNanny) {
|
||||
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_startswith); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
|
||||
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
|
||||
__pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
@@ -10789,7 +10792,7 @@ if (!__Pyx_RefNanny) {
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_callback_query, __pyx_kp_s_types_CallbackQuery) < 0) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_state, __pyx_n_s_FSMContext) < 0) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_4process_amount_selection, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_amount_selection, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__5)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_4process_amount_selection, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_amount_selection, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__6)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 98, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_6);
|
||||
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
|
||||
@@ -10810,7 +10813,7 @@ if (!__Pyx_RefNanny) {
|
||||
__pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_request, __pyx_kp_s_web_Request) < 0) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_7yoomoney_webhook, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_yoomoney_webhook, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__11)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_7yoomoney_webhook, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_yoomoney_webhook, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__12)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
__Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_6);
|
||||
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
|
||||
@@ -10844,7 +10847,7 @@ if (!__Pyx_RefNanny) {
|
||||
__Pyx_GOTREF(__pyx_t_3);
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_callback_query, __pyx_kp_s_types_CallbackQuery) < 0) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_state, __pyx_n_s_FSMContext) < 0) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_10process_enter_custom_amount, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_enter_custom_amount, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__14)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_10process_enter_custom_amount, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_enter_custom_amount, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__15)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 171, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_3);
|
||||
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
|
||||
@@ -10880,7 +10883,7 @@ if (!__Pyx_RefNanny) {
|
||||
__Pyx_GOTREF(__pyx_t_5);
|
||||
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_message, __pyx_kp_s_types_Message) < 0) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_state, __pyx_n_s_FSMContext) < 0) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_13process_custom_amount_input, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_custom_amount_input, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__18)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_8handlers_8payments_12yoomoney_pay_13process_custom_amount_input, __Pyx_CYFUNCTION_COROUTINE, __pyx_n_s_process_custom_amount_input, NULL, __pyx_n_s_handlers_payments_yoomoney_pay, __pyx_d, ((PyObject *)__pyx_codeobj__19)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 186, __pyx_L1_error)
|
||||
__Pyx_GOTREF(__pyx_t_6);
|
||||
__Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_5);
|
||||
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
|
||||
@@ -15082,7 +15085,7 @@ static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *
|
||||
#endif
|
||||
static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) {
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyObject *module, *from_list, *star = __pyx_n_s__21;
|
||||
PyObject *module, *from_list, *star = __pyx_n_s__22;
|
||||
CYTHON_UNUSED_VAR(parts_tuple);
|
||||
from_list = PyList_New(1);
|
||||
if (unlikely(!from_list))
|
||||
@@ -15145,7 +15148,7 @@ static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple)
|
||||
if (unlikely(!module_name_str)) { goto modbad; }
|
||||
module_name = PyUnicode_FromString(module_name_str);
|
||||
if (unlikely(!module_name)) { goto modbad; }
|
||||
module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__22);
|
||||
module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__23);
|
||||
if (unlikely(!module_dot)) { goto modbad; }
|
||||
full_name = PyUnicode_Concat(module_dot, name);
|
||||
if (unlikely(!full_name)) { goto modbad; }
|
||||
@@ -16996,7 +16999,7 @@ __Pyx_PyType_GetName(PyTypeObject* tp)
|
||||
if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) {
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(name);
|
||||
name = __Pyx_NewRef(__pyx_n_s__29);
|
||||
name = __Pyx_NewRef(__pyx_n_s__30);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
Binary file not shown.
+42
-19
@@ -7,17 +7,26 @@ from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
from config import NEWS_MESSAGE, RENEWAL_PLANS
|
||||
from database import get_balance, get_key_count, get_referral_stats
|
||||
from handlers.buttons.profile import ADD_SUB, GIFTS, INSTRUCTIONS, INVITE, MAIN_MENU, MY_SUBS, PAYMENT, TARRIFS
|
||||
from handlers.texts import get_referral_link, invite_message_send, profile_message_send
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "profile")
|
||||
@router.message(F.text == "/profile")
|
||||
async def process_callback_view_profile(
|
||||
callback_query: types.CallbackQuery, state: FSMContext, admin: bool
|
||||
callback_query_or_message: types.Message | types.CallbackQuery, state: FSMContext, admin: bool
|
||||
):
|
||||
chat_id = callback_query.message.chat.id
|
||||
username = callback_query.from_user.full_name
|
||||
if isinstance(callback_query_or_message, types.CallbackQuery):
|
||||
chat_id = callback_query_or_message.message.chat.id
|
||||
username = callback_query_or_message.from_user.full_name
|
||||
is_callback = True
|
||||
elif isinstance(callback_query_or_message, types.Message):
|
||||
chat_id = callback_query_or_message.chat.id
|
||||
username = callback_query_or_message.from_user.full_name
|
||||
is_callback = False
|
||||
|
||||
image_path = os.path.join("img", "pic.jpg")
|
||||
key_count = await get_key_count(chat_id)
|
||||
balance = await get_balance(chat_id)
|
||||
@@ -33,42 +42,56 @@ async def process_callback_view_profile(
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="➕ Устройство", callback_data="create_key"),
|
||||
InlineKeyboardButton(text="📱 Мои устройства", callback_data="view_keys"),
|
||||
InlineKeyboardButton(text=ADD_SUB, callback_data="create_key"),
|
||||
InlineKeyboardButton(text=MY_SUBS, callback_data="view_keys"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="💳 Пополнить баланс",
|
||||
text=PAYMENT,
|
||||
callback_data="pay",
|
||||
)
|
||||
)
|
||||
builder.row()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="👥 Пригласить", callback_data="invite"),
|
||||
InlineKeyboardButton(text="🎁 Подарить", callback_data="gifts"),
|
||||
InlineKeyboardButton(text=INVITE, callback_data="invite"),
|
||||
InlineKeyboardButton(text=GIFTS, callback_data="gifts"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="💡 Тарифы", callback_data="view_tariffs"),
|
||||
InlineKeyboardButton(text="📘 Инструкции", callback_data="instructions"),
|
||||
InlineKeyboardButton(text=TARRIFS, callback_data="view_tariffs"),
|
||||
InlineKeyboardButton(text=INSTRUCTIONS, callback_data="instructions"),
|
||||
)
|
||||
if admin:
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="🔧 Администратор", callback_data="admin")
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="⬅️ Главное меню", callback_data="start"))
|
||||
builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="start"))
|
||||
|
||||
if os.path.isfile(image_path):
|
||||
with open(image_path, "rb") as image_file:
|
||||
await callback_query.message.answer_photo(
|
||||
photo=BufferedInputFile(image_file.read(), filename="pic.jpg"),
|
||||
caption=profile_message,
|
||||
if is_callback:
|
||||
await callback_query_or_message.message.answer_photo(
|
||||
photo=BufferedInputFile(image_file.read(), filename="pic.jpg"),
|
||||
caption=profile_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
else:
|
||||
await callback_query_or_message.answer_photo(
|
||||
photo=BufferedInputFile(image_file.read(), filename="pic.jpg"),
|
||||
caption=profile_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
else:
|
||||
if is_callback:
|
||||
await callback_query_or_message.message.answer(
|
||||
text=profile_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
else:
|
||||
await callback_query.message.answer(
|
||||
text=profile_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
else:
|
||||
await callback_query_or_message.answer(
|
||||
text=profile_message,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@router.callback_query(F.data == "view_tariffs")
|
||||
|
||||
+5
-2
@@ -216,7 +216,10 @@ async def handle_connect_vpn(callback_query: CallbackQuery, session: Any):
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="💻 Windows/Linux", callback_data=f"connect_pc|{email}"
|
||||
text="💻 Компьютеры", callback_data=f"connect_pc|{email}"
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text="📺 Андроид TV", callback_data=f"connect_tv|{email}"
|
||||
)
|
||||
)
|
||||
builder.row(
|
||||
@@ -245,5 +248,5 @@ async def handle_about_vpn(callback_query: CallbackQuery):
|
||||
builder.row(InlineKeyboardButton(text="⬅️ Назад", callback_data="start"))
|
||||
|
||||
await callback_query.message.answer(
|
||||
get_about_vpn("3.2.3-beta-gifts"), reply_markup=builder.as_markup()
|
||||
get_about_vpn("3.2.3-minor"), reply_markup=builder.as_markup()
|
||||
)
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the virtual environment directory exists
|
||||
if [ ! -d "venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
python3 -m venv venv
|
||||
fi
|
||||
|
||||
# Activate the virtual environment
|
||||
source venv/bin/activate
|
||||
|
||||
# Install dependencies if they haven't been installed yet
|
||||
if [ ! -f "venv/lib/python*/site-packages/installed" ]; then
|
||||
echo "Installing wheel for faster installing..."
|
||||
pip3 install wheel
|
||||
|
||||
echo "Installing dependencies..."
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip3 install -r requirements.txt
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Installation completed successfully!"
|
||||
Reference in New Issue
Block a user