1
0
mirror of https://gitlab.com/brutaldon/brutaldon.git synced 2024-12-04 14:46:24 -05:00

Log in to an instance and display a home timeline.

Only supports single user, lots of display elements not supported yet.
But it actually has something to show.

Actually display a home timeline.

Still only single user, doesn't correctly handle boosts, CWs, and
probably a lot of other things.
This commit is contained in:
Jason McBrayer 2018-04-23 18:16:22 -04:00
parent f6d91ca88b
commit 73e105517c
13 changed files with 276 additions and 0 deletions

9
brutaldon/forms.py Normal file
View File

@ -0,0 +1,9 @@
from django import forms
class LoginForm(forms.Form):
instance = forms.CharField(label="Instance",
max_length=256)
username = forms.CharField(label="Username",
max_length=256)
password = forms.CharField(widget=forms.PasswordInput())

View File

@ -0,0 +1,24 @@
# Generated by Django 2.0.1 on 2018-04-23 18:25
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Client',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField(default='brutaldon')),
('api_base_id', models.URLField(default='mastodon.social')),
('client_id', models.TextField(blank=True, null=True)),
('client_secret', models.TextField(blank=True, null=True)),
],
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 2.0.1 on 2018-04-23 21:34
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('brutaldon', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Account',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=80)),
('access_token', models.TextField(blank=True, null=True)),
('django_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

16
brutaldon/models.py Normal file
View File

@ -0,0 +1,16 @@
from django.db import models
from django.conf import settings
class Client(models.Model):
name = models.TextField(default = "brutaldon")
api_base_id = models.URLField(default="mastodon.social")
client_id = models.TextField(null=True, blank=True)
client_secret = models.TextField(null=True, blank=True)
def __str__(self):
return self.name + ": " + self.api_base_id
class Account(models.Model):
username = models.CharField(max_length=80)
django_user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, null=True)
access_token = models.TextField(null=True, blank=True)

View File

@ -37,6 +37,9 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'widget_tweaks',
'django.contrib.humanize',
'brutaldon',
]
MIDDLEWARE = [

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}brutaldon{% endblock %}</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.0/css/bulma.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.0.11/css/fork-awesome.min.css"
integrity="sha256-MGU/JUq/40CFrfxjXb5pZjpoZmxiP2KuICN5ElLFNd8="
crossorigin="anonymous">
</head>
<body>
<section class="section">
<div class="container">
{% block content %}
<h1 class="title">
Title
</h1>
<p class="subtitle">
My first website with <strong>Bulma</strong>!
</p>
{% endblock %}
</div>
</section>
</body>
</html>

View File

@ -0,0 +1 @@
{% extends "base.html" %}

View File

@ -0,0 +1,52 @@
{% extends "base.html" %}
{% load humanize %}
{% block content %}
{% for toot in toots %}
<article class="media">
<figure class="media-left">
<p class="image is-64x64">
<img src="{{ toot.account.avatar }}"
alt="">
</p>
</figure>
<div class="media-content">
<div class="content">
<p>
<strong>{{ toot.account.display_name }}</strong>
<small>@{{ toot.account.username }}</small>
<small>{{ toot.created_at |naturaltime }}</small>
<br>
{{ toot.content | safe }}
</p>
</div>
<nav class="level is-mobile">
<div class="level-left">
<a class="level-item">
<span class="icon is-small"><i class="fa fa-reply">
<span class="is-invisible">Reply</span>
</i></span>
</a>
<a class="level-item">
<span class="icon is-small"><i class="fa fa-retweet">
<span class="is-invisible" >Boost</span>
</i></span>
</a>
<a class="level-item">
<span class="icon is-small"><i class="fa fa-heart">
<span class="is-invisible" >Favorite</span>
</i></span>
</a>
</div>
<div class="level-right">
<a class="level-item">
{{ toot.visibility }}
</a>
</div>
</nav>
</div>
<div class="media-right">
</div>
</article>
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,53 @@
{% extends "base.html" %}
{% load widget_tweaks %}
{% block content %}
<h1 class="title">Log in to your instance</h1>
<form method="post" action="{% url "login" %}">
{% csrf_token %}
<div class="field">
<label class="label">{{ form.instance.label }}</label>
<div class="control has-icons-left">
{% render_field form.instance class+="input" %}
<span class="icon is-small is-left">
<i class="fa fa-mastodon"></i>
</span>
</div>
</div>
<div class="field">
<label class="label">{{ form.username.label }}</label>
<div class="control has-icons-left">
{% render_field form.username class+="input" %}
<span class="icon is-small is-left">
<i class="fa fa-user"></i>
</span>
</div>
</div>
<div class="field" >
<label class="label" >{{ form.password.label }}</label>
<div class="control has-icons-left" >
{% render_field form.password class+="input" type="password" %}
<span class="icon is-small is-left">
<i class="fa fa-lock" ></i>
</span>
</div>
</div>
<div class="field">
<input type="submit" name="log_in"
value="Log in" class="button is-primary" >
</div>
</form>
<div class="notification">
<button class="delete"></button>
<p>
This information is only used to log you in to your instance for the
first time. Brutaldon never stores your username and password; it
only uses it to acquire a token which you can disable from the
settings page of your Mastodon instance.
</p>
</div>
{% endblock %}

View File

@ -15,7 +15,12 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path
from brutaldon import views
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', views.home),
path('login', views.login, name="login"),
path('error', views.error),
path('', views.home),
]

61
brutaldon/views.py Normal file
View File

@ -0,0 +1,61 @@
from django.http import HttpResponse
from django.shortcuts import render, redirect
from brutaldon.forms import LoginForm
from brutaldon.models import Client, Account
from mastodon import Mastodon
import datetime
def home(request):
now = datetime.datetime.now()
try:
client = Client.objects.all()[0]
user = Account.objects.all()[0]
except:
return redirect(login)
mastodon = Mastodon(
client_id = client.client_id,
client_secret = client.client_secret,
access_token = user.access_token,
api_base_url = client.api_base_id,
ratelimit_method="pace")
data = mastodon.timeline()
return render(request, 'main/timeline.html', {'toots': data })
def 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'] # Fixme, make sure this is url
username = form.cleaned_data['username']
password = form.cleaned_data['password']
(client_id, client_secret) = Mastodon.create_app('brutaldon',
api_base_url=api_base_url)
client = Client(
api_base_id = api_base_url,
client_id=client_id,
client_secret = client_secret)
client.save()
mastodon = Mastodon(
client_id = client_id,
client_secret = client_secret,
api_base_url = api_base_url)
access_token = mastodon.log_in(username,
password)
account = Account(
username = username,
access_token = access_token)
account.save()
return redirect(home)
else:
return redirect(error)
def error(request):
return render('error.html', { 'error': "Not logged in yet."})

View File

@ -2,6 +2,7 @@ certifi==2017.11.5
chardet==3.0.4
decorator==4.1.2
Django==2.0.1
django-widget-tweaks==1.4.2
idna==2.6
Mastodon.py==1.2.1
python-dateutil==2.6.1