Support user timelines.

Other user stuff (profile info, follows/followers) and operations on users
(follow, block, report) are not added, but relatively easy.
This commit is contained in:
Jason McBrayer 2018-05-08 21:47:17 -04:00
parent 9c038a35dd
commit 0191bc2f98
5 changed files with 91 additions and 15 deletions

View File

@ -5,12 +5,16 @@
<article class="media">
<figure class="media-left">
<p class="image is-64x64">
<a href="{% url "user" toot.account.acct %}">
<img src="{{ toot.account.avatar }}"
alt="">
</a>
</p>
{% if reblog %}
<p class="image is-32x32 reblog-icon" >
<a href="{% url "user" reblog_by %}">
<img src ="{{ reblog_icon }}" alt="">
</a>
</p>
{% endif %}
</figure>
@ -18,7 +22,7 @@
<div class="content">
<p>
<strong>{{ toot.account.display_name }}</strong>
<small>@{{ toot.account.acct }}</small>
<small><a href="{% url "user" toot.account.acct %}">@{{ toot.account.acct }}</a></small>
<a href="{{ toot.url }}">
<small>{{ toot.created_at |naturaltime }}</small>
</a>

View File

@ -0,0 +1,44 @@
{% extends "base.html" %}
{% load humanize %}
{% block title %}
Brutaldon - {{ timeline }} timelime
{% endblock %}
{% block content %}
<h1 class="title">User information for {{ user.display_name }} (@{{ user.acct }})</h1>
<div class="box">
<p>FIXME</p>
</div>
<h1 class="title">{{ user.display_name }}'s visible toots</h1>
{% for toot in toots %}
<div class="box">
{% if toot.reblog %}
{% include "main/toot_partial.html" with toot=toot.reblog reblog=True reblog_by=toot.account.acct reblog_icon=toot.account.avatar %}
{% else %}
{% include "main/toot_partial.html" with toot=toot reblog=False %}
{% endif %}
</div>
<hr class="is-hidden">
{% endfor %}
<nav class="pagination" role="navigation" aria-label="pagination">
<a class="pagination-previous"
title="This is the first page" disabled>Previous</a>
<a class="pagination-next">Next page</a>
<ul class="pagination-list">
<li>
<a class="pagination-link is-current" aria-label="Page 1"
aria-current="page">1</a>
</li>
<li>
<a class="pagination-link" aria-label="Goto page 2">2</a>
</li>
<li>
<a class="pagination-link" aria-label="Goto page 3">3</a>
</li>
</ul>
</nav>
{% endblock %}

View File

@ -13,13 +13,34 @@ def relink_tags(value):
not necessarily GNU Social, Pleroma, or other fediverse servers, because
it relies on the markup that Mastodon puts on tags.
FIXME: handle arbitrary tag lengths.
FIXME: handle arbitrary tag links
'''
soup = BeautifulSoup(value, 'html.parser')
for link in soup.find_all('a', class_='hashtag'):
link['href'] = reverse('tag', args=[link.span.string])
return soup.decode(formatter=None)
@register.filter
def relink_mentions(value):
'''Treat the text as html, and replace mention links with app-internal links
Currently, this only works for mentions in toots coming from Mastodon servers,
not necessarily GNU Social, Pleroma, or other fediverse servers, because
it relies on the markup that Mastodon puts on mentions.
FIXME: handle arbitrary mention links
'''
soup = BeautifulSoup(value, 'html.parser')
for link in soup.find_all('a', class_='mention'):
parsed = parse.urlparse(link['href'])
try:
instance = parsed[1]
user = parsed[2][2:]
link['href'] = reverse('user', args=[user+'@'+instance])
except:
continue
return soup.decode(formatter=None)
@register.filter
def relink_toot(value):
return relink_tags(value)
return relink_tags(relink_mentions(value))

View File

@ -29,6 +29,7 @@ urlpatterns = [
path('settings', views.settings, name='settings'),
path('thread/<int:id>', views.thread, name='thread'),
path('tags/<tag>', views.tag, name='tag'),
path('user/<username>', views.user, name='user'),
path('toot', views.toot, name="toot"),
path('reply/<int:id>', views.reply, name='reply'),
path('fav/<int:id>', views.fav, name='fav'),

View File

@ -1,4 +1,4 @@
from django.http import HttpResponse
from django.http import HttpResponse, Http404
from django.shortcuts import render, redirect
from django.views.decorators.cache import never_cache
from brutaldon.forms import LoginForm, SettingsForm, PostForm
@ -48,19 +48,15 @@ def timeline(request, timeline='home', timeline_name='Home'):
{'toots': data, 'form': form, 'timeline': timeline_name,
'fullbrutalism': fullbrutalism_p(request)})
@never_cache
def home(request):
return timeline(request, 'home', 'Home')
@never_cache
def local(request):
return timeline(request, 'local', 'Local')
@never_cache
def fed(request):
return timeline(request, 'public', 'Federated')
@never_cache
def tag(request, tag):
try:
mastodon = get_mastodon(request)
@ -71,7 +67,7 @@ def tag(request, tag):
{'toots': data, 'timeline': '#'+tag,
'fullbrutalism': fullbrutalism_p(request)})
@never_cache
def login(request):
if request.method == "GET":
form = LoginForm()
@ -129,6 +125,7 @@ def login(request):
else:
return render(request, 'setup/login.html', {'form': form})
@never_cache
def logout(request):
request.session.flush()
return redirect(home)
@ -136,7 +133,6 @@ def logout(request):
def error(request):
return render(request, 'error.html', { 'error': "Not logged in yet."})
@never_cache
def note(request):
mastodon = get_mastodon(request)
notes = mastodon.notifications()
@ -144,7 +140,6 @@ def note(request):
{'notes': notes,'timeline': 'Notifications',
'fullbrutalism': fullbrutalism_p(request)})
@never_cache
def thread(request, id):
mastodon = get_mastodon(request)
context = mastodon.status_context(id)
@ -153,6 +148,18 @@ def thread(request, id):
{'context': context, 'toot': toot,
'fullbrutalism': fullbrutalism_p(request)})
def user(request, username):
mastodon = get_mastodon(request)
try:
user_dict = mastodon.account_search(username)[0]
except IndexError:
raise Http404("The user %s could not be found." % username)
data = mastodon.account_statuses(user_dict.id)
return render(request, 'main/user.html',
{'toots': data, 'user': user_dict,
'fullbrutalism': fullbrutalism_p(request)})
@never_cache
def settings(request):
if request.method == 'POST':
@ -202,7 +209,6 @@ def toot(request):
else:
return redirect(toot)
@never_cache
def reply(request, id):
if request.method == 'GET':
mastodon = get_mastodon(request)