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 Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ urwid-readline = ">=0.11"
beautifulsoup4 = ">=4.9.0"
lxml = ">=4.5.2"
typing_extensions = ">=3.7"
python-dateutil = ">=2.8.1"
tzlocal = ">=2.1"

[dev-packages]
pytest = "==5.3.5"
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ isort==4.3.21
urwid_readline>=0.11
beautifulsoup4>=4.9.0
lxml>=4.5.2
python-dateutil>=2.8.1
tzlocal>=2.1

zipp==1.0.0 # To support Python 3.5
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,7 @@ def long_description():
'beautifulsoup4>=4.9.0',
'lxml>=4.5.2',
'typing_extensions>=3.7',
'python-dateutil>=2.8.1',
'tzlocal>=2.1',
],
)
17 changes: 15 additions & 2 deletions tests/ui/test_ui_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
from typing import Any, Dict

import pytest
import pytz
from bs4 import BeautifulSoup
from urwid import Columns, Divider, Padding, Text

from zulipterminal.config.keys import is_command_key, keys_for_command
from zulipterminal.config.symbols import (
QUOTED_TEXT_MARKER, STREAM_TOPIC_SEPARATOR,
QUOTED_TEXT_MARKER, STREAM_TOPIC_SEPARATOR, TIME_MENTION_MARKER,
)
from zulipterminal.helper import powerset
from zulipterminal.ui_tools.boxes import MessageBox
Expand Down Expand Up @@ -1723,6 +1724,15 @@ def test_private_message_to_self(self, mocker):
'│ ', (None, ' '), ' │\n',
'└─', '───────', '─┘',
]),
('<time datetime="2020-08-07T04:30:00Z"> Fri, Aug 7 2020, 10:00AM IST'
'</time>', [(
'msg_time',
' {} Fri, Aug 7 2020, 10:00 (IST) '.format(TIME_MENTION_MARKER)
)]),
('<time datetime="2020-08-11T16:32:58Z"> 1597163578</time>', [(
'msg_time',
' {} Tue, Aug 11 2020, 22:02 (IST) '.format(TIME_MENTION_MARKER)
)]),
('<span class="katex-display">some-math</span>', ['some-math']),
('<span class="katex">some-math</span>', ['some-math']),
('<ul><li>text</li></ul>', ['', ' \N{BULLET} ', '', 'text']),
Expand Down Expand Up @@ -1758,13 +1768,16 @@ def test_private_message_to_self(self, mocker):
'table_with_center_and_right_alignments',
'table_with_single_column',
'table_with_the_bare_minimum',
'time_human_readable_input', 'time_UNIX_timestamp_input',
'math', 'math2',
'ul', 'ul_with_ul_li_newlines',
'ol', 'ol_with_ol_li_newlines', 'ol_starting_at_5',
'strikethrough_del', 'inline_image', 'inline_ref',
'emoji', 'preview-twitter', 'zulip_extra_emoji', 'custom_emoji'
])
def test_soup2markup(self, content, markup):
def test_soup2markup(self, content, markup, mocker):
mocker.patch(BOXES + '.get_localzone',
return_value=pytz.timezone('Asia/Kolkata'))
message = dict(display_recipient=['x'], stream_id=5, subject='hi',
sender_email='[email protected]', id=4, sender_id=4209,
type='stream', # NOTE Output should not vary with PM
Expand Down
3 changes: 3 additions & 0 deletions zulipterminal/config/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
APPLICATION_TITLE_BAR_LINE = '═'
PINNED_STREAMS_DIVIDER = '-'
LIST_TITLE_BAR_LINE = '━'
# NOTE: The '⏱' emoji needs an extra space while rendering. Otherwise, it
# appears to overlap its subsequent text.
TIME_MENTION_MARKER = '⏱ ' # Other tested options are: '⧗' and '⧖'.
7 changes: 7 additions & 0 deletions zulipterminal/config/themes.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
'msg_quote': 'underline',
'msg_code': 'bold',
'msg_bold': 'bold',
'msg_time': 'bold',
'footer': 'standout',
'starred': 'bold',
'popup_category': 'bold',
Expand Down Expand Up @@ -139,6 +140,8 @@
None, DEF['black'], DEF['white']),
('msg_bold', 'white, bold', 'black',
None, DEF['white:bold'], DEF['black']),
('msg_time', 'black', 'white',
None, DEF['black'], DEF['white']),
('footer', 'white', 'dark red',
None, DEF['white'], DEF['dark_red']),
('starred', 'light red, bold', 'black',
Expand Down Expand Up @@ -205,6 +208,8 @@
None, BLACK, WHITE),
('msg_bold', 'white, bold', 'black',
None, WHITEBOLD, BLACK),
('msg_time', 'black', 'white',
None, BLACK, WHITE),
('footer', 'white', 'dark red',
None, WHITE, DARKRED),
('starred', 'light red, bold', 'black',
Expand Down Expand Up @@ -244,6 +249,7 @@
('msg_quote', 'black', 'brown'),
('msg_code', 'black', 'light gray'),
('msg_bold', 'white, bold', 'dark gray'),
('msg_time', 'white', 'dark gray'),
('footer', 'white', 'dark red'),
('starred', 'light red, bold', 'white'),
('popup_category', 'dark gray, bold', 'light gray'),
Expand Down Expand Up @@ -277,6 +283,7 @@
('msg_quote', 'brown', 'dark blue'),
('msg_code', 'dark blue', 'white'),
('msg_bold', 'white, bold', 'dark blue'),
('msg_time', 'dark blue', 'white'),
('footer', 'white', 'dark red'),
('starred', 'light red, bold', 'light blue'),
('popup_category', 'light gray, bold', 'light blue'),
Expand Down
22 changes: 21 additions & 1 deletion zulipterminal/ui_tools/boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
from urllib.parse import urljoin, urlparse

import dateutil.parser
import urwid
from bs4 import BeautifulSoup
from bs4.element import NavigableString
from tzlocal import get_localzone
from urwid_readline import ReadlineEdit

from zulipterminal import emoji_names
from zulipterminal.config.keys import is_command_key, keys_for_command
from zulipterminal.config.symbols import (
MESSAGE_CONTENT_MARKER, MESSAGE_HEADER_DIVIDER, QUOTED_TEXT_MARKER,
STREAM_TOPIC_SEPARATOR,
STREAM_TOPIC_SEPARATOR, TIME_MENTION_MARKER,
)
from zulipterminal.helper import (
Message, format_string, match_emoji, match_group, match_stream, match_user,
Expand Down Expand Up @@ -740,6 +742,24 @@ def soup2markup(self, soup: Any, **state: Any) -> List[Any]:
markup.extend(self.soup2markup(element, **state))
elif element.name == 'table':
markup.extend(render_table(element))
elif element.name == 'time':
# New in feature level 16, server version 3.0.
# Render time in current user's local time zone.
timestamp = element.get('datetime')

# This should not happen. Regardless, we are interested in
# debugging and reporting it to zulip/zulip if it does.
assert timestamp is not None, 'Could not find datetime attr'

utc_time = dateutil.parser.parse(timestamp)
local_time = utc_time.astimezone(get_localzone())
# TODO: Address 12-hour format support with application-wide
# support for different formats.
time_string = local_time.strftime('%a, %b %-d %Y, %-H:%M (%Z)')
markup.append((
'msg_time',
' {} {} '.format(TIME_MENTION_MARKER, time_string)
))
else:
markup.extend(self.soup2markup(element))
return markup
Expand Down