feat(bot): Коммит — навигация по дереву репозитория загрузок
- UploadsRepo: локальный клон, fetch не чаще fetch_interval, ls-tree -z (пробелы/кириллица), cat-file, последний коммит по пути; git без shell, ssh с -F /dev/null (без конфига хоста) - «📝 Коммит»: папки/файлы с размерами, ⬆️ Вверх, страницы по 20, карточка файла с последним коммитом, «👁 Показать» (<pre> или документом); в кнопках только индексы - ключ для контейнера: GIT_SSH_KEY_B64 → временный файл 0600 (смонтированный файл хоста контейнерному uid не прочитать); volume /data для клона - тесты на настоящем bare-репозитории во временной папке Refs #8 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+5
-3
@@ -10,25 +10,27 @@ from app import __version__
|
||||
from app.access.service import AccessService
|
||||
from app.bot.fsm import make_storage
|
||||
from app.bot.middlewares.access import AccessMiddleware
|
||||
from app.bot.routers import common, members
|
||||
from app.bot.routers import commit, common, members
|
||||
from app.config import Settings
|
||||
from app.db.maintenance import cleanup_loop
|
||||
from app.db.migrate import upgrade
|
||||
from app.db.session import SessionMaker, make_engine, make_sessionmaker
|
||||
from app.health import heartbeat
|
||||
from app.logs_setup import setup_logging
|
||||
from app.repo.git import UploadsRepo
|
||||
from app.texts import Texts, load_texts
|
||||
|
||||
log = logging.getLogger("tgit")
|
||||
|
||||
|
||||
def build_dispatcher(texts: Texts, sessions: SessionMaker, access: AccessService) -> Dispatcher:
|
||||
def build_dispatcher(texts: Texts, sessions: SessionMaker, access: AccessService, repo: UploadsRepo) -> Dispatcher:
|
||||
dp = Dispatcher(storage=make_storage(sessions))
|
||||
gate = AccessMiddleware(access, texts)
|
||||
# Outer middleware: runs before filters, so nothing — not even a stale button — reaches a handler unchecked.
|
||||
dp.message.outer_middleware(gate)
|
||||
dp.callback_query.outer_middleware(gate)
|
||||
dp.include_router(members.build_router(texts, access))
|
||||
dp.include_router(commit.build_router(texts, repo))
|
||||
dp.include_router(common.build_router(texts, access))
|
||||
return dp
|
||||
|
||||
@@ -40,7 +42,7 @@ async def run(settings: Settings) -> None:
|
||||
sessions = make_sessionmaker(engine)
|
||||
access = AccessService(sessions, settings.access)
|
||||
await access.bootstrap_admins()
|
||||
dp = build_dispatcher(texts, sessions, access)
|
||||
dp = build_dispatcher(texts, sessions, access, UploadsRepo(settings.git))
|
||||
rt = settings.runtime
|
||||
background = [
|
||||
asyncio.create_task(heartbeat(rt.heartbeat_file, rt.heartbeat_interval)),
|
||||
|
||||
Reference in New Issue
Block a user