kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
a1a7ceef51
commit
8b3881dfe3
|
@ -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,
|
||||
|
|
63
pages.py
63
pages.py
|
@ -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'
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
{% block subtabs %}
|
||||
<div class="row">
|
||||
Subscribe:
|
||||
<a href="{{ g.user.user_page_path('feed?format=html') }}">HTML</a>
|
||||
· <a href="{{ g.user.user_page_path('feed?format=atom') }}">Atom</a>
|
||||
· <a href="{{ g.user.user_page_path('feed?format=rss') }}">RSS</a>
|
||||
<a href="{{ user.user_page_path('feed?format=html') }}">HTML</a>
|
||||
· <a href="{{ user.user_page_path('feed?format=atom') }}">Atom</a>
|
||||
· <a href="{{ user.user_page_path('feed?format=rss') }}">RSS</a>
|
||||
</div>
|
||||
{% endblock subtabs %}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
{% block subtabs %}
|
||||
<div class="row">
|
||||
Subscribe:
|
||||
<a href="{{ g.user.user_page_path('notifications?format=html') }}">HTML</a>
|
||||
· <a href="{{ g.user.user_page_path('notifications?format=atom') }}">Atom</a>
|
||||
· <a href="{{ g.user.user_page_path('notifications?format=rss') }}">RSS</a>
|
||||
<a href="{{ user.user_page_path('notifications?format=html') }}">HTML</a>
|
||||
· <a href="{{ user.user_page_path('notifications?format=atom') }}">Atom</a>
|
||||
· <a href="{{ user.user_page_path('notifications?format=rss') }}">RSS</a>
|
||||
</div>
|
||||
{% endblock subtabs %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 }}
|
||||
·
|
||||
<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>
|
||||
|
|
Ładowanie…
Reference in New Issue