From cb605e96c6c9b92109a5de8c90b109593c731a27 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Mon, 6 Feb 2023 21:28:40 -0800 Subject: [PATCH] user page activities: if object is user, render as pretty user link for #406 --- common.py | 10 +++++++++- models.py | 4 ++-- pages.py | 9 +++++---- tests/test_common.py | 4 ++++ 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/common.py b/common.py index 129ac84..24e3472 100644 --- a/common.py +++ b/common.py @@ -94,13 +94,21 @@ def default_signature_user(): return _DEFAULT_SIGNATURE_USER -def pretty_link(url, text=None): +def pretty_link(url, text=None, user=None): """Wrapper around util.pretty_link() that converts Mastodon user URLs to @-@. Eg for URLs like https://mastodon.social/@foo and https://mastodon.social/users/foo, defaults text to @foo@mastodon.social if it's not provided. + + Args: + url: str + text: str + user: :class:`User`, optional, user for the current request """ + if user and re.match(f'https?://{user.key.id()}/?$', url.strip('/')): + return user.user_page_link() + if text is None: match = re.match(r'https?://([^/]+)/(@|users/)([^/]+)$', url) if match: diff --git a/models.py b/models.py index 7fb9654..e06cda4 100644 --- a/models.py +++ b/models.py @@ -352,13 +352,13 @@ class Object(StringIdModel): or util.get_first(activity, 'author') or {}) if isinstance(actor, str): - return common.pretty_link(actor) + return common.pretty_link(actor, user=user) url = util.get_first(actor, 'url') or '' name = actor.get('displayName') or '' image = util.get_url(actor, 'image') or '' if not image: - return common.pretty_link(url, text=name) + return common.pretty_link(url, text=name, user=user) return f"""\ diff --git a/pages.py b/pages.py index 09f0be0..bf5059e 100644 --- a/pages.py +++ b/pages.py @@ -77,7 +77,7 @@ def user(domain): Object.domains == domain, Object.labels.IN(('notification', 'user')), ) - objects, before, after = fetch_objects(query) + objects, before, after = fetch_objects(query, user) followers = Follower.query(Follower.dest == domain, Follower.status == 'active')\ .count(limit=FOLLOWERS_UI_LIMIT) @@ -153,7 +153,7 @@ def feed(domain): return body, {'Content-Type': rss.CONTENT_TYPE} -def fetch_objects(query): +def fetch_objects(query, user): """Fetches a page of Object entities from a datastore query. Wraps :func:`common.fetch_page` and adds attributes to the returned Object @@ -161,6 +161,7 @@ def fetch_objects(query): Args: query: :class:`ndb.Query` + user: :class:`User` Returns: (results, new_before, new_after) tuple with: @@ -205,7 +206,7 @@ def fetch_objects(query): content = inner_obj.get('content') or inner_obj.get('displayName') url = util.get_first(inner_obj, 'url') or inner_obj.get('id') if url: - content = common.pretty_link(url, text=content) + content = common.pretty_link(url, text=content, user=user) elif (obj.domains and obj_as1.get('id', '').strip('/') == f'https://{obj.domains[0]}'): obj.phrase = 'updated' @@ -217,7 +218,7 @@ def fetch_objects(query): if (type in ('like', 'follow', 'repost', 'share') or not obj.content): if obj.url: - obj.phrase = common.pretty_link(obj.url, text=obj.phrase) + obj.phrase = common.pretty_link(obj.url, text=obj.phrase, user=user) if content: obj.content = content obj.url = url diff --git a/tests/test_common.py b/tests/test_common.py index ea3fbd3..31d46da 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -57,6 +57,10 @@ class CommonTest(testutil.TestCase): ): self.assertEqual(expected, common.pretty_link(url, text=text)) + self.assertEqual( + ' site', + common.pretty_link('https://site/', user=self.user)) + @mock.patch('requests.get', return_value=AS2) def test_get_as2_direct(self, mock_get): resp = common.get_as2('http://orig', user=self.user)