обновление публикации новостей от stable до stable

This commit is contained in:
2024-07-24 23:06:24 +03:00
parent 4ad6c4dafc
commit 7e726a06b5

View File

@@ -3,6 +3,7 @@
import re import re
import sys import sys
import time import time
import schedule
import asyncio import asyncio
import discord import discord
import logging import logging
@@ -19,10 +20,10 @@ 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 = f"https://linux-gaming.ru/c/news/6.json" url_news = f"https://linux-gaming.ru/c/news/{keys.cat_num}.json"
url_vk_post = "https://api.vk.com/method/wall.post" url_vk_post = "https://api.vk.com/method/wall.post"
url_vk_get = "https://api.vk.com/method/wall.get" url_vk_get = "https://api.vk.com/method/wall.get"
url_changelog = "https://gitlab.eterfund.ru/Castro-Fidel/PortWINE/raw/devel/data_from_portwine/changelog_ru" url_changelog = "https://gitlab.eterfund.ru/Castro-Fidel/PortWINE/raw/master/data_from_portwine/changelog_ru"
heads_site = { heads_site = {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -44,7 +45,8 @@ logger.setLevel(logging.DEBUG)
handler = colorlog.StreamHandler() handler = colorlog.StreamHandler()
handler.setFormatter(colorlog.ColoredFormatter( handler.setFormatter(colorlog.ColoredFormatter(
'%(log_color)s%(levelname)s: %(message)s', '%(log_color)s%(asctime)s - %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
log_colors={ log_colors={
'DEBUG': 'cyan', 'DEBUG': 'cyan',
'INFO': 'green', 'INFO': 'green',
@@ -57,12 +59,12 @@ handler.setFormatter(colorlog.ColoredFormatter(
logger.addHandler(handler) logger.addHandler(handler)
def main(): async def job():
last_changelog, resp_changelog = resp_change() matches_changelog, last_changelog, resp_changelog = resp_change()
check_version(last_changelog, resp_changelog) check_version(matches_changelog, last_changelog, resp_changelog)
check_discord_public() await check_discord_public()
check_vk_posts() check_vk_posts()
check_tg_news() await check_tg_news()
def make_soup(resp_changelog): def make_soup(resp_changelog):
@@ -83,6 +85,8 @@ def html_to_text(html_content):
logging.debug(f"Текст до обработки регулярками {markdown_text}") logging.debug(f"Текст до обработки регулярками {markdown_text}")
#Удаляем лишние записи о версии скриптов
# Удаление переносов строк из-за - # Удаление переносов строк из-за -
markdown_text = re.sub(r'-\s*\n\s*', '-', markdown_text, flags=re.DOTALL) markdown_text = re.sub(r'-\s*\n\s*', '-', markdown_text, flags=re.DOTALL)
markdown_text = re.sub(r'-\s*\n*', '-', markdown_text, flags=re.DOTALL) markdown_text = re.sub(r'-\s*\n*', '-', markdown_text, flags=re.DOTALL)
@@ -167,7 +171,7 @@ def remove_empty_lines(text_data):
def remove_markdown_links(markdown_text): def remove_markdown_links(markdown_text):
logging.debug(f"Входим в remove_markdown_links") logging.debug(f"Входим в remove_markdown_links")
# Регулярное выражение для поиска Markdown-ссылок и замена их на только URL # Регулярное выражение для поиска Markdown-ссылок и замена их на только URL
markdown_text = re.sub(r'\[.*?\]\((https?://.*?)\)', r'\1' or r'(`https?://.*?)`\)', markdown_text) markdown_text = re.sub(r'\[.*?\]\((https?://.*?)\)', r'\1' or r'(https?://.*?)\)', markdown_text)
logging.debug(f"Возврат markdown_text {markdown_text}") logging.debug(f"Возврат markdown_text {markdown_text}")
return markdown_text return markdown_text
@@ -199,38 +203,35 @@ def extract_links(text):
return url_pattern return url_pattern
def script_content(last_topics_script, last_changelog, resp_changelog): def script_content(script_ver, next_version, resp_changelog):
logging.debug(f"Вход в script_content") logging.debug(f"Вход в script_content c версией стабильного скрипта {script_ver}")
soup = make_soup(resp_changelog) soup = make_soup(resp_changelog)
page_text = str(soup) page_text = str(soup)
page_text = page_text.replace("Вы можете помочь развитию проекта: https://linux-gaming.ru/donate/", '') page_text = page_text.replace("Вы можете помочь развитию проекта: https://linux-gaming.ru/donate/", '')
changelog_text = "" # Находим текст до определенного текста, тега или класса (например, до тега <hr>)
for script_ver in range(last_topics_script + 1, last_changelog + 1): last_text = f"###Scripts version {next_version}### / stable"
current_ver_text = f"###Scripts version {script_ver}### / stable" last_text = str(last_text)
next_ver_text = f"###Scripts version {script_ver + 1}### / stable" index_last_text = page_text.find(last_text)
start_index = page_text.find(current_ver_text) if index_last_text != -1:
end_index = page_text.find(next_ver_text) changelog_text_last = page_text[:index_last_text]
prev_text = f"###Scripts version {script_ver}### / stable"
if start_index != -1: index_script_ver = changelog_text_last.find(prev_text)
if end_index != -1: changelog_text = changelog_text_last[index_script_ver:]
changelog_text += page_text[start_index:end_index] changelog_text = re.sub(r'###Scripts version (\d+)### / Дата: (\d{2}\.\d{2}\.\d{4}) / Размер скачиваемого обновления: \d+ \S+', r'\1 - \2'":", changelog_text)
else: post_text = (f"-----------------------------\n") + changelog_text
changelog_text += page_text[start_index:] site_text = (f"[center][img]/uploads/default/original/1X/5cfa59077a5275971401fab0114e56f3ffdd0ec4.png[/img][/center]\n{post_text}")
post_text = f"-----------------------------\n{changelog_text}"
site_text = f"[center][img]/uploads/default/original/1X/5cfa59077a5275971401fab0114e56f3ffdd0ec4.png[/img][/center]\n{post_text}"
logging.debug(f"Сообщение на сайт {site_text}") logging.debug(f"Сообщение на сайт {site_text}")
post_data = { post_data = {
"title": f"Обновление скриптов {last_changelog}", "title": f"Обновление скриптов {script_ver}",
"raw": site_text, "raw": site_text,
"category": keys.cat_num "category": keys.cat_num
} }
logging.debug(f"Возвращаем post_text - {post_text}\n post_data - {post_data}") logging.debug(f"Возвращаем post_text - {post_text}\n post_data - {post_data}")
return post_text, post_data return post_text, post_data, post_text
def news_content(post_id): def news_content(post_id):
@@ -269,8 +270,8 @@ def resp_change():
matches_changelog = re.findall(r'###Scripts version (\d+)### / stable', resp_changelog.text) matches_changelog = re.findall(r'###Scripts version (\d+)### / stable', resp_changelog.text)
logging.debug(f"Найдены версии в истории изменений: {matches_changelog}") logging.debug(f"Найдены версии в истории изменений: {matches_changelog}")
last_changelog = int(max(matches_changelog)) last_changelog = int(max(matches_changelog))
logging.info(f"Последняя версия в истории изменений: {last_changelog}") logging.info(f"Последняя стабильная версия в истории изменений: {last_changelog}")
return last_changelog, resp_changelog return matches_changelog, last_changelog, resp_changelog
else: else:
logging.error( logging.error(
f'Ошибка при запросе changelog: {resp_changelog.status_code if resp_changelog else "No Response"}') f'Ошибка при запросе changelog: {resp_changelog.status_code if resp_changelog else "No Response"}')
@@ -311,7 +312,7 @@ def site_post(url, headers, json):
time.sleep(900) time.sleep(900)
def check_version(last_changelog, resp_changelog): def check_version(matches_changelog, last_changelog, resp_changelog):
list_titles_and_ids = news() list_titles_and_ids = news()
pattern = re.compile(r'Обновление скриптов (\d+)') pattern = re.compile(r'Обновление скриптов (\d+)')
@@ -321,31 +322,31 @@ def check_version(last_changelog, resp_changelog):
return int(match.group(1)) return int(match.group(1))
return None return None
numbers = [extract_number(title) for _, title in list_titles_and_ids if extract_number(title) is not None] def posting_news():
list_new_ver = []
for script_ver, next_version in zip(reversed(matches_changelog[:-1]), reversed(matches_changelog[1:])):
logging.info(f"Найдена новая версия скрипта {script_ver}")
changelog_text, post_data, params = script_content(script_ver, next_version, resp_changelog)
if post_data:
logging.debug(f"Публикуем {post_data}")
site_post(url_post, heads_site, post_data)
if not list_new_ver:
logging.warning(f"Не найдена новая стабильная версия скрипта")
numbers = [extract_number(title) for _, title in list_titles_and_ids if extract_number(title) is not None]
if numbers: if numbers:
last_topics_script = max(numbers) last_topics_script = max(numbers)
logging.info(f"Последняя новость на сайте о версии: {last_topics_script}") logging.info(f"Последняя новость на сайте о версии: {last_topics_script}")
else:
logging.warning("На сайте нет новостей о скриптах")
last_topics_script = 0
if last_topics_script < last_changelog: if last_topics_script < last_changelog:
changelog_text, post_data = script_content(last_topics_script, last_changelog, resp_changelog) posting_news()
if post_data:
logging.debug(f"Публикуем {post_data}")
site_post(url_post, heads_site, post_data)
else:
logging.warning("Нет новых версий скриптов PortProton")
# Публикация топиков
if not numbers or last_topics_script < last_changelog:
changelog_text, post_data = script_content(last_topics_script, last_changelog, resp_changelog)
if post_data:
logging.debug(f"Публикуем {post_data}")
site_post(url_post, heads_site, post_data)
else: else:
logging.warning("Нет новых версий скриптов PortProton") logging.warning("Нет новых версий скриптов PortProton")
else:
logging.warning("На сайте нет новостей о скриптах")
posting_news()
async def discord_post(post_text, client): async def discord_post(post_text, client):
@@ -372,7 +373,7 @@ async def get_discord_messages(client_discord, channel_id):
return messages return messages
def check_discord_public(): async def check_discord_public():
intents = discord.Intents.default() intents = discord.Intents.default()
intents.messages = True intents.messages = True
client_discord = discord.Client(intents=intents) client_discord = discord.Client(intents=intents)
@@ -411,7 +412,7 @@ def check_discord_public():
await channel.send(content[i:i+2000]) await channel.send(content[i:i+2000])
await client_discord.close() await client_discord.close()
client_discord.run(keys.discord_token) await client_discord.start(keys.discord_token)
def vk_post(url, post_text, links=None): def vk_post(url, post_text, links=None):
@@ -527,18 +528,11 @@ async def get_tg_messages(client_tg, channel_username_tg):
return messages return messages
def check_tg_news(): async def check_tg_news():
session_file = 'LG_news' session_file = 'LG_news'
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
client_tg = TelegramClient(session_file, keys.api_id_tg, keys.api_hash_tg) client_tg = TelegramClient(session_file, keys.api_id_tg, keys.api_hash_tg)
@client_tg.on(events.NewMessage(chats=keys.channel_username_tg)) async with client_tg:
async def handler(event):
logging.debug(f"Новое сообщение в Telegram: {event.message.message}")
async def main_tg():
await client_tg.start() await client_tg.start()
tg_messages = await get_tg_messages(client_tg, keys.channel_username_tg) tg_messages = await get_tg_messages(client_tg, keys.channel_username_tg)
list_titles_and_ids = news() list_titles_and_ids = news()
@@ -551,7 +545,6 @@ def check_tg_news():
if not list_for_public: if not list_for_public:
logging.warning(f"Новостей для публикации в Telegram нет") logging.warning(f"Новостей для публикации в Telegram нет")
await client_tg.disconnect()
else: else:
logging.info(f"Новости для публикации в Telegram: {list_for_public}") logging.info(f"Новости для публикации в Telegram: {list_for_public}")
for topic_id, topic_title in reversed(list_for_public): for topic_id, topic_title in reversed(list_for_public):
@@ -565,11 +558,21 @@ def check_tg_news():
except FloodWaitError as e: except FloodWaitError as e:
logging.warning(f"Flood wait error: нужно подождать {e.seconds} секунд.") logging.warning(f"Flood wait error: нужно подождать {e.seconds} секунд.")
await asyncio.sleep(e.seconds) # Ждем указанное время перед повторной попыткой await asyncio.sleep(e.seconds) # Ждем указанное время перед повторной попыткой
await client_tg.disconnect()
def run_job():
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.run_until_complete(main_tg()) loop.run_until_complete(job())
if __name__ == '__main__': if __name__ == '__main__':
main() # Выполняем задачу немедленно при старте
run_job()
# Планируем выполнение задачи каждые 10 минут
schedule.every(30).minutes.do(run_job)
logger.info("Запуск планировщика задач")
while True:
schedule.run_pending()
time.sleep(1)