Skip to content

Commit

Permalink
Fix #1428 Add rich_text classes to slack_sdk.models module (#1431)
Browse files Browse the repository at this point in the history
  • Loading branch information
seratch authored Nov 21, 2023
1 parent 3e2d7e8 commit 750d97c
Show file tree
Hide file tree
Showing 4 changed files with 574 additions and 1 deletion.
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):
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

0 comments on commit 750d97c

Please sign in to comment.