This commit is contained in:
@@ -20,4 +20,4 @@ alwaysApply: true
|
|||||||
|
|
||||||
5. Не поднимать версию за косметические правки без изменения поведения.
|
5. Не поднимать версию за косметические правки без изменения поведения.
|
||||||
|
|
||||||
Текущая базовая версия: **1.0.4**.
|
Текущая базовая версия: **1.1.0**.
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ RESPONDER_BOT_NAME = "posto_1638_bot"
|
|||||||
ORG_MESSAGE_TAG = "#оргинфаЗиланткона"
|
ORG_MESSAGE_TAG = "#оргинфаЗиланткона"
|
||||||
# tag to detect posts to not repost from VK
|
# tag to detect posts to not repost from VK
|
||||||
VK_NO_REPOST_TAG = "#окоЗиланта"
|
VK_NO_REPOST_TAG = "#окоЗиланта"
|
||||||
|
# Минимум букв в тексте VK-поста (без учёта цифр/знаков). Меньше — «пустой пост», не в публикацию
|
||||||
|
VK_POST_MIN_LETTERS = 5
|
||||||
|
|
||||||
|
|
||||||
# Minutes delay before publishing an event
|
# Minutes delay before publishing an event
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ MAX_TEXT_LENGTH=4000
|
|||||||
ORG_MESSAGE_TAG=#оргинфаЗиланткона
|
ORG_MESSAGE_TAG=#оргинфаЗиланткона
|
||||||
# VK posts with no repost tag are skipped by poster
|
# VK posts with no repost tag are skipped by poster
|
||||||
VK_NO_REPOST_TAG=#окоЗиланта
|
VK_NO_REPOST_TAG=#окоЗиланта
|
||||||
|
# Минимум букв (isalpha) в тексте VK-поста. Меньше — в БД как «- = Пустой пост = -», не для публикации
|
||||||
|
VK_POST_MIN_LETTERS=5
|
||||||
|
|
||||||
# --- Публикация событий ------------------------------------------------------
|
# --- Публикация событий ------------------------------------------------------
|
||||||
# Задержка перед публикацией события (минуты). В БД время в UTC.
|
# Задержка перед публикацией события (минуты). В БД время в UTC.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Zilant / VOLK — Telegram poster и подписки
|
# Zilant / VOLK — Telegram poster и подписки
|
||||||
|
|
||||||
**Версия:** 1.0.4 ([`VERSION`](VERSION))
|
**Версия:** 1.1.0 ([`VERSION`](VERSION))
|
||||||
|
|
||||||
Автоматическая публикация постов и событий в Telegram-канал, веб-редактор, бот подписок с сезонными deep link.
|
Автоматическая публикация постов и событий в Telegram-канал, веб-редактор, бот подписок с сезонными deep link.
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ cp .env.example .env
|
|||||||
| `MDB_*`, `MDBASE` | MariaDB |
|
| `MDB_*`, `MDBASE` | MariaDB |
|
||||||
| `POSTER_BOT_TOKEN`, `RESPONDER_BOT_TOKEN` | Токены ботов |
|
| `POSTER_BOT_TOKEN`, `RESPONDER_BOT_TOKEN` | Токены ботов |
|
||||||
| `PZK_PREFIX`, `EVT_PREFIX`, `DESC_PREFIX` | Ссылки ZILANT |
|
| `PZK_PREFIX`, `EVT_PREFIX`, `DESC_PREFIX` | Ссылки ZILANT |
|
||||||
|
| `VK_NO_REPOST_TAG` | Тег VK, отключающий автопубликацию |
|
||||||
|
| `VK_POST_MIN_LETTERS` | Минимум букв в тексте VK-поста (иначе «пустой пост», не публиковать) |
|
||||||
| `VOLK_*` | API VOLK (при `WORKMODE=VOLK`) |
|
| `VOLK_*` | API VOLK (при `WORKMODE=VOLK`) |
|
||||||
| `RA_KEY`, `RA_MODEL` | RouterAI для shortname |
|
| `RA_KEY`, `RA_MODEL` | RouterAI для shortname |
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,16 @@
|
|||||||
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/).
|
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/).
|
||||||
Версия проекта — в файле [`VERSION`](../VERSION) (SemVer).
|
Версия проекта — в файле [`VERSION`](../VERSION) (SemVer).
|
||||||
|
|
||||||
|
## [1.1.0] - 2026-08-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Импорт VK (`vk_load.py`): посты с числом букв меньше `VK_POST_MIN_LETTERS` (по умолчанию 5) сохраняются с названием `- = Пустой пост = -` и без отметки «к публикации».
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- Параметр `VK_POST_MIN_LETTERS` в `.env.example` и `.env`.
|
||||||
|
|
||||||
## [1.0.4] - 2026-08-30
|
## [1.0.4] - 2026-08-30
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
+43
-9
@@ -19,6 +19,14 @@ VK_API_VERSION = os.getenv('VK_API_VERSION', '5.131')
|
|||||||
IS_EVENT = os.getenv('IS_EVENT', 'false').lower() in ('true', '1', 'yes', 'on')
|
IS_EVENT = os.getenv('IS_EVENT', 'false').lower() in ('true', '1', 'yes', 'on')
|
||||||
AUTO_PUBLISH = os.getenv('AUTO_PUBLISH', 'false').lower() in ('true', '1', 'yes', 'on')
|
AUTO_PUBLISH = os.getenv('AUTO_PUBLISH', 'false').lower() in ('true', '1', 'yes', 'on')
|
||||||
VK_NO_REPOST_TAG = os.getenv('VK_NO_REPOST_TAG', '') # Тег для отключения автопубликации
|
VK_NO_REPOST_TAG = os.getenv('VK_NO_REPOST_TAG', '') # Тег для отключения автопубликации
|
||||||
|
# Минимум букв (isalpha), чтобы пост не считался пустым (видео без описания и т.п.)
|
||||||
|
try:
|
||||||
|
VK_POST_MIN_LETTERS = int((os.getenv('VK_POST_MIN_LETTERS') or '5').strip().strip('"').strip("'"))
|
||||||
|
except ValueError:
|
||||||
|
VK_POST_MIN_LETTERS = 5
|
||||||
|
if VK_POST_MIN_LETTERS < 0:
|
||||||
|
VK_POST_MIN_LETTERS = 0
|
||||||
|
EMPTY_POST_SHORTNAME = "- = Пустой пост = -"
|
||||||
LOG_FILE = os.getenv('LOG_FILE', 'vk_loader.log') # Путь к лог-файлу
|
LOG_FILE = os.getenv('LOG_FILE', 'vk_loader.log') # Путь к лог-файлу
|
||||||
LOG_PREFIX = "VK_loader" # Уникальный префикс для идентификации скрипта
|
LOG_PREFIX = "VK_loader" # Уникальный префикс для идентификации скрипта
|
||||||
|
|
||||||
@@ -86,6 +94,12 @@ def get_vk_posts():
|
|||||||
log_message(error_msg)
|
log_message(error_msg)
|
||||||
raise Exception(error_msg)
|
raise Exception(error_msg)
|
||||||
|
|
||||||
|
|
||||||
|
def count_letters(text):
|
||||||
|
"""Количество букв в тексте (Unicode isalpha), без цифр и знаков."""
|
||||||
|
return sum(1 for c in (text or "") if c.isalpha())
|
||||||
|
|
||||||
|
|
||||||
def process_post(post):
|
def process_post(post):
|
||||||
"""Извлекает необходимые данные из поста VK, включая обработку репостов"""
|
"""Извлекает необходимые данные из поста VK, включая обработку репостов"""
|
||||||
post_id = post['id']
|
post_id = post['id']
|
||||||
@@ -144,11 +158,15 @@ def process_post(post):
|
|||||||
|
|
||||||
# Формируем текст поста: если это репост, добавляем префикс и информацию об оригинале
|
# Формируем текст поста: если это репост, добавляем префикс и информацию об оригинале
|
||||||
post_text = source_post.get('text', '')
|
post_text = source_post.get('text', '')
|
||||||
|
own_text = post.get('text', '')
|
||||||
|
letter_count = count_letters(post_text)
|
||||||
if is_repost:
|
if is_repost:
|
||||||
|
letter_count += count_letters(own_text)
|
||||||
# Если у репоста есть свой текст, добавляем его перед текстом оригинала
|
# Если у репоста есть свой текст, добавляем его перед текстом оригинала
|
||||||
if post.get('text', '').strip():
|
if own_text.strip():
|
||||||
post_text = f"{post['text']}\n\n---\n\n{post_text}"
|
post_text = f"{own_text}\n\n---\n\n{post_text}"
|
||||||
post_text = repost_prefix + post_text + repost_info
|
post_text = repost_prefix + post_text + repost_info
|
||||||
|
is_empty_text = letter_count < VK_POST_MIN_LETTERS
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'vk_post_id': post_id,
|
'vk_post_id': post_id,
|
||||||
@@ -161,7 +179,9 @@ def process_post(post):
|
|||||||
'poll_options': poll_options,
|
'poll_options': poll_options,
|
||||||
'poll_multiple': poll_multiple,
|
'poll_multiple': poll_multiple,
|
||||||
'poll_end_date': poll_end_date,
|
'poll_end_date': poll_end_date,
|
||||||
'is_repost': is_repost
|
'is_repost': is_repost,
|
||||||
|
'is_empty_text': is_empty_text,
|
||||||
|
'letter_count': letter_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
def save_to_database(posts):
|
def save_to_database(posts):
|
||||||
@@ -175,9 +195,14 @@ def save_to_database(posts):
|
|||||||
try:
|
try:
|
||||||
# Проверка наличия тега VK_NO_REPOST_TAG в тексте поста
|
# Проверка наличия тега VK_NO_REPOST_TAG в тексте поста
|
||||||
post_text = post.get('text', '')
|
post_text = post.get('text', '')
|
||||||
|
is_empty_text = post.get('is_empty_text', False)
|
||||||
should_auto_publish = AUTO_PUBLISH
|
should_auto_publish = AUTO_PUBLISH
|
||||||
|
shortname = None
|
||||||
|
|
||||||
if VK_NO_REPOST_TAG and VK_NO_REPOST_TAG in post_text:
|
if is_empty_text:
|
||||||
|
should_auto_publish = False
|
||||||
|
shortname = EMPTY_POST_SHORTNAME
|
||||||
|
elif VK_NO_REPOST_TAG and VK_NO_REPOST_TAG in post_text:
|
||||||
# Если тег найден, отключаем автопубликацию независимо от AUTO_PUBLISH
|
# Если тег найден, отключаем автопубликацию независимо от AUTO_PUBLISH
|
||||||
should_auto_publish = False
|
should_auto_publish = False
|
||||||
|
|
||||||
@@ -201,16 +226,21 @@ def save_to_database(posts):
|
|||||||
int(post['poll_multiple']),
|
int(post['poll_multiple']),
|
||||||
post['poll_end_date'],
|
post['poll_end_date'],
|
||||||
IS_EVENT,
|
IS_EVENT,
|
||||||
int(should_auto_publish), # Значение с учетом проверки тега
|
int(should_auto_publish),
|
||||||
None, # shortname - пока не используется, устанавливаем NULL
|
shortname,
|
||||||
None # action_number - пока не используется, устанавливаем NULL
|
None # action_number
|
||||||
))
|
))
|
||||||
if cursor.rowcount > 0:
|
if cursor.rowcount > 0:
|
||||||
new_posts_count += 1
|
new_posts_count += 1
|
||||||
# Логируем добавление нового поста с указанием причины отключения автопубликации
|
# Логируем добавление нового поста с указанием причины отключения автопубликации
|
||||||
auto_publish_reason = 'Да'
|
auto_publish_reason = 'Да'
|
||||||
if not should_auto_publish:
|
if not should_auto_publish:
|
||||||
if VK_NO_REPOST_TAG and VK_NO_REPOST_TAG in post_text:
|
if is_empty_text:
|
||||||
|
auto_publish_reason = (
|
||||||
|
f'Нет (пустой текст: {post.get("letter_count", 0)} букв '
|
||||||
|
f'< {VK_POST_MIN_LETTERS})'
|
||||||
|
)
|
||||||
|
elif VK_NO_REPOST_TAG and VK_NO_REPOST_TAG in post_text:
|
||||||
auto_publish_reason = 'Нет (найден тег ' + VK_NO_REPOST_TAG + ')'
|
auto_publish_reason = 'Нет (найден тег ' + VK_NO_REPOST_TAG + ')'
|
||||||
else:
|
else:
|
||||||
auto_publish_reason = 'Нет'
|
auto_publish_reason = 'Нет'
|
||||||
@@ -246,7 +276,11 @@ def vk_load_10():
|
|||||||
Возвращает количество добавленных постов
|
Возвращает количество добавленных постов
|
||||||
"""
|
"""
|
||||||
# Стартовая информация
|
# Стартовая информация
|
||||||
start_msg = f"Старт скрипта | База: {DB_CONFIG['database']}@{DB_CONFIG['host']} | IS_EVENT: {IS_EVENT} | AUTO_PUBLISH: {AUTO_PUBLISH}"
|
start_msg = (
|
||||||
|
f"Старт скрипта | База: {DB_CONFIG['database']}@{DB_CONFIG['host']} | "
|
||||||
|
f"IS_EVENT: {IS_EVENT} | AUTO_PUBLISH: {AUTO_PUBLISH} | "
|
||||||
|
f"VK_POST_MIN_LETTERS: {VK_POST_MIN_LETTERS}"
|
||||||
|
)
|
||||||
print(start_msg)
|
print(start_msg)
|
||||||
log_message(start_msg)
|
log_message(start_msg)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user