Coverage for src / rendercv / schema / models / settings / settings.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-25 13:49 +0000

1import datetime 

2from typing import Literal 

3 

4import pydantic 

5 

6from ..base import BaseModelWithoutExtraKeys 

7from .render_command import RenderCommand 

8 

9 

10class Settings(BaseModelWithoutExtraKeys): 

11 current_date: datetime.date | Literal["today"] = pydantic.Field( 

12 default="today", 

13 title="Date", 

14 description=( 

15 'The date to use as "current date" for filenames, the "last updated" label,' 

16 " and time span calculations. Defaults to the actual current date." 

17 ), 

18 ) 

19 render_command: RenderCommand = pydantic.Field( 

20 default_factory=RenderCommand, 

21 title="Render Command Settings", 

22 description=( 

23 "Settings for the `render` command. These correspond to command-line" 

24 " arguments. CLI arguments take precedence over these settings." 

25 ), 

26 ) 

27 bold_keywords: list[str] = pydantic.Field( 

28 default=[], 

29 title="Bold Keywords", 

30 description="Keywords to automatically bold in the output.", 

31 ) 

32 pdf_title: str = pydantic.Field( 

33 default="NAME - CV", 

34 title="PDF Title", 

35 description=( 

36 "Title metadata for the PDF document. This appears in browser tabs and" 

37 " PDF readers. Available placeholders:\n" 

38 "- `NAME`: The CV owner's name from `cv.name`\n" 

39 "- `CURRENT_DATE`: Formatted date based on" 

40 " `design.templates.single_date`\n" 

41 "- `MONTH_NAME`: Full month name (e.g., January)\n" 

42 "- `MONTH_ABBREVIATION`: Abbreviated month name (e.g., Jan)\n" 

43 "- `MONTH`: Month number (e.g., 1)\n" 

44 "- `MONTH_IN_TWO_DIGITS`: Zero-padded month (e.g., 01)\n" 

45 "- `DAY`: Day of the month (e.g., 5)\n" 

46 "- `DAY_IN_TWO_DIGITS`: Zero-padded day (e.g., 05)\n" 

47 "- `YEAR`: Full year (e.g., 2025)\n" 

48 "- `YEAR_IN_TWO_DIGITS`: Two-digit year (e.g., 25)\n\n" 

49 "The default value is `NAME - CV`." 

50 ), 

51 ) 

52 _resolved_current_date: datetime.date = pydantic.PrivateAttr() 

53 

54 @pydantic.field_validator("bold_keywords") 

55 @classmethod 

56 def keep_unique_keywords(cls, value: list[str]) -> list[str]: 

57 """Remove duplicate keywords from bold list. 

58 

59 Why: 

60 Users might accidentally list same keyword multiple times. Deduplication 

61 prevents redundant bold highlighting operations during rendering. 

62 

63 Args: 

64 value: List of keywords potentially with duplicates. 

65 

66 Returns: 

67 List with unique keywords only. 

68 """ 

69 return list(dict.fromkeys(value)) 

70 

71 @pydantic.model_validator(mode="after") 

72 def resolve_current_date(self) -> "Settings": 

73 self._resolved_current_date = ( 

74 datetime.date.today() if self.current_date == "today" else self.current_date 

75 ) 

76 return self