Skip to content

PostBuilder

boostylib.builders.post_builder.PostBuilder

Fluent builder for constructing PostCreateRequest.

Example::

post = (
    PostBuilder()
    .title("My Post")
    .text("Hello, world!")
    .image(url="https://example.com/img.png")
    .access_level(level_id="abc123")
    .tags(["devlog", "update"])
    .build()
)
Source code in src/boostylib/builders/post_builder.py
class PostBuilder:
    """Fluent builder for constructing PostCreateRequest.

    Example::

        post = (
            PostBuilder()
            .title("My Post")
            .text("Hello, world!")
            .image(url="https://example.com/img.png")
            .access_level(level_id="abc123")
            .tags(["devlog", "update"])
            .build()
        )
    """

    def __init__(self) -> None:
        self._title: str | None = None
        self._content: list[ContentBlock] = []
        self._access_type: PostAccess = PostAccess.FREE
        self._access_level_id: str | None = None
        self._min_donation_amount: int | None = None
        self._min_donation_currency: str = "RUB"
        self._tags: list[str] = []
        self._teaser: str | None = None
        self._scheduled_at: datetime | None = None

    def title(self, title: str) -> Self:
        """Set the post title."""
        self._title = title
        return self

    def text(self, content: str) -> Self:
        """Add a text content block."""
        self._content.append(ContentBlock(type=ContentType.TEXT, content=content))
        return self

    def image(
        self,
        *,
        url: str | None = None,
        file_path: str | None = None,
        media_id: str | None = None,
    ) -> Self:
        """Add an image content block."""
        self._content.append(ContentBlock(type=ContentType.IMAGE, url=url or media_id or file_path))
        return self

    def video(self, *, url: str | None = None, media_id: str | None = None) -> Self:
        """Add a video content block."""
        self._content.append(ContentBlock(type=ContentType.VIDEO, url=url or media_id))
        return self

    def audio(self, *, url: str | None = None, media_id: str | None = None) -> Self:
        """Add an audio content block."""
        self._content.append(ContentBlock(type=ContentType.AUDIO, url=url or media_id))
        return self

    def file(
        self,
        *,
        media_id: str | None = None,
        filename: str | None = None,
        size: int | None = None,
        file_path: str | None = None,
    ) -> Self:
        """Add a file content block."""
        self._content.append(
            ContentBlock(
                type=ContentType.FILE,
                url=media_id or file_path,
                content=filename,
            )
        )
        return self

    def link(self, *, url: str, title: str | None = None) -> Self:
        """Add a link content block."""
        self._content.append(ContentBlock(type=ContentType.LINK, url=url, content=title))
        return self

    def free(self) -> Self:
        """Set post as free for everyone."""
        self._access_type = PostAccess.FREE
        self._access_level_id = None
        self._min_donation_amount = None
        return self

    def access_level(self, *, level_id: str) -> Self:
        """Restrict post to a subscription level and above."""
        self._access_type = PostAccess.SUBSCRIPTION
        self._access_level_id = level_id
        return self

    def minimum_donation(self, *, amount: int, currency: str = "RUB") -> Self:
        """Restrict post to users who donated at least the specified amount."""
        self._access_type = PostAccess.DONATION
        self._min_donation_amount = amount
        self._min_donation_currency = currency
        return self

    def subscribers_only(self) -> Self:
        """Restrict post to any subscribers (any paid level)."""
        self._access_type = PostAccess.SUBSCRIPTION
        return self

    def tags(self, tags: list[str]) -> Self:
        """Set post tags."""
        self._tags = tags
        return self

    def teaser(self, text: str) -> Self:
        """Set teaser text shown to non-subscribers."""
        self._teaser = text
        return self

    def scheduled_at(self, dt: datetime) -> Self:
        """Schedule the post for later publication."""
        self._scheduled_at = dt
        return self

    def build(self) -> PostCreateRequest:
        """Build the PostCreateRequest.

        Raises:
            ValueError: If title or content is missing.
        """
        if not self._title:
            raise ValueError("Post title is required")
        if not self._content:
            raise ValueError("Post must have at least one content block")

        return PostCreateRequest(
            title=self._title,
            content=self._content,
            access_type=self._access_type,
            access_level_id=self._access_level_id,
            minimum_donation_amount=self._min_donation_amount,
            minimum_donation_currency=self._min_donation_currency,
            tags=self._tags,
            teaser=self._teaser,
            scheduled_at=self._scheduled_at,
        )

__init__()

Source code in src/boostylib/builders/post_builder.py
def __init__(self) -> None:
    self._title: str | None = None
    self._content: list[ContentBlock] = []
    self._access_type: PostAccess = PostAccess.FREE
    self._access_level_id: str | None = None
    self._min_donation_amount: int | None = None
    self._min_donation_currency: str = "RUB"
    self._tags: list[str] = []
    self._teaser: str | None = None
    self._scheduled_at: datetime | None = None

title(title)

Set the post title.

Source code in src/boostylib/builders/post_builder.py
def title(self, title: str) -> Self:
    """Set the post title."""
    self._title = title
    return self

text(content)

Add a text content block.

Source code in src/boostylib/builders/post_builder.py
def text(self, content: str) -> Self:
    """Add a text content block."""
    self._content.append(ContentBlock(type=ContentType.TEXT, content=content))
    return self

image(*, url=None, file_path=None, media_id=None)

Add an image content block.

Source code in src/boostylib/builders/post_builder.py
def image(
    self,
    *,
    url: str | None = None,
    file_path: str | None = None,
    media_id: str | None = None,
) -> Self:
    """Add an image content block."""
    self._content.append(ContentBlock(type=ContentType.IMAGE, url=url or media_id or file_path))
    return self

video(*, url=None, media_id=None)

Add a video content block.

Source code in src/boostylib/builders/post_builder.py
def video(self, *, url: str | None = None, media_id: str | None = None) -> Self:
    """Add a video content block."""
    self._content.append(ContentBlock(type=ContentType.VIDEO, url=url or media_id))
    return self

audio(*, url=None, media_id=None)

Add an audio content block.

Source code in src/boostylib/builders/post_builder.py
def audio(self, *, url: str | None = None, media_id: str | None = None) -> Self:
    """Add an audio content block."""
    self._content.append(ContentBlock(type=ContentType.AUDIO, url=url or media_id))
    return self

file(*, media_id=None, filename=None, size=None, file_path=None)

Add a file content block.

Source code in src/boostylib/builders/post_builder.py
def file(
    self,
    *,
    media_id: str | None = None,
    filename: str | None = None,
    size: int | None = None,
    file_path: str | None = None,
) -> Self:
    """Add a file content block."""
    self._content.append(
        ContentBlock(
            type=ContentType.FILE,
            url=media_id or file_path,
            content=filename,
        )
    )
    return self

Add a link content block.

Source code in src/boostylib/builders/post_builder.py
def link(self, *, url: str, title: str | None = None) -> Self:
    """Add a link content block."""
    self._content.append(ContentBlock(type=ContentType.LINK, url=url, content=title))
    return self

free()

Set post as free for everyone.

Source code in src/boostylib/builders/post_builder.py
def free(self) -> Self:
    """Set post as free for everyone."""
    self._access_type = PostAccess.FREE
    self._access_level_id = None
    self._min_donation_amount = None
    return self

access_level(*, level_id)

Restrict post to a subscription level and above.

Source code in src/boostylib/builders/post_builder.py
def access_level(self, *, level_id: str) -> Self:
    """Restrict post to a subscription level and above."""
    self._access_type = PostAccess.SUBSCRIPTION
    self._access_level_id = level_id
    return self

minimum_donation(*, amount, currency='RUB')

Restrict post to users who donated at least the specified amount.

Source code in src/boostylib/builders/post_builder.py
def minimum_donation(self, *, amount: int, currency: str = "RUB") -> Self:
    """Restrict post to users who donated at least the specified amount."""
    self._access_type = PostAccess.DONATION
    self._min_donation_amount = amount
    self._min_donation_currency = currency
    return self

subscribers_only()

Restrict post to any subscribers (any paid level).

Source code in src/boostylib/builders/post_builder.py
def subscribers_only(self) -> Self:
    """Restrict post to any subscribers (any paid level)."""
    self._access_type = PostAccess.SUBSCRIPTION
    return self

tags(tags)

Set post tags.

Source code in src/boostylib/builders/post_builder.py
def tags(self, tags: list[str]) -> Self:
    """Set post tags."""
    self._tags = tags
    return self

teaser(text)

Set teaser text shown to non-subscribers.

Source code in src/boostylib/builders/post_builder.py
def teaser(self, text: str) -> Self:
    """Set teaser text shown to non-subscribers."""
    self._teaser = text
    return self

scheduled_at(dt)

Schedule the post for later publication.

Source code in src/boostylib/builders/post_builder.py
def scheduled_at(self, dt: datetime) -> Self:
    """Schedule the post for later publication."""
    self._scheduled_at = dt
    return self

build()

Build the PostCreateRequest.

Raises:

Type Description
ValueError

If title or content is missing.

Source code in src/boostylib/builders/post_builder.py
def build(self) -> PostCreateRequest:
    """Build the PostCreateRequest.

    Raises:
        ValueError: If title or content is missing.
    """
    if not self._title:
        raise ValueError("Post title is required")
    if not self._content:
        raise ValueError("Post must have at least one content block")

    return PostCreateRequest(
        title=self._title,
        content=self._content,
        access_type=self._access_type,
        access_level_id=self._access_level_id,
        minimum_donation_amount=self._min_donation_amount,
        minimum_donation_currency=self._min_donation_currency,
        tags=self._tags,
        teaser=self._teaser,
        scheduled_at=self._scheduled_at,
    )