Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions slack_sdk/models/blocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
from .block_elements import StaticSelectElement
from .block_elements import UserMultiSelectElement
from .block_elements import UserSelectElement
from .block_elements import RichTextElement
from .block_elements import RichTextElementParts
from .block_elements import RichTextListElement
from .block_elements import RichTextPreformattedElement
from .block_elements import RichTextQuoteElement
from .block_elements import RichTextSectionElement
from .blocks import ActionsBlock
from .blocks import Block
from .blocks import CallBlock
Expand All @@ -54,6 +60,7 @@
from .blocks import InputBlock
from .blocks import SectionBlock
from .blocks import VideoBlock
from .blocks import RichTextBlock

__all__ = [
"ButtonStyles",
Expand Down Expand Up @@ -93,6 +100,12 @@
"StaticSelectElement",
"UserMultiSelectElement",
"UserSelectElement",
"RichTextElement",
"RichTextElementParts",
"RichTextListElement",
"RichTextPreformattedElement",
"RichTextQuoteElement",
"RichTextSectionElement",
"ActionsBlock",
"Block",
"CallBlock",
Expand All @@ -104,4 +117,5 @@
"InputBlock",
"SectionBlock",
"VideoBlock",
"RichTextBlock",
]
306 changes: 306 additions & 0 deletions slack_sdk/models/blocks/block_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -1834,3 +1834,309 @@ def __init__(
self.workflow = workflow
self.style = style
self.accessibility_label = accessibility_label


# -------------------------------------------------
# Rich text elements
# -------------------------------------------------


class RichTextElement(BlockElement):
pass


class RichTextListElement(RichTextElement):
type = "rich_text_list"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"elements", "style", "indent", "offset", "border"})

def __init__(
self,
*,
elements: Sequence[Union[dict, RichTextElement]],
style: Optional[str] = None, # bullet, ordered
indent: Optional[int] = None,
offset: Optional[int] = None,
border: Optional[int] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.elements = elements
self.style = style
self.indent = indent
self.offset = offset
self.border = border


class RichTextPreformattedElement(RichTextElement):
type = "rich_text_preformatted"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"elements", "border"})

def __init__(
self,
*,
elements: Sequence[Union[dict, RichTextElement]],
border: Optional[int] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.elements = elements
self.border = border


class RichTextQuoteElement(RichTextElement):
type = "rich_text_quote"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"elements"})

def __init__(
self,
*,
elements: Sequence[Union[dict, RichTextElement]],
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.elements = elements


class RichTextSectionElement(RichTextElement):
type = "rich_text_section"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"elements"})

def __init__(
self,
*,
elements: Sequence[Union[dict, RichTextElement]],
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.elements = elements


class RichTextElementParts:
class TextStyle:
def __init__(
self,
*,
bold: Optional[bool] = None,
italic: Optional[bool] = None,
strike: Optional[bool] = None,
code: Optional[bool] = None,
):
self.bold = bold
self.italic = italic
self.strike = strike
self.code = code

def to_dict(self, *args) -> dict:
result = {
"bold": self.bold,
"italic": self.italic,
"strike": self.strike,
"code": self.code,
}
return {k: v for k, v in result.items() if v is not None}

class Text(RichTextElement):
type = "text"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"text", "style"})

def __init__(
self,
*,
text: str,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.text = text
self.style = style

class Channel(RichTextElement):
type = "channel"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"channel_id", "style"})

def __init__(
self,
*,
channel_id: str,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.channel_id = channel_id
self.style = style

class User(RichTextElement):
type = "user"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"user_id", "style"})

def __init__(
self,
*,
user_id: str,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.user_id = user_id
self.style = style

class Emoji(RichTextElement):
type = "emoji"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"name", "skin_tone", "unicode", "style"})

def __init__(
self,
*,
name: str,
skin_tone: Optional[int] = None,
unicode: Optional[str] = None,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.name = name
self.skin_tone = skin_tone
self.unicode = unicode
self.style = style

class Link(RichTextElement):
type = "link"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"url", "text", "style"})

def __init__(
self,
*,
url: str,
text: Optional[str] = None,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.url = url
self.text = text
self.style = style

class Team(RichTextElement):
type = "team"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"team_id", "style"})

def __init__(
self,
*,
team_id: str,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.team_id = team_id
self.style = style

class UserGroup(RichTextElement):
type = "usergroup"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"usergroup_id", "style"})

def __init__(
self,
*,
usergroup_id: str,
style: Optional[Union[dict, "RichTextElementParts.TextStyle"]] = None,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.usergroup_id = usergroup_id
self.style = style

class Date(RichTextElement):
type = "date"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"timestamp"})

def __init__(
self,
*,
timestamp: str,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.timestamp = timestamp

class Broadcast(RichTextElement):
type = "broadcast"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"range"})

def __init__(
self,
*,
range: str, # channel, here, ..
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.range = range

class Color(RichTextElement):
type = "color"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"value"})

def __init__(
self,
*,
value: str,
**others: dict,
):
super().__init__(type=self.type)
show_unknown_key_warning(self, others)
self.value = value
33 changes: 32 additions & 1 deletion slack_sdk/models/blocks/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .basic_components import MarkdownTextObject
from .basic_components import PlainTextObject
from .basic_components import TextObject
from .block_elements import BlockElement
from .block_elements import BlockElement, RichTextElement
from .block_elements import ImageElement
from .block_elements import InputInteractiveElement
from .block_elements import InteractiveElement
Expand Down Expand Up @@ -604,3 +604,34 @@ def _validate_title_length(self):
@JsonValidator(f"author_name attribute cannot exceed {author_name_max_length} characters")
def _validate_author_name_length(self):
return self.author_name is None or len(self.author_name) < self.author_name_max_length


class RichTextBlock(Block):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still having an issue with the parsing of this block. Looks like it needs to be added here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tj-smith47 Thanks for pointing this out. Here is a PR to fix it: #1433 We will release a new version shortly

type = "rich_text"

@property
def attributes(self) -> Set[str]:
return super().attributes.union({"elements"})

def __init__(
self,
*,
elements: Sequence[Union[dict, RichTextElement]],
block_id: Optional[str] = None,
**others: dict,
):
"""A block that is used to hold interactive elements.
https://api.slack.com/reference/block-kit/blocks#rich_text

Args:
elements (required): An array of rich text objects -
rich_text_section, rich_text_list, rich_text_quote, rich_text_preformatted
block_id: A unique identifier for a block. If not specified, one will be generated.
Maximum length for this field is 255 characters.
block_id should be unique for each message or view and each iteration of a message or view.
If a message or view is updated, use a new block_id.
"""
super().__init__(type=self.type, block_id=block_id)
show_unknown_key_warning(self, others)

self.elements = BlockElement.parse_all(elements)
Loading