Daniel Brötzmann pushed to branch master at gajim / gajim

Commits:

6 changed files:

Changes:

  • gajim/common/helpers.py
    ... ... @@ -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
     
    

  • gajim/common/setting_values.py
    ... ... @@ -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',
    

  • test/common/__init__.py
    ... ... @@ -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()

  • test/common/test_get_uf_relative_time.py
    ... ... @@ -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
     
    

  • test/common/test_message_needs_highlight.py
    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))

  • test/common/test_styling.py
    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':  {