Telegram +

This commit is contained in:
2024-06-02 16:29:06 +03:00
parent 9d8e823f7f
commit 03990b3b8a
2 changed files with 89 additions and 16 deletions

4
.gitignore vendored
View File

@@ -1,4 +1,6 @@
.fleet .fleet
__pycache__ __pycache__
keys*.py keys*.py
vkdel.py vkdel.py
tgdel.py
*.session

View File

@@ -3,17 +3,21 @@
import re import re
import sys import sys
import time import time
import urllib.parse import asyncio
import discord import discord
import logging import logging
import colorlog import colorlog
import requests import requests
import html2text import html2text
import urllib.parse
from telethon import events
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from telethon.sync import TelegramClient
from telethon.errors import FloodWaitError
import keys import keys
url_post = "https://linux-gaming.ru/posts.json" url_post = "https://linux-gaming.ru/posts.json"
url_news = "https://linux-gaming.ru/c/news/6.json" url_news = "https://linux-gaming.ru/c/news/6.json"
url_vk_post = "https://api.vk.com/method/wall.post" url_vk_post = "https://api.vk.com/method/wall.post"
@@ -58,6 +62,7 @@ def main():
check_version(last_changelog, resp_changelog) check_version(last_changelog, resp_changelog)
check_discord_public() check_discord_public()
check_vk_posts() check_vk_posts()
check_tg_news()
def make_soup(resp_changelog): def make_soup(resp_changelog):
@@ -87,6 +92,7 @@ def html_to_text(html_content):
# Удаление строк, содержащих '* * *' # Удаление строк, содержащих '* * *'
markdown_text = re.sub(r'^.*\* \* \*.*$', '', markdown_text, flags=re.MULTILINE) markdown_text = re.sub(r'^.*\* \* \*.*$', '', markdown_text, flags=re.MULTILINE)
# Фикс ненумерованных списков
markdown_text = re.sub(r'^.*\* ', '* ', markdown_text, flags=re.MULTILINE) markdown_text = re.sub(r'^.*\* ', '* ', markdown_text, flags=re.MULTILINE)
# Убираем переносы строк, кроме строк, начинающихся с * # Убираем переносы строк, кроме строк, начинающихся с *
@@ -111,6 +117,10 @@ def html_to_text(html_content):
# Удаление избыточных пустых строк после удаления строк # Удаление избыточных пустых строк после удаления строк
markdown_text = re.sub(r'\n\s*\n', '\n', markdown_text) markdown_text = re.sub(r'\n\s*\n', '\n', markdown_text)
# Замена текстов типа "image1280×474 99.7 KB", "807×454 64.1 KB" на "."
markdown_text = re.sub(r'image\d+×\d+\s+\d+(\.\d+)?\s+KB', '.', markdown_text)
markdown_text = re.sub(r'\d+×\d+\s+\d+(\.\d+)?\s+KB', '.', markdown_text)
# Изменение ссылок без описания # Изменение ссылок без описания
markdown_text = re.sub(r'\[\]\((https:\/\/[^\)]+)\)', r'[.](\1)', markdown_text) markdown_text = re.sub(r'\[\]\((https:\/\/[^\)]+)\)', r'[.](\1)', markdown_text)
markdown_text = re.sub(r'\[\s]\((https:\/\/[^\)]+)\)', r'[.](\1)', markdown_text) markdown_text = re.sub(r'\[\s]\((https:\/\/[^\)]+)\)', r'[.](\1)', markdown_text)
@@ -322,8 +332,8 @@ async def discord_post(post_text, client):
await channel.send(f"{post_text}") await channel.send(f"{post_text}")
async def get_discord_messages(client, channel_id): async def get_discord_messages(client_discord, channel_id):
channel = client.get_channel(channel_id) channel = client_discord.get_channel(channel_id)
if not channel: if not channel:
logging.error(f"ID канала Discord {channel_id} не существует") logging.error(f"ID канала Discord {channel_id} не существует")
return [] return []
@@ -344,31 +354,31 @@ async def get_discord_messages(client, channel_id):
def check_discord_public(): def check_discord_public():
intents = discord.Intents.default() intents = discord.Intents.default()
intents.messages = True intents.messages = True
client = discord.Client(intents=intents) client_discord = discord.Client(intents=intents)
@client.event @client_discord.event
async def on_ready(): async def on_ready():
logging.debug(f"Успешный логин в discord {client.user}") logging.debug(f"Успешный логин в discord {client_discord.user}")
channel_id = keys.dicord_channel channel_id = keys.dicord_channel
discord_messages = await get_discord_messages(client, channel_id) discord_messages = await get_discord_messages(client_discord, channel_id)
list_titles_and_ids = news() list_titles_and_ids = news()
if list_titles_and_ids: if list_titles_and_ids:
list_for_public = [] list_for_public = []
for topic_id, topic_title in list_titles_and_ids: for topic_id, topic_title in list_titles_and_ids:
if topic_title not in discord_messages and topic_id > 698: if topic_title not in discord_messages and topic_id > keys.start_topic_id:
list_for_public.append((topic_id, topic_title)) list_for_public.append((topic_id, topic_title))
if not list_for_public: if not list_for_public:
logging.info(f"Новостей для публикации в дискорд нет") logging.info(f"Новостей для публикации в дискорд нет")
await client.close() await client_discord.close()
else: else:
logging.info(f"Новости для публикации в дискорд: {list_for_public}") logging.info(f"Новости для публикации в дискорд: {list_for_public}")
channel = client.get_channel(channel_id) channel = client_discord.get_channel(channel_id)
if not channel: if not channel:
logging.error(f"ID канала Discord {channel_id} не существует") logging.error(f"ID канала Discord {channel_id} не существует")
await client.close() await client_discord.close()
return return
for topic_id, topic_title in reversed(list_for_public): for topic_id, topic_title in reversed(list_for_public):
@@ -378,9 +388,9 @@ def check_discord_public():
# Разбиваем содержимое на части по 4000 символов # Разбиваем содержимое на части по 4000 символов
for i in range(0, len(content), 2000): for i in range(0, len(content), 2000):
await channel.send(content[i:i+2000]) await channel.send(content[i:i+2000])
await client.close() await client_discord.close()
client.run(keys.discord_token) client_discord.run(keys.discord_token)
def vk_post(url, post_text, links=None): def vk_post(url, post_text, links=None):
@@ -460,7 +470,7 @@ def check_vk_posts():
logging.info(f"Новостей для публикации в ВК нет") logging.info(f"Новостей для публикации в ВК нет")
else: else:
for topic_id, topic_title in reversed(list_for_public): for topic_id, topic_title in reversed(list_for_public):
if topic_id > 698: if topic_id > keys.start_topic_id:
logging.info(f"Новости для публикации в ВК: {list_for_public}") logging.info(f"Новости для публикации в ВК: {list_for_public}")
text_data = news_content(topic_id) text_data = news_content(topic_id)
if text_data: if text_data:
@@ -480,5 +490,66 @@ def check_vk_posts():
logging.info(f"Новостей для публикации в ВК нет") logging.info(f"Новостей для публикации в ВК нет")
def tg_post(post_text, client_tg):
# Отправка сообщения
client_tg.send_message(keys.channel_username_tg, post_text)
# Завершение сеанса
client_tg.disconnect()
async def get_tg_messages(client_tg, channel_username_tg):
messages = []
async for message in client_tg.iter_messages(channel_username_tg, limit=999):
if message.text: # Проверка на NoneType
logging.debug(f"Найдены сообщения в Telegram канале {message.text}")
messages.append(message.text)
return messages
def check_tg_news():
session_file = 'LG_news'
loop = asyncio.new_event_loop() # Создание нового цикла событий
asyncio.set_event_loop(loop) # Установка нового цикла событий
client_tg = TelegramClient('LG_news', keys.api_id_tg, keys.api_hash_tg)
@client_tg.on(events.NewMessage(chats=keys.channel_username_tg))
async def handler(event):
logging.debug(f"Новое сообщение в Telegram: {event.message.message}")
async def main_tg():
await client_tg.start()
tg_messages = await get_tg_messages(client_tg, keys.channel_username_tg)
list_titles_and_ids = news()
if list_titles_and_ids:
list_for_public = []
for topic_id, topic_title in list_titles_and_ids:
if all(topic_title not in (msg or '') for msg in tg_messages) and topic_id > keys.start_topic_id:
list_for_public.append((topic_id, topic_title))
if not list_for_public:
logging.info(f"Новостей для публикации в Telegram нет")
await client_tg.disconnect()
else:
logging.info(f"Новости для публикации в Telegram: {list_for_public}")
for topic_id, topic_title in reversed(list_for_public):
text_data = news_content(topic_id)
if text_data:
content = f"----------------------------------------------------------\n### {topic_title}\t\n" + text_data + "\n"
while True:
try:
await client_tg.send_message(keys.channel_username_tg, content)
break # Сообщение отправлено успешно, выходим из цикла
except FloodWaitError as e:
logging.warning(f"Flood wait error: нужно подождать {e.seconds} секунд.")
await asyncio.sleep(e.seconds) # Ждем указанное время перед повторной попыткой
await client_tg.disconnect()
loop = asyncio.get_event_loop()
loop.run_until_complete(main_tg())
if __name__ == '__main__': if __name__ == '__main__':
main() main()