Update dependency libbot to v1.7 #28

Closed
Renovate wants to merge 2 commits from renovate/libbot-1.x into dev
10 changed files with 244 additions and 197 deletions
Showing only changes of commit 1881e345c5 - Show all commits

View File

@ -1,11 +1,11 @@
<h1 align="center">TelegramPoster</h1> <h1 align="center">TelegramPoster</h1>
<p align="center"> <p align="center">
<a href="https://git.end-play.xyz/profitroll/TelegramPoster/src/branch/dev/LICENSE"><img alt="License: GPL" src="https://img.shields.io/badge/License-GPL-blue"></a> <a href="https://git.end-play.xyz/profitroll/TelegramPoster/src/branch/master/LICENSE"><img alt="License: GPL" src="https://img.shields.io/badge/License-GPL-blue"></a>
<a href="https://git.end-play.xyz/profitroll/TelegramPoster"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a> <a href="https://git.end-play.xyz/profitroll/TelegramPoster"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
</p> </p>
> Шукаєш інструкцію українською? А вона [ось тут](https://git.end-play.xyz/profitroll/TelegramPoster/src/branch/dev/README_uk.md) знаходиться) > Шукаєш інструкцію українською? А вона [ось тут](https://git.end-play.xyz/profitroll/TelegramPoster/src/branch/master/README_uk.md) знаходиться)
This bot is used for one and only task - post pictures from my personal archive. Here's its source code so you can also host a bot and have fun with it. Just don't exepect it to be brilliant. It is not. But hey, you can always fork it ;) This bot is used for one and only task - post pictures from my personal archive. Here's its source code so you can also host a bot and have fun with it. Just don't exepect it to be brilliant. It is not. But hey, you can always fork it ;)
@ -21,7 +21,7 @@ Please note that Photos API also requires MongoDB so it makes sense to install a
## Installation ## Installation
To make this bot run at first you need to have a Python interpreter, Photos API, MongoDB and optionally git. You can also ignore git and simply download source code, should also work fine. After that you're ready to go. To make this bot run at first you need to have a Python interpreter, Photos API, MongoDB and optionally git (if you want to update using `git pull`). You can also ignore git and simply download source code, should also work fine. After that you're ready to go.
> In this README I assume that you're using default python in your > In this README I assume that you're using default python in your
> system and your system's PATH contains it. If your default python > system and your system's PATH contains it. If your default python
@ -29,7 +29,7 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
> If it's non-standard executable path - you should also change > If it's non-standard executable path - you should also change
> it in scripts you will use (`loop.sh`, `loop.bat`, `start.sh` and `start.bat`). > it in scripts you will use (`loop.sh`, `loop.bat`, `start.sh` and `start.bat`).
1. Install Mongo and Photos API: 1. Install MongoDB and Photos API:
1. Install MongoDB by following [official installation manual](https://www.mongodb.com/docs/manual/installation) 1. Install MongoDB by following [official installation manual](https://www.mongodb.com/docs/manual/installation)
2. Install Photos API by following [Photos API's README](https://git.end-play.xyz/profitroll/PhotosAPI/src/branch/master/README.md) 2. Install Photos API by following [Photos API's README](https://git.end-play.xyz/profitroll/PhotosAPI/src/branch/master/README.md)
@ -42,19 +42,19 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
3. Create virtual environment [Optional]: 3. Create virtual environment [Optional]:
1. Install virtualenv module: `pip install virtualenv` 1. Install virtualenv module: `pip install virtualenv`
2. Create venv: `python -m venv env` 2. Create venv: `python -m venv .venv`
3. Activate it using `source venv/bin/activate` on Linux, `venv\Scripts\activate.bat` in CMD or `venv\Scripts\Activate.ps1` in PowerShell. 3. Activate it using `source .venv/bin/activate` on Linux, `.venv\Scripts\activate.bat` in CMD or `.venv\Scripts\Activate.ps1` in PowerShell.
4. Install project's dependencies: 4. Install project's dependencies:
`python -m pip install -r requirements.txt` `python -m pip install -r requirements.txt`
Without installing those - bot cannot work at all. Without installing those - bot cannot work at all.
5. Configure "bot" and "owner" with your favorite text editor: 5. Configure required keys with your favorite text editor:
1. Copy file `config_example.json` to `config.json` 1. Copy config file: `cp config_example.json config.json`
2. Open `config.json` using your favorite text editor. For example `nano config.json`, but you can edit with vim, nano, on Windows it's Notepad or Notepad++. Whatever 2. Open `config.json` using your favorite text editor. For example `nano config.json`, but you can also edit it with vim, mcedit, or Notepad/Notepad++ on Windows
3. Change `"bot.owner"`, `"reports.chat_id"`, `"bot.api_id"`, `"bot.api_hash"` and `"bot.bot_token"` keys' values. 3. Change `"bot.owner"`, `"bot.api_id"`, `"bot.api_hash"` and `"bot.bot_token"` keys' values.
If you don't know where to find bot_token and your id - here you can find some hints: [get bot token](https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token), [get your id](https://www.alphr.com/telegram-find-user-id), [get api_hash and api_id](https://core.telegram.org/api/obtaining_api_id). If you don't know where to find bot_token and your id - here you can find some hints: [get bot token](https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token), [get your id](https://www.alphr.com/telegram-find-user-id), [get api_hash and api_id](https://core.telegram.org/api/obtaining_api_id).
@ -66,26 +66,26 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
3. If you've changed user and password to access the db, you should also change `"database.user"` and `"database.password"` keys, otherwise leave them `null` (default). 3. If you've changed user and password to access the db, you should also change `"database.user"` and `"database.password"` keys, otherwise leave them `null` (default).
2. Configure Photos API: 2. Configure Photos API:
1. Change `"posting.api.address"` to the one your API servers uses 1. Change `"posting.api.address"` and `"posting.api.address_external"` to the ones your API server uses
2. Run your bot using `python main.py --create-user --create-album` to configure its new user and album. You can also use manual user and album creation described [in the wiki](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Configuring-API). You can also change username, password and album in`"posting.api"` to the user and album you have if you already have Photos API album and user set up. In that case you don't need to create a new one. 2. Run your bot using `python main.py --create-user --create-album` to configure its new user and album. You can also use manual user and album creation described [in the wiki](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Configuring-API). You can also change username, password and album in`"posting.api"` to the user and album you have if you already have Photos API album and user set up. In that case you don't need to create a new one.
7. Add bot to the channel: 7. Add bot to the channel:
To use your bot of course you need to have a channel or group otherwise makes no sense to have such a bot. [Here](https://stackoverflow.com/a/33497769) you can find a quick guide how to add your bot to a channel. After that simply set `"posting.channel"` to your channel's ID and `"posting.comments"` to comments group's ID. To use your bot of course you need to have a channel or group otherwise it makes no sense to have such a bot. [Here](https://stackoverflow.com/a/33497769) you can find a quick guide how to add your bot to a channel. After that simply set `"posting.channel"` to your channel's ID and `"posting.comments"` to comments group's ID.
8. Configure posting time: 8. Configure posting time:
To make your bot post random content you need to configure `"posting.time"` with a list of "DD:MM" formatted strings or use `"posting.interval"` formatted as "XdXhXmXs". To use interval instead of selected time set `"posting.use_interval"` to `true`. To make your bot post random content you need to configure `"posting.time"` with a list of "DD:MM" formatted strings or use `"posting.interval"` formatted as "XdXhXmXs". To use interval instead of selected time, set `"posting.use_interval"` to `true`.
9. Good to go, run it! 9. Good to go, run it!
Make sure MongoDB and Photos API are running and use `python main.py` to start it. Make sure MongoDB and Photos API are running and use `python main.py` to start the bot.
Or you can also use `.\start.bat` on Windows and `bash ./start.sh` on Linux. Or you can also use `.\start.bat` on Windows and `bash ./start.sh` on Linux.
Additionally there are `loop.sh` and `loop.bat` available if you want your bot to start again after being stopped or after using `/shutdown` command. Additionally there are `loop.sh` and `loop.bat` available if you want your bot to start again after being stopped or after using `/shutdown` command.
If you need any further instructions on how to configure your bot or you had any difficulties doing so - please use [wiki in this repository](https://git.end-play.xyz/profitroll/TelegramPoster/wiki) to get more detailed instructions. If you need any further instructions on how to configure your bot or you had any difficulties doing so - please use [wiki in this repository](https://git.end-play.xyz/profitroll/TelegramPoster/wiki) to get more detailed instructions.
## Command line arguments ## CLI arguments
Of course bot also has them. You can perform some actions with them. Of course bot also has them. You can perform some actions with them.
@ -105,6 +105,6 @@ Examples:
Bot is capable of using custom locales. There are some that are pre-installed (English and Ukrainian), however you can add your own locales too. Bot is capable of using custom locales. There are some that are pre-installed (English and Ukrainian), however you can add your own locales too.
All localization files are located in the `locale` folder, otherwise in folder specified in config file. Just copy locale file of your choice, name it in accordance to [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag) (if you want your locale to be compatible with Telegram's locales) or define your own name. Save it as json and you're good to go. If you want to change default locale for messages, that cannot determine admin's locale - edit `"locale"` parameter in the `config.json`. If this locale is not available - `"locale_fallback"` will be used instead. If both are not available - error will be shown. For console output and logging locale you should edit `"locale_log"`. All localization files are located in the `locale`. Just copy locale file of your choice, name it in accordance to [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag) (if you want your locale to be compatible with Telegram's locales) or define your own name. Save it as json and you're good to go. If you want to change default locale for messages - edit `"locale"` parameter in the `config.json`.
We recommend to only make changes to your custom locale. Or at least always have your backup of for example `en.json` as your fallback. We recommend to only make changes to your custom locale. Or at least always have your backup of for example `en.json` as your fallback.

View File

@ -5,67 +5,104 @@
<a href="https://git.end-play.xyz/profitroll/TelegramPoster"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a> <a href="https://git.end-play.xyz/profitroll/TelegramPoster"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
</p> </p>
## ⚠️ Українська версія README dev гілки ще не готова! Користуйтесь англійською! ⚠️ Цей бот використовується для однієї-єдиної задачі - публікувати фотографії з мого особистого архіву. Ось його код, тож ви також можете запустити бота і погратися з ним самостійно. Тільки не очікуйте, що він буде ідеальним. Це не так. Але ви завжди можете його форкнути ;)
Цей бот використовується для однієї-єдиної задачі - розміщувати фотографії з мого особистого архіву. Ось його код, тож Ви також можете захостити бота самостійно та розважитися з ним. Тільки не очікуйте, що він ідеальним. Не буде. Але гей, Ви завжди можете його доробити під себе ;) ## Залежності
## Установка * [Python 3.8+](https://www.python.org) (рекомендується 3.9+)
* [MongoDB](https://www.mongodb.com)
* [PhotosAPI](https://git.end-play.xyz/profitroll/PhotosAPI)
Для запуску цього бота спочатку потрібно мати інтерпретатор Python та встановлений git. Google — Ваш друг у пошуках. Ви також можете ігнорувати git і просто завантажити код, також має спрацювати добре. Після цього Ви готові до встановлення. Користуйтесь [інструкцією зі встановлення MongoDB](https://www.mongodb.com/docs/manual/installation) та [README Photos API](https://git.end-play.xyz/profitroll/PhotosAPI/src/branch/master/README.md).
> У цьому README я вважаю, що Ви використовуєте python за замовчуванням у своїй Зверніть увагу, що Photos API також потребує MongoDB, тому має сенс спочатку встановити й налаштувати Mongo.
> системі і PATH Вашої системи містить його. Якщо Ваш python за замовчуванням
> є `python3` або, наприклад, `/home/user/.local/bin/python3.9` - використовуйте його натомість.
> Якщо це нестандартний шлях до виконуваного файлу - Вам також слід змінити
> це у скриптах, які Ви використовуватимете (`loop.sh`, `loop.bat`, `start.sh` та `start.bat`).
1. Завантажте бота: ## Встановлення
1. `git clone https://git.end-play.xyz/profitroll/TelegramSender.git` (якщо хочете використовувати git)
2. `cd ./TelegramSender`
2. Встановіть залежності: Щоб запустити бота, вам потрібно мати інтерпретатор Python, Photos API, MongoDB і, за бажанням, git (якщо ви хочете оновлювати за допомогою `git pull`). Ви також можете проігнорувати git і просто завантажити вихідний код, це також повинно спрацювати. Після цього ви готові до роботи.
`python -m pip install -r requirements.txt`
Без їх установки бот не зможе працювати взагалі
3. Встановіть додаткові залежності [Не обов'язково]: > У цьому README я припускаю, що ви використовуєте python за замовчуванням у вашій
`python -m pip install -r requirements-optional.txt` > системі, і він міститься у вашому системному PATH. Якщо ваш python за замовчуванням
Вони не є обов’язковими, але можуть прискорити роботу бота > це `python3` або, наприклад, `/home/user/.local/bin/python3.9` - використовуйте його.
> Якщо це нестандартний шлях до виконуваного файлу - вам також слід змінити
> його у скриптах, які ви будете використовувати (`loop.sh`, `loop.bat`, `start.sh` та `start.bat`).
4. Налаштуйте свого бота за допомогою текстового редактора: 1. Встановіть MongoDB та Photos API:
`nano config.json`
Ви можете редагувати за допомогою vim, nano, у Windows це Notepad або Notepad++. На Ваш смак.
Якщо Ви не знаєте, де знайти bot_token і свій ідентифікатор, тут Ви можете знайти кілька підказок: [отримати токен бота](https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token), [отримати свій ідентифікатор](https://www.alphr.com/telegram-find-user-id/), [отримати api_hash і api_id](https://core.telegram.org/api/obtaining_api_id).
Також не забудьте змінити режим роботи бота. Ключ `"mode"` має в собі ключі `"post"` та `"submit"`, кожен з який може бути `true` або `false`.
5. Додайте бота на канал: 1. Встановіть MongoDB, дотримуючись [офіційного посібника зі встановлення](https://www.mongodb.com/docs/manual/installation)
Звичайно, щоб використовувати свого бота, Вам потрібно мати канал або групу, інакше немає сенсу мати такого бота. [Тут](https://stackoverflow.com/a/33497769) Ви можете знайти короткий гайд, як додати свого бота до каналу. 2. Встановіть Photos API, дотримуючись [README Photos API](https://git.end-play.xyz/profitroll/PhotosAPI/src/branch/master/README.md)
6. Заповніть папку вмістом: 2. Завантажте бота:
Звичайно, бот не може опублікувати щось із нічого. Налаштуйте свій `config.json`, які медіа-типи бот повинен публікувати (`"posting", "extensions"`), коли їх публікувати (`"posting", "time"`), а також де їх знайти (`"locations"`). Ви також можете переміщати їх після надсилання, встановивши для `"posting", "move_sent"` значення `true`.
6. Готово, запускайте! 1. `git clone https://git.end-play.xyz/profitroll/TelegramPoster.git` (якщо ви використовуєте git)
`python ./main.py` 2. `cd TelegramPoster`
Або ви також можете використовувати `.\start.bat` на Windows і `bash ./start.sh` на Linux.
Крім того, доступні `loop.sh` і `loop.bat`, якщо ви хочете, щоб ваш бот запускався знову після зупинки або після використання команди `/reboot`.
## Аргументи командного рядка 3. Створіть віртуальне середовище [Необов'язково]:
Звичайно, у бота вони також є. З ними можна виконувати деякі дії. 1. Встановіть модуль virtualenv: `pip install virtualenv`
2. Створіть venv: `python -m venv .venv`
3. Активуйте його за допомогою `ource .venv/bin/activate` в Linux, `.venv\Scripts\activate.bat` в CMD або `.venv\Scripts\Activate.ps1` в PowerShell.
* `--move-sent` - дозволяє перемістити всі надіслані файли з черги до папки надісланих 4. Встановіть залежності проекту:
* `--cleanup` - очистити файли в папках `queue` і `sent`, якщо вони вже надіслані. Потрібен аргумент `--confirm`
* `--cleanup-index` - видалити всі надіслані записи з індексу. Потрібен аргумент `--confirm` `python -m pip install -r requirements.txt`.
* `--norun` - дозволяє виконувати наведені вище аргументи, не запускаючи самого бота Без їх встановлення бот не зможе працювати взагалі.
5. Налаштуйте необхідні ключі за допомогою вашого улюбленого текстового редактора:
1. Скопіюйте конфігураційний файл: `cp config_example.json config.json`
2. Відкрийте `config.json` за допомогою вашого улюбленого текстового редактора. Наприклад, `nano config.json`, але ви також можете відредагувати його за допомогою vim, mcedit або Notepad/Notepad++ на Windows
3. Змініть значення ключів `"bot.owner"`, `"bot.api_id"`, `"bot.api_hash"` і `"bot.bot_token"`.
Якщо ви не знаєте, де знайти bot_token і ваш id - тут ви можете знайти кілька підказок: [отримати токен бота](https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token), [отримати свій id](https://www.alphr.com/telegram-find-user-id), [отримати api_hash та api_id](https://core.telegram.org/api/obtaining_api_id).
6. Налаштування бази даних та API:
1. Налаштуйте базу даних:
1. Змініть хост і порт бази даних у ключах `"database.host"` і `"database.port"`. Для локальної установки за замовчуванням це будуть `127.0.0.1` і `27017` відповідно
2. Змініть ім'я бази даних в `"database.name"`. Вона буде автоматично створена при запуску
3. Якщо ви змінили користувача та пароль для доступу до бази даних, вам також слід змінити ключі `"database.user"` та `"database.password"`, інакше залиште їх `null` (за замовчуванням).
2. Налаштуйте Photos API:
1. Змініть `"posting.api.address"` та `"posting.api.address_external"` на ті, що використовує ваш сервер API
2. Запустіть бота за допомогою `python main.py --create-user --create-album`, щоб налаштувати нового користувача та альбом. Ви також можете скористатися ручним створенням користувача і альбому, описаним [у вікі](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Configuring-API). Ви також можете змінити ім'я користувача, пароль і альбом у `"posting.api"` на користувача і альбом, які у вас є, якщо у вас вже налаштовані альбом і користувач Photos API. У цьому випадку вам не потрібно створювати нові.
7. Додайте бота до каналу:
Щоб використовувати бота, вам, звичайно, потрібно мати канал або групу, інакше немає сенсу мати такого бота. [Тут](https://stackoverflow.com/a/33497769) ви можете знайти короткий посібник, як додати бота до каналу. Після цього просто встановіть `"posting.channel"` на ID вашого каналу і `"posting.comments"` на ID групи коментарів.
8. Налаштуйте час публікації:
Щоб ваш бот публікував випадковий контент, вам потрібно налаштувати `"posting.time"` зі списком рядків у форматі "ДД:ММ" або використовувати `"posting.interval"` у форматі "XdXhXmXs". Щоб використовувати інтервал замість вибраного часу, встановіть `"posting.use_interval"` у значення `true`.
9. Готово, запускайте!
Переконайтеся, що MongoDB і Photos API запущені і використовуйте `python main.py` для запуску бота.
Або ви також можете використовувати `.\start.bat` в Windows і `bash ./start.sh` в Linux.
Додатково доступні `loop.sh` і `loop.bat`, якщо ви хочете, щоб ваш бот запустився знову після зупинки або після використання команди `/shutdown`.
Якщо вам потрібні додаткові інструкції щодо налаштування бота або у вас виникли труднощі - скористайтеся [вікі в цьому репозиторії](https://git.end-play.xyz/profitroll/TelegramPoster/wiki), щоб отримати детальніші інструкції.
## CLI аргументи
Звичайно, бот також має CLI аргументи. За допомогою них можна виконувати деякі дії.
* `--create-user` - створити нового користувача API. Потребує встановленого конфігураційного ключа `"posting.api.address"`;
* `--create-album` - створити новий альбом API. Вимагає заповнених адреси API та конфігурації користувача (`"posting.api"`).
Приклади: Приклади:
* `python3 ./main.py --move-sent --norun` * `python main.py --create-user`
* `python3 ./main.py --cleanup --confirm` * `python main.py --create-user --create-album`
## Поради та покращення
* Можливо, ви захочете налаштувати бота для роботи як системну службу. У вікі є [сторінка з цього питання](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Configuring-Service).
## Локалізація ## Локалізація
Бот може використовувати різні мови. Є деякі попередньо встановлені (Англійська та Українська), однак Ви можете додавати свої власні локалізації теж. Бот може використовувати файли локалізації. Деякі з них встановлено за замовчуванням (англійська та українська), але ви також можете додавати свої власні.
Всі файли локалізації знаходяться у папці `locale`, якщо в конфігураційному файлі не вказано іншу. Просто скопіюйте цікавлячий Вас файл, назвіть його відповідно до [тегів мови IETF](https://en.wikipedia.org/wiki/IETF_language_tag) (якщо Ви хочете, щоб переклад був сумісним з перекладами Telegram) або просто вкажіть свою власну назву. Збережіть свій переклад як json файл і все готово. Якщо ви хочете змінити мову за замовчуванням для повідомлень самого бота, які не можуть визначити мову адміністратора, відредагуйте параметр `"locale"` у `config.json`. Якщо ця мова недоступна, замість неї буде використано `"locale_fallback"`. Якщо обидві мови недоступні - буде показано помилку. Для зміни мови виведення консолі та логування вам слід відредагувати `"locale_log"`. Усі файли локалізації знаходяться у теці `locale`. Просто скопіюйте файл локалі за вашим вибором, назвіть його відповідно до [мовних кодів IETF](https://en.wikipedia.org/wiki/IETF_language_tag) (якщо ви хочете, щоб ваша локаль була сумісна з локалями Telegram) або дайте йому власну назву. Збережіть переклад у форматі json, і все буде готово. Якщо ви хочете змінити локаль за замовчуванням для повідомлень - відредагуйте параметр `"locale"` у файлі `config.json`.
Ми рекомендуємо вносити будь-які зміни лише до вашої окремої мови. Або, принаймні, завжди мати резервну копію, наприклад, `en.json` як запасний варіант. Ми рекомендуємо вносити зміни лише у вашу власну локаль. Або, принаймні, завжди мати резервну копію, наприклад, `en.json` як запасний варіант.

View File

@ -1,6 +1,5 @@
{ {
"locale": "en", "locale": "en",
"locale_log": "en",
"bot": { "bot": {
"owner": 0, "owner": 0,
"admins": [], "admins": [],
@ -18,7 +17,7 @@
"name": "tgposter" "name": "tgposter"
}, },
"reports": { "reports": {
"chat_id": 0, "chat_id": "owner",
"sent": false, "sent": false,
"error": true, "error": true,
"update": true, "update": true,

View File

@ -101,49 +101,5 @@
"sub_duplicates_found": "There're duplicates in bot's database", "sub_duplicates_found": "There're duplicates in bot's database",
"locale_set": "Your language now is: {locale}", "locale_set": "Your language now is: {locale}",
"nothing": "🏁 This action is already finished" "nothing": "🏁 This action is already finished"
},
"console": {
"shutdown": "Shutting down bot with pid {0}",
"startup": "Starting with pid {0}",
"keyboard_interrupt": "\nShutting down...",
"exception_occured": "Exception {0} happened on task execution",
"post_sent": "Sent {0} to {1} with caption {2} and silently {3}",
"post_exception": "Could not send content due to {0}. Traceback: {1}",
"post_invalid_pic": "Error while sending photo HTTP {0}: {1}",
"post_empty": "Could not send content due to queue empty or contains only forbidden extensions",
"sub_mime_not_allowed": "Got submission from {0} but type of {1} which is not allowed",
"sub_document_too_large": "Got submission from {0} but but file is too large ({1} > {2})",
"sub_received": "Got submission from {0} with a caption {1}",
"sub_cooldown": "Got submission from {0} but user is on a cooldown",
"sub_no_id": "from_user in function get_submission does not contain id (maybe user posted in a channel)",
"sub_msg_unavail": "Could not download submission {0} from user {1}: message not available",
"sub_media_unavail": "Could not download submission {0} from user {1}: media not available",
"sub_media_downloading": "Downloading media of submission {0} from user {1}...",
"sub_media_downloaded": "Downloaded media of submission {0} from user {1}",
"sub_accepted": "Accepted submission {0} from user {1}",
"sub_declined": "Declined submission {0} from user {1}",
"sub_blocked": "Blocked user {0}",
"sub_unblocked": "Unblocked user {0}",
"deps_missing": "Required modules are not installed. Run 'pip3 install -r requirements.txt' and restart the program.",
"passed_norun": "Argument --norun passed, not running the main script",
"move_sent_doesnt_exist": "File '{0}' is already moved or does not exist",
"move_sent_doesnt_exception": "Could not move sent file '{0}' to '{1}' due to {2}",
"move_sent_completed": "Moved all sent files to the sent folder",
"cleanup_exception": "Could not remove '{0}' due to {1}",
"cleanup_completed": "Performed cleanup of the sent files",
"cleanup_unathorized": "Requested cleanup of sent files but not authorized. Please pass '--confirm' to perform that",
"cleanup_index_completed": "Performed cleanup of sent files index",
"cleanup_index_unathorized": "Requested cleanup of sent files index but not authorized. Please pass '--confirm' to perform that",
"random_pic_response": "Random pic response: {0}",
"random_pic_error_code": "Could not get photos from album {0}: HTTP {1}",
"random_pic_error_debug": "Could not get photos from '{0}/albums/{1}/photos?q=&page_size={2}&caption=queue' using token '{3}': HTTP {4}",
"find_pic_error": "Could not find image with name '{0}' and caption '{1}' due to: {2}",
"pic_upload_error": "Could not upload '{0}' to API: HTTP {1} with message '{2}'",
"api_creds_invalid": "Incorrect API credentials! Could not login into '{0}' using login '{1}': HTTP {2}",
"user_blocked": "User {0} has been blocked",
"user_unblocked": "User {0} has been unblocked",
"submission_accepted": "Submission with ID '{0}' accepted and uploaded with ID '{1}'",
"submission_rejected": "Submission with ID '{0}' rejected",
"submission_duplicate": "Submission with ID '{0}' could not be accepted because of the duplicates: {1}"
} }
} }

View File

@ -100,49 +100,5 @@
"sub_duplicates_found": "Знайдено дублікати в базі даних бота", "sub_duplicates_found": "Знайдено дублікати в базі даних бота",
"locale_set": "Встановлено мову: {locale}", "locale_set": "Встановлено мову: {locale}",
"nothing": "🏁 Цю дію вже було завершено" "nothing": "🏁 Цю дію вже було завершено"
},
"console": {
"shutdown": "Вимкнення бота з підом {0}",
"startup": "Запуск бота з підом {0}",
"keyboard_interrupt": "\nВимикаюсь...",
"exception_occured": "Помилка {0} сталась під час виконання",
"post_sent": "Надіслано {0} у {1} з підписом {2} та без звуку {3}",
"post_exception": "Не вдалося надіслати контент через {0}. Traceback: {1}",
"post_invalid_pic": "Помилка надсилання фото HTTP {0}: {1}",
"post_empty": "Не вдалося надіслати контент адже черга з дозволеними розширеннями порожня",
"sub_mime_not_allowed": "Отримано подання від {0} але типу {1} який не є дозволеним",
"sub_document_too_large": "Отримано подання від {0} але файл завеликий({1} > {2})",
"sub_received": "Отримано подання від {0} з підписом {1}",
"sub_cooldown": "Отримано подання від {0} але користувач на тайм-ауті",
"sub_no_id": "from_user у функції get_submission не має атрибуту id (можливо, користувач запостив щось у канал)",
"sub_msg_unavail": "Не вдалося завантажити подання {0} від користувача {1}: повідомлення більше не існує",
"sub_media_unavail": "Не вдалося завантажити подання {0} від користувача {1}: медіафайл більше не існує",
"sub_media_downloading": "Завантажуємо медіа з подання {0} від користувача{1}...",
"sub_media_downloaded": "Завантажено медіа з подання{0} від користувача{1}",
"sub_accepted": "Прийнято подання {0} від користувача {1}",
"sub_declined": "Відхилено подання {0} від користувача {1}",
"sub_blocked": "Заблоковано користувача {0}",
"sub_unblocked": "Розблоковано користувача {0}",
"deps_missing": "Необхідні модулі не встановлені. Запустіть 'pip3 install -r requirements.txt' і перезапустіть програму.",
"passed_norun": "Аргумент --norun надано, основний скрипт не запускається",
"move_sent_doesnt_exist": "Файл '{0}' уже переміщено або він не існує",
"move_sent_doesnt_exception": "Неможливо перемістити надісланий файл '{0}' до '{1}' через {2}",
"move_sent_completed": "Переміщено всі надіслані файли до папки надісланих",
"cleanup_exception": "Не вдалося видалити '{0}' через {1}",
"cleanup_completed": "Виконано очищення надісланих файлів",
"cleanup_unathorized": "Надіслано запит на очищення надісланих файлів, але не авторизовано. Для цього надайте аргумент '--confirm'",
"cleanup_index_completed": "Виконано очищення індексу надісланих файлів",
"cleanup_index_unathorized": "Надіслано запит на очищення індексу надісланих файлів, але не авторизовано. Для цього надайте аргумент '--confirm'",
"random_pic_response": "Відповідь на пошук випадкової картинки: {0}",
"random_pic_error_code": "Не вдалося отримати фото з альбому {0}: HTTP {1}",
"random_pic_error_debug": "Не вдалося отримати фотографії з '{0}/albums/{1}/photos?q=&page_size={2}&caption=queue', використовуючи токен '{3}': HTTP {4}",
"find_pic_error": "Не вдалося знайти зображення з назвою '{0}' та підписом '{1}' через: {2}",
"pic_upload_error": "Не вдалося завантажити '{0}' до API: HTTP {1} з повідомленням '{2}'",
"api_creds_invalid": "Невірні облікові дані API! Не вдалося увійти в '{0}' за допомогою логіна '{1}': HTTP {2}",
"user_blocked": "Користувача {0} було заблоковано",
"user_unblocked": "Користувача {0} було розблоковано",
"submission_accepted": "Подання з ID '{0}' прийнято та завантажено з ID '{1}'",
"submission_rejected": "Подання з ID '{0}' відхилено",
"submission_duplicate": "Подання з ID '{0}' не може бути прийнято через наявність дублікатів: {1}"
} }
} }

View File

@ -4,6 +4,10 @@ from os import getpid
from convopyro import Conversation from convopyro import Conversation
# This import MUST be done earlier than PyroClient!
# Even if isort does not like it...
from modules.cli import *
from classes.pyroclient import PyroClient from classes.pyroclient import PyroClient
from modules.scheduler import scheduler from modules.scheduler import scheduler

View File

@ -100,15 +100,10 @@ async def authorize(custom_session: Union[ClientSession, None] = None) -> str:
) )
if not response.ok: if not response.ok:
logger.warning( logger.warning(
i18n._( "Incorrect API credentials! Could not login into '%s' using login '%s': HTTP %s",
"api_creds_invalid", await config_get("address", "posting", "api"),
"console", await config_get("username", "posting", "api"),
locale=(await config_get("locale_log")).format( response.status,
await config_get("address", "posting", "api"),
await config_get("username", "posting", "api"),
response.status,
),
)
) )
raise ValueError raise ValueError
async with aiofiles.open( async with aiofiles.open(
@ -126,6 +121,7 @@ unauthorized_client = Client(
timeout=5.0, timeout=5.0,
verify_ssl=True, verify_ssl=True,
raise_on_unexpected_status=True, raise_on_unexpected_status=True,
follow_redirects=False,
) )
login_token = login( login_token = login(
@ -150,6 +146,7 @@ client = AuthenticatedClient(
verify_ssl=True, verify_ssl=True,
raise_on_unexpected_status=True, raise_on_unexpected_status=True,
token=login_token.access_token, token=login_token.access_token,
follow_redirects=False,
) )
if __name__ == "__main__": if __name__ == "__main__":

117
modules/cli.py Normal file
View File

@ -0,0 +1,117 @@
import asyncio
from argparse import ArgumentParser
from sys import exit
from traceback import print_exc
from libbot import config_get, config_set, sync
from photosapi_client.api.default.album_create_albums_post import (
asyncio as album_create,
)
from photosapi_client.api.default.login_for_access_token_token_post import (
asyncio as login,
)
from photosapi_client.api.default.user_create_users_post import asyncio as user_create
from photosapi_client.client import AuthenticatedClient, Client
from photosapi_client.models.body_login_for_access_token_token_post import (
BodyLoginForAccessTokenTokenPost,
)
from photosapi_client.models.body_user_create_users_post import BodyUserCreateUsersPost
parser = ArgumentParser(
prog="Telegram Poster",
description="Bot for posting some of your stuff and also receiving submissions.",
)
parser.add_argument("--create-user", action="store_true")
parser.add_argument("--create-album", action="store_true")
args = parser.parse_args()
unauthorized_client = Client(
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
follow_redirects=False,
)
async def cli_create_user() -> None:
print(
"To set up Photos API connection you need to create a new user.\nIf you have email confirmation enabled in your Photos API config - you need to use a real email that will get a confirmation code afterwards.",
flush=True,
)
username = input("Choose username for new Photos API user: ").strip()
email = input(f"Choose email for user '{username}': ").strip()
password = input(f"Choose password for user '{username}': ").strip()
try:
result_1 = await user_create(
client=unauthorized_client,
form_data=BodyUserCreateUsersPost(
user=username, email=email, password=password
),
)
# asyncio.run(create_user(username, email, password))
await config_set("username", username, "posting", "api")
await config_set("password", password, "posting", "api")
none = input(
"Alright. If you have email confirmation enabled - please confirm registration by using the link in your email. After that press Enter. Otherwise just press Enter."
)
except Exception as exp:
print(f"Could not create a user due to {exp}", flush=True)
print_exc()
exit()
if not args.create_album:
print("You're done!", flush=True)
exit()
return None
async def cli_create_album() -> None:
print(
"To use Photos API your user needs to have an album to store its data.\nThis wizard will help you to create a new album with its name and title.",
flush=True,
)
name = input("Choose a name for your album: ").strip()
title = input(f"Choose a title for album '{name}': ").strip()
try:
login_token = await login(
client=unauthorized_client,
form_data=BodyLoginForAccessTokenTokenPost(
grant_type="password",
scope="me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
username=await config_get("username", "posting", "api"),
password=await config_get("password", "posting", "api"),
),
)
client = AuthenticatedClient(
base_url=await config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
token=login_token.access_token,
follow_redirects=False,
)
result_2 = await album_create(client=client, name=name, title=title)
# asyncio.run(create_album(name, title))
await config_set("album", name, "posting", "api")
except Exception as exp:
print(f"Could not create an album due to {exp}", flush=True)
print_exc()
exit()
print("You're done!", flush=True)
exit()
if args.create_user or args.create_album:
loop = asyncio.get_event_loop()
tasks = []
if args.create_user:
loop.run_until_complete(asyncio.wait([loop.create_task(cli_create_user())]))
if args.create_album:
loop.run_until_complete(asyncio.wait([loop.create_task(cli_create_album())]))
loop.close()

View File

@ -111,7 +111,9 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
return return
except (KeyError, AttributeError, TypeError, IndexError): except (KeyError, AttributeError, TypeError, IndexError):
logger.info(app._("post_empty", "console")) logger.info(
"Could not send content due to queue empty or contains only forbidden extensions"
)
if app.config["reports"]["error"]: if app.config["reports"]["error"]:
await app.send_message( await app.send_message(
app.owner, app.owner,
@ -244,16 +246,17 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
rmtree(path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True) rmtree(path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True)
logger.info( logger.info(
app._("post_sent", "console").format( "Sent %s to %s with caption %s and silently %s",
media.id, media.id,
str(app.config["posting"]["channel"]), str(app.config["posting"]["channel"]),
caption.replace("\n", "%n"), caption.replace("\n", "%n"),
str(app.config["posting"]["silent"]), str(app.config["posting"]["silent"]),
)
) )
except Exception as exp: except Exception as exp:
logger.error(app._("post_exception", "console").format(str(exp), format_exc())) logger.error(
"Could not send content due to %s. Traceback: %s", exp, format_exc()
)
if app.config["reports"]["error"]: if app.config["reports"]["error"]:
await app.send_message( await app.send_message(
app.owner, app.owner,

View File

@ -55,14 +55,9 @@ async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
quote=True, quote=True,
) )
logger.info( logger.info(
app._( "Submission with ID '%s' could not be accepted because of the duplicates: %s",
"submission_duplicate", fullclb[2],
"console", str(exp.duplicates),
locale=app.config["locale_log"],
).format(
fullclb[2],
str(exp.duplicates),
),
) )
return return
@ -121,11 +116,9 @@ async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
) )
logger.info( logger.info(
app._( "Submission with ID '%s' accepted and uploaded with ID '%s'",
"submission_accepted", fullclb[2],
"console", submission[1],
locale=app.config["locale_log"],
).format(fullclb[2], submission[1]),
) )
@ -197,11 +190,8 @@ async def callback_query_no(app: PyroClient, clb: CallbackQuery):
reply_markup=InlineKeyboardMarkup(edited_markup) reply_markup=InlineKeyboardMarkup(edited_markup)
) )
logger.info( logger.info(
app._( "Submission with ID '%s' rejected",
"submission_rejected", fullclb[2],
"console",
locale=app.config["locale_log"],
).format(fullclb[2]),
) )
@ -237,13 +227,7 @@ async def callback_query_block(app: PyroClient, clb: CallbackQuery):
await clb.message.edit_reply_markup( await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup) reply_markup=InlineKeyboardMarkup(edited_markup)
) )
logger.info( logger.info("User %s has been blocked", fullclb[2])
app._(
"user_blocked",
"console",
locale=app.config["locale_log"],
).format(fullclb[2]),
)
@Client.on_callback_query(filters.regex("sub_unblock_[\s\S]*")) @Client.on_callback_query(filters.regex("sub_unblock_[\s\S]*"))
@ -279,10 +263,4 @@ async def callback_query_unblock(app: PyroClient, clb: CallbackQuery):
await clb.message.edit_reply_markup( await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup) reply_markup=InlineKeyboardMarkup(edited_markup)
) )
logger.info( logger.info("User %s has been unblocked", fullclb[2])
app._(
"user_unblocked",
"console",
locale=app.config["locale_log"],
).format(fullclb[2]),
)