1
1
from .env import env
2
+ from slack_sdk import WebClient
3
+ from urllib .parse import quote
2
4
3
5
import re
6
+ import mistune
4
7
5
- from slack_sdk import WebClient
6
8
7
9
client = WebClient (token = env .slack_bot_token )
8
-
10
+ ZWSP = ' \u200B '
9
11
10
12
def user_in_safehouse (user_id : str ):
11
13
sad_members = client .conversations_members (channel = env .slack_sad_channel )["members" ]
@@ -18,17 +20,36 @@ def parse_elements(elements):
18
20
if element ["type" ] == "text" :
19
21
text = element ["text" ]
20
22
if "style" in element :
21
- if element ["style" ].get ("bold" ):
23
+ styles = element ["style" ]
24
+ if styles .get ("bold" ) and styles .get ("italic" ):
25
+ text = f"**_{ text } _**"
26
+ elif styles .get ("bold" ):
22
27
text = f"**{ text } **"
23
- if element [ "style" ] .get ("italic" ):
24
- text = f"* { text } * "
25
- if element [ "style" ] .get ("strike" ):
28
+ elif styles .get ("italic" ):
29
+ text = f"_ { text } _ "
30
+ if styles .get ("strike" ):
26
31
text = f"~~{ text } ~~"
27
- if element [ "style" ] .get ("code" ):
32
+ if styles .get ("code" ):
28
33
text = f"`{ text } `"
29
34
markdown += text
30
35
elif element ["type" ] == "link" :
31
36
markdown += f"[{ element ['text' ]} ]({ element ['url' ]} )"
37
+ elif element ["type" ] == "user" :
38
+ markdown += f"<@{ element ['user_id' ]} >"
39
+ elif element ["type" ] == "emoji" :
40
+ markdown += f":{ element ['name' ]} :"
41
+ elif element ["type" ] == "channel" :
42
+ markdown += f"<#{ element ['channel_id' ]} >"
43
+ elif element ["type" ] == "subteam" :
44
+ markdown += f"<!subteam^{ element ['subteam_id' ]} |{ element ['name' ]} >"
45
+ elif element ["type" ] == "date" :
46
+ markdown += f"<!date^{ element ['timestamp' ]} ^{ element ['format' ]} |{ element ['fallback' ]} >"
47
+ elif element ["type" ] == "url" :
48
+ markdown += f"<{ element ['url' ]} >"
49
+ elif element ["type" ] == "line_break" :
50
+ markdown += "\n "
51
+ elif element ["type" ] == "usergroup" :
52
+ markdown += f"<!subteam^{ element ['usergroup_id' ]} >"
32
53
return markdown
33
54
34
55
@@ -59,26 +80,65 @@ def rich_text_to_md(input_data, indent_level=0, in_quote=False):
59
80
return markdown
60
81
61
82
62
- def md_to_mrkdwn (md ):
63
- # Convert bold and italic text (bold first to avoid conflicts)
64
- md = re .sub (r"\*\*\*(.*?)\*\*\*" , r"***\1***" , md ) # Bold and italic
65
- md = re .sub (r"\*\*(.*?)\*\*" , r"*\1*" , md ) # Bold
66
- md = re .sub (r"\b\*(.*?)\*\b" , r"_\1_" , md ) # Italic
67
- # Convert strikethrough text
68
- md = re .sub (r"~~(.*?)~~" , r"~\1~" , md )
69
- # Convert inline code
70
- md = re .sub (r"`(.*?)`" , r"`\1`" , md )
71
- # Convert links
72
- md = re .sub (r"\[(.*?)\]\((.*?)\)" , r"<\2|\1>" , md )
73
- # Convert blockquotes
74
- md = re .sub (r"^> (.*)" , r"> \1" , md , flags = re .MULTILINE )
75
- # Convert code blocks
76
- md = re .sub (r"```(.*?)```" , r"```\1```" , md , flags = re .DOTALL )
77
- # Convert unordered lists
78
- md = re .sub (r"^\s*-\s+(.*)" , r"• \1" , md , flags = re .MULTILINE )
79
- # Convert ordered lists
80
- md = re .sub (r"^\s*\d+\.\s+(.*)" , r"1. \1" , md , flags = re .MULTILINE )
81
- # Handle nested lists
82
- md = re .sub (r"(\n\s*)•" , r"\1 •" , md )
83
- md = re .sub (r"(\n\s*)1\." , r"\1 1." , md )
84
- return md
83
+ def parse_elements_to_mrkdwn (elements ):
84
+ mrkdwn = ""
85
+ for element in elements :
86
+ if element ["type" ] == "text" :
87
+ text = element ["text" ]
88
+ if "style" in element :
89
+ styles = element ["style" ]
90
+ words = re .split (r'(\s+)' , text ) # Split by whitespace but keep the whitespace
91
+ formatted_words = []
92
+ for word in words :
93
+ if word .strip (): # Only apply formatting to non-whitespace words
94
+ if styles .get ("bold" ) and styles .get ("italic" ):
95
+ word = f"*_{ word .strip ()} _*"
96
+ elif styles .get ("bold" ):
97
+ word = f"*{ word .strip ()} *"
98
+ elif styles .get ("italic" ):
99
+ word = f"_{ word .strip ()} _"
100
+ if styles .get ("strike" ):
101
+ word = f"~{ word .strip ()} ~"
102
+ if styles .get ("code" ):
103
+ word = f"`{ word .strip ()} `"
104
+ formatted_words .append (word )
105
+ text = "" .join (formatted_words ) # Join without adding extra spaces
106
+ mrkdwn += text
107
+ elif element ["type" ] == "link" :
108
+ mrkdwn += f"<{ element ['url' ]} |{ element ['text' ]} >"
109
+ elif element ["type" ] == "user" :
110
+ mrkdwn += f"<@{ element ['user_id' ]} >"
111
+ elif element ["type" ] == "emoji" :
112
+ mrkdwn += f":{ element ['name' ]} :"
113
+ elif element ["type" ] == "channel" :
114
+ mrkdwn += f"<#{ element ['channel_id' ]} >"
115
+ elif element ["type" ] == "subteam" :
116
+ mrkdwn += f"<!subteam^{ element ['subteam_id' ]} |{ element ['name' ]} >"
117
+ elif element ["type" ] == "date" :
118
+ mrkdwn += f"<!date^{ element ['timestamp' ]} ^{ element ['format' ]} |{ element ['fallback' ]} >"
119
+ elif element ["type" ] == "url" :
120
+ mrkdwn += f"<{ element ['url' ]} >"
121
+ elif element ["type" ] == "line_break" :
122
+ mrkdwn += "\n "
123
+ elif element ["type" ] == "usergroup" :
124
+ mrkdwn += f"<!subteam^{ element ['usergroup_id' ]} >"
125
+ return mrkdwn
126
+
127
+ def rich_text_to_mrkdwn (data ):
128
+ mrkdwn = ""
129
+ for block in data :
130
+ if isinstance (block , dict ) and block ["type" ] == "rich_text_section" :
131
+ mrkdwn += parse_elements_to_mrkdwn (block ["elements" ]) + "\n "
132
+ elif isinstance (block , dict ) and block ["type" ] == "rich_text_quote" :
133
+ mrkdwn += "> " + parse_elements_to_mrkdwn (block ["elements" ]) + "\n "
134
+ # Handle nested lists within quotes
135
+ mrkdwn += rich_text_to_mrkdwn (block ["elements" ])
136
+ elif isinstance (block , dict ) and block ["type" ] == "rich_text_preformatted" :
137
+ mrkdwn += "```\n " + parse_elements_to_mrkdwn (block ["elements" ]) + "\n ```\n "
138
+ elif isinstance (block , dict ) and block ["type" ] == "rich_text_list" :
139
+ for item in block ["elements" ]:
140
+ mrkdwn += f"- { parse_elements_to_mrkdwn (item ['elements' ])} \n "
141
+ # Recursively parse nested lists
142
+ if "elements" in item :
143
+ mrkdwn += rich_text_to_mrkdwn (item ["elements" ])
144
+ return mrkdwn
0 commit comments