from app.config import settings from app.models import Cloud, CloudType, Profile, User from app.schemas import ( CloudOut, CloudOwnerOut, CloudTypeOut, CloudTypeSummary, ProfileOut, PublicProfileOut, UserOut, ) def media_url(path: str | None) -> str | None: if not path: return None return f"{settings.media_base_url}/{path.lstrip('/')}" def profile_out(profile: Profile) -> ProfileOut: return ProfileOut( id=profile.id, username=profile.username, avatar_url=media_url(profile.avatar_path), role=profile.role, is_disabled=profile.is_disabled, created_at=profile.created_at, ) def public_profile_out(profile: Profile) -> PublicProfileOut: return PublicProfileOut( id=profile.id, username=profile.username, avatar_url=media_url(profile.avatar_path), created_at=profile.created_at, ) def user_out(user: User) -> UserOut: return UserOut( id=user.id, email=user.email, email_verified=user.email_verified_at is not None, created_at=user.created_at, ) def cloud_type_summary(cloud_type: CloudType) -> CloudTypeSummary: return CloudTypeSummary( id=cloud_type.id, name=cloud_type.name, name_en=cloud_type.name_en, rarity=cloud_type.rarity, ) def cloud_type_out(cloud_type: CloudType) -> CloudTypeOut: return CloudTypeOut( id=cloud_type.id, name=cloud_type.name, name_en=cloud_type.name_en, genus=cloud_type.genus, rarity=cloud_type.rarity, description=cloud_type.description, icon_url=cloud_type.icon_url, created_at=cloud_type.created_at, ) def cloud_out(cloud: Cloud, *, include_private: bool = True) -> CloudOut: cloud_type = cloud.cloud_type profile = cloud.user.profile type_name = cloud_type.name if cloud_type else (cloud.custom_cloud_type or "未知") rarity = cloud_type.rarity if cloud_type else "common" return CloudOut( id=cloud.id, user_id=cloud.user_id, cloud_type_id=cloud.cloud_type_id, custom_cloud_type=cloud.custom_cloud_type, image_url=media_url(cloud.image_path) or "", thumbnail_url=media_url(cloud.thumbnail_path) or "", latitude=float(cloud.latitude) if cloud.latitude is not None else None, longitude=float(cloud.longitude) if cloud.longitude is not None else None, location_name=cloud.location_name, description=cloud.description, captured_at=cloud.captured_at, status=cloud.status if include_private else "approved", is_hidden=cloud.is_hidden if include_private else False, created_at=cloud.created_at, updated_at=cloud.updated_at, cloud_type=cloud_type_summary(cloud_type) if cloud_type else None, owner=CloudOwnerOut(id=profile.id, username=profile.username), cloud_type_name=type_name, cloud_type_rarity=rarity, username=profile.username, )