Skip to content
Closed
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
2 changes: 2 additions & 0 deletions chat_exporter/parse/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,12 @@ def parse_normal_markdown(self):
[r"__(.*?)__", '<span style="text-decoration: underline">%s</span>'],
[r"\*\*(.*?)\*\*", '<strong>%s</strong>'],
[r"\*(.*?)\*", '<em>%s</em>'],
[r"(?<!\w)_(.*?)_(?!\w)", '<em>%s</em>'],
[r"~~(.*?)~~", '<span style="text-decoration: line-through">%s</span>'],
[r"^###\s(.*?)\n", '<h3>%s</h1>'],
[r"^##\s(.*?)\n", '<h2>%s</h1>'],
[r"^#\s(.*?)\n", '<h1>%s</h1>'],
[r"^-#\s(.*?)\n", '<small>%s</small>'],
[r"\|\|(.*?)\|\|", '<span class="spoiler spoiler--hidden" onclick="showSpoiler(event, this)"> <span '
'class="spoiler-text">%s</span></span>'],
)
Expand Down
29 changes: 23 additions & 6 deletions chat_exporter/parse/mention.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,29 @@ async def time_mention(self):
match = re.search(regex, self.content)
while match is not None:
timestamp = int(match.group(1)) - 1
time_stamp = time.gmtime(timestamp)
datetime_stamp = datetime.datetime(2010, *time_stamp[1:6], tzinfo=pytz.utc)
ui_time = datetime_stamp.strftime(strf)
ui_time = ui_time.replace(str(datetime_stamp.year), str(time_stamp[0]))
tooltip_time = datetime_stamp.strftime("%A, %e %B %Y at %H:%M")
tooltip_time = tooltip_time.replace(str(datetime_stamp.year), str(time_stamp[0]))
try:
time_stamp = time.gmtime(timestamp)
datetime_stamp = datetime.datetime(2010, *time_stamp[1:6], tzinfo=pytz.utc)
ui_time = datetime_stamp.strftime(strf)
ui_time = ui_time.replace(str(datetime_stamp.year), str(time_stamp[0]))
tooltip_time = datetime_stamp.strftime("%A, %e %B %Y at %H:%M")
tooltip_time = tooltip_time.replace(str(datetime_stamp.year), str(time_stamp[0]))
except (OSError, OverflowError, ValueError):
# overflow error occurs when timestamp is too large, manual parsing
CYCLE_SECONDS = 12_622_780_800 # Exactly 400 years in seconds
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The constant CYCLE_SECONDS is defined inside the exception handler, which means it will be redefined every time an overflow occurs. Consider moving this constant to the class level (e.g., as a class variable in ParseMention) or module level for better performance and code organization. For example, add CYCLE_SECONDS = 12_622_780_800 near the top of the class definition alongside other constants like REGEX_TIME_HOLDER.

Copilot uses AI. Check for mistakes.
# Project the timestamp into a safe range that doesn't cause issues with system or python limitations
# Strip out 400-year chunks until the timestamp fits in Python's logic
safe_ts = timestamp % CYCLE_SECONDS
years_shifted = (timestamp // CYCLE_SECONDS) * 400
# Create the datetime object using the safe timestamp
dt = datetime.datetime.fromtimestamp(safe_ts, pytz.utc)
# Format normally, but inject the real year calculation
final_year = dt.year + years_shifted
ui_time = dt.strftime(strf)
ui_time = ui_time.replace(str(dt.year), str(final_year))
tooltip_time = dt.strftime("%A, %e %B %Y at %H:%M")
tooltip_time = tooltip_time.replace(str(dt.year), str(final_year))

original = match.group().replace("&lt;", "<").replace("&gt;", ">")
replacement = (
f'<span class="unix-timestamp" data-timestamp="{tooltip_time}" raw-content="{original}">'
Expand Down
Loading