add /v1/settings/appearance, bump suou requirement

This commit is contained in:
Yusur 2025-11-01 09:54:55 +01:00
parent 41be26d484
commit d1f33afe09
4 changed files with 51 additions and 7 deletions

View file

@ -26,7 +26,7 @@ from suou import twocolon_list, WantsContentType
from .colors import color_themes, theme_classes
__version__ = '0.5.0-dev42'
__version__ = '0.5.0-dev43'
APP_BASE_DIR = os.path.dirname(os.path.dirname(__file__))

View file

@ -5,6 +5,7 @@ import enum
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from suou.sqlalchemy.asyncio import AsyncSession
from .models import User, db
from quart_auth import AuthUser, Action as _Action
@ -42,7 +43,7 @@ class UserLoader(AuthUser):
def __init__(self, auth_id: str | None, action: _Action= _Action.PASS):
self._auth_id = auth_id
self._auth_obj = None
self._auth_sess = None
self._auth_sess: AsyncSession | None = None
self.action = action
@property
@ -69,6 +70,10 @@ class UserLoader(AuthUser):
def __bool__(self):
return self._auth_obj is not None
@property
def session(self):
return self._auth_sess
async def _unload(self):
# user is not expected to mutate
if self._auth_sess:

View file

@ -1,15 +1,16 @@
from __future__ import annotations
from typing import Iterable
from typing import Iterable, TypeVar
from quart import session
from quart import abort, Blueprint, redirect, request, url_for
from pydantic import BaseModel
from quart_auth import AuthUser, current_user, login_required, login_user, logout_user
from quart_schema import QuartSchema, validate_request, validate_response
from quart_auth import current_user, login_required, login_user, logout_user
from quart_schema import validate_request, validate_response
from sqlalchemy import delete, insert, select
from suou import Snowflake, deprecated, makelist, not_implemented, want_isodate
from suou.classtools import MISSING, MissingType
from werkzeug.security import check_password_hash
from suou.quart import add_rest
@ -20,6 +21,8 @@ from freak.search import SearchQuery
from ..models import Comment, Guild, Post, PostUpvote, User, db
from .. import UserLoader, app, app_config, __version__ as freak_version, csrf
_T = TypeVar('_T')
bp = Blueprint('rest', __name__, url_prefix='/v1')
rest = add_rest(app, '/v1', '/ajax')
@ -332,7 +335,7 @@ async def search_top(data: QueryIn):
async with db as session:
sq = SearchQuery(data.query)
result: Iterable[Post] = (await session.execute(sq.select(Post, [Post.title]).limit(20))).scalars()
result = (await session.execute(sq.select(Post, [Post.title]).limit(20))).scalars()
return dict(has = [p.feed_info() for p in result])
@ -353,3 +356,39 @@ async def suggest_guild(data: QueryIn):
return dict(has = [g.simple_info() for g in result if await g.allows_posting(current_user.user)])
## SETTINGS
@bp.get("/settings/appearance")
@login_required
async def get_settings_appearance():
return dict(
color_theme = current_user.user.color_theme
)
class SettingsAppearanceIn(BaseModel):
color_theme : int | None = None
color_scheme : int | None = None
def _missing_or(obj: _T | MissingType, obj2: _T) -> _T:
if obj is None:
return obj2
return obj
@bp.patch("/settings/appearance")
@login_required
@validate_request(SettingsAppearanceIn)
async def patch_settings_appearance(data: SettingsIn):
u = current_user.user
if u is None:
abort(401)
u.color_theme = (
_missing_or(data.color_theme, u.color_theme % (1 << 8)) % 256 +
_missing_or(data.color_scheme, u.color_theme >> 8) << 8
)
current_user.session.add(u)
await current_user.session.commit()
return '', 204

View file

@ -19,7 +19,7 @@ dependencies = [
"libsass",
"setuptools>=78.1.0",
"Hypercorn",
"suou>=0.6.1"
"suou[sqlalchemy]>=0.7.5"
]
requires-python = ">=3.10"
classifiers = [