diff --git a/modules/lolz.py b/modules/lolz.py index c7453f5..e815ac5 100644 --- a/modules/lolz.py +++ b/modules/lolz.py @@ -17,8 +17,14 @@ class Lolz: raise async def get_post(self, post_id: Union[str, int]) -> Dict[str, Any]: + logger.debug(f"Запрашиваю данные поста {post_id}...") response = await self.client.posts.get(post_id=post_id) - return (response.json()).get("post", {}) + post = (response.json()).get("post", {}) + + if post == {}: + logger.warning(f"Пост {post_id} не найден или вернул пустой ответ.") + + return post async def get_thread_posts( self, thread_id: Union[str, int], start_page: int = 1 @@ -41,7 +47,7 @@ class Lolz: all_posts.extend(posts) last_page = page - logger.info( + logger.debug( f"Получено {len(posts)} постов из темы {thread_id} на странице {page}." ) @@ -62,9 +68,10 @@ class Lolz: return posts async def get_post_comments(self, post_id: int) -> List[Dict[str, Any]]: + logger.debug(f"Запрашиваю комментарии к посту {post_id}...") response = await self.client.posts.comments.list(post_id=post_id) comments = (response.json()).get("comments", []) - + logger.debug(f"Найдено {len(comments)} комментариев к посту {post_id}.") return comments async def has_comments( diff --git a/modules/misc.py b/modules/misc.py index 753af9f..ce1088f 100644 --- a/modules/misc.py +++ b/modules/misc.py @@ -1,5 +1,9 @@ +import logging + from typing import Set, List +logger = logging.getLogger(__name__) + class ProcessedPostsManager: def __init__(self, file_path: str = "processed.txt"): @@ -9,9 +13,16 @@ class ProcessedPostsManager: def _load(self) -> Set[str]: try: with open(self.file_path, "r", encoding="utf-8") as processed: - return {line.strip() for line in processed if line.strip()} + ids = {line.strip() for line in processed if line.strip()} + logger.info(f"Загружено {len(ids)} обработанных постов из {self.file_path}.") + return ids - except: + except FileNotFoundError: + logger.info(f"Файл {self.file_path} не найден, начинаем с пустого списка.") + return set() + + except Exception as e: + logger.error(f"Ошибка при загрузке {self.file_path}: {e}. Начинаем с пустого списка.") return set() def _save(self): @@ -31,9 +42,12 @@ class ProcessedPostsManager: self.processed_posts.add(str_id) with open(self.file_path, "a", encoding="utf-8") as f: f.write(str_id + "\n") + logger.debug(f"Пост {post_id} отмечен как обработанный.") def add_existing_posts(self, post_ids: List[int]): + before = len(self.processed_posts) for post_id in post_ids: self.processed_posts.add(str(post_id)) - self._save() + added = len(self.processed_posts) - before + logger.info(f"Добавлено {added} новых записей в список обработанных (всего: {len(self.processed_posts)}).") diff --git a/modules/telegram.py b/modules/telegram.py index 0758a69..6da1d09 100644 --- a/modules/telegram.py +++ b/modules/telegram.py @@ -114,7 +114,9 @@ class TelegramStarsBot: except FloodWait as e: wait_time = getattr(e, "value", getattr(e, "x", 10)) + 2 - logger.warning(f"FloodWait: необходимо подождать {wait_time} секунд.") + logger.warning( + f"FloodWait: необходимо подождать {wait_time} секунд." + ) await asyncio.sleep(wait_time) except Exception as e: @@ -125,7 +127,10 @@ class TelegramStarsBot: if attempt < self.config.max_retries - 1: await asyncio.sleep(3 * (attempt + 1)) - return False + logger.error( + f"Все {self.config.max_retries} попытки отправки звезд в https://t.me/{channel} исчерпаны." + ) + return False except Exception as e: logger.error(f"Критическая ошибка при отправке звезд: {e}") @@ -136,6 +141,10 @@ class TelegramStarsBot: poster_user_id = post.get("poster_user_id") if not post_id or self.processed_manager.is_processed(post_id): + if post_id: + logger.debug(f"Пост {post_id} уже обработан, пропускаю.") + else: + logger.warning("Пост без post_id, пропускаю.") return logger.info(f"Найден новый пост для обработки: ID {post_id}") @@ -160,20 +169,23 @@ class TelegramStarsBot: self.processed_manager.mark_processed(post_id) return + logger.info(f"В посте {post_id} найдено ссылок: {len(links)}.") + successful_reactions = 0 for link in links: parsed_link = TelegramLinkExtractor.parse(link) if parsed_link: channel, message_id = parsed_link + if await self.send_star(channel, message_id): successful_reactions += 1 + break # stop after first successful reaction + await asyncio.sleep(1) if successful_reactions > 0 and self.config.enable_reply: await asyncio.sleep(self.config.api_delay) - # Теперь можно отправлять больше 1 сообщения - # см. README.md if poster_user_id: replies = self.config.reply_templates @@ -182,6 +194,14 @@ class TelegramStarsBot: reply_message = f"[userids={poster_user_id};align=left]{random.choice(reply_options)}[/userids]" await self.lolz_api.create_comment(post_id, reply_message) + else: + logger.warning( + f"Пост {post_id}: poster_user_id отсутствует, комментарий не оставлен." + ) + elif successful_reactions == 0: + logger.warning( + f"Пост {post_id}: ни одна звезда не была отправлена успешно ({len(links)} ссылок)." + ) logger.info(f"Пост {post_id} полностью обработан.") self.processed_manager.mark_processed(post_id) @@ -199,9 +219,8 @@ class TelegramStarsBot: if posts: for post in posts: await self._process_single_post(post) - # Next cycle starts from the last page that had posts — - # new posts always appear there or on a new page beyond it, - # never on earlier pages. + if last_page > self.start_page: + logger.info(f"Мониторинг продвинулся до страницы {last_page}.") self.start_page = last_page else: logger.info("Новых постов для обработки не найдено.")