kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
f37baeba58
commit
b1b2478b66
34
pages.py
34
pages.py
|
@ -110,7 +110,6 @@ def web_user_redirects(**kwargs):
|
||||||
@app.get(f'/ap/@<id>', defaults={'protocol': 'ap'})
|
@app.get(f'/ap/@<id>', defaults={'protocol': 'ap'})
|
||||||
def profile(protocol, id):
|
def profile(protocol, id):
|
||||||
load_user(protocol, id)
|
load_user(protocol, id)
|
||||||
|
|
||||||
query = Object.query(Object.users == g.user.key)
|
query = Object.query(Object.users == g.user.key)
|
||||||
objects, before, after = fetch_objects(query, by=Object.updated)
|
objects, before, after = fetch_objects(query, by=Object.updated)
|
||||||
num_followers, num_following = count_followers()
|
num_followers, num_following = count_followers()
|
||||||
|
@ -120,7 +119,6 @@ def profile(protocol, id):
|
||||||
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/home')
|
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/home')
|
||||||
def home(protocol, id):
|
def home(protocol, id):
|
||||||
load_user(protocol, id)
|
load_user(protocol, id)
|
||||||
|
|
||||||
query = Object.query(Object.feed == g.user.key)
|
query = Object.query(Object.feed == g.user.key)
|
||||||
objects, before, after = fetch_objects(query, by=Object.created)
|
objects, before, after = fetch_objects(query, by=Object.created)
|
||||||
return render_template('home.html', **TEMPLATE_VARS, **locals())
|
return render_template('home.html', **TEMPLATE_VARS, **locals())
|
||||||
|
@ -132,6 +130,13 @@ def notifications(protocol, id):
|
||||||
|
|
||||||
query = Object.query(Object.notify == g.user.key)
|
query = Object.query(Object.notify == g.user.key)
|
||||||
objects, before, after = fetch_objects(query, by=Object.updated)
|
objects, before, after = fetch_objects(query, by=Object.updated)
|
||||||
|
|
||||||
|
format = request.args.get('format')
|
||||||
|
if format:
|
||||||
|
return serve_feed(objects=objects, format=format,
|
||||||
|
title=f'Bridgy Fed notifications for {id}')
|
||||||
|
|
||||||
|
# notifications tab UI page
|
||||||
return render_template('notifications.html', **TEMPLATE_VARS, **locals())
|
return render_template('notifications.html', **TEMPLATE_VARS, **locals())
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,16 +168,30 @@ def count_followers():
|
||||||
|
|
||||||
return num_followers, num_following
|
return num_followers, num_following
|
||||||
|
|
||||||
|
|
||||||
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/feed')
|
@app.get(f'/<any({",".join(PROTOCOLS)}):protocol>/<id>/feed')
|
||||||
def feed(protocol, id):
|
def feed(protocol, id):
|
||||||
format = request.args.get('format', 'html')
|
load_user(protocol, id)
|
||||||
|
query = Object.query(Object.feed == g.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}')
|
||||||
|
|
||||||
|
|
||||||
|
def serve_feed(*, objects, format, title):
|
||||||
|
"""Generates a feed based on :class:`Object`s.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
objects (sequence of models.Object)
|
||||||
|
format (str): ``html``, ``atom``, or ``rss``
|
||||||
|
title (str)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str or (str, dict) tuple: Flask response
|
||||||
|
"""
|
||||||
if format not in ('html', 'atom', 'rss'):
|
if format not in ('html', 'atom', 'rss'):
|
||||||
error(f'format {format} not supported; expected html, atom, or rss')
|
error(f'format {format} not supported; expected html, atom, or rss')
|
||||||
|
|
||||||
load_user(protocol, id)
|
|
||||||
|
|
||||||
query = Object.query(Object.feed == g.user.key)
|
|
||||||
objects, _, _ = fetch_objects(query, by=Object.created)
|
|
||||||
activities = [obj.as1 for obj in objects if not obj.deleted]
|
activities = [obj.as1 for obj in objects if not obj.deleted]
|
||||||
|
|
||||||
# hydrate authors, actors, objects from stored Objects
|
# hydrate authors, actors, objects from stored Objects
|
||||||
|
@ -198,7 +217,6 @@ def feed(protocol, id):
|
||||||
'displayName': id,
|
'displayName': id,
|
||||||
'url': g.user.web_url(),
|
'url': g.user.web_url(),
|
||||||
}
|
}
|
||||||
title = f'Bridgy Fed feed for {id}'
|
|
||||||
|
|
||||||
# TODO: inject/merge common.pretty_link into microformats2.render_content
|
# TODO: inject/merge common.pretty_link into microformats2.render_content
|
||||||
# (specifically into hcard_to_html) somehow to convert Mastodon URLs to @-@
|
# (specifically into hcard_to_html) somehow to convert Mastodon URLs to @-@
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="big">None yet. Check back soon!</span>
|
<span class="big">No one yet. Check back soon!</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="big">None yet. Check back soon!</span>
|
<span class="big">No activity yet. Check back soon!</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
{% block title %}{{ g.user.handle_or_id() }}'s feed - Bridgy Fed{% endblock %}
|
{% block title %}{{ g.user.handle_or_id() }}'s feed - Bridgy Fed{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="h-feed">
|
||||||
<div class="row big">Feed</div>
|
<div class="row big p-name">{{ title }}</div>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/feed.css" type="text/css" />
|
<link rel="stylesheet" href="/static/feed.css" type="text/css" />
|
||||||
<div class="row h-feed">
|
<div class="row">
|
||||||
{% for e in entries %}
|
{% for e in entries %}
|
||||||
{{ e|safe }}
|
{{ e|safe }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Nothing yet. <a href="/#To+use+it">Follow more people</a>, check back soon!
|
Nothing yet. <a href="/#To+use+it">Follow more people</a>, check back soon!
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
{% block subtabs %}
|
{% block subtabs %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
Subscribe:
|
Subscribe:
|
||||||
<a href="{{ g.user.user_page_path('feed') }}">HTML</a>
|
<a href="{{ g.user.user_page_path('notifications?format=html') }}">HTML</a>
|
||||||
· <a href="{{ g.user.user_page_path('feed?format=atom') }}">Atom</a>
|
· <a href="{{ g.user.user_page_path('notifications?format=atom') }}">Atom</a>
|
||||||
· <a href="{{ g.user.user_page_path('feed?format=rss') }}">RSS</a>
|
· <a href="{{ g.user.user_page_path('notifications?format=rss') }}">RSS</a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock subtabs %}
|
{% endblock subtabs %}
|
||||||
|
|
|
@ -40,7 +40,8 @@
|
||||||
{{ g.user.user_link()|safe }}
|
{{ g.user.user_link()|safe }}
|
||||||
·
|
·
|
||||||
<nobr>
|
<nobr>
|
||||||
<a href="{{ g.user.web_url() }}" title="{{ g.user.__class__.__name__ }}">
|
<a href="{{ g.user.web_url() }}"
|
||||||
|
title="{{ g.user.__class__.__name__ }} (native)">
|
||||||
<span class="logo">{{ g.user.LOGO_HTML }}</span>
|
<span class="logo">{{ g.user.LOGO_HTML }}</span>
|
||||||
{{ g.user.handle_or_id() }}</a>
|
{{ g.user.handle_or_id() }}</a>
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,37 @@ class PagesTest(TestCase):
|
||||||
got = self.client.get('/web/user.com/home')
|
got = self.client.get('/web/user.com/home')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
|
||||||
|
def test_notifications_fake(self):
|
||||||
|
self.make_user('fake:foo', cls=Fake)
|
||||||
|
got = self.client.get('/fa/fake:foo/notifications')
|
||||||
|
self.assert_equals(200, got.status_code)
|
||||||
|
|
||||||
|
def test_notifications_objects(self):
|
||||||
|
self.add_objects()
|
||||||
|
got = self.client.get('/web/user.com/notifications')
|
||||||
|
self.assert_equals(200, got.status_code)
|
||||||
|
|
||||||
|
def test_notifications_rss(self):
|
||||||
|
self.add_objects()
|
||||||
|
got = self.client.get('/web/user.com/notifications?format=rss')
|
||||||
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(rss.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
|
self.assert_equals(self.EXPECTED, contents(rss.to_activities(got.text)))
|
||||||
|
|
||||||
|
def test_notifications_atom(self):
|
||||||
|
self.add_objects()
|
||||||
|
got = self.client.get('/web/user.com/notifications?format=atom')
|
||||||
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(atom.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
|
self.assert_equals(self.EXPECTED, contents(atom.atom_to_activities(got.text)))
|
||||||
|
|
||||||
|
def test_notifications_html(self):
|
||||||
|
self.add_objects()
|
||||||
|
got = self.client.get('/web/user.com/notifications?format=html')
|
||||||
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(self.EXPECTED,
|
||||||
|
contents(microformats2.html_to_activities(got.text)))
|
||||||
|
|
||||||
def test_followers_fake(self):
|
def test_followers_fake(self):
|
||||||
self.make_user('fake:foo', cls=Fake)
|
self.make_user('fake:foo', cls=Fake)
|
||||||
got = self.client.get('/fa/fake:foo/followers')
|
got = self.client.get('/fa/fake:foo/followers')
|
||||||
|
@ -294,12 +325,14 @@ class PagesTest(TestCase):
|
||||||
def test_feed_atom_empty(self):
|
def test_feed_atom_empty(self):
|
||||||
got = self.client.get('/web/user.com/feed?format=atom')
|
got = self.client.get('/web/user.com/feed?format=atom')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(atom.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
self.assert_equals([], atom.atom_to_activities(got.text))
|
self.assert_equals([], atom.atom_to_activities(got.text))
|
||||||
|
|
||||||
def test_feed_atom(self):
|
def test_feed_atom(self):
|
||||||
self.add_objects()
|
self.add_objects()
|
||||||
got = self.client.get('/web/user.com/feed?format=atom')
|
got = self.client.get('/web/user.com/feed?format=atom')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(atom.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
self.assert_equals(self.EXPECTED, contents(atom.atom_to_activities(got.text)))
|
self.assert_equals(self.EXPECTED, contents(atom.atom_to_activities(got.text)))
|
||||||
|
|
||||||
# NOTE's and MENTION's authors; check for two instances
|
# NOTE's and MENTION's authors; check for two instances
|
||||||
|
@ -315,12 +348,14 @@ class PagesTest(TestCase):
|
||||||
def test_feed_rss_empty(self):
|
def test_feed_rss_empty(self):
|
||||||
got = self.client.get('/web/user.com/feed?format=rss')
|
got = self.client.get('/web/user.com/feed?format=rss')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(rss.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
self.assert_equals([], rss.to_activities(got.text))
|
self.assert_equals([], rss.to_activities(got.text))
|
||||||
|
|
||||||
def test_feed_rss(self):
|
def test_feed_rss(self):
|
||||||
self.add_objects()
|
self.add_objects()
|
||||||
got = self.client.get('/web/user.com/feed?format=rss')
|
got = self.client.get('/web/user.com/feed?format=rss')
|
||||||
self.assert_equals(200, got.status_code)
|
self.assert_equals(200, got.status_code)
|
||||||
|
self.assert_equals(rss.CONTENT_TYPE, got.headers['Content-Type'])
|
||||||
self.assert_equals(self.EXPECTED, contents(rss.to_activities(got.text)))
|
self.assert_equals(self.EXPECTED, contents(rss.to_activities(got.text)))
|
||||||
|
|
||||||
# NOTE's and MENTION's authors; check for two instances
|
# NOTE's and MENTION's authors; check for two instances
|
||||||
|
|
Ładowanie…
Reference in New Issue