mirror of
https://github.com/jfmcbrayer/brutaldon
synced 2025-01-07 04:42:06 +01:00
1660 lines
55 KiB
Python
1660 lines
55 KiB
Python
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
|
from django.db import IntegrityError
|
|
from django.conf import settings as django_settings
|
|
from django.shortcuts import render, redirect
|
|
from django.urls import reverse
|
|
from django.views.decorators.cache import never_cache, cache_page
|
|
from django.urls import reverse
|
|
from django.core.files.uploadhandler import TemporaryFileUploadHandler
|
|
from django.utils.translation import gettext as _
|
|
from brutaldon.forms import (
|
|
LoginForm,
|
|
OAuthLoginForm,
|
|
PreferencesForm,
|
|
PostForm,
|
|
FilterForm,
|
|
)
|
|
from brutaldon.models import Client, Account, Preference, Theme
|
|
from mastodon import (
|
|
Mastodon,
|
|
AttribAccessDict,
|
|
MastodonError,
|
|
MastodonAPIError,
|
|
MastodonNotFoundError,
|
|
)
|
|
from urllib import parse
|
|
from pdb import set_trace
|
|
from inscriptis import get_text
|
|
from time import sleep
|
|
from requests import Session
|
|
import re
|
|
|
|
|
|
class NotLoggedInException(Exception):
|
|
pass
|
|
|
|
global sessons_cache
|
|
sessions_cache = {}
|
|
|
|
###
|
|
### Utility functions
|
|
###
|
|
|
|
def get_session(domain):
|
|
if domain in sessions_cache:
|
|
return sessions_cache[domain]
|
|
else:
|
|
s = Session()
|
|
sessions_cache[domain] = s
|
|
return s
|
|
|
|
def get_usercontext(request):
|
|
if is_logged_in(request):
|
|
try:
|
|
client = Client.objects.get(api_base_id=request.session["active_instance"])
|
|
user = Account.objects.get(username=request.session["active_username"])
|
|
except (
|
|
Client.DoesNotExist,
|
|
Client.MultipleObjectsReturned,
|
|
Account.DoesNotExist,
|
|
Account.MultipleObjectsReturned,
|
|
):
|
|
raise NotLoggedInException()
|
|
mastodon = Mastodon(
|
|
client_id=client.client_id,
|
|
client_secret=client.client_secret,
|
|
access_token=user.access_token,
|
|
api_base_url=client.api_base_id,
|
|
session = get_session(client.api_base_id),
|
|
ratelimit_method="throw",
|
|
)
|
|
return user, mastodon
|
|
else:
|
|
return None, None
|
|
|
|
|
|
def is_logged_in(request):
|
|
return request.session.has_key("active_user")
|
|
|
|
|
|
def _notes_count(account, mastodon):
|
|
if not mastodon:
|
|
return ""
|
|
notes = mastodon.notifications(limit=40)
|
|
if account.preferences.filter_notifications:
|
|
notes = [
|
|
note for note in notes if note.type == "mention" or note.type == "follow"
|
|
]
|
|
for index, item in enumerate(notes):
|
|
if account.note_seen is None:
|
|
account.note_seen = "0"
|
|
account.save()
|
|
if str(item.id) <= str(account.note_seen):
|
|
break
|
|
else:
|
|
index = "40+"
|
|
return str(index)
|
|
|
|
|
|
def br_login_required(function=None, home_url=None, redirect_field_name=None):
|
|
"""Check that the user is logged in to a Mastodon instance.
|
|
|
|
This decorator ensures that the view functions it is called on can be
|
|
accessed only by logged in users. When an instanceless user accesses
|
|
such a protected view, they are redirected to the address specified in
|
|
the field named in `next_field` or, lacking such a value, the URL in
|
|
`home_url`, or the `ANONYMOUS_HOME_URL` setting.
|
|
"""
|
|
if home_url is None:
|
|
home_url = django_settings.ANONYMOUS_HOME_URL
|
|
|
|
def _dec(view_func):
|
|
def _view(request, *args, **kwargs):
|
|
if not is_logged_in(request):
|
|
url = None
|
|
if redirect_field_name and redirect_field_name in request.REQUEST:
|
|
url = request.REQUEST[redirect_field_name]
|
|
if not url:
|
|
url = home_url
|
|
if not url:
|
|
url = "/"
|
|
return HttpResponseRedirect(url)
|
|
else:
|
|
return view_func(request, *args, **kwargs)
|
|
|
|
_view.__name__ = view_func.__name__
|
|
_view.__dict__ = view_func.__dict__
|
|
_view.__doc__ = view_func.__doc__
|
|
|
|
return _view
|
|
|
|
if function is None:
|
|
return _dec
|
|
else:
|
|
return _dec(function)
|
|
|
|
|
|
def user_search(request):
|
|
check = request.POST.get("status", "").split()
|
|
if len(check):
|
|
check = check[-1]
|
|
if len(check) > 1 and check.startswith("@"):
|
|
check = check[1:]
|
|
return user_search_inner(request, check)
|
|
else:
|
|
check = " "
|
|
else:
|
|
check = " "
|
|
return HttpResponse(check)
|
|
|
|
|
|
def user_search_inner(request, query):
|
|
account, mastodon = get_usercontext(request)
|
|
results = mastodon.search(query)
|
|
return render(
|
|
request,
|
|
"intercooler/users.html",
|
|
{
|
|
"users": "\n".join([user.acct for user in results.accounts]),
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
def timeline(
|
|
request,
|
|
timeline="home",
|
|
timeline_name="Home",
|
|
max_id=None,
|
|
min_id=None,
|
|
filter_context="home",
|
|
):
|
|
account, mastodon = get_usercontext(request)
|
|
data = mastodon.timeline(timeline, limit=40, max_id=max_id, min_id=min_id)
|
|
form = PostForm(
|
|
initial={"visibility": request.session["active_user"].source.privacy}
|
|
)
|
|
try:
|
|
prev = data[0]._pagination_prev
|
|
if len(mastodon.timeline(min_id=prev["min_id"])) == 0:
|
|
prev = None
|
|
else:
|
|
prev["min_id"] = data[0].id
|
|
except (IndexError, AttributeError, KeyError):
|
|
prev = None
|
|
try:
|
|
next = data[-1]._pagination_next
|
|
next["max_id"] = data[-1].id
|
|
except (IndexError, AttributeError, KeyError):
|
|
next = None
|
|
|
|
notifications = _notes_count(account, mastodon)
|
|
filters = get_filters(mastodon, filter_context)
|
|
|
|
# This filtering has to be done *after* getting next/prev links
|
|
if account.preferences.filter_replies:
|
|
data = [x for x in data if not x.in_reply_to_id]
|
|
if account.preferences.filter_boosts:
|
|
data = [x for x in data if not x.reblog]
|
|
|
|
# Apply filters
|
|
data = [x for x in data if not toot_matches_filters(x, filters)]
|
|
|
|
return render(
|
|
request,
|
|
"main/%s_timeline.html" % timeline,
|
|
{
|
|
"toots": data,
|
|
"form": form,
|
|
"timeline": timeline,
|
|
"timeline_name": timeline_name,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
"notifications": notifications,
|
|
"prev": prev,
|
|
"next": next,
|
|
},
|
|
)
|
|
|
|
|
|
def get_filters(mastodon, context=None):
|
|
try:
|
|
if context:
|
|
return [ff for ff in mastodon.filters() if context in ff.context]
|
|
else:
|
|
return mastodon.filters()
|
|
except:
|
|
return []
|
|
|
|
|
|
def toot_matches_filters(toot, filters=[]):
|
|
if not filters:
|
|
return False
|
|
|
|
def maybe_rewrite_filter(filter):
|
|
if filter.whole_word:
|
|
return f"\\b{filter.phrase}\\b"
|
|
else:
|
|
return filter.phrase
|
|
|
|
phrases = [maybe_rewrite_filter(x) for x in filters]
|
|
pattern = "|".join(phrases)
|
|
try:
|
|
if toot.get("type") in ["reblog", "favourite"]:
|
|
return re.search(
|
|
pattern, toot.status.spoiler_text + toot.status.content, re.I
|
|
)
|
|
return re.search(pattern, toot.spoiler_text + toot.content, re.I)
|
|
except:
|
|
return False
|
|
|
|
|
|
def switch_accounts(request, new_account):
|
|
"""Try to switch accounts to the specified account, if it is already in
|
|
the user's session. Sets up new session variables. Returns boolean success
|
|
code."""
|
|
accounts_dict = request.session.get("accounts_dict")
|
|
if not accounts_dict or not new_account in accounts_dict.keys():
|
|
return False
|
|
try:
|
|
account = Account.objects.get(id=accounts_dict[new_account]["account_id"])
|
|
if account.username != new_account:
|
|
return False
|
|
except Account.DoesNotExist:
|
|
return False
|
|
|
|
request.session["active_username"] = account.username
|
|
request.session["active_instance"] = account.client.api_base_id
|
|
account, mastodon = get_usercontext(request)
|
|
request.session["active_user"] = mastodon.account_verify_credentials()
|
|
accounts_dict[new_account]["user"] = request.session["active_user"]
|
|
request.session["accounts_dict"] = accounts_dict
|
|
return True
|
|
|
|
|
|
def forget_account(request, account_name):
|
|
"""Forget that you were logged into an account. If it's the last one, log out
|
|
entirely. Sets up session variables. Returns a redirect to the correct
|
|
view.
|
|
"""
|
|
accounts_dict = request.session.get("accounts_dict")
|
|
if not accounts_dict or not account_name in accounts_dict.keys():
|
|
return redirect("accounts")
|
|
del accounts_dict[account_name]
|
|
if len(accounts_dict) == 0:
|
|
request.session.flush()
|
|
return redirect("about")
|
|
elif account_name == request.session["active_username"]:
|
|
key = [*accounts_dict][0]
|
|
if switch_accounts(request, key):
|
|
return redirect("accounts")
|
|
else:
|
|
request.session.flush()
|
|
return redirect("about")
|
|
else:
|
|
request.session["accounts_dict"] = accounts_dict
|
|
return redirect("accounts")
|
|
|
|
|
|
###
|
|
### View functions
|
|
###
|
|
|
|
|
|
def notes_count(request):
|
|
account, mastodon = get_usercontext(request)
|
|
count = _notes_count(account, mastodon)
|
|
return render(
|
|
request,
|
|
"intercooler/notes.html",
|
|
{"notifications": count, "preferences": account.preferences},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def home(request, next=None, prev=None):
|
|
return timeline(
|
|
request, "home", "Home", max_id=next, min_id=prev, filter_context="home"
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def local(request, next=None, prev=None, filter_context="public"):
|
|
return timeline(request, "local", "Local", max_id=next, min_id=prev)
|
|
|
|
|
|
@br_login_required
|
|
def fed(request, next=None, prev=None, filter_context="public"):
|
|
return timeline(request, "public", "Federated", max_id=next, min_id=prev)
|
|
|
|
|
|
@br_login_required
|
|
def tag(request, tag):
|
|
try:
|
|
account, mastodon = get_usercontext(request)
|
|
except NotLoggedInException:
|
|
return redirect(login)
|
|
data = mastodon.timeline_hashtag(tag)
|
|
notifications = _notes_count(account, mastodon)
|
|
return render(
|
|
request,
|
|
"main/timeline.html",
|
|
{
|
|
"toots": data,
|
|
"timeline_name": "#" + tag,
|
|
"own_acct": request.session["active_user"],
|
|
"notifications": notifications,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
def login(request):
|
|
# User posts instance name in form.
|
|
# POST page redirects user to instance, where they log in.
|
|
# Instance redirects user to oauth_after_login view.
|
|
# oauth_after_login view saves credential in session, then redirects to home.
|
|
if request.method == "GET":
|
|
form = OAuthLoginForm()
|
|
return render(request, "setup/login-oauth.html", {"form": form})
|
|
elif request.method == "POST":
|
|
form = OAuthLoginForm(request.POST)
|
|
redirect_uris = request.build_absolute_uri(reverse("oauth_callback"))
|
|
if form.is_valid():
|
|
api_base_url = form.cleaned_data["instance"]
|
|
if "gab.com" in api_base_url:
|
|
return redirect(django_settings.GAB_RICKROLL_URL)
|
|
tmp_base = parse.urlparse(api_base_url.lower())
|
|
if tmp_base.netloc == "":
|
|
api_base_url = parse.urlunparse(
|
|
("https", tmp_base.path, "", "", "", "")
|
|
)
|
|
request.session["active_instance_hostname"] = tmp_base.path
|
|
else:
|
|
api_base_url = api_base_url.lower()
|
|
request.session["active_instance_hostname"] = tmp_base.netloc
|
|
|
|
request.session["active_instance"] = api_base_url
|
|
try:
|
|
client = Client.objects.get(api_base_id=api_base_url)
|
|
except (Client.DoesNotExist, Client.MultipleObjectsReturned):
|
|
(client_id, client_secret) = Mastodon.create_app(
|
|
"brutaldon",
|
|
api_base_url=api_base_url,
|
|
redirect_uris=redirect_uris,
|
|
scopes=["read", "write", "follow"],
|
|
)
|
|
client = Client(
|
|
api_base_id=api_base_url,
|
|
client_id=client_id,
|
|
client_secret=client_secret,
|
|
)
|
|
client.save()
|
|
|
|
request.session["active_client_id"] = client.client_id
|
|
request.session["active_client_secret"] = client.client_secret
|
|
|
|
mastodon = Mastodon(
|
|
client_id=client.client_id,
|
|
client_secret=client.client_secret,
|
|
api_base_url=api_base_url,
|
|
)
|
|
client.version = mastodon.instance().get("version")
|
|
client.save()
|
|
return redirect(
|
|
mastodon.auth_request_url(
|
|
redirect_uris=redirect_uris, scopes=["read", "write", "follow"]
|
|
)
|
|
)
|
|
else:
|
|
return render(request, "setup/login.html", {"form": form})
|
|
|
|
else:
|
|
return redirect(login)
|
|
|
|
|
|
@never_cache
|
|
def oauth_callback(request):
|
|
code = request.GET.get("code", "")
|
|
mastodon = Mastodon(
|
|
client_id=request.session["active_client_id"],
|
|
client_secret=request.session["active_client_secret"],
|
|
api_base_url=request.session["active_instance"],
|
|
)
|
|
redirect_uri = request.build_absolute_uri(reverse("oauth_callback"))
|
|
access_token = mastodon.log_in(
|
|
code=code, redirect_uri=redirect_uri, scopes=["read", "write", "follow"]
|
|
)
|
|
request.session["access_token"] = access_token
|
|
user = mastodon.account_verify_credentials()
|
|
try:
|
|
account = Account.objects.get(
|
|
username=user.username + "@" + request.session["active_instance_hostname"]
|
|
)
|
|
account.access_token = access_token
|
|
if not account.preferences:
|
|
preferences = Preference(theme=Theme.objects.get(id=1))
|
|
preferences.save()
|
|
account.preferences = preferences
|
|
else:
|
|
request.session["timezone"] = account.preferences.timezone
|
|
account.save()
|
|
except (Account.DoesNotExist, Account.MultipleObjectsReturned):
|
|
preferences = Preference(theme=Theme.objects.get(id=1))
|
|
preferences.save()
|
|
account = Account(
|
|
username=user.username + "@" + request.session["active_instance_hostname"],
|
|
access_token=access_token,
|
|
client=Client.objects.get(api_base_id=request.session["active_instance"]),
|
|
preferences=preferences,
|
|
)
|
|
account.save()
|
|
|
|
request.session["active_user"] = user
|
|
request.session["active_username"] = (
|
|
user.username + "@" + request.session["active_instance_hostname"]
|
|
)
|
|
|
|
accounts_dict = request.session.get("accounts_dict")
|
|
if not accounts_dict:
|
|
accounts_dict = {}
|
|
accounts_dict[account.username] = {"account_id": account.id, "user": user}
|
|
request.session["accounts_dict"] = accounts_dict
|
|
|
|
return redirect(home)
|
|
|
|
|
|
@never_cache
|
|
def old_login(request):
|
|
if request.method == "GET":
|
|
form = LoginForm()
|
|
return render(request, "setup/login.html", {"form": form})
|
|
elif request.method == "POST":
|
|
form = LoginForm(request.POST)
|
|
if form.is_valid():
|
|
api_base_url = form.cleaned_data["instance"]
|
|
if "gab.com" in api_base_url:
|
|
return redirect(django_settings.GAB_RICKROLL_URL)
|
|
tmp_base = parse.urlparse(api_base_url.lower())
|
|
if tmp_base.netloc == "":
|
|
api_base_url = parse.urlunparse(
|
|
("https", tmp_base.path, "", "", "", "")
|
|
)
|
|
request.session["active_instance_hostname"] = tmp_base.path
|
|
else:
|
|
api_base_url = api_base_url.lower()
|
|
request.session["active_instance_hostname"] = tmp_base.netloc
|
|
|
|
request.session["active_instance"] = api_base_url
|
|
email = form.cleaned_data["email"]
|
|
password = form.cleaned_data["password"]
|
|
|
|
try:
|
|
client = Client.objects.get(api_base_id=api_base_url)
|
|
except (Client.DoesNotExist, Client.MultipleObjectsReturned):
|
|
(client_id, client_secret) = Mastodon.create_app(
|
|
"brutaldon",
|
|
api_base_url=api_base_url,
|
|
scopes=["read", "write", "follow"],
|
|
)
|
|
client = Client(
|
|
api_base_id=api_base_url,
|
|
client_id=client_id,
|
|
client_secret=client_secret,
|
|
)
|
|
client.save()
|
|
|
|
mastodon = Mastodon(
|
|
client_id=client.client_id,
|
|
client_secret=client.client_secret,
|
|
api_base_url=api_base_url,
|
|
)
|
|
client.version = mastodon.instance().get("version")
|
|
client.save()
|
|
|
|
try:
|
|
account = Account.objects.get(email=email, client_id=client.id)
|
|
except (Account.DoesNotExist, Account.MultipleObjectsReturned):
|
|
preferences = Preference(theme=Theme.objects.get(id=1))
|
|
preferences.save()
|
|
account = Account(
|
|
email=email, access_token="", client=client, preferences=preferences
|
|
)
|
|
try:
|
|
access_token = mastodon.log_in(
|
|
email, password, scopes=["read", "write", "follow"]
|
|
)
|
|
account.access_token = access_token
|
|
user = mastodon.account_verify_credentials()
|
|
request.session["active_user"] = user
|
|
request.session["active_username"] = (
|
|
user.username + "@" + request.session["active_instance_hostname"]
|
|
)
|
|
account.username = request.session["active_username"]
|
|
request.session["timezone"] = account.preferences.timezone
|
|
|
|
accounts_dict = request.session.get("accounts_dict")
|
|
if not accounts_dict:
|
|
accounts_dict = {}
|
|
accounts_dict[account.username] = {
|
|
"account_id": account.id,
|
|
"user": user,
|
|
}
|
|
request.session["accounts_dict"] = accounts_dict
|
|
account.save()
|
|
|
|
return redirect(home)
|
|
except IntegrityError:
|
|
account = Account.objects.get(username=account.username)
|
|
accounts_dict[account.username] = {
|
|
"account_id": account.id,
|
|
"user": user,
|
|
}
|
|
request.session["accounts_dict"] = accounts_dict
|
|
return redirect(home)
|
|
except Exception as ex:
|
|
form.add_error("", ex)
|
|
return render(request, "setup/login.html", {"form": form})
|
|
else:
|
|
return render(request, "setup/login.html", {"form": form})
|
|
|
|
|
|
@never_cache
|
|
def logout(request):
|
|
request.session.flush()
|
|
return redirect(about)
|
|
|
|
|
|
def error(request):
|
|
return render(request, "error.html", {"error": _("Not logged in yet.")})
|
|
|
|
|
|
@br_login_required
|
|
def note(request, next=None, prev=None):
|
|
try:
|
|
account, mastodon = get_usercontext(request)
|
|
except NotLoggedInException:
|
|
return redirect(about)
|
|
last_seen = mastodon.notifications(limit=1)[0]
|
|
account.note_seen = last_seen.id
|
|
account.save()
|
|
|
|
notes = mastodon.notifications(limit=40, max_id=next, min_id=prev)
|
|
filters = get_filters(mastodon, context="notifications")
|
|
|
|
if account.preferences.filter_notifications:
|
|
notes = [
|
|
note for note in notes if note.type == "mention" or note.type == "follow"
|
|
]
|
|
|
|
# Apply filters
|
|
notes = [x for x in notes if not toot_matches_filters(x, filters)]
|
|
|
|
try:
|
|
prev = notes[0]._pagination_prev
|
|
if len(mastodon.notifications(min_id=prev["min_id"])) == 0:
|
|
prev = None
|
|
except (IndexError, AttributeError, KeyError):
|
|
prev = None
|
|
try:
|
|
next = notes[-1]._pagination_next
|
|
except (IndexError, AttributeError, KeyError):
|
|
next = None
|
|
return render(
|
|
request,
|
|
"main/notifications.html",
|
|
{
|
|
"notes": notes,
|
|
"timeline": "Notifications",
|
|
"timeline_name": "Notifications",
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
"prev": prev,
|
|
"next": next,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def thread(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
root = toot
|
|
try:
|
|
context = mastodon.status_context(id)
|
|
if context.ancestors and len(context.ancestors) > 0:
|
|
root = context.ancestors[0]
|
|
context = mastodon.status_context(context.ancestors[0])
|
|
except MastodonNotFoundError:
|
|
raise Http404(_("Thread not found; the message may have been deleted."))
|
|
notifications = _notes_count(account, mastodon)
|
|
filters = get_filters(mastodon, context="thread")
|
|
|
|
# Apply filters
|
|
descendants = [
|
|
x for x in context.descendants if not toot_matches_filters(x, filters)
|
|
]
|
|
|
|
return render(
|
|
request,
|
|
"main/thread.html",
|
|
{
|
|
"context": context,
|
|
"toot": toot,
|
|
"root": root,
|
|
"descendants": descendants,
|
|
"own_acct": request.session["active_user"],
|
|
"notifications": notifications,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def user(request, username, prev=None, next=None):
|
|
try:
|
|
account, mastodon = get_usercontext(request)
|
|
except NotLoggedInException:
|
|
return redirect(about)
|
|
try:
|
|
user_dict = [
|
|
dict
|
|
for dict in mastodon.account_search(username)
|
|
if (
|
|
(dict.acct == username)
|
|
or (
|
|
dict.acct == username.split("@")[0]
|
|
and username.split("@")[1] == account.username.split("@")[1]
|
|
)
|
|
)
|
|
][0]
|
|
except (IndexError, AttributeError):
|
|
raise Http404(_("The user %s could not be found.") % username)
|
|
data = mastodon.account_statuses(user_dict.id, max_id=next, min_id=prev)
|
|
relationship = mastodon.account_relationships(user_dict.id)[0]
|
|
notifications = _notes_count(account, mastodon)
|
|
try:
|
|
prev = data[0]._pagination_prev
|
|
if len(mastodon.account_statuses(user_dict.id, min_id=prev["min_id"])) == 0:
|
|
prev = None
|
|
except (IndexError, AttributeError, KeyError):
|
|
prev = None
|
|
try:
|
|
next = data[-1]._pagination_next
|
|
except (IndexError, AttributeError, KeyError):
|
|
next = None
|
|
return render(
|
|
request,
|
|
"main/user.html",
|
|
{
|
|
"toots": data,
|
|
"user": user_dict,
|
|
"relationship": relationship,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
"notifications": notifications,
|
|
"prev": prev,
|
|
"next": next,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def settings(request):
|
|
try:
|
|
account, mastodon = get_usercontext(request)
|
|
account.client.version = mastodon.instance().get("version")
|
|
account.client.save()
|
|
|
|
except NotLoggedInException:
|
|
return redirect(about)
|
|
if request.method == "POST":
|
|
form = PreferencesForm(request.POST)
|
|
if form.is_valid():
|
|
account.preferences.theme = form.cleaned_data["theme"]
|
|
account.preferences.filter_replies = form.cleaned_data["filter_replies"]
|
|
account.preferences.filter_boosts = form.cleaned_data["filter_boosts"]
|
|
account.preferences.timezone = form.cleaned_data["timezone"]
|
|
account.preferences.no_javascript = form.cleaned_data["no_javascript"]
|
|
account.preferences.notifications = form.cleaned_data["notifications"]
|
|
account.preferences.click_to_load = form.cleaned_data["click_to_load"]
|
|
account.preferences.lightbox = form.cleaned_data["lightbox"]
|
|
account.preferences.filter_notifications = form.cleaned_data[
|
|
"filter_notifications"
|
|
]
|
|
account.preferences.poll_frequency = form.cleaned_data["poll_frequency"]
|
|
request.session["timezone"] = account.preferences.timezone
|
|
account.preferences.save()
|
|
account.save()
|
|
|
|
# Update this here because it's a handy place to do it.
|
|
user_info = mastodon.account_verify_credentials()
|
|
request.session["active_user"] = user_info
|
|
accounts_dict = request.session["accounts_dict"]
|
|
|
|
accounts_dict[account.username]["user"] = user_info
|
|
request.session["accounts_dict"] = accounts_dict
|
|
|
|
return redirect(home)
|
|
else:
|
|
return render(
|
|
request, "setup/settings.html", {"form": form, "account": account}
|
|
)
|
|
else:
|
|
request.session["timezone"] = account.preferences.timezone
|
|
form = PreferencesForm(instance=account.preferences)
|
|
return render(
|
|
request,
|
|
"setup/settings.html",
|
|
{"form": form, "account": account, "preferences": account.preferences},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def toot(request, mention=None):
|
|
account, mastodon = get_usercontext(request)
|
|
if request.method == "GET":
|
|
if mention:
|
|
if not mention.startswith("@"):
|
|
mention = "@" + mention
|
|
form = PostForm(
|
|
initial={
|
|
"visibility": request.session["active_user"].source.privacy,
|
|
"status": mention + " ",
|
|
}
|
|
)
|
|
else:
|
|
form = PostForm(
|
|
initial={"visibility": request.session["active_user"].source.privacy}
|
|
)
|
|
if request.GET.get("ic-request"):
|
|
return render(
|
|
request,
|
|
"intercooler/post.html",
|
|
{
|
|
"form": form,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/post.html",
|
|
{
|
|
"form": form,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
elif request.method == "POST":
|
|
form = PostForm(request.POST, request.FILES)
|
|
if form.is_valid():
|
|
# create media objects
|
|
media_objects = []
|
|
for index in range(1, 5):
|
|
if "media_file_" + str(index) in request.FILES:
|
|
media_objects.append(
|
|
mastodon.media_post(
|
|
request.FILES[
|
|
"media_file_" + str(index)
|
|
].temporary_file_path(),
|
|
description=request.POST.get(
|
|
"media_text_" + str(index), None
|
|
),
|
|
)
|
|
)
|
|
if form.cleaned_data["visibility"] == "":
|
|
form.cleaned_data["visibility"] = request.session[
|
|
"active_user"
|
|
].source.privacy
|
|
try:
|
|
try:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
content_type="text/markdown",
|
|
)
|
|
except TypeError:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
)
|
|
except MastodonAPIError as error:
|
|
form.add_error(
|
|
"",
|
|
"%s (%s used)"
|
|
% (
|
|
error.args[-1],
|
|
len(form.cleaned_data["status"])
|
|
+ len(form.cleaned_data["spoiler_text"]),
|
|
),
|
|
)
|
|
return render(
|
|
request,
|
|
"main/post.html",
|
|
{
|
|
"form": form,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
return redirect(home)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/post.html",
|
|
{
|
|
"form": form,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return redirect(toot)
|
|
|
|
|
|
@br_login_required
|
|
def redraft(request, id):
|
|
if request.method == "GET":
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
toot_content = get_text(toot.content) # convert to plain text
|
|
# fix up white space
|
|
toot_content = re.sub("(^\n)|(\n$)", "", re.sub("\n\n", "\n", toot_content))
|
|
# Fix up references
|
|
for mention in toot.mentions:
|
|
menchie_re = re.compile(r"\s?@" + mention.username + r"\s", re.I)
|
|
toot_content = menchie_re.sub(
|
|
" @" + mention.acct + " ", toot_content, count=1
|
|
)
|
|
form = PostForm(
|
|
{
|
|
"status": toot_content.strip(),
|
|
"visibility": toot.visibility,
|
|
"spoiler_text": toot.spoiler_text,
|
|
"media_text_1": safe_get_attachment(toot, 0).description,
|
|
"media_text_2": safe_get_attachment(toot, 1).description,
|
|
"media_text_3": safe_get_attachment(toot, 2).description,
|
|
"media_text_4": safe_get_attachment(toot, 3).description,
|
|
}
|
|
)
|
|
return render(
|
|
request,
|
|
"main/redraft.html",
|
|
{
|
|
"toot": toot,
|
|
"form": form,
|
|
"redraft": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
elif request.method == "POST":
|
|
form = PostForm(request.POST, request.FILES)
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
if form.is_valid():
|
|
media_objects = []
|
|
for index in range(1, 5):
|
|
if "media_file_" + str(index) in request.FILES:
|
|
media_objects.append(
|
|
mastodon.media_post(
|
|
request.FILES[
|
|
"media_file_" + str(index)
|
|
].temporary_file_path(),
|
|
description=request.POST.get(
|
|
"media_text_" + str(index), None
|
|
),
|
|
)
|
|
)
|
|
if form.cleaned_data["visibility"] == "":
|
|
form.cleaned_data["visibility"] = request.session[
|
|
"active_user"
|
|
].source.privacy
|
|
try:
|
|
try:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
in_reply_to_id=toot.in_reply_to_id,
|
|
content_type="text/markdown",
|
|
)
|
|
except TypeError:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
in_reply_to_id=toot.in_reply_to_id,
|
|
)
|
|
mastodon.status_delete(id)
|
|
except MastodonAPIError as error:
|
|
form.add_error(
|
|
"",
|
|
"%s (%s used)"
|
|
% (
|
|
error.args[-1],
|
|
len(form.cleaned_data["status"])
|
|
+ len(form.cleaned_data["spoiler_text"]),
|
|
),
|
|
)
|
|
return render(
|
|
request,
|
|
"main/redraft.html",
|
|
{
|
|
"toot": toot,
|
|
"form": form,
|
|
"redraft": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
return redirect(home)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/redraft.html",
|
|
{
|
|
"toot": toot,
|
|
"form": form,
|
|
"redraft": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return redirect(redraft, id)
|
|
|
|
|
|
def safe_get_attachment(toot, index):
|
|
"""Get an attachment from a toot, without crashing if it isn't there."""
|
|
try:
|
|
return toot.media_attachments[index]
|
|
except IndexError:
|
|
adict = AttribAccessDict()
|
|
adict.id, adict.type, adict.description = "", "unknown", ""
|
|
adict.url, adict.remote_url, adict.preview_url = "", "", ""
|
|
adict.text_url = ""
|
|
return adict
|
|
|
|
|
|
@br_login_required
|
|
def reply(request, id):
|
|
if request.method == "GET":
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
context = mastodon.status_context(id)
|
|
notifications = _notes_count(account, mastodon)
|
|
if toot.account.acct != request.session["active_user"].acct:
|
|
initial_text = "@" + toot.account.acct + " "
|
|
else:
|
|
initial_text = ""
|
|
for mention in [
|
|
x
|
|
for x in toot.mentions
|
|
if x.acct != request.session["active_user"].acct
|
|
and x.acct != toot.account.acct
|
|
]:
|
|
initial_text += "@" + mention.acct + " "
|
|
form = PostForm(
|
|
initial={
|
|
"status": initial_text,
|
|
"visibility": toot.visibility,
|
|
"spoiler_text": toot.spoiler_text,
|
|
}
|
|
)
|
|
return render(
|
|
request,
|
|
"main/reply.html",
|
|
{
|
|
"context": context,
|
|
"toot": toot,
|
|
"form": form,
|
|
"reply": True,
|
|
"own_acct": request.session["active_user"],
|
|
"notifications": notifications,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
elif request.method == "POST":
|
|
form = PostForm(request.POST, request.FILES)
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
context = mastodon.status_context(id)
|
|
notifications = _notes_count(account, mastodon)
|
|
if form.is_valid():
|
|
# create media objects
|
|
media_objects = []
|
|
for index in range(1, 5):
|
|
if "media_file_" + str(index) in request.FILES:
|
|
media_objects.append(
|
|
mastodon.media_post(
|
|
request.FILES[
|
|
"media_file_" + str(index)
|
|
].temporary_file_path(),
|
|
description=request.POST.get(
|
|
"media_text_" + str(index), None
|
|
),
|
|
)
|
|
)
|
|
try:
|
|
try:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
in_reply_to_id=id,
|
|
content_type="text/markdown",
|
|
)
|
|
except TypeError:
|
|
mastodon.status_post(
|
|
status=form.cleaned_data["status"],
|
|
visibility=form.cleaned_data["visibility"],
|
|
spoiler_text=form.cleaned_data["spoiler_text"],
|
|
media_ids=media_objects,
|
|
in_reply_to_id=id,
|
|
)
|
|
except MastodonAPIError as error:
|
|
form.add_error(
|
|
"",
|
|
"%s (%s used)"
|
|
% (
|
|
error.args[-1],
|
|
len(form.cleaned_data["status"])
|
|
+ len(form.cleaned_data["spoiler_text"]),
|
|
),
|
|
)
|
|
return render(
|
|
request,
|
|
"main/reply.html",
|
|
{
|
|
"context": context,
|
|
"toot": toot,
|
|
"form": form,
|
|
"reply": True,
|
|
"own_acct": request.session["active_user"],
|
|
"notifications": notifications,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
return HttpResponseRedirect(
|
|
reverse("thread", args=[id]) + "#toot-" + str(id)
|
|
)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/reply.html",
|
|
{
|
|
"context": context,
|
|
"toot": toot,
|
|
"form": form,
|
|
"reply": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return HttpResponseRedirect(reverse("reply", args=[id]) + "#toot-" + str(id))
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def fav(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
if request.method == "POST":
|
|
if not request.POST.get("cancel", None):
|
|
if toot.favourited:
|
|
mastodon.status_unfavourite(id)
|
|
else:
|
|
mastodon.status_favourite(id)
|
|
if request.POST.get("ic-request"):
|
|
toot["favourited"] = not toot["favourited"]
|
|
return render(
|
|
request,
|
|
"intercooler/fav.html",
|
|
{
|
|
"toot": toot,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return HttpResponseRedirect(
|
|
reverse("thread", args=[id]) + "#toot-" + str(id)
|
|
)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/fav.html",
|
|
{
|
|
"toot": toot,
|
|
"own_acct": request.session["active_user"],
|
|
"confirm_page": True,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def boost(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
if request.method == "POST":
|
|
if not request.POST.get("cancel", None):
|
|
if toot.reblogged:
|
|
mastodon.status_unreblog(id)
|
|
else:
|
|
mastodon.status_reblog(id)
|
|
if request.POST.get("ic-request"):
|
|
toot["reblogged"] = not toot["reblogged"]
|
|
return render(
|
|
request,
|
|
"intercooler/boost.html",
|
|
{
|
|
"toot": toot,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return HttpResponseRedirect(
|
|
reverse("thread", args=[id]) + "#toot-" + str(id)
|
|
)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/boost.html",
|
|
{
|
|
"toot": toot,
|
|
"own_acct": request.session["active_user"],
|
|
"confirm_page": True,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def delete(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
if request.method == "POST" or request.method == "DELETE":
|
|
if toot.account.acct != request.session["active_user"].acct:
|
|
return redirect("home")
|
|
if not request.POST.get("cancel", None):
|
|
mastodon.status_delete(id)
|
|
if request.POST.get("ic-request"):
|
|
return HttpResponse("")
|
|
return redirect(home)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/delete.html",
|
|
{
|
|
"toot": toot,
|
|
"own_acct": request.session["active_user"],
|
|
"confirm_page": True,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def follow(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
try:
|
|
user_dict = mastodon.account(id)
|
|
relationship = mastodon.account_relationships(user_dict.id)[0]
|
|
except (IndexError, AttributeError, KeyError):
|
|
raise Http404("The user could not be found.")
|
|
if request.method == "POST":
|
|
if not request.POST.get("cancel", None):
|
|
if relationship.requested or relationship.following:
|
|
mastodon.account_unfollow(id)
|
|
else:
|
|
mastodon.account_follow(id)
|
|
if request.POST.get("ic-request"):
|
|
sleep(
|
|
1
|
|
) # This is annoying, but the next call will return Requested instead of Following in some cases
|
|
relationship = mastodon.account_relationships(user_dict.id)[0]
|
|
return render(
|
|
request,
|
|
"intercooler/follow.html",
|
|
{
|
|
"user": user_dict,
|
|
"relationship": relationship,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
return redirect(user, user_dict.acct)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/follow.html",
|
|
{
|
|
"user": user_dict,
|
|
"relationship": relationship,
|
|
"confirm_page": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def block(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
try:
|
|
user_dict = mastodon.account(id)
|
|
relationship = mastodon.account_relationships(user_dict.id)[0]
|
|
except (IndexError, AttributeError, KeyError):
|
|
raise Http404("The user could not be found.")
|
|
if request.method == "POST":
|
|
if not request.POST.get("cancel", None):
|
|
if relationship.blocking:
|
|
mastodon.account_unblock(id)
|
|
else:
|
|
mastodon.account_block(id)
|
|
if request.POST.get("ic-request"):
|
|
relationship["blocking"] = not relationship["blocking"]
|
|
return render(
|
|
request,
|
|
"intercooler/block.html",
|
|
{"user": user_dict, "relationship": relationship},
|
|
)
|
|
else:
|
|
return redirect(user, user_dict.acct)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/block.html",
|
|
{
|
|
"user": user_dict,
|
|
"relationship": relationship,
|
|
"confirm_page": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@never_cache
|
|
@br_login_required
|
|
def mute(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
try:
|
|
user_dict = mastodon.account(id)
|
|
relationship = mastodon.account_relationships(user_dict.id)[0]
|
|
except (IndexError, AttributeError, KeyError):
|
|
raise Http404("The user could not be found.")
|
|
if request.method == "POST":
|
|
if not request.POST.get("cancel", None):
|
|
if relationship.muting:
|
|
mastodon.account_unmute(id)
|
|
else:
|
|
mastodon.account_mute(id)
|
|
if request.POST.get("ic-request"):
|
|
relationship["muting"] = not relationship["muting"]
|
|
return render(
|
|
request,
|
|
"intercooler/mute.html",
|
|
{"user": user_dict, "relationship": relationship},
|
|
)
|
|
else:
|
|
return redirect(user, user_dict.acct)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/mute.html",
|
|
{
|
|
"user": user_dict,
|
|
"relationship": relationship,
|
|
"confirm_page": True,
|
|
"own_acct": request.session["active_user"],
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def search(request):
|
|
account, mastodon = get_usercontext(request)
|
|
if request.GET.get("ic-request"):
|
|
return render(
|
|
request,
|
|
"intercooler/search.html",
|
|
{
|
|
"preferences": account.preferences,
|
|
"own_acct": request.session["active_user"],
|
|
},
|
|
)
|
|
else:
|
|
return render(
|
|
request,
|
|
"main/search.html",
|
|
{
|
|
"preferences": account.preferences,
|
|
"own_acct": request.session["active_user"],
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
@cache_page(60 * 5)
|
|
def search_results(request):
|
|
if request.method == "GET":
|
|
query = request.GET.get("q", "")
|
|
elif request.method == "POST":
|
|
query = request.POST.get("q", "")
|
|
else:
|
|
query = ""
|
|
account, mastodon = get_usercontext(request)
|
|
results = mastodon.search(query)
|
|
notifications = _notes_count(account, mastodon)
|
|
return render(
|
|
request,
|
|
"main/search_results.html",
|
|
{
|
|
"results": results,
|
|
"own_acct": request.session["active_user"],
|
|
"notifications": notifications,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@cache_page(60 * 30)
|
|
def about(request):
|
|
version = django_settings.BRUTALDON_VERSION
|
|
account, mastodon = get_usercontext(request)
|
|
if account:
|
|
preferences = account.preferences
|
|
else:
|
|
preferences = None
|
|
return render(
|
|
request,
|
|
"about.html",
|
|
{
|
|
"preferences": preferences,
|
|
"version": version,
|
|
"own_acct": request.session.get("active_user", None),
|
|
},
|
|
)
|
|
|
|
|
|
@cache_page(60 * 30)
|
|
def privacy(request):
|
|
account, mastodon = get_usercontext(request)
|
|
if account:
|
|
preferences = account.preferences
|
|
else:
|
|
preferences = None
|
|
return render(
|
|
request,
|
|
"privacy.html",
|
|
{
|
|
"preferences": preferences,
|
|
"own_acct": request.session.get("active_user", None),
|
|
},
|
|
)
|
|
|
|
|
|
@cache_page(60 * 30)
|
|
@br_login_required
|
|
def emoji_reference(request):
|
|
account, mastodon = get_usercontext(request)
|
|
emojos = mastodon.custom_emojis()
|
|
notifications = _notes_count(account, mastodon)
|
|
return render(
|
|
request,
|
|
"main/emoji.html",
|
|
{
|
|
"preferences": account.preferences,
|
|
"emojos": sorted(emojos, key=lambda x: x["shortcode"]),
|
|
"notifications": notifications,
|
|
"own_acct": request.session["active_user"],
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def list_filters(request):
|
|
account, mastodon = get_usercontext(request)
|
|
filters = mastodon.filters()
|
|
return render(
|
|
request,
|
|
"filters/list.html",
|
|
{"account": account, "preferences": account.preferences, "filters": filters},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def create_filter(request):
|
|
account, mastodon = get_usercontext(request)
|
|
if request.method == "POST":
|
|
form = FilterForm(request.POST)
|
|
if form.is_valid():
|
|
contexts = []
|
|
if form.cleaned_data["context_home"]:
|
|
contexts.append("home")
|
|
if form.cleaned_data["context_public"]:
|
|
contexts.append("public")
|
|
if form.cleaned_data["context_notes"]:
|
|
contexts.append("notifications")
|
|
if form.cleaned_data["context_thread"]:
|
|
contexts.append("thread")
|
|
expires = form.cleaned_data["expires_in"]
|
|
if expires == "":
|
|
expires = None
|
|
mastodon.filter_create(
|
|
form.cleaned_data["phrase"],
|
|
contexts,
|
|
whole_word=form.cleaned_data["whole_word"],
|
|
expires_in=expires,
|
|
)
|
|
return redirect(list_filters)
|
|
else:
|
|
return render(
|
|
request,
|
|
"filters/create.html",
|
|
{"form": form, "account": account, "preferences": account.preferences},
|
|
)
|
|
else:
|
|
form = FilterForm()
|
|
return render(
|
|
request,
|
|
"filters/create.html",
|
|
{"form": form, "account": account, "preferences": account.preferences},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def delete_filter(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
filter = mastodon.filter(id)
|
|
|
|
if request.method == "POST" or request.method == "DELETE":
|
|
if not request.POST.get("cancel", None):
|
|
mastodon.filter_delete(filter.id)
|
|
if request.POST.get("ic-request"):
|
|
return HttpResponse("")
|
|
return redirect(list_filters)
|
|
else:
|
|
return render(
|
|
request,
|
|
"filters/delete.html",
|
|
{
|
|
"filter": filter,
|
|
"own_acct": request.session["active_user"],
|
|
"confirm_page": True,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def edit_filter(request, id):
|
|
account, mastodon = get_usercontext(request)
|
|
filter = mastodon.filter(id)
|
|
|
|
contexts = []
|
|
if request.method == "POST":
|
|
form = FilterForm(request.POST)
|
|
if form.is_valid():
|
|
if form.cleaned_data["context_home"]:
|
|
contexts.append("home")
|
|
if form.cleaned_data["context_public"]:
|
|
contexts.append("public")
|
|
if form.cleaned_data["context_notes"]:
|
|
contexts.append("notifications")
|
|
if form.cleaned_data["context_thread"]:
|
|
contexts.append("thread")
|
|
expires = form.cleaned_data["expires_in"]
|
|
if expires == "":
|
|
expires = None
|
|
mastodon.filter_update(
|
|
id,
|
|
form.cleaned_data["phrase"],
|
|
contexts,
|
|
whole_word=form.cleaned_data["whole_word"],
|
|
expires_in=expires,
|
|
)
|
|
return redirect(list_filters)
|
|
else:
|
|
return render(
|
|
request,
|
|
"filters/edit.html",
|
|
{
|
|
"form": form,
|
|
"account": account,
|
|
"filter": filter,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
else:
|
|
contexts = []
|
|
form = FilterForm(
|
|
{
|
|
"phrase": filter.phrase,
|
|
"context_home": "home" in filter.context,
|
|
"context_public": "public" in filter.context,
|
|
"context_notes": "notifications" in filter.context,
|
|
"context_thread": "thread" in filter.context,
|
|
"whole_word": filter.whole_word,
|
|
}
|
|
)
|
|
return render(
|
|
request,
|
|
"filters/edit.html",
|
|
{
|
|
"form": form,
|
|
"account": account,
|
|
"filter": filter,
|
|
"preferences": account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def follow_requests(request, id=None):
|
|
account, mastodon = get_usercontext(request)
|
|
if request.method == "GET":
|
|
reqs = mastodon.follow_requests()
|
|
return render(
|
|
request,
|
|
"requests/list.html",
|
|
{"account": account, "preferences": account.preferences, "requests": reqs},
|
|
)
|
|
elif id is None:
|
|
return redirect(follow_requests)
|
|
else:
|
|
if request.POST.get("accept", None):
|
|
mastodon.follow_request_authorize(id)
|
|
elif request.POST.get("reject", None):
|
|
mastodon.follow_request_reject(id)
|
|
return redirect(follow_requests)
|
|
|
|
|
|
@br_login_required
|
|
def accounts(request, id=None):
|
|
active_account, mastodon = get_usercontext(request)
|
|
if request.method == "GET":
|
|
accounts = [x for x in request.session.get("accounts_dict").values()]
|
|
return render(
|
|
request,
|
|
"accounts/list.html",
|
|
{
|
|
"active_account": active_account,
|
|
"own_acct": request.session["active_user"],
|
|
"accounts": accounts,
|
|
"preferences": active_account.preferences,
|
|
},
|
|
)
|
|
if request.method == "POST":
|
|
if request.POST.get("activate"):
|
|
to_account = Account.objects.get(id=id).username
|
|
if switch_accounts(request, to_account):
|
|
return redirect(home)
|
|
else:
|
|
return redirect("accounts")
|
|
elif request.POST.get("forget"):
|
|
account = Account.objects.get(id=id).username
|
|
return forget_account(request, account)
|
|
else:
|
|
accounts = [x for x in request.session.get("accounts_dict").values()]
|
|
return render(
|
|
request,
|
|
"accounts/list.html",
|
|
{
|
|
"active_account": active_account,
|
|
"own_acct": request.session["active_user"],
|
|
"accounts": accounts,
|
|
"preferences": active_account.preferences,
|
|
},
|
|
)
|
|
|
|
|
|
@br_login_required
|
|
def vote(request, id):
|
|
if request.method == "GET":
|
|
return redirect("thread", id)
|
|
if request.method == "POST":
|
|
account, mastodon = get_usercontext(request)
|
|
toot = mastodon.status(id)
|
|
poll = toot.poll
|
|
if not poll:
|
|
return redirect("thread", id)
|
|
# radio buttons
|
|
if "poll-single" in request.POST.keys():
|
|
mastodon.poll_vote(poll.id, request.POST["poll-single"])
|
|
# checkboxes
|
|
else:
|
|
values = [x for x in request.POST.getlist("poll-multiple")]
|
|
if values:
|
|
mastodon.poll_vote(poll.id, values)
|
|
|
|
if request.POST.get("ic-request"):
|
|
return render(
|
|
request, "main/toot_partial.html", {"toot": mastodon.status(id)}
|
|
)
|
|
else:
|
|
return redirect("thread", id)
|