web UI: tweak user links in user page header

pull/837/head
Ryan Barrett 2024-02-11 14:35:10 -08:00
rodzic 855efa04f3
commit 675e39809e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
7 zmienionych plików z 55 dodań i 28 usunięć

6
ids.py
Wyświetl plik

@ -108,7 +108,7 @@ def translate_user_id(*, id, from_proto, to_proto):
case 'fake' | 'other', _:
return id
assert False, (id, from_proto, to_proto)
assert False, (id, from_proto.LABEL, to_proto.LABEL)
def translate_handle(*, handle, from_proto, to_proto, enhanced):
@ -155,7 +155,7 @@ def translate_handle(*, handle, from_proto, to_proto, enhanced):
case _, 'other':
return f'other:handle:{handle}'
assert False, (id, from_proto, to_proto)
assert False, (handle, from_proto.LABEL, to_proto.LABEL)
def translate_object_id(*, id, from_proto, to_proto):
@ -197,4 +197,4 @@ def translate_object_id(*, id, from_proto, to_proto):
case _, 'fake' | 'other':
return f'{to_proto.LABEL}:o:{from_proto.ABBREV}:{id}'
assert False, (id, from_proto, to_proto)
assert False, (id, from_proto.LABEL, to_proto.LABEL)

Wyświetl plik

@ -485,12 +485,18 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
def user_link(self):
"""Returns a pretty link to the external user with name and profile picture."""
actor = self.obj.as1 if self.obj and self.obj.as1 else {}
img = util.get_url(actor, 'image') or ''
pic = self.profile_picture()
img = f'<img src="{pic}" class="profile"> ' if pic else ''
return f"""\
<a class="h-card u-author" href="{self.web_url()}">
<img src="{img}" class="profile">
{self.name()}</a>"""
{img}
{self.name()}
</a>"""
def profile_picture(self):
"""Returns the user's profile picture image URL, if available, or None."""
if self.obj and self.obj.as1:
return util.get_url(self.obj.as1, 'image')
@cachetools.cached(cachetools.TTLCache(50000, 60 * 60 * 2), # 2h expiration
key=lambda user: user.key.id(), lock=Lock())

Wyświetl plik

@ -30,13 +30,22 @@
<div class="row">
<span class="big">
{{ user.user_link()|safe }}
&middot;
{% if user.name() != user.handle_or_id() %}
{{ user.user_link()|safe }}
&middot;
{% else %}
{% if user.profile_picture() %}
<img src="{{ user.profile_picture() }}" class="profile">
{% endif %}
{% endif %}
<nobr>
<a href="{{ user.web_url() }}"
title="{{ user.__class__.__name__ }} (native)">
<span class="logo">{{ user.LOGO_HTML|safe }}</span>
{{ user.handle_or_id() }}</a>
<a href="{{ user.web_url() }}"
title="{{ user.__class__.__name__ }} (native)">
<span class="logo">{{ user.LOGO_HTML|safe }}</span>
{{ user.handle_or_id() }}
</a>
{% if user.LABEL == 'web' %}
<form method="post" action="/webmention-interactive">
@ -46,15 +55,15 @@
</form>
{% endif %}
</nobr>
&middot;
</span>
{% for proto in set(PROTOCOLS.values()) %}
{% if proto and not isinstance(user, proto)
and proto.LABEL not in ('atproto', 'ui') %}
and proto.LABEL not in ('atproto', 'ui', 'web') %}
&middot;
<nobr title="{{ proto.__name__ }} (bridged)">
<span class="logo">{{ proto.LOGO_HTML|safe }}</span>
{{ user.handle_as('activitypub') }}
{{ user.handle_as(proto) }}
</nobr>
{% endif %}
{% endfor %}

Wyświetl plik

@ -29,8 +29,9 @@ class CommonTest(TestCase):
# current user's homepage gets converted to BF user page
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://user.com/">
<img src="" class="profile">
user.com</a>""", common.pretty_link('https://user.com/', user=Web(id='user.com')))
user.com
</a>""", common.pretty_link('https://user.com/', user=Web(id='user.com')))
def test_redirect_wrap_empty(self):
self.assertIsNone(common.redirect_wrap(None))

Wyświetl plik

@ -23,7 +23,7 @@ from .testutil import Fake, OtherFake, TestCase
from atproto import ATProto
import common
import models
from models import Follower, Object, OBJECT_EXPIRE_AGE, Target, User
from models import Follower, Object, OBJECT_EXPIRE_AGE, PROTOCOLS, Target, User
import protocol
from protocol import Protocol
from web import Web
@ -136,14 +136,16 @@ class UserTest(TestCase):
def test_user_link(self):
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://y.z/">
<img src="" class="profile">
y.z</a>""", self.user.user_link())
y.z
</a>""", self.user.user_link())
self.user.obj = Object(id='a', as2=ACTOR)
self.assert_multiline_equals("""\
<a class="h-card u-author" href="https://y.z/">
<img src="https://user.com/me.jpg" class="profile">
Mrs. Foo</a>""", self.user.user_link())
Mrs. Foo
</a>""", self.user.user_link())
def test_is_web_url(self):
for url in 'y.z', '//y.z', 'http://y.z', 'https://y.z':
@ -187,12 +189,16 @@ class UserTest(TestCase):
def test_handle_as_None(self):
class NoHandle(Fake):
ABBREV = 'nohandle'
@ndb.ComputedProperty
def handle(self):
return None
user = NoHandle()
self.assertIsNone(user.handle_as(OtherFake))
try:
user = NoHandle()
self.assertIsNone(user.handle_as(OtherFake))
finally:
PROTOCOLS.pop('nohandle')
def test_load_multi(self):
# obj_key is None

Wyświetl plik

@ -179,6 +179,7 @@ class PagesTest(TestCase):
from_=self.make_user('http://masto/user', cls=ActivityPub,
obj_as2=ACTOR_WITH_PREFERRED_USERNAME))
from models import PROTOCOLS
got = self.client.get('/web/user.com/followers')
self.assert_equals(200, got.status_code)

Wyświetl plik

@ -8,6 +8,7 @@ from oauth_dropins.webutil.testutil import requests_response
# import first so that Fake is defined before URL routes are registered
from .testutil import Fake, TestCase
from models import PROTOCOLS
import protocol
from web import Web
from webfinger import fetch, fetch_actor_url
@ -309,12 +310,15 @@ class WebfingerTest(TestCase):
def test_no_handle(self):
class NoHandle(Fake):
ABBREV = 'noh'
ABBREV = 'nohandle'
handle = None
got = self.client.get(
'/.well-known/webfinger?resource=acct:nohandle:user@noh.brid.gy')
self.assertEqual(404, got.status_code)
try:
got = self.client.get(
'/.well-known/webfinger?resource=acct:nohandle:user@nohandle.brid.gy')
self.assertEqual(404, got.status_code)
finally:
PROTOCOLS.pop('nohandle')
@patch('requests.get')
def test_create_user(self, mock_get):