83 Commits

Author SHA1 Message Date
f82c7b309f Added media removal 2023-03-21 14:34:25 +01:00
399fc5050d Updated user messages 2023-03-20 14:50:57 +01:00
56adb16a3e Replaced strings 2023-03-20 13:59:22 +01:00
1684c5177c Replaced /reboot with /shutdown 2023-03-20 13:56:18 +01:00
fba52bcfc4 Updated docs 2023-03-20 13:55:55 +01:00
20666fc0f8 Improved shutdown 2023-03-20 13:55:42 +01:00
03b6bbe039 Prototype: Files import 2023-03-20 12:03:03 +01:00
1749d49a52 Fixed enumerate error 2023-03-18 21:17:04 +01:00
a4323981fb WIP: Media import/export 2023-03-18 20:53:26 +01:00
06b6b49f43 This commit closes #13 2023-03-17 14:51:41 +01:00
1f345e87f7 Improved logging 2023-03-17 14:44:37 +01:00
717586a9f0 Improved logging 2023-03-17 14:13:28 +01:00
95351f247c This commit closed #12 2023-03-17 13:52:16 +01:00
b5e3abd4ad WIP: default config replacement for (#12) 2023-03-16 16:32:26 +01:00
4ec69c2a05 This commit closes #9 2023-03-16 15:03:14 +01:00
Profitroll
62e0a4986c WIP: ID returns 2023-03-16 12:58:57 +01:00
Profitroll
be8f0262d0 This commit closes #11 2023-03-15 21:58:14 +01:00
Profitroll
ba5a0f116c Merge branch 'dev' of https://git.end-play.xyz/profitroll/TelegramPoster into dev 2023-03-15 21:52:48 +01:00
Profitroll
e85adeafd0 Added info about venv to the README 2023-03-15 21:50:06 +01:00
87d2a2c6d3 Improved README 2023-03-13 13:02:06 +01:00
bc6080e832 Added venv guide to README 2023-03-13 11:33:30 +01:00
9bf4663b9e Made execution order correct 2023-03-12 22:58:55 +01:00
b74ce9ec89 Small fixes 2023-03-12 22:58:41 +01:00
6ed3673682 Fixed a typo 2023-03-12 22:45:06 +01:00
c593be156d Rearranged content 2023-03-12 22:30:35 +01:00
c96f98560c WIP: New readme 2023-03-12 22:29:53 +01:00
e1c1b58ffb Added warning about readme not being ready yet 2023-03-12 22:26:16 +01:00
bd2a1f0b12 WIP: New readme 2023-03-12 22:23:02 +01:00
8cc7808afb Disabled slash-escape for .json 2023-03-12 22:14:41 +01:00
6684c4d750 Bump Pyrogram to 2.0.102 2023-03-12 22:14:23 +01:00
c670db72fa Added user-friendly CLI 2023-03-12 22:14:03 +01:00
48acab2d5e WIP: New readme 2023-03-12 19:57:22 +01:00
62f076148c Wiki pages init 2023-03-12 19:43:51 +01:00
59b504e6d9 Temp: removed strings about API based in config 2023-03-12 19:34:27 +01:00
ad281ba981 WIP: New readme 2023-03-12 19:25:35 +01:00
0073120bf2 Moved ujson to required dependencies 2023-03-12 14:54:06 +01:00
244173e556 Bumped Pyrogram to 2.0.101 2023-03-12 14:25:22 +01:00
98e9c5f5a2 Fixed line being displayed incorrectly 2023-03-09 16:17:35 +01:00
a8545dd097 Fixed project name align 2023-03-09 16:16:38 +01:00
3f22340852 Added license and code style badges 2023-03-09 11:48:50 +01:00
c2fb88ed65 Bumped APScheduler to 3.10.1 2023-03-09 11:35:02 +01:00
88692ebc85 Now using black for formatting 2023-03-09 11:33:02 +01:00
4331af415e Moved to aiohttp and aiofiles 2023-03-02 22:38:48 +01:00
a913ba19c6 WIP: aiohttp migration 2023-03-02 16:39:59 +01:00
2387823151 Added missing texts 2023-02-25 23:31:09 +01:00
88f8bb4a52 WIP: Photos and queue removal 2023-02-25 23:19:08 +01:00
cf6c1f03d7 Disabled notification for accepted submissions 2023-02-25 23:12:33 +01:00
0a309a9f59 Added one more rule 2023-02-25 23:10:57 +01:00
7810f3b7b9 Fixed absence of None check 2023-02-24 21:06:18 +01:00
7b2534012d Fixed typo 2023-02-24 13:48:06 -05:00
6e8b47cf4b Improved submissions randomness 2023-02-24 13:33:34 -05:00
c27b1c5a5b Temporarily disabled album creation on start 2023-02-24 13:25:57 -05:00
c7228a006b Improved randomness 2023-02-24 13:25:36 -05:00
64ae3fb047 Added option to mention submissions 2023-02-24 12:39:33 -05:00
Profitroll
056fc52353 This commit closes #4 and closes #6 2023-02-19 20:54:58 +01:00
Profitroll
8bafd0cb35 This commit closes #3 2023-02-19 20:44:00 +01:00
Profitroll
fd47217bad This commit closes #5 2023-02-19 20:31:08 +01:00
Profitroll
6b7b5c22f2 Reverted web preview disable 2023-02-18 00:58:09 +01:00
Profitroll
b3698cfa70 Added support for duplicates access tokens 2023-02-18 00:55:58 +01:00
Profitroll
7607003f55 Added callback message for "nothing" 2023-02-17 23:45:55 +01:00
Profitroll
7918049f49 Fixed language code typo 2023-02-17 23:18:54 +01:00
Profitroll
fcd59b7aca Fixed caption display 2023-02-17 23:18:34 +01:00
Profitroll
8c478072c6 Fixed reply message not getting quoted 2023-02-17 23:18:19 +01:00
Profitroll
b766d0c52c Improved linting and removed unused imports 2023-02-17 22:59:03 +01:00
Profitroll
807e629ae7 Moved cooldowns to PosterUser class 2023-02-17 22:48:37 +01:00
Profitroll
87af9fd333 Fixed captions not getting detected 2023-02-17 22:26:07 +01:00
Profitroll
a54081a2ae Fixed some issues with locale 2023-02-17 21:58:46 +01:00
Profitroll
664284a6f8 Integrated previous commits 2023-02-17 21:55:38 +01:00
Profitroll
bd9917fb17 Replaced user block logic 2023-02-17 21:54:52 +01:00
Profitroll
68ea087963 Integrated interval-based schedule 2023-02-17 21:54:30 +01:00
Profitroll
d1813856d9 Imported callback "nothing" 2023-02-17 21:54:14 +01:00
Profitroll
cf204577e4 Added external address for links 2023-02-17 21:53:57 +01:00
Profitroll
68c887999e Divided admins and owner 2023-02-17 21:53:43 +01:00
Profitroll
642e17ee55 Image resize when too big 2023-02-17 16:46:44 +01:00
Profitroll
25af9b31f8 Changed Client to PosterClient 2023-02-17 16:46:33 +01:00
Profitroll
28fc359593 WIP: export and import 2023-02-17 16:46:13 +01:00
Profitroll
07203a9db9 Changed the way exceptions are handled 2023-02-17 16:45:51 +01:00
Profitroll
663a7b0db8 Submission without confirmation added 2023-02-17 16:44:56 +01:00
Profitroll
0d2e9fa6ec Using PosterClient instead of Client 2023-02-17 16:44:30 +01:00
Profitroll
c90e5eb697 Added Pillow to requirements 2023-02-17 16:44:03 +01:00
Profitroll
f4359aa6cd Added upload_pic method 2023-02-17 11:51:38 +01:00
4cd37be5dc WIP: New submission system 2023-02-16 16:41:01 +01:00
05042f01c6 Disabled WIP warning 2023-02-15 14:07:40 +01:00
11 changed files with 44 additions and 131 deletions

View File

@@ -1,20 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
"baseBranches": [
"dev"
],
"packageRules": [
{
"matchUpdateTypes": [
"minor",
"patch",
"pin",
"digest"
],
"automerge": true
}
]
}

View File

@@ -50,7 +50,12 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
`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. Install optional dependencies [Optional]:
`python -m pip install -r requirements-optional.txt`
These are not required but can make the bot run a bit faster.
6. Configure "bot" and "owner" with your favorite text editor:
1. Copy file `config_example.json` to `config.json` 1. Copy file `config_example.json` to `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 edit with vim, nano, on Windows it's Notepad or Notepad++. Whatever
@@ -58,7 +63,7 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
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).
6. Configure database and API: 7. Configure database and API:
1. Configure database: 1. Configure database:
1. Change database host and port in keys `"database.host"` and `"database.port"`. For default local installation those will be `127.0.0.1` and `27017` respectively 1. Change database host and port in keys `"database.host"` and `"database.port"`. For default local installation those will be `127.0.0.1` and `27017` respectively
@@ -69,15 +74,15 @@ To make this bot run at first you need to have a Python interpreter, Photos API,
1. Change `"posting.api.address"` to the one your API servers uses 1. Change `"posting.api.address"` to the one your API servers uses
2. Run your bot using `python poster.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 poster.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: 8. 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. 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.
8. Configure posting time: 9. 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! 10. Good to go, run it!
Make sure MongoDB and Photos API are running and use `python poster.py` to start it. Make sure MongoDB and Photos API are running and use `python poster.py` to start it.
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.

View File

@@ -23,7 +23,6 @@
"reports": { "reports": {
"sent": false, "sent": false,
"error": true, "error": true,
"update": true,
"startup": true, "startup": true,
"shutdown": true "shutdown": true
}, },

View File

@@ -1 +0,0 @@
# Updating your bot

View File

@@ -59,8 +59,7 @@
"remove_ignored": "No response, aborting removal.", "remove_ignored": "No response, aborting removal.",
"remove_abort": "Removal aborted.", "remove_abort": "Removal aborted.",
"remove_success": "Removed media with ID `{0}`.", "remove_success": "Removed media with ID `{0}`.",
"remove_failure": "Could not remove media with ID `{0}`. Check if provided ID is correct and if it is - you can also check bot's log for details.", "remove_failure": "Could not remove media with ID `{0}`. Check if provided ID is correct and if it is - you can also check bot's log for details."
"update_available": "**New version found**\nThere's a newer version of a bot found. You can update your bot to [{0}]({1}) using command line of your host.\n\n**Release notes**\n{2}\n\nRead more about updating you bot on the [wiki page](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Updating-Instance).\n\nPlease not that you can also disable this notification by editing `reports.update` key of the config."
}, },
"button": { "button": {
"sub_yes": "✅ Accept", "sub_yes": "✅ Accept",

View File

@@ -59,8 +59,7 @@
"remove_ignored": "Немає відповіді, перериваємо видалення.", "remove_ignored": "Немає відповіді, перериваємо видалення.",
"remove_abort": "Видалення перервано.", "remove_abort": "Видалення перервано.",
"remove_success": "Видалено медіа з ID `{0}`.", "remove_success": "Видалено медіа з ID `{0}`.",
"remove_failure": "Не вдалося видалити медіа з ID `{0}`. Перевірте, чи вказано правильний ID, і якщо він правильний, ви також можете переглянути логи бота для отримання більш детальної інформації.", "remove_failure": "Не вдалося видалити медіа з ID `{0}`. Перевірте, чи вказано правильний ID, і якщо він правильний, ви також можете переглянути логи бота для отримання більш детальної інформації."
"update_available": "**Знайдено нову версію**\nЗнайдено нову версію бота. Ви можете оновити бота до [{0}]({1}) за допомогою командного рядка вашого хосту.\n\n**Примітки до релізу**\n{2}\n\nДетальніше про оновлення бота можна знайти на [вікі-сторінці](https://git.end-play.xyz/profitroll/TelegramPoster/wiki/Updating-Instance).\n\nЗверніть увагу, що ви також можете вимкнути це сповіщення, відредагувавши ключ `reports.update` у конфігурації."
}, },
"button": { "button": {
"sub_yes": "✅ Прийняти", "sub_yes": "✅ Прийняти",

View File

@@ -8,7 +8,8 @@ from traceback import print_exc
from typing import Tuple, Union from typing import Tuple, Union
import aiofiles import aiofiles
from aiohttp import FormData from aiohttp import ClientSession, FormData
from ujson import dumps
from classes.exceptions import ( from classes.exceptions import (
AlbumCreationDuplicateError, AlbumCreationDuplicateError,
@@ -20,7 +21,10 @@ from classes.exceptions import (
) )
from modules.logger import logWrite from modules.logger import logWrite
from modules.utils import configGet, locale from modules.utils import configGet, locale
from modules.http_client import http_session
http_session = ClientSession(
json_serialize=dumps,
)
async def authorize() -> str: async def authorize() -> str:

View File

@@ -1,6 +0,0 @@
from aiohttp import ClientSession
from ujson import dumps
http_session = ClientSession(
json_serialize=dumps,
)

102
poster.py
View File

@@ -1,21 +1,18 @@
from datetime import datetime
from os import getpid, path from os import getpid, path
from datetime import datetime
from sys import exit from sys import exit
from time import time from time import time
from traceback import format_exc
from modules.api_client import authorize
from modules.cli import * from modules.cli import *
from modules.http_client import http_session
from modules.logger import logWrite from modules.logger import logWrite
from modules.scheduler import scheduler from modules.scheduler import scheduler
from modules.utils import configGet, jsonLoad, jsonSave, locale from modules.utils import configGet, jsonLoad, jsonSave, killProc, locale
# Import =================================================================================================================================== # Import ===================================================================================================================================
try: try:
from dateutil.relativedelta import relativedelta
from pyrogram.errors import bad_request_400
from pyrogram.sync import idle from pyrogram.sync import idle
from pyrogram.errors import bad_request_400
from dateutil.relativedelta import relativedelta
from modules.app import app from modules.app import app
except ModuleNotFoundError: except ModuleNotFoundError:
@@ -25,7 +22,6 @@ except ModuleNotFoundError:
pid = getpid() pid = getpid()
version = 0.1
# Work in progress # Work in progress
# def check_forwards(app): # def check_forwards(app):
@@ -63,10 +59,9 @@ version = 0.1
# check_forwards(app) # check_forwards(app)
from plugins.callbacks.shutdown import *
# Imports ================================================================================================================================== # Imports ==================================================================================================================================
from plugins.commands.general import * from plugins.commands.general import *
from plugins.callbacks.shutdown import *
if configGet("submit", "mode"): if configGet("submit", "mode"):
from plugins.callbacks.nothing import * from plugins.callbacks.nothing import *
@@ -121,11 +116,10 @@ if configGet("post", "mode"):
# uvloop.install() # uvloop.install()
# asyncio.run(main()) # asyncio.run(main())
if __name__ == "__main__":
async def main():
logWrite(locale("startup", "console").format(str(pid))) logWrite(locale("startup", "console").format(str(pid)))
await app.start() app.start()
if configGet("startup", "reports"): if configGet("startup", "reports"):
try: try:
@@ -139,7 +133,7 @@ async def main():
), ),
) )
if downtime.days >= 1: if downtime.days >= 1:
await app.send_message( app.send_message(
configGet("owner"), configGet("owner"),
locale( locale(
"startup_downtime_days", "startup_downtime_days",
@@ -147,7 +141,7 @@ async def main():
).format(pid, downtime.days), ).format(pid, downtime.days),
) )
elif downtime.hours >= 1: elif downtime.hours >= 1:
await app.send_message( app.send_message(
configGet("owner"), configGet("owner"),
locale( locale(
"startup_downtime_hours", "startup_downtime_hours",
@@ -155,7 +149,7 @@ async def main():
).format(pid, downtime.hours), ).format(pid, downtime.hours),
) )
else: else:
await app.send_message( app.send_message(
configGet("owner"), configGet("owner"),
locale( locale(
"startup_downtime_minutes", "startup_downtime_minutes",
@@ -164,7 +158,7 @@ async def main():
).format(pid, downtime.minutes), ).format(pid, downtime.minutes),
) )
else: else:
await app.send_message( app.send_message(
configGet("owner"), configGet("owner"),
locale("startup", "message").format(pid), locale("startup", "message").format(pid),
) )
@@ -173,75 +167,18 @@ async def main():
f"Could not send startup message to bot owner. Perhaps user has not started the bot yet." f"Could not send startup message to bot owner. Perhaps user has not started the bot yet."
) )
if configGet("update", "reports"):
try:
check_update = await http_session.get(
"https://git.end-play.xyz/api/v1/repos/profitroll/TelegramPoster/releases?page=1&limit=1"
)
response = await check_update.json()
if len(response) == 0:
raise ValueError("No bot releases on git found.")
if float(response[0]["tag_name"].replace("v.", "")) > version:
logWrite(
f'New version {response[0]["tag_name"].replace("v.", "")} found (current {version})'
)
await app.send_message(
configGet("owner"),
locale(
"update_available",
"message",
).format(
response[0]["tag_name"],
response[0]["html_url"],
response[0]["body"],
),
)
else:
logWrite(f"No updates found, bot is up to date.")
except bad_request_400.PeerIdInvalid:
logWrite(
f"Could not send startup message to bot owner. Perhaps user has not started the bot yet."
)
except Exception as exp:
logWrite(f"Update check failed due to {exp}: {format_exc()}")
if configGet("post", "mode"): if configGet("post", "mode"):
scheduler.start() scheduler.start()
try: # if configGet("api_based", "mode"):
token = await authorize() # token = await authorize()
# if len(get(f'{configGet("address", "posting", "api")}/albums?q={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"}).json()["results"]) == 0:
# post(f'{configGet("address", "posting", "api")}/albums?name={configGet("queue", "posting", "api", "albums")}&title={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"})
if ( idle()
len(
(
await (
await http_session.get(
f'{configGet("address", "posting", "api")}/albums?q={configGet("album", "posting", "api")}',
headers={"Authorization": f"Bearer {token}"},
)
).json()
)["results"]
)
== 0
):
logWrite("Media album does not exist on API server. Trying to create it...")
try:
await http_session.post(
f'{configGet("address", "posting", "api")}/albums?name={configGet("album", "posting", "api")}&title={configGet("album", "posting", "api")}',
headers={"Authorization": f"Bearer {token}"},
)
logWrite("Created media album on API server.")
except Exception as exp:
logWrite(
f"Could not create media album on API server due to {exp}: {format_exc()}"
)
except Exception as exp:
logWrite(f"Could not check if API album exists due to {exp}: {format_exc()}")
await idle()
try: try:
await app.send_message( app.send_message(
configGet("owner"), configGet("owner"),
locale("shutdown", "message").format(pid), locale("shutdown", "message").format(pid),
) )
@@ -260,7 +197,4 @@ async def main():
scheduler.shutdown() scheduler.shutdown()
killProc(pid)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

View File

@@ -0,0 +1 @@
tgcrypto==1.2.5

View File

@@ -1,12 +1,11 @@
python_dateutil==2.8.2 python_dateutil==2.8.2
apscheduler==3.10.1 apscheduler~=3.10.1
pytimeparse==1.1.8 pytimeparse~=1.1.8
convopyro==0.5 convopyro==0.5
pyrogram==2.0.104 pyrogram~=2.0.102
aiofiles~=23.1.0 aiofiles~=23.1.0
tgcrypto==1.2.5
aiohttp~=3.8.4 aiohttp~=3.8.4
psutil==5.9.5 psutil~=5.9.4
pymongo==4.3.3 pymongo~=4.3.3
pillow~=9.5.0 pillow~=9.4.0
ujson==5.7.0 ujson~=5.7.0