Skip to content

Commit 834f679

Browse files
author
mithmith
committed
Merge remote-tracking branch 'origin/dev'
2 parents 76f21e1 + 6e492a5 commit 834f679

22 files changed

+867
-117
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ yt-dlp
1212
*.pyo
1313
__pycache__/
1414
.pytest_cache/
15+
.mypy_cache/
1516

1617
# Файл со списком каналов для мониторинга
17-
channels_list.json
18+
*_channels*.json
1819

1920
# Игнорирование файлов с секретами и ключи
2021
.env
22+
*.env
2123
*oauth2*.json
2224
*secret*.json
2325
*.pickle
@@ -42,6 +44,7 @@ dist/
4244
# Игнорирование зависимостей
4345
node_modules/
4446
venv/
47+
.venv/
4548
*.wheel
4649

4750
# Игнорирование IDE и редакторов

TODO.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- [ ] Выборка статистической информацией по каналам и видео, включая просмотры, лайки, количество подписчиков, количество видео, новые видео и другие метрики.
1313

1414
- [ ] **Скачивание контента**:
15-
- [ ] Скачивание shorts видео
15+
- [x] Скачивание shorts видео
1616
- [ ] Скачивание видео, аудио, субтитров и миниатюр.
1717

1818
- [ ] **Редактирование видео**:
@@ -37,6 +37,9 @@
3737
- [ ] **Интеграция с сервером Peertube**:
3838
- [ ] Зеркальное размещение видео на децентрализованном хостинге.
3939

40+
- [ ] **Тесты**:
41+
- [ ] Добавить в github CI прогон тестов
42+
4043
## Frontend + back API для нескольких подборок каналов:
4144
- [ ] Сделать фронт-дашбоард для визуализации данных
4245
- [ ] Сделать API для вывода на фронт-дашбоард для визуализации данных с нескольких подборок каналов
@@ -48,6 +51,11 @@
4851
- [ ] Мониторинг логов: вывод последних 10 ошибок
4952
- [ ] Возможность просмотра или скачивания логов
5053
- [ ] Статистика публикации сообщений в телеграмм
54+
- [ ] Редактирование конфигов
55+
- [ ] Редактирование списка каналов
56+
- [ ] Редактирование шаблонов сообщений
5157

5258
## Docker-контейнер:
53-
- [x] Собрать контейнер с postgres, peertube и всем необходимым для работы
59+
- [x] Собрать контейнер со всем необходимым для работы
60+
- [x] Скрипты для запуска контейнеров с разными `channels_list` для публикации в разных tg каналах
61+
- [ ] Добавить сборку и публикацию контенера в github при формировании релизов

app/__main__.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import json
21
import logging
32
from multiprocessing import Queue
43

5-
from app.config import logger, settings
4+
from app.config import settings
65
from app.service.telegram import TelegramBotService
6+
from app.service.utils import load_channels_data
77
from app.service.yt_monitor import YTMonitorService
88

99
# Настройка уровня логирования SQLAlchemy
@@ -16,29 +16,6 @@
1616
logging.getLogger("sqlalchemy.engine").removeHandler(handler)
1717

1818

19-
def load_channels_list(file_path: str = "channels_list.json") -> list[str]:
20-
"""
21-
Загружает список каналов из JSON файла.
22-
23-
:param file_path: Путь к JSON файлу.
24-
:return: Список каналов или пустой список в случае ошибки.
25-
"""
26-
try:
27-
logger.debug(f"Channels list loading from {file_path}")
28-
with open(file_path, encoding="utf8") as f:
29-
data = json.load(f)
30-
channels = data.get("channels", [])
31-
logger.debug(f"Loaded {len(channels)} channels")
32-
return channels
33-
except FileNotFoundError:
34-
logger.error(f"Файл {file_path} не найден")
35-
except json.JSONDecodeError as e:
36-
logger.error(f"Ошибка декодирования JSON: {e}")
37-
except Exception as e:
38-
logger.error(f"Неизвестная ошибка при загрузке списка каналов: {e}")
39-
return []
40-
41-
4219
if __name__ == "__main__":
4320
# Общая очередь для передачи данных между сервисами
4421
news_queue = Queue()
@@ -47,11 +24,11 @@ def load_channels_list(file_path: str = "channels_list.json") -> list[str]:
4724
else:
4825
shorts_queue = None
4926
# Загружаем список каналов
50-
channels_list = load_channels_list()
27+
channels_list, channels_name = load_channels_data(settings.channels_list_path)
5128

5229
# Инициализируем мониторинг YouTube
5330
monitor = YTMonitorService(
54-
channels_list=channels_list, new_videos_queue=news_queue, shorts_videos_queue=shorts_queue
31+
channels_list, channels_name, new_videos_queue=news_queue, shorts_videos_queue=shorts_queue
5532
)
5633

5734
# Запускаем процессы

app/config.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
from functools import lru_cache
4+
from pathlib import Path
45

56
from loguru import logger as log
67
from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -10,17 +11,18 @@ class Settings(BaseSettings):
1011
app_host: str = "localhost"
1112
app_port: int = 9191
1213

14+
channels_list_path: str = "channels_list.json"
1315
storage_path: str = "/mnt/volume"
1416
video_download_path: str = "videos"
1517
shorts_download_path: str = "shorts"
16-
thumbnail_download_path: str = "videos/thumbnail"
18+
thumbnail_download_path: str = "thumbnails"
1719

1820
db_host: str = "localhost"
1921
db_port: int = 5432
20-
db_name: str = "peer_tube_db"
22+
db_name: str = "youtube_db"
2123
db_schema: str = "youtube"
22-
db_username: str = "peer_tube_user"
23-
db_password: str = "peer_tube_password"
24+
db_username: str = "you_tube_db_user"
25+
db_password: str = "you_tube_db_password"
2426

2527
monitor_new: bool = True
2628
monitor_history: bool = False
@@ -35,7 +37,13 @@ class Settings(BaseSettings):
3537
tg_bot_token: str = "TELEGRAM_BOT_TOKEN"
3638
tg_group_id: str = "group_id"
3739
tg_admin_id: int = 0
40+
tg_new_video_template: Path = "./templates/new_video.md"
41+
tg_shorts_template: Path = "./templates/shorts.md"
42+
tg_new_video_template_default: Path = "./templates/new_video.md"
43+
tg_shorts_template_default: Path = "./templates/shorts.md"
3844

45+
use_proxy: bool = False
46+
use_ssh_tunnel: bool = False
3947
ssh_host: str = "localhost"
4048
ssh_port: int = 22
4149
ssh_user: str = "root"
@@ -57,6 +65,13 @@ def database_url(self) -> str:
5765
f"postgresql+psycopg2://{self.db_username}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}"
5866
)
5967

68+
def __init__(self, **kwargs):
69+
super().__init__(**kwargs)
70+
self.tg_new_video_template = Path(self.tg_new_video_template).resolve()
71+
self.tg_shorts_template = Path(self.tg_shorts_template).resolve()
72+
self.tg_new_video_template_default = Path(self.tg_new_video_template_default).resolve()
73+
self.tg_shorts_template_default = Path(self.tg_shorts_template_default).resolve()
74+
6075

6176
@lru_cache()
6277
def get_logger(log_lvl: str, log_dir: str, log_to_file: bool):
@@ -66,7 +81,7 @@ def get_logger(log_lvl: str, log_dir: str, log_to_file: bool):
6681
"| <cyan>{file.name}:{line}</cyan> - <level>{message}</level>"
6782
)
6883
log_format_file = "{time:YYYY-MM-DD HH:mm:ss.SS} | {level:<8} | {file.name}:{line} - {message}"
69-
84+
7085
log.remove()
7186
log.add(sys.stderr, level=log_lvl, format=log_format_console, colorize=True, enqueue=True)
7287
if log_to_file:

app/db/data_table.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Channel(Base, table=True):
4646
banner_path: Optional[str] = Field(default=None)
4747
avatar_path: Optional[str] = Field(default=None)
4848
last_update: datetime = Field(default_factory=lambda: datetime.now().replace(microsecond=0))
49+
list_name: Optional[str] = Field(default=None)
4950

5051
thumbnails: List["Thumbnail"] = Relationship(back_populates="channel")
5152
videos: List["Video"] = Relationship(back_populates="channel")

app/db/repository.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,9 @@ def get_new_and_existing_video_ids(self, video_ids: list[str], channel_id: str)
458458
new_v_ids = [v_id for v_id in video_ids if v_id not in existing_v_ids]
459459
return new_v_ids, existing_v_ids
460460

461-
def upsert_channel(self, channel_data: Union[ChannelInfoSchema, ChannelAPIInfoSchema]) -> Channel:
461+
def upsert_channel(
462+
self, channel_data: Union[ChannelInfoSchema, ChannelAPIInfoSchema], channels_list_name: str
463+
) -> Channel:
462464
"""
463465
Updates the details of an existing channel or creates a new channel if it does not exist.
464466
@@ -490,11 +492,13 @@ def upsert_channel(self, channel_data: Union[ChannelInfoSchema, ChannelAPIInfoSc
490492
if hasattr(channel, key):
491493
setattr(channel, key, value)
492494
channel.last_update = datetime.now().replace(microsecond=0)
495+
channel.list_name = channels_list_name
493496
else:
494497
# Create a new channel
495498
new_channel_data = {key: value for key, value in channel_dict.items() if hasattr(Channel, key)}
496499
new_channel_data["last_update"] = datetime.now().replace(microsecond=0)
497500
channel = Channel(**new_channel_data)
501+
channel.list_name = channels_list_name
498502
self._session.add(channel)
499503

500504
# Commit the transaction

0 commit comments

Comments
 (0)