Daniel Brötzmann pushed to branch master at gajim / gajim
Commits:
-
94e227f0
by wurstsalat at 2023-02-14T21:45:26+01:00
-
0618ab18
by wurstsalat at 2023-02-14T21:45:26+01:00
-
1526a6db
by wurstsalat at 2023-02-14T21:45:26+01:00
-
c1225720
by wurstsalat at 2023-02-14T21:45:26+01:00
6 changed files:
- gajim/common/helpers.py
- gajim/common/setting_values.py
- test/common/__init__.py
- test/common/test_get_uf_relative_time.py
- + test/common/test_message_needs_highlight.py
- test/common/test_styling.py
Changes:
| ... | ... | @@ -562,35 +562,44 @@ def get_os_info() -> str: |
| 562 | 562 | |
| 563 | 563 | def message_needs_highlight(text: str, nickname: str, own_jid: str) -> bool:
|
| 564 | 564 | '''
|
| 565 | - Check text to see whether any of the words in (muc_highlight_words and
|
|
| 566 | - nick) appear
|
|
| 565 | + Check whether 'text' contains 'nickname', 'own_jid', or any string of the
|
|
| 566 | + 'muc_highlight_words' setting.
|
|
| 567 | 567 | '''
|
| 568 | 568 | |
| 569 | - uri = parse_uri(text)
|
|
| 570 | - if uri.type != URIType.INVALID:
|
|
| 571 | - # Don't highlight message if it's an URI
|
|
| 572 | - return False
|
|
| 569 | + search_strings = app.settings.get('muc_highlight_words').split(';')
|
|
| 570 | + search_strings.append(nickname)
|
|
| 571 | + search_strings.append(own_jid)
|
|
| 573 | 572 | |
| 574 | - special_words = app.settings.get('muc_highlight_words').split(';')
|
|
| 575 | - special_words.append(nickname)
|
|
| 576 | - special_words.append(own_jid)
|
|
| 577 | - # Strip empties: ''.split(';') == [''] and would highlight everything.
|
|
| 578 | - # Also lowercase everything for case insensitive compare.
|
|
| 579 | - special_words = [word.lower() for word in special_words if word]
|
|
| 573 | + search_strings = [word.lower() for word in search_strings if word]
|
|
| 580 | 574 | text = text.lower()
|
| 581 | 575 | |
| 582 | - for special_word in special_words:
|
|
| 583 | - found_here = text.find(special_word)
|
|
| 584 | - while found_here > -1:
|
|
| 585 | - end_here = found_here + len(special_word)
|
|
| 586 | - if ((found_here == 0 or not text[found_here - 1].isalpha()) and
|
|
| 587 | - (end_here == len(text) or not text[end_here].isalpha())):
|
|
| 588 | - # It is beginning of text or char before is not alpha AND
|
|
| 589 | - # it is end of text or char after is not alpha
|
|
| 576 | + for search_string in search_strings:
|
|
| 577 | + match = text.find(search_string)
|
|
| 578 | + |
|
| 579 | + while match > -1:
|
|
| 580 | + search_end = match + len(search_string)
|
|
| 581 | + |
|
| 582 | + if match == 0 and search_end == len(text):
|
|
| 583 | + # Text contains search_string only (exact match)
|
|
| 584 | + return True
|
|
| 585 | + |
|
| 586 | + char_before_allowed = bool(
|
|
| 587 | + not text[match - 1].isalpha() and
|
|
| 588 | + text[match - 1] not in ('/', '-'))
|
|
| 589 | + |
|
| 590 | + if char_before_allowed and search_end == len(text):
|
|
| 591 | + # search_string found at the end of text and
|
|
| 592 | + # char before search_string is allowed.
|
|
| 593 | + return True
|
|
| 594 | + |
|
| 595 | + if char_before_allowed and not text[search_end].isalpha():
|
|
| 596 | + # char_before search_string is allowed and
|
|
| 597 | + # char_after search_string is not alpha.
|
|
| 590 | 598 | return True
|
| 591 | - # continue searching
|
|
| 592 | - start = found_here + 1
|
|
| 593 | - found_here = text.find(special_word, start)
|
|
| 599 | + |
|
| 600 | + start = match + 1
|
|
| 601 | + match = text.find(search_string, start)
|
|
| 602 | + |
|
| 594 | 603 | return False
|
| 595 | 604 | |
| 596 | 605 |
| ... | ... | @@ -36,7 +36,6 @@ class _ACCOUNTDEFAULT: |
| 36 | 36 | |
| 37 | 37 | |
| 38 | 38 | BoolSettings = Literal[
|
| 39 | - 'additional_uri_schemes',
|
|
| 40 | 39 | 'allow_open_file_uris',
|
| 41 | 40 | 'always_english_wikipedia',
|
| 42 | 41 | 'always_english_wiktionary',
|
| ... | ... | @@ -129,6 +128,7 @@ class _ACCOUNTDEFAULT: |
| 129 | 128 | |
| 130 | 129 | StringSettings = Literal[
|
| 131 | 130 | 'action_on_close',
|
| 131 | + 'additional_uri_schemes',
|
|
| 132 | 132 | 'audio_input_device',
|
| 133 | 133 | 'audio_output_device',
|
| 134 | 134 | 'autoaway_message',
|
| ... | ... | @@ -10,5 +10,10 @@ def require_versions(): |
| 10 | 10 | 'GObject': '2.0',
|
| 11 | 11 | 'Pango': '1.0'})
|
| 12 | 12 | |
| 13 | - |
|
| 14 | 13 | require_versions()
|
| 14 | + |
|
| 15 | +from gajim.common import app
|
|
| 16 | +from gajim.common.settings import Settings
|
|
| 17 | + |
|
| 18 | +app.settings = Settings(in_memory=True)
|
|
| 19 | +app.settings.init() |
| ... | ... | @@ -6,9 +6,10 @@ |
| 6 | 6 | |
| 7 | 7 | from gajim.common import app
|
| 8 | 8 | from gajim.common.helpers import get_uf_relative_time
|
| 9 | -from gajim.common.settings import Settings
|
|
| 9 | +from gajim.common.i18n import _
|
|
| 10 | +from gajim.common.i18n import ngettext
|
|
| 10 | 11 | |
| 11 | -app.settings = Settings(in_memory=True)
|
|
| 12 | +local_timezone = datetime.now(timezone.utc).astimezone().tzinfo
|
|
| 12 | 13 | |
| 13 | 14 | |
| 14 | 15 | class GetRelativeTimeTest(unittest.TestCase):
|
| ... | ... | @@ -16,30 +17,41 @@ class GetRelativeTimeTest(unittest.TestCase): |
| 16 | 17 | |
| 17 | 18 | def test_sub_1_minute(self):
|
| 18 | 19 | '''Test timedelta less than 1 minute'''
|
| 19 | - timenow = datetime(2023, 1, 2, 3, 4, 0, tzinfo=timezone.utc)
|
|
| 20 | + timenow = datetime(2023, 1, 2, 3, 4, 0, tzinfo=local_timezone)
|
|
| 20 | 21 | timestamp1 = timenow - timedelta(seconds=30)
|
| 21 | 22 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 22 | - timenow.timestamp()), 'Just now')
|
|
| 23 | + timenow.timestamp()),
|
|
| 24 | + _('Just now'))
|
|
| 23 | 25 | |
| 24 | 26 | def test_sub_15_minutes(self):
|
| 25 | 27 | '''Test timedelta less than 15 minutes and more than 1 minute ago'''
|
| 26 | - timenow = datetime(2023, 1, 2, 3, 4, 0, tzinfo=timezone.utc)
|
|
| 28 | + timenow = datetime(2023, 1, 2, 3, 4, 0, tzinfo=local_timezone)
|
|
| 27 | 29 | timestamp1 = timenow - timedelta(minutes=3)
|
| 28 | 30 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 29 | 31 | timenow.timestamp()),
|
| 30 | - '3 mins ago')
|
|
| 32 | + ngettext(
|
|
| 33 | + '%i min ago',
|
|
| 34 | + '%i mins ago',
|
|
| 35 | + 3,
|
|
| 36 | + 3,
|
|
| 37 | + 3))
|
|
| 31 | 38 | |
| 32 | 39 | def test_sub_15_minutes_next_day(self):
|
| 33 | 40 | '''Test timedelta less than 15 minutes and it is the next day'''
|
| 34 | - timenow = datetime(2023, 1, 1, 0, 5, 0, tzinfo=timezone.utc)
|
|
| 41 | + timenow = datetime(2023, 1, 1, 0, 5, 0, tzinfo=local_timezone)
|
|
| 35 | 42 | timestamp1 = timenow - timedelta(minutes=10)
|
| 36 | 43 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 37 | 44 | timenow.timestamp()),
|
| 38 | - '10 mins ago')
|
|
| 45 | + ngettext(
|
|
| 46 | + '%i min ago',
|
|
| 47 | + '%i mins ago',
|
|
| 48 | + 10,
|
|
| 49 | + 10,
|
|
| 50 | + 10))
|
|
| 39 | 51 | |
| 40 | 52 | def test_today(self):
|
| 41 | 53 | '''Test today: same day and more than 15 minutes ago'''
|
| 42 | - timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=timezone.utc)
|
|
| 54 | + timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=local_timezone)
|
|
| 43 | 55 | timestamp1 = timenow - timedelta(hours=4)
|
| 44 | 56 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 45 | 57 | timenow.timestamp()),
|
| ... | ... | @@ -47,40 +59,41 @@ def test_today(self): |
| 47 | 59 | |
| 48 | 60 | def test_yesterday_less_than_24h(self):
|
| 49 | 61 | '''Test yesterday and less than 24h ago'''
|
| 50 | - timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=timezone.utc)
|
|
| 51 | - timestamp1 = datetime(2023, 1, 1, 14, 0, 0, tzinfo=timezone.utc)
|
|
| 62 | + timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=local_timezone)
|
|
| 63 | + timestamp1 = datetime(2023, 1, 1, 14, 0, 0, tzinfo=local_timezone)
|
|
| 52 | 64 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 53 | - timenow.timestamp()), 'Yesterday')
|
|
| 65 | + timenow.timestamp()),
|
|
| 66 | + _('Yesterday'))
|
|
| 54 | 67 | |
| 55 | 68 | def test_yesterday_more_than_24h(self):
|
| 56 | 69 | '''Test yesterday and more than 24h ago'''
|
| 57 | - timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=timezone.utc)
|
|
| 58 | - timestamp1 = datetime(2023, 1, 1, 10, 0, 0, tzinfo=timezone.utc)
|
|
| 70 | + timenow = datetime(2023, 1, 2, 12, 0, 0, tzinfo=local_timezone)
|
|
| 71 | + timestamp1 = datetime(2023, 1, 1, 10, 0, 0, tzinfo=local_timezone)
|
|
| 59 | 72 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 60 | 73 | timenow.timestamp()),
|
| 61 | - 'Yesterday')
|
|
| 74 | + _('Yesterday'))
|
|
| 62 | 75 | |
| 63 | 76 | def test_weekday(self):
|
| 64 | 77 | '''Test weekday: timestamp older than yesterday and less
|
| 65 | 78 | than 7 days ago, should return the weekday, i.e. 'Sun' for Sunday'''
|
| 66 | - timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=timezone.utc)
|
|
| 67 | - timestamp1 = datetime(2023, 1, 1, 4, 5, 6, tzinfo=timezone.utc)
|
|
| 79 | + timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=local_timezone)
|
|
| 80 | + timestamp1 = datetime(2023, 1, 1, 4, 5, 6, tzinfo=local_timezone)
|
|
| 68 | 81 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 69 | 82 | timenow.timestamp()),
|
| 70 | 83 | timestamp1.strftime('%a'))
|
| 71 | 84 | |
| 72 | 85 | def test_month_day(self):
|
| 73 | 86 | '''Test month_day: timestamp more than 7 days ago but less than 365'''
|
| 74 | - timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=timezone.utc)
|
|
| 75 | - timestamp1 = datetime(2022, 11, 15, 4, 5, 6, tzinfo=timezone.utc)
|
|
| 87 | + timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=local_timezone)
|
|
| 88 | + timestamp1 = datetime(2022, 11, 15, 4, 5, 6, tzinfo=local_timezone)
|
|
| 76 | 89 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 77 | 90 | timenow.timestamp()),
|
| 78 | 91 | timestamp1.strftime('%b %d'))
|
| 79 | 92 | |
| 80 | 93 | def test_year(self):
|
| 81 | 94 | '''Test year: timestamp more than 365 days ago'''
|
| 82 | - timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=timezone.utc)
|
|
| 83 | - timestamp1 = datetime(2022, 1, 1, 4, 5, 6, tzinfo=timezone.utc)
|
|
| 95 | + timenow = datetime(2023, 1, 5, 1, 2, 3, tzinfo=local_timezone)
|
|
| 96 | + timestamp1 = datetime(2022, 1, 1, 4, 5, 6, tzinfo=local_timezone)
|
|
| 84 | 97 | self.assertEqual(get_uf_relative_time(timestamp1.timestamp(),
|
| 85 | 98 | timenow.timestamp()), '2022')
|
| 86 | 99 |
| 1 | +import unittest
|
|
| 2 | + |
|
| 3 | +from gajim.common import app
|
|
| 4 | +from gajim.common.helpers import message_needs_highlight
|
|
| 5 | + |
|
| 6 | +app.settings.set('muc_highlight_words', 'test;gajim')
|
|
| 7 | +JID = 'romemo@xmppserver'
|
|
| 8 | +NICK = 'Romeo'
|
|
| 9 | + |
|
| 10 | + |
|
| 11 | +class HighlightTest(unittest.TestCase):
|
|
| 12 | + '''Tests for message_needs_highlight'''
|
|
| 13 | + |
|
| 14 | + def test_highlight(self):
|
|
| 15 | + t_text1 = 'Romeo: Does this work?'
|
|
| 16 | + t_text2 = 'Romeo:Does this work?'
|
|
| 17 | + t_text3 = 'Romeo Does this work?'
|
|
| 18 | + t_text4 = 'Does this work, romeo?'
|
|
| 19 | + t_text5 = 'Does this work,Romeo?'
|
|
| 20 | + t_text6 = 'Are you using Gajim?'
|
|
| 21 | + t_text7 = 'Did you test this?'
|
|
| 22 | + t_text8 = 'Hi romeo'
|
|
| 23 | + t_text9 = 'My address is romeo@xmppserver'
|
|
| 24 | + |
|
| 25 | + f_text1 = 'RomeoDoes this work?'
|
|
| 26 | + f_text2 = ''
|
|
| 27 | + f_text3 = 'https://romeo.tld'
|
|
| 28 | + f_text4 = 'https://romeo.tld message'
|
|
| 29 | + f_text5 = 'https://test.tld/where-is-romeo'
|
|
| 30 | + |
|
| 31 | + self.assertTrue(message_needs_highlight(t_text1, NICK, JID))
|
|
| 32 | + self.assertTrue(message_needs_highlight(t_text2, NICK, JID))
|
|
| 33 | + self.assertTrue(message_needs_highlight(t_text3, NICK, JID))
|
|
| 34 | + self.assertTrue(message_needs_highlight(t_text4, NICK, JID))
|
|
| 35 | + self.assertTrue(message_needs_highlight(t_text5, NICK, JID))
|
|
| 36 | + self.assertTrue(message_needs_highlight(t_text6, NICK, JID))
|
|
| 37 | + self.assertTrue(message_needs_highlight(t_text7, NICK, JID))
|
|
| 38 | + self.assertTrue(message_needs_highlight(t_text8, NICK, JID))
|
|
| 39 | + self.assertTrue(message_needs_highlight(t_text9, NICK, JID))
|
|
| 40 | + |
|
| 41 | + self.assertFalse(message_needs_highlight(f_text1, NICK, JID))
|
|
| 42 | + self.assertFalse(message_needs_highlight(f_text2, NICK, JID))
|
|
| 43 | + self.assertFalse(message_needs_highlight(f_text3, NICK, JID))
|
|
| 44 | + self.assertFalse(message_needs_highlight(f_text4, NICK, JID))
|
|
| 45 | + self.assertFalse(message_needs_highlight(f_text5, NICK, JID)) |
| 1 | 1 | import unittest
|
| 2 | -from unittest.mock import MagicMock
|
|
| 3 | 2 | |
| 4 | 3 | from gajim.common import app # Avoids circular imports from common.helpers
|
| 5 | 4 | from gajim.common import styling
|
| ... | ... | @@ -14,9 +13,8 @@ |
| 14 | 13 | from gajim.common.styling import StrongSpan
|
| 15 | 14 | from gajim.common.util.text import escape_iri_query
|
| 16 | 15 | |
| 17 | -app.settings = MagicMock()
|
|
| 18 | -# additional_uri_schemes
|
|
| 19 | -app.settings.get = MagicMock(return_value='a a- a. scheme')
|
|
| 16 | +app.settings.set('additional_uri_schemes', 'a a- a. scheme')
|
|
| 17 | + |
|
| 20 | 18 | |
| 21 | 19 | STYLING = {
|
| 22 | 20 | 'pre cannot have children': {
|