From 5ec21595469e531d0448de6d37f61bc911dec56b Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Fri, 12 Apr 2024 08:46:59 -0700 Subject: [PATCH] user page: link to bridged Bluesky profile for #825 --- atproto.py | 17 +++++++++++++++++ protocol.py | 4 ++-- templates/user_base.html | 3 +++ tests/test_atproto.py | 11 +++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/atproto.py b/atproto.py index 536ffd4..4762c45 100644 --- a/atproto.py +++ b/atproto.py @@ -147,6 +147,23 @@ class ATProto(User, Protocol): def profile_id(self): return self.profile_at_uri(self.key.id()) + @classmethod + def bridged_web_url_for(cls, user): + """Returns a bridged user's profile URL on bsky.app. + + For example, returns ``https://bsky.app/profile/alice.com.web.brid.gy`` + for Web user ``alice.com``. + + Args: + user (models.User) + + Returns: + str, or None if there isn't a canonical URL + """ + if not isinstance(user, ATProto): + if did := user.get_copy(ATProto): + return bluesky.Bluesky.user_url(did_to_handle(did) or did) + @classmethod def target_for(cls, obj, shared=False): """Returns our PDS URL as the target for the given object. diff --git a/protocol.py b/protocol.py index 29b963d..d1e8968 100644 --- a/protocol.py +++ b/protocol.py @@ -354,14 +354,14 @@ class Protocol: return (None, None) @classmethod - def bridged_web_url_for(self, user): + def bridged_web_url_for(cls, user): """Returns the web URL for a user's bridged profile in this protocol. For example, for Web user ``alice.com``, :meth:`ATProto.bridged_web_url_for` returns ``https://bsky.app/profile/alice.com.web.brid.gy`` Args: - proto (str or Protocol) + user (models.User) Returns: str, or None if there isn't a canonical URL diff --git a/templates/user_base.html b/templates/user_base.html index 1a0c0e1..d0c7bb6 100644 --- a/templates/user_base.html +++ b/templates/user_base.html @@ -62,10 +62,13 @@ {% if proto and not isinstance(user, proto) and proto.LABEL not in ('ui', 'web') and (proto.LABEL not in ids.COPIES_PROTOCOLS or proto.LABEL in copies) %} + {% set url = proto.bridged_web_url_for(user) %} · + {% if url %} {% endif %} {{ user.handle_as(proto) }} + {% if url %} {% endif %} {% endif %} {% endfor %} diff --git a/tests/test_atproto.py b/tests/test_atproto.py index 10c81c9..3ee4177 100644 --- a/tests/test_atproto.py +++ b/tests/test_atproto.py @@ -142,6 +142,17 @@ class ATProtoTest(TestCase): def test_handle_to_id_not_found(self, *_): self.assertIsNone(ATProto.handle_to_id('han.dull')) + def test_bridged_web_url_for(self): + self.assertIsNone(ATProto.bridged_web_url_for(ATProto(id='did:plc:foo'))) + + fake = Fake(id='fake:user') + self.assertIsNone(ATProto.bridged_web_url_for(fake)) + + fake.copies = [Target(uri='did:plc:user', protocol='atproto')] + self.store_object(id='did:plc:user', raw=DID_DOC) + self.assertEqual('https://bsky.app/profile/han.dull', + ATProto.bridged_web_url_for(fake)) + def test_pds_for_did_no_doc(self): self.assertIsNone(ATProto.pds_for(Object(id='did:plc:user')))