From 89b1e1e6827003ac696e6ed446732590f83ea187 Mon Sep 17 00:00:00 2001 From: nicoco Date: Tue, 22 Nov 2022 08:43:53 +0100 Subject: [PATCH 1/5] XEP-0461: use integers for fallback start/end --- slixmpp/plugins/xep_0461/stanza.py | 27 +++++++++++++++++++++------ tests/test_stanza_xep_0461.py | 4 ++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/slixmpp/plugins/xep_0461/stanza.py b/slixmpp/plugins/xep_0461/stanza.py index b99b2745..1035fd83 100644 --- a/slixmpp/plugins/xep_0461/stanza.py +++ b/slixmpp/plugins/xep_0461/stanza.py @@ -23,13 +23,10 @@ class FeatureFallBack(ElementBase): start = self["fallback_body"]["start"] end = self["fallback_body"]["end"] body = self.parent()["body"] - try: - start = int(start) - end = int(end) - except ValueError: - return body - else: + if start < end < len(body): return body[:start] + body[end:] + else: + return body class FallBackBody(ElementBase): @@ -40,6 +37,24 @@ class FallBackBody(ElementBase): plugin_attrib = "fallback_body" interfaces = {"start", "end"} + def set_start(self, v: int): + self._set_attr("start", str(v)) + + def get_start(self): + try: + return int(self._get_attr("start")) + except ValueError: + return 0 + + def set_end(self, v: int): + self._set_attr("end", str(v)) + + def get_end(self): + try: + return int(self._get_attr("end")) + except ValueError: + return 0 + def register_plugins(): register_stanza_plugin(Message, Reply) diff --git a/tests/test_stanza_xep_0461.py b/tests/test_stanza_xep_0461.py index b9550481..90aa751b 100644 --- a/tests/test_stanza_xep_0461.py +++ b/tests/test_stanza_xep_0461.py @@ -27,8 +27,8 @@ class TestReply(SlixTest): message = Message() message["body"] = "12345\nrealbody" message["feature_fallback"]["for"] = "NS" - message["feature_fallback"]["fallback_body"]["start"] = "0" - message["feature_fallback"]["fallback_body"]["end"] = "6" + message["feature_fallback"]["fallback_body"]["start"] = 0 + message["feature_fallback"]["fallback_body"]["end"] = 6 self.check( message, From 9b51be1e177ca18dae5e63068648c3d23ba9821a Mon Sep 17 00:00:00 2001 From: nicoco Date: Tue, 22 Nov 2022 08:45:41 +0100 Subject: [PATCH 2/5] XEP-0461: add quoted fallback helper --- slixmpp/plugins/xep_0461/stanza.py | 8 ++++++++ tests/test_stanza_xep_0461.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/slixmpp/plugins/xep_0461/stanza.py b/slixmpp/plugins/xep_0461/stanza.py index 1035fd83..37021c00 100644 --- a/slixmpp/plugins/xep_0461/stanza.py +++ b/slixmpp/plugins/xep_0461/stanza.py @@ -28,6 +28,14 @@ class FeatureFallBack(ElementBase): else: return body + def add_quoted_fallback(self, fallback: str): + msg = self.parent() + quoted = "\n".join("> " + x.strip() for x in fallback.split("\n")) + "\n" + msg["body"] = quoted + msg["body"] + msg["feature_fallback"]["for"] = NS + msg["feature_fallback"]["fallback_body"]["start"] = 0 + msg["feature_fallback"]["fallback_body"]["end"] = len(quoted) + class FallBackBody(ElementBase): # According to https://xmpp.org/extensions/inbox/compatibility-fallback.html diff --git a/tests/test_stanza_xep_0461.py b/tests/test_stanza_xep_0461.py index 90aa751b..3eb6a3ac 100644 --- a/tests/test_stanza_xep_0461.py +++ b/tests/test_stanza_xep_0461.py @@ -44,5 +44,22 @@ class TestReply(SlixTest): assert message["feature_fallback"].get_stripped_body() == "realbody" + def testAddFallBackHelper(self): + msg = Message() + msg["body"] = "Great" + msg["feature_fallback"].add_quoted_fallback("Anna wrote:\nHi, how are you?") + # ugly dedent but the test does not pass without it + self.check( + msg, + """ + + > Anna wrote:\n> Hi, how are you?\nGreat + + + + + """ + ) + suite = unittest.TestLoader().loadTestsFromTestCase(TestReply) From 7300f1285e04e64fdb33f75d9152e4b5cbacc148 Mon Sep 17 00:00:00 2001 From: nicoco Date: Tue, 22 Nov 2022 08:47:31 +0100 Subject: [PATCH 3/5] XEP-0461: add to plugins.__all__ --- slixmpp/plugins/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/slixmpp/plugins/__init__.py b/slixmpp/plugins/__init__.py index ac7482ee..be01b06e 100644 --- a/slixmpp/plugins/__init__.py +++ b/slixmpp/plugins/__init__.py @@ -113,4 +113,5 @@ __all__ = [ 'xep_0439', # Quick Response 'xep_0441', # Message Archive Management Preferences 'xep_0444', # Message Reactions + 'xep_0461', # Message Replies ] From 9b89401b36a10c8248ff6011232929b39301272f Mon Sep 17 00:00:00 2001 From: nicoco Date: Tue, 22 Nov 2022 10:23:52 +0100 Subject: [PATCH 4/5] XEP-0461: add get fallback body helper --- slixmpp/plugins/xep_0461/stanza.py | 10 ++++++++++ tests/test_stanza_xep_0461.py | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/slixmpp/plugins/xep_0461/stanza.py b/slixmpp/plugins/xep_0461/stanza.py index 37021c00..09a25f97 100644 --- a/slixmpp/plugins/xep_0461/stanza.py +++ b/slixmpp/plugins/xep_0461/stanza.py @@ -18,6 +18,16 @@ class FeatureFallBack(ElementBase): plugin_attrib = "feature_fallback" interfaces = {"for"} + def get_fallback_body(self): + # only works for a single fallback_body attrib + start = self["fallback_body"]["start"] + end = self["fallback_body"]["end"] + body = self.parent()["body"] + if start < end < len(body): + return body[start:end] + else: + return "" + def get_stripped_body(self): # only works for a single fallback_body attrib start = self["fallback_body"]["start"] diff --git a/tests/test_stanza_xep_0461.py b/tests/test_stanza_xep_0461.py index 3eb6a3ac..76f07c80 100644 --- a/tests/test_stanza_xep_0461.py +++ b/tests/test_stanza_xep_0461.py @@ -61,5 +61,15 @@ class TestReply(SlixTest): """ ) + def testGetFallBackBody(self): + body = "Anna wrote:\nHi, how are you?" + quoted = "> Anna wrote:\n> Hi, how are you?\n" + + msg = Message() + msg["body"] = "Great" + msg["feature_fallback"].add_quoted_fallback(body) + body2 = msg["feature_fallback"].get_fallback_body() + self.assertTrue(body2 == quoted, body2) + suite = unittest.TestLoader().loadTestsFromTestCase(TestReply) From fdca7d82c427b2da77f852b9e2f882decedd257a Mon Sep 17 00:00:00 2001 From: nicoco Date: Mon, 28 Nov 2022 07:15:26 +0100 Subject: [PATCH 5/5] XEP-0461: fix character counting Turns out we need to include the fallback/end code point, unlike python slicing conventions --- slixmpp/plugins/xep_0461/stanza.py | 8 ++++---- tests/test_stanza_xep_0461.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/slixmpp/plugins/xep_0461/stanza.py b/slixmpp/plugins/xep_0461/stanza.py index 09a25f97..f52d0964 100644 --- a/slixmpp/plugins/xep_0461/stanza.py +++ b/slixmpp/plugins/xep_0461/stanza.py @@ -23,8 +23,8 @@ class FeatureFallBack(ElementBase): start = self["fallback_body"]["start"] end = self["fallback_body"]["end"] body = self.parent()["body"] - if start < end < len(body): - return body[start:end] + if start <= end: + return body[start:end+1] else: return "" @@ -33,7 +33,7 @@ class FeatureFallBack(ElementBase): start = self["fallback_body"]["start"] end = self["fallback_body"]["end"] body = self.parent()["body"] - if start < end < len(body): + if start <= end < len(body): return body[:start] + body[end:] else: return body @@ -44,7 +44,7 @@ class FeatureFallBack(ElementBase): msg["body"] = quoted + msg["body"] msg["feature_fallback"]["for"] = NS msg["feature_fallback"]["fallback_body"]["start"] = 0 - msg["feature_fallback"]["fallback_body"]["end"] = len(quoted) + msg["feature_fallback"]["fallback_body"]["end"] = len(quoted) - 1 class FallBackBody(ElementBase): diff --git a/tests/test_stanza_xep_0461.py b/tests/test_stanza_xep_0461.py index 76f07c80..e43b8138 100644 --- a/tests/test_stanza_xep_0461.py +++ b/tests/test_stanza_xep_0461.py @@ -33,7 +33,7 @@ class TestReply(SlixTest): self.check( message, """ - + M 12345\nrealbody @@ -55,7 +55,7 @@ class TestReply(SlixTest): > Anna wrote:\n> Hi, how are you?\nGreat - + """