stop using g.user in pages, activitypub followers/ing collections

for #690
pull/731/head
Ryan Barrett 2023-11-19 20:48:31 -08:00
rodzic a1a7ceef51
commit 8b3881dfe3
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
9 zmienionych plików z 69 dodań i 68 usunięć

Wyświetl plik

@ -895,12 +895,12 @@ def follower_collection(id, collection):
"""
protocol = Protocol.for_request(fed='web')
assert protocol
g.user = protocol.get_by_id(id)
if not g.user:
user = protocol.get_by_id(id)
if not user:
return f'{protocol} user {id} not found', 404
# page
followers, new_before, new_after = Follower.fetch_page(collection)
followers, new_before, new_after = Follower.fetch_page(collection, user=user)
page = {
'type': 'CollectionPage',
'partOf': request.base_url,
@ -920,7 +920,7 @@ def follower_collection(id, collection):
return page, {'Content-Type': as2.CONTENT_TYPE}
# collection
num_followers, num_following = g.user.count_followers()
num_followers, num_following = user.count_followers()
collection = {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': request.base_url,

Wyświetl plik

@ -47,7 +47,7 @@ TEMPLATE_VARS = {
def load_user(protocol, id):
"""Loads the current request's user into `g.user`.
"""Loads and returns the current request's user.
Args:
protocol (str):
@ -64,31 +64,31 @@ def load_user(protocol, id):
id = '@' + id
cls = PROTOCOLS[protocol]
g.user = cls.get_by_id(id)
user = cls.get_by_id(id)
if protocol != 'web':
if not g.user:
g.user = cls.query(OR(cls.handle == id,
if not user:
user = cls.query(OR(cls.handle == id,
cls.readable_id == id),
).get()
if g.user and g.user.use_instead:
g.user = g.user.use_instead.get()
if user and user.use_instead:
user = user.use_instead.get()
if g.user and id not in (g.user.key.id(), g.user.handle):
error('', status=302, location=g.user.user_page_path())
if user and id not in (user.key.id(), user.handle):
error('', status=302, location=user.user_page_path())
elif g.user and id != g.user.key.id(): # use_instead redirect
error('', status=302, location=g.user.user_page_path())
elif user and id != user.key.id(): # use_instead redirect
error('', status=302, location=user.user_page_path())
if not g.user or not g.user.direct or g.user.status == 'opt-out':
if not user or not user.direct or user.status == 'opt-out':
# TODO: switch back to USER_NOT_FOUND_HTML
# not easy via exception/abort because this uses Werkzeug's built in
# NotFound exception subclass, and we'd need to make it implement
# get_body to return arbitrary HTML.
error(f'{protocol} user {id} not found', status=404)
assert not g.user.use_instead
return g.user
assert not user.use_instead
return user
@app.route('/')
@ -122,18 +122,18 @@ def web_user_redirects(**kwargs):
@app.get(f'/ap/@<id>', defaults={'protocol': 'ap'})
@canonicalize_request_domain(common.PROTOCOL_DOMAINS, common.PRIMARY_DOMAIN)
def profile(protocol, id):
load_user(protocol, id)
query = Object.query(Object.users == g.user.key)
user = load_user(protocol, id)
query = Object.query(Object.users == user.key)
objects, before, after = fetch_objects(query, by=Object.updated)
num_followers, num_following = g.user.count_followers()
num_followers, num_following = user.count_followers()
return render_template('profile.html', **TEMPLATE_VARS, **locals())
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/home')
@canonicalize_request_domain(common.PROTOCOL_DOMAINS, common.PRIMARY_DOMAIN)
def home(protocol, id):
load_user(protocol, id)
query = Object.query(Object.feed == g.user.key)
user = load_user(protocol, id)
query = Object.query(Object.feed == user.key)
objects, before, after = fetch_objects(query, by=Object.created)
# this calls Object.actor_link serially for each object, which loads the
@ -144,15 +144,15 @@ def home(protocol, id):
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/notifications')
@canonicalize_request_domain(common.PROTOCOL_DOMAINS, common.PRIMARY_DOMAIN)
def notifications(protocol, id):
load_user(protocol, id)
user = load_user(protocol, id)
query = Object.query(Object.notify == g.user.key)
query = Object.query(Object.notify == user.key)
objects, before, after = fetch_objects(query, by=Object.updated)
format = request.args.get('format')
if format:
return serve_feed(objects=objects, format=format, as_snippets=True,
title=f'Bridgy Fed notifications for {id}',
user=user, title=f'Bridgy Fed notifications for {id}',
quiet=request.args.get('quiet'))
# notifications tab UI page
@ -163,9 +163,8 @@ def notifications(protocol, id):
@canonicalize_request_domain(common.PROTOCOL_DOMAINS, common.PRIMARY_DOMAIN)
def followers_or_following(protocol, id, collection):
user = load_user(protocol, id)
followers, before, after = Follower.fetch_page(collection, user)
num_followers, num_following = g.user.count_followers()
num_followers, num_following = user.count_followers()
return render_template(
f'{collection}.html',
address=request.args.get('address'),
@ -179,19 +178,20 @@ def followers_or_following(protocol, id, collection):
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/feed')
@canonicalize_request_domain(common.PROTOCOL_DOMAINS, common.PRIMARY_DOMAIN)
def feed(protocol, id):
load_user(protocol, id)
query = Object.query(Object.feed == g.user.key)
user = load_user(protocol, id)
query = Object.query(Object.feed == user.key)
objects, _, _ = fetch_objects(query, by=Object.created)
return serve_feed(objects=objects, format=request.args.get('format', 'html'),
title=f'Bridgy Fed feed for {id}')
user=user, title=f'Bridgy Fed feed for {id}')
def serve_feed(*, objects, format, title, as_snippets=False, quiet=False):
def serve_feed(*, objects, format, user, title, as_snippets=False, quiet=False):
"""Generates a feed based on :class:`Object`s.
Args:
objects (sequence of models.Object)
format (str): ``html``, ``atom``, or ``rss``
user (models.User)
title (str)
as_snippets (bool): if True, render short snippets for objects instead of
full contents
@ -239,8 +239,8 @@ def serve_feed(*, objects, format, title, as_snippets=False, quiet=False):
tasklets.wait_all(gets)
actor = (g.user.obj.as1 if g.user.obj and g.user.obj.as1
else {'displayName': g.user.readable_id, 'url': g.user.web_url()})
actor = (user.obj.as1 if user.obj and user.obj.as1
else {'displayName': user.readable_id, 'url': user.web_url()})
# TODO: inject/merge common.pretty_link into microformats2.render_content
# (specifically into hcard_to_html) somehow to convert Mastodon URLs to @-@
@ -291,7 +291,7 @@ def bridge_user():
return render_template('bridge_user.html')
def fetch_objects(query, by=None):
def fetch_objects(query, by=None, user=None):
"""Fetches a page of :class:`models.Object` entities from a datastore query.
Wraps :func:`models.fetch_page` and adds attributes to the returned
@ -301,6 +301,7 @@ def fetch_objects(query, by=None):
query (ndb.Query)
by (ndb.model.Property): either :attr:`models.Object.updated` or
:attr:`models.Object.created`
user (models.User): current user
Returns:
(list of models.Object, str, str) tuple:
@ -357,7 +358,7 @@ def fetch_objects(query, by=None):
id = common.unwrap(inner_obj.get('id', ''))
url = urls[0] if urls else id
if (type == 'update' and
(obj.users and (g.user.is_web_url(id)
(obj.users and (user.is_web_url(id)
or id.strip('/') == obj.users[0].id())
or obj.domains and id.strip('/') == f'https://{obj.domains[0]}')):
obj.phrase = 'updated'

Wyświetl plik

@ -17,7 +17,7 @@
{% if page_name == 'following' %}
<form method="post" action="/unfollow/start" class="col-xs-2 col-sm-1 col-lg-1">
<input type="hidden" name="me" value="{{ g.user.web_url() }}/" />
<input type="hidden" name="me" value="{{ user.web_url() }}/" />
<input type="hidden" name="key" value="{{ f.key.id() }}" />
<input type="submit" title="Unfollow (requires IndieAuth)" value="✖"
class="btn delete-website" />

Wyświetl plik

@ -2,7 +2,7 @@
{% set subtab = "followers" %}
{% block subsubtabs %}
{% if g.user.LABEL != 'activitypub' %}
{% if user.LABEL != 'activitypub' %}
<div class="row">
<form method="post" action="/remote-follow">
<nobr>
@ -11,7 +11,7 @@
placeholder="@user@domain.social" alt="fediverse address"
value="{{ follow_url or '' }}"></input>
<input name="domain" type="hidden" value="{{ id }}"></input>
<input name="protocol" type="hidden" value="{{ g.user.LABEL }}"></input>
<input name="protocol" type="hidden" value="{{ user.LABEL }}"></input>
<button type="submit" class="btn btn-default">Follow</button>
</nobr>
</form>

Wyświetl plik

@ -2,7 +2,7 @@
{% set subtab = "following" %}
{% block subsubtabs %}
{% if g.user.LABEL != 'activitypub' %}
{% if user.LABEL != 'activitypub' %}
<div class="row">
<form method="post" action="/follow/start">
<p>
@ -10,7 +10,7 @@
<input id="follower-address" name="address" type="text" required
placeholder="@user@domain.social" alt="fediverse address"
value="{{ address or '' }}"></input>
<input name="me" type="hidden" value="{{ g.user.web_url() }}"></input>
<input name="me" type="hidden" value="{{ user.web_url() }}"></input>
<button type="submit" class="btn btn-default">Follow</button>
</p>
</form>

Wyświetl plik

@ -4,8 +4,8 @@
{% block subtabs %}
<div class="row">
Subscribe:
<a href="{{ g.user.user_page_path('feed?format=html') }}">HTML</a>
&middot; <a href="{{ g.user.user_page_path('feed?format=atom') }}">Atom</a>
&middot; <a href="{{ g.user.user_page_path('feed?format=rss') }}">RSS</a>
<a href="{{ user.user_page_path('feed?format=html') }}">HTML</a>
&middot; <a href="{{ user.user_page_path('feed?format=atom') }}">Atom</a>
&middot; <a href="{{ user.user_page_path('feed?format=rss') }}">RSS</a>
</div>
{% endblock subtabs %}

Wyświetl plik

@ -4,8 +4,8 @@
{% block subtabs %}
<div class="row">
Subscribe:
<a href="{{ g.user.user_page_path('notifications?format=html') }}">HTML</a>
&middot; <a href="{{ g.user.user_page_path('notifications?format=atom') }}">Atom</a>
&middot; <a href="{{ g.user.user_page_path('notifications?format=rss') }}">RSS</a>
<a href="{{ user.user_page_path('notifications?format=html') }}">HTML</a>
&middot; <a href="{{ user.user_page_path('notifications?format=atom') }}">Atom</a>
&middot; <a href="{{ user.user_page_path('notifications?format=rss') }}">RSS</a>
</div>
{% endblock subtabs %}

Wyświetl plik

@ -4,13 +4,13 @@
{% block subtabs %}
<div class="row tabs">
<a></a>
<a href="{{ g.user.user_page_path() }}"
<a href="{{ user.user_page_path() }}"
{% if not subtab %}class="active-tab"{% endif %}
>activity</a><a
href="{{ g.user.user_page_path('followers') }}"
href="{{ user.user_page_path('followers') }}"
{% if subtab == 'followers' %}class="active-tab"{% endif %}
>{{ num_followers }} follower{% if followers != '1' %}s{% endif %}</a><a
href="{{ g.user.user_page_path('following') }}"
href="{{ user.user_page_path('following') }}"
{% if subtab == 'following' %}class="active-tab"{% endif %}
>following {{ num_following }}</a>
<a></a>

Wyświetl plik

@ -4,31 +4,31 @@
{% block content %}
{% if g.user.LABEL == 'web' %}
{% if g.user.has_redirects == False %}
{% if user.LABEL == 'web' %}
{% if user.has_redirects == False %}
<div class="row promo warning">
<form method="post" action="/web-site">
Next step:
<a href="/docs#redirect+these+URL+paths">
add the .well-known redirects.
</a>
<input type="hidden" name="url" value="{{ g.user.web_url() }}" />
<input type="hidden" name="url" value="{{ user.web_url() }}" />
<input type="submit" class="btn btn-default" value="Check now" />
</form>
{% if g.user.redirects_error %}
{% if user.redirects_error %}
<details class="small">
{{ g.user.redirects_error|safe }}
{{ user.redirects_error|safe }}
</details>
{% endif %}
</div>
{% endif %}
{% if g.user.has_hcard == False %}
{% if user.has_hcard == False %}
<div class="row promo warning">
<form method="post" action="/web-site">
Next step: <a href="/docs#profile">add a representative h-card.</a>
<input type="hidden" name="url" value="{{ g.user.web_url() }}" />
<input type="hidden" name="url" value="{{ user.web_url() }}" />
<input type="submit" class="btn btn-default" value="Check now" />
</form>
</div>
@ -37,17 +37,17 @@
<div class="row">
<span class="big">
{{ g.user.user_link()|safe }}
{{ user.user_link()|safe }}
&middot;
<nobr>
<a href="{{ g.user.web_url() }}"
title="{{ g.user.__class__.__name__ }} (native)">
<span class="logo">{{ g.user.LOGO_HTML|safe }}</span>
{{ g.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>
<!-- TODO: make this work with protocols other than Web -->
<form method="post" action="/webmention-interactive">
<input name="source" type="hidden" value="{{ g.user.web_url() }}" />
<input name="source" type="hidden" value="{{ user.web_url() }}" />
<button id="update-profile-button" type="submit" title="Update profile"
class="btn btn-default glyphicon glyphicon-refresh"></button>
</form>
@ -56,11 +56,11 @@
</span>
{% for proto in set(PROTOCOLS.values()) %}
{% if proto and not isinstance(g.user, proto)
{% if proto and not isinstance(user, proto)
and proto.LABEL not in ('atproto', 'ui') %}
<nobr title="{{ proto.__name__ }} (bridged)">
<span class="logo">{{ proto.LOGO_HTML|safe }}</span>
{{ g.user.ap_address() }}
{{ user.ap_address() }}
</nobr>
{% endif %}
{% endfor %}
@ -69,13 +69,13 @@
<!-- tabs -->
<div class="row tabs">
<a class="left-tab"></a>
<a href="{{ g.user.user_page_path() }}"
<a href="{{ user.user_page_path() }}"
{% if tab == 'profile' %}class="active-tab"{% endif %}
>👤 Profile</a>{% if g.user.LABEL == 'web' %}<a
href="{{ g.user.user_page_path('home') }}"
>👤 Profile</a>{% if user.LABEL == 'web' %}<a
href="{{ user.user_page_path('home') }}"
{% if tab == 'home' %}class="active-tab"{% endif %}
>🏠 Feed</a>{% endif %}<a
href="{{ g.user.user_page_path('notifications') }}"
href="{{ user.user_page_path('notifications') }}"
{% if tab == 'notifications' %}class="active-tab"{% endif %}
>🔔 Notifications</a>
<a class="right-tab"></a>