normalize project structure: rename app/ → src/, add .mise.toml, .env.example, CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-05 07:22:33 +01:00
parent fae1159536
commit 20b93df9b0
13 changed files with 54 additions and 6 deletions

2
.mise.toml Normal file
View File

@@ -0,0 +1,2 @@
[tools]
python = "3.14.2"

44
CLAUDE.md Normal file
View File

@@ -0,0 +1,44 @@
# sticker-cloner — Telegram Sticker Cloner
Telegram bot that clones sticker packs. Built with Python (FastAPI + uvicorn).
## Stack
- **Backend:** Python 3.14, FastAPI, uvicorn, tstickers, Pillow
- **Bot:** python-telegram-bot
## Project Structure
```
backend/
├── src/ ← FastAPI application
├── requirements.txt
├── deploy.sh
└── .env.example
```
## Local Development
```bash
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn src.main:app --reload --port 8080
```
## Deployment
```bash
cd backend
./deploy.sh
```
Deploys to Uberspace (`serve.uber.space`):
- Backend → `~/services/sticker-cloner/` (systemd: `sticker-cloner.service`, port 8080)
- Route: `/sticker-cloner/*` → port 8080 (prefix removed)
## Environment Variables
See `.env.example`:
- `BOT_TOKEN` — Telegram bot API token

1
backend/.env.example Normal file
View File

@@ -0,0 +1 @@
BOT_TOKEN=

1
backend/.gitignore vendored
View File

@@ -8,3 +8,4 @@ __pycache__/
.idea/ .idea/
.cache/ .cache/
.vscode/ .vscode/
.mise.local.toml

View File

@@ -44,7 +44,7 @@ Description=sticker-cloner backend
[Service] [Service]
WorkingDirectory=${REMOTE_APP_DIR} WorkingDirectory=${REMOTE_APP_DIR}
ExecStart=${REMOTE_APP_DIR}/.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port ${PORT} --root-path ${URL_PATH} ExecStart=${REMOTE_APP_DIR}/.venv/bin/uvicorn src.main:app --host 0.0.0.0 --port ${PORT} --root-path ${URL_PATH}
Restart=always Restart=always
[Install] [Install]

View File

@@ -1,7 +1,7 @@
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from app.routers import stickersets from src.routers import stickersets
app = FastAPI(title="StickerCloner API") app = FastAPI(title="StickerCloner API")

View File

@@ -1,8 +1,8 @@
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
from app.models import StickerSetResponse from src.models import StickerSetResponse
from app.services import sticker_service from src.services import sticker_service
router = APIRouter(prefix="/api/stickersets") router = APIRouter(prefix="/api/stickersets")

View File

@@ -3,8 +3,8 @@ from pathlib import Path
from tstickers.convert import Backend from tstickers.convert import Backend
from tstickers.manager import StickerManager from tstickers.manager import StickerManager
from app.config import settings from src.config import settings
from app.models import StickerResponse, StickerSetResponse from src.models import StickerResponse, StickerSetResponse
_manager: StickerManager | None = None _manager: StickerManager | None = None