150 lines
4.6 KiB
Python
150 lines
4.6 KiB
Python
import json
|
|
from uuid import uuid4
|
|
|
|
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
|
|
from pydantic import BaseModel
|
|
|
|
from backend.app.api.dependencies import get_current_user
|
|
from backend.app.database import AVATARS_DIR, get_connection
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class UserConfigUpdate(BaseModel):
|
|
email: str | None = None
|
|
bio: str | None = None
|
|
|
|
|
|
class UserPluginConfigUpdate(BaseModel):
|
|
instance: str | None = None
|
|
access_token: str | None = None
|
|
post_prefix: str | None = None
|
|
hashtag: str | None = None
|
|
|
|
|
|
@router.get('/me')
|
|
def get_current_user_profile(user: dict = Depends(get_current_user)):
|
|
with get_connection() as conn:
|
|
row = conn.execute(
|
|
'SELECT * FROM users WHERE id = ?',
|
|
(user['id'],),
|
|
).fetchone()
|
|
if row is None:
|
|
raise HTTPException(status_code=404, detail='User not found')
|
|
return dict(row)
|
|
|
|
|
|
@router.put('/me')
|
|
def update_current_user_profile(
|
|
payload: UserConfigUpdate,
|
|
user: dict = Depends(get_current_user),
|
|
):
|
|
with get_connection() as conn:
|
|
current = conn.execute('SELECT * FROM users WHERE id = ?', (user['id'],)).fetchone()
|
|
if current is None:
|
|
raise HTTPException(status_code=404, detail='User not found')
|
|
|
|
email = payload.email or current['email']
|
|
bio = payload.bio if payload.bio is not None else current['bio']
|
|
|
|
conn.execute(
|
|
'''
|
|
UPDATE users
|
|
SET email = ?, bio = ?, updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = ?
|
|
''',
|
|
(email, bio, user['id']),
|
|
)
|
|
conn.commit()
|
|
|
|
return {'status': 'updated'}
|
|
|
|
|
|
@router.post('/avatar')
|
|
async def upload_avatar(
|
|
avatar: UploadFile = File(...),
|
|
user: dict = Depends(get_current_user),
|
|
):
|
|
allowed_types = {
|
|
'image/gif': '.gif',
|
|
'image/jpeg': '.jpg',
|
|
'image/png': '.png',
|
|
'image/webp': '.webp',
|
|
}
|
|
suffix = allowed_types.get(avatar.content_type or '')
|
|
if suffix is None:
|
|
raise HTTPException(status_code=415, detail='Avatar must be a PNG, JPEG, GIF, or WebP image')
|
|
|
|
contents = await avatar.read(2 * 1024 * 1024 + 1)
|
|
if len(contents) > 2 * 1024 * 1024:
|
|
raise HTTPException(status_code=413, detail='Avatar must be 2 MB or smaller')
|
|
|
|
avatar_path = AVATARS_DIR / f'{user["id"]}{suffix}'
|
|
for existing_path in AVATARS_DIR.glob(f'{user["id"]}.*'):
|
|
if existing_path != avatar_path:
|
|
existing_path.unlink(missing_ok=True)
|
|
avatar_path.write_bytes(contents)
|
|
avatar_url = f'/media/{avatar_path.name}'
|
|
|
|
with get_connection() as conn:
|
|
conn.execute(
|
|
'UPDATE users SET avatar_url = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
|
(avatar_url, user['id']),
|
|
)
|
|
conn.commit()
|
|
return {'avatar_url': avatar_url}
|
|
|
|
|
|
@router.get('/plugins/{plugin_name}')
|
|
def get_user_plugin_config(plugin_name: str, user: dict = Depends(get_current_user)):
|
|
with get_connection() as conn:
|
|
row = conn.execute(
|
|
'SELECT * FROM user_plugin_config WHERE user_id = ? AND plugin_name = ?',
|
|
(user['id'], plugin_name),
|
|
).fetchone()
|
|
|
|
if row is None:
|
|
return {}
|
|
|
|
config = json.loads(row['config']) if row['config'] else {}
|
|
return config
|
|
|
|
|
|
@router.put('/plugins/{plugin_name}')
|
|
def update_user_plugin_config(
|
|
plugin_name: str,
|
|
payload: UserPluginConfigUpdate,
|
|
user: dict = Depends(get_current_user),
|
|
):
|
|
with get_connection() as conn:
|
|
current = conn.execute(
|
|
'SELECT * FROM user_plugin_config WHERE user_id = ? AND plugin_name = ?',
|
|
(user['id'], plugin_name),
|
|
).fetchone()
|
|
|
|
current_config = json.loads(current['config']) if current and current['config'] else {}
|
|
updates = payload.model_dump(exclude_none=True)
|
|
merged = {**current_config, **updates}
|
|
|
|
if current is None:
|
|
conn.execute(
|
|
'''
|
|
INSERT INTO user_plugin_config (id, user_id, plugin_name, config, created_at, updated_at)
|
|
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
''',
|
|
(str(uuid4()), user['id'], plugin_name, json.dumps(merged, ensure_ascii=False)),
|
|
)
|
|
else:
|
|
conn.execute(
|
|
'''
|
|
UPDATE user_plugin_config
|
|
SET config = ?, updated_at = CURRENT_TIMESTAMP
|
|
WHERE user_id = ? AND plugin_name = ?
|
|
''',
|
|
(json.dumps(merged, ensure_ascii=False), user['id'], plugin_name),
|
|
)
|
|
|
|
conn.commit()
|
|
|
|
return merged
|