def get_latest_messages(group_name: str, count: int = 10) -> list[dict]:
"""
Получить заданное количество последних сообщений из указанной группы.
Возвращает список словарей с полями: Msg-Num, Message-ID, Subject, Date, Name, Mail.
Сообщения строго отсортированы от самых новых к старым.
This commit is contained in:
1 parent
8d36a62ca2
commit
8b4659cffb
1 file changed
+66
@@ -362,6 +362,72 @@ def save_text_to_file(filename: str, content: str) -> str:
|
||||
return f"ERROR: {str(e)}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_latest_messages(group_name: str, count: int = 10) -> list[dict]:
|
||||
"""
|
||||
Получить заданное количество последних сообщений из указанной группы.
|
||||
|
||||
Возвращает список словарей с полями: Msg-Num, Message-ID, Subject, Date, Name, Mail.
|
||||
Сообщения строго отсортированы от самых новых к старым.
|
||||
"""
|
||||
from email.utils import parseaddr
|
||||
|
||||
try:
|
||||
latest_messages = []
|
||||
with nntplib.NNTP(NNTP_SERVER, port=PORT, timeout=15) as s:
|
||||
# Получаем информацию о группе и номера сообщений
|
||||
resp, total_count, first, last, name = s.group(group_name)
|
||||
first_num = int(first)
|
||||
last_num = int(last)
|
||||
|
||||
if first_num > last_num or total_count == 0:
|
||||
return []
|
||||
|
||||
# Берем диапазон с запасом, чтобы гарантированно набрать count живых сообщений
|
||||
# (на случай, если часть постов между first и last были удалены)
|
||||
start_msg = max(first_num, last_num - (count * 2) + 1)
|
||||
|
||||
# Получаем овервью (заголовки) сообщений в выбранном диапазоне
|
||||
resp, overviews = s.over((str(start_msg), str(last_num)))
|
||||
|
||||
# СТРОГАЯ СОРТИРОВКА: переводим ключи в int и сортируем по убыванию (от новых к старым)
|
||||
sorted_overviews = sorted(overviews, key=lambda x: int(x[0]), reverse=True)
|
||||
|
||||
# Обходим сообщения уже в гарантированно правильном порядке
|
||||
for msg_num, over in sorted_overviews:
|
||||
# Извлекаем message-id из овервью или генерируем запасной
|
||||
raw_msg_id = over.get('message-id', f"<{msg_num}@{NNTP_SERVER}>")
|
||||
|
||||
raw_author = over.get('from', '')
|
||||
raw_subject = over.get('subject', '')
|
||||
raw_date = over.get('date', '')
|
||||
|
||||
# Декодируем MIME-заголовки с помощью существующих функций проекта
|
||||
author = decode_mime_header(raw_author)
|
||||
subject = decode_mime_header(raw_subject)
|
||||
date = decode_mime_header(raw_date)
|
||||
|
||||
# Разделяем From на Имя и Почту
|
||||
name_part, mail_part = parseaddr(author)
|
||||
|
||||
latest_messages.append({
|
||||
"Msg-Num": str(msg_num), # Локальный порядковый номер в группе
|
||||
"Message-ID": raw_msg_id, # Глобальный уникальный идентификатор
|
||||
"Subject": subject if subject else "[Без темы]",
|
||||
"Date": date,
|
||||
"Name": name_part if name_part else "[Без имени]",
|
||||
"Mail": mail_part if mail_part else "[Без почты]"
|
||||
})
|
||||
|
||||
# Прерываем цикл, как только набрали нужное количество
|
||||
if len(latest_messages) >= count:
|
||||
break
|
||||
|
||||
return latest_messages
|
||||
except Exception as e:
|
||||
return [{"error": f"Ошибка NNTP при получении последних сообщений: {e}"}]
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Для современного пакета MCPServer (MCP v2.x)
|
||||
|
||||
Reference in new issue
Block a user