Coverage for src/data_api/models/libraries.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-11-13 19:28 +0000

1"""Shared library feed and live response models.""" 

2 

3from enum import Enum 

4from typing import Annotated, Optional 

5from urllib.parse import urlsplit, urlunsplit 

6 

7from pydantic import BaseModel, BeforeValidator, Field, HttpUrl 

8 

9from data_api.utils.schema import url_corrector 

10 

11 

12def rss_image_url_corrector(value: object) -> object: 

13 value = url_corrector(value) 

14 if isinstance(value, str): 

15 parts = urlsplit(value) 

16 return urlunsplit(parts._replace(path=parts.path.replace(" ", "%20"))) 

17 return value 

18 

19 

20class LibraryRssImage(BaseModel): 

21 url: Optional[Annotated[HttpUrl, BeforeValidator(rss_image_url_corrector)]] = Field( 

22 None, description="圖片網址" 

23 ) 

24 title: Optional[str] = Field(None, description="圖片標題") 

25 link: Optional[Annotated[HttpUrl, BeforeValidator(url_corrector)]] = Field( 

26 None, description="連結" 

27 ) 

28 

29 

30class LibraryRssItem(BaseModel): 

31 guid: Optional[str] = Field(None, description="文章 id") 

32 category: Optional[str] = Field(None, description="文章分類") 

33 title: str = Field(..., description="文章標題") 

34 link: Optional[str] = Field(None, description="文章連結文字,可能包含多個網址") 

35 pubDate: Optional[str] = Field(None, description="文章發布日期") 

36 description: str = Field(..., description="文章內容") 

37 author: Optional[str] = Field(None, description="文章作者") 

38 image: Optional[LibraryRssImage] = Field(None, description="文章圖片") 

39 

40 

41class LibraryRssData(BaseModel): 

42 title: Optional[str] = Field(None, description="電子報標題") 

43 link: Annotated[HttpUrl, BeforeValidator(url_corrector)] = Field(..., description="電子報網址") 

44 date: Optional[str] = Field(None, description="發布日期") 

45 

46 

47class LibraryRssType(str, Enum): 

48 news = "news" 

49 eresources = "eresources" 

50 exhibit = "exhibit" 

51 branches = "branches" 

52 

53 

54class LibrarySpace(BaseModel): 

55 spacetype: int = Field(..., description="空間類型") 

56 spacetypename: str = Field(..., description="空間類型名稱") 

57 zoneid: str = Field(..., description="區域代號") 

58 zonename: str = Field(..., description="區域名稱") 

59 count: int = Field(..., description="空間剩餘數量") 

60 

61 

62class LibraryLostAndFound(BaseModel): 

63 序號: str = Field(..., description="序號") 

64 拾獲時間: str = Field(..., description="拾獲日期") 

65 拾獲地點: str = Field(..., description="拾獲地點") 

66 描述: str = Field(..., description="物品描述")