1from __future__ import annotations
 2
 3import datetime
 4from itertools import islice
 5from typing import Any
 6
 7from plain.utils.html import json_script
 8from plain.utils.timesince import timesince, timeuntil
 9from plain.utils.timezone import localtime
10
11
12def localtime_filter(
13    value: datetime.datetime | None, timezone: Any = None
14) -> datetime.datetime:
15    """Converts a datetime to local time in a template."""
16    if not value:
17        # Without this, we get the current localtime
18        # which doesn't make sense as a filter
19        raise ValueError("localtime filter requires a datetime")
20    return localtime(value, timezone)
21
22
23def pluralize_filter(value: Any, singular: str = "", plural: str = "s") -> str:
24    """Returns plural suffix based on the value count.
25
26    Usage:
27        {{ count }} item{{ count|pluralize }}
28        {{ count }} ox{{ count|pluralize("en") }}
29        {{ count }} cact{{ count|pluralize("us","i") }}
30    """
31    try:
32        count = int(value)
33    except (ValueError, TypeError):
34        return singular
35
36    if count == 1:
37        return singular
38
39    return plural
40
41
42default_filters = {
43    # The standard Python ones
44    "strftime": datetime.datetime.strftime,
45    "strptime": datetime.datetime.strptime,
46    "fromtimestamp": datetime.datetime.fromtimestamp,
47    "fromisoformat": datetime.datetime.fromisoformat,
48    # To convert to user time zone
49    "localtime": localtime_filter,
50    "timeuntil": timeuntil,
51    "timesince": timesince,
52    "json_script": json_script,
53    "islice": islice,  # slice for dict.items()
54    "pluralize": pluralize_filter,
55}