Skip to content

Commit c7ea55b

Browse files
committed
PARSING WORKS OML FUCK YEAH
1 parent d7e5783 commit c7ea55b

File tree

4 files changed

+103
-37
lines changed

4 files changed

+103
-37
lines changed

events/views/create_event.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from datetime import datetime, timezone
44

55
from utils.env import env
6-
from utils.utils import rich_text_to_md, md_to_mrkdwn
6+
from utils.utils import rich_text_to_md, rich_text_to_mrkdwn
77
from views.app_home import get_home
8+
import json
89

910

1011
def handle_create_event_view(ack: Callable, body: dict[str, Any], client: WebClient):
@@ -52,7 +53,8 @@ def handle_create_event_view(ack: Callable, body: dict[str, Any], client: WebCli
5253
user_id = body.get("user", {}).get("id", "")
5354
host_mention = f"for <@{host_id}>" if host_id != user_id else ""
5455
host_str = f"<@{user_id}> {host_mention}"
55-
mrkdwn = md_to_mrkdwn(md)
56+
rich_text = json.loads(event["fields"]["Raw Description"])
57+
mrkdwn = rich_text_to_mrkdwn(rich_text)
5658
client.chat_postMessage(
5759
channel=env.slack_approval_channel,
5860
text=f"New event request by <@{body['user']['id']}>!\nTitle: {title[0]}\nDescription: {mrkdwn}\nStart Time: {start_time[0]}\nEnd Time: {end_time[0]}",

events/views/edit_event.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from datetime import datetime, timezone
44

55
from utils.env import env
6-
from utils.utils import rich_text_to_md, md_to_mrkdwn
6+
from utils.utils import rich_text_to_md, rich_text_to_mrkdwn
77
from views.app_home import get_home
88

99
import json
@@ -66,7 +66,8 @@ def handle_edit_event_view(ack: Callable, body: dict[str, Any], client: WebClien
6666
user_id = body.get("user", {}).get("id", "")
6767
host_mention = f"for <@{host_id}>" if host_id != user_id else ""
6868
host_str = f"<@{user_id}> {host_mention}"
69-
mrkdwn = md_to_mrkdwn(md)
69+
rich_text = json.loads(raw_description_string)
70+
mrkdwn = rich_text_to_mrkdwn(rich_text)
7071
client.chat_postMessage(
7172
channel=env.slack_approval_channel,
7273
text=f"New event request by <@{body['user']['id']}>!\nTitle: {title[0]}\nDescription: {mrkdwn}\nStart Time: {start_time[0]}\nEnd Time: {end_time[0]}",

utils/utils.py

Lines changed: 90 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from .env import env
2+
from slack_sdk import WebClient
3+
from urllib.parse import quote
24

35
import re
6+
import mistune
47

5-
from slack_sdk import WebClient
68

79
client = WebClient(token=env.slack_bot_token)
8-
10+
ZWSP = '\u200B'
911

1012
def user_in_safehouse(user_id: str):
1113
sad_members = client.conversations_members(channel=env.slack_sad_channel)["members"]
@@ -18,17 +20,36 @@ def parse_elements(elements):
1820
if element["type"] == "text":
1921
text = element["text"]
2022
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"):
2227
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"):
2631
text = f"~~{text}~~"
27-
if element["style"].get("code"):
32+
if styles.get("code"):
2833
text = f"`{text}`"
2934
markdown += text
3035
elif element["type"] == "link":
3136
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']}>"
3253
return markdown
3354

3455

@@ -59,26 +80,65 @@ def rich_text_to_md(input_data, indent_level=0, in_quote=False):
5980
return markdown
6081

6182

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

views/app_home.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from slack_sdk import WebClient
33

44
from utils.env import env
5-
from utils.utils import user_in_safehouse, md_to_mrkdwn
5+
from utils.utils import user_in_safehouse, rich_text_to_mrkdwn
6+
import json
67

78

89
def get_home(user_id: str, client: WebClient):
@@ -47,7 +48,8 @@ def get_home(user_id: str, client: WebClient):
4748
"Ends at %I:%M %p"
4849
)
4950
formatted_time = f"<!date^{int(datetime.fromisoformat(event['fields']['End Time']).timestamp())}^Ends at {{time}}|{fallback_time}>"
50-
mrkdwn = md_to_mrkdwn(event["fields"]["Description"])
51+
rich_text = json.loads(event["fields"]["Raw Description"])
52+
mrkdwn = rich_text_to_mrkdwn(rich_text['elements'])
5153
current_events_blocks.append(
5254
{
5355
"type": "section",
@@ -117,7 +119,8 @@ def get_home(user_id: str, client: WebClient):
117119
"%A, %B %d at %I:%M %p"
118120
)
119121
formatted_time = f"<!date^{int(datetime.fromisoformat(event['fields']['Start Time']).timestamp())}^{{date_long_pretty}} at {{time}}|{fallback_time}>"
120-
mrkdwn = md_to_mrkdwn(event["fields"]["Description"])
122+
rich_text = json.loads(event["fields"]["Raw Description"])
123+
mrkdwn = rich_text_to_mrkdwn(rich_text['elements'])
121124
upcoming_events_blocks.append(
122125
{
123126
"type": "section",

0 commit comments

Comments
 (0)