diff --git a/brutaldon/forms.py b/brutaldon/forms.py new file mode 100644 index 0000000..c6c3dc9 --- /dev/null +++ b/brutaldon/forms.py @@ -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()) + diff --git a/brutaldon/migrations/0001_initial.py b/brutaldon/migrations/0001_initial.py new file mode 100644 index 0000000..83207f5 --- /dev/null +++ b/brutaldon/migrations/0001_initial.py @@ -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)), + ], + ), + ] diff --git a/brutaldon/migrations/0002_account.py b/brutaldon/migrations/0002_account.py new file mode 100644 index 0000000..f755886 --- /dev/null +++ b/brutaldon/migrations/0002_account.py @@ -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)), + ], + ), + ] diff --git a/brutaldon/migrations/__init__.py b/brutaldon/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/brutaldon/models.py b/brutaldon/models.py new file mode 100644 index 0000000..a1536ac --- /dev/null +++ b/brutaldon/models.py @@ -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) diff --git a/brutaldon/settings.py b/brutaldon/settings.py index ec7b89c..e3c19f8 100644 --- a/brutaldon/settings.py +++ b/brutaldon/settings.py @@ -37,6 +37,9 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'widget_tweaks', + 'django.contrib.humanize', + 'brutaldon', ] MIDDLEWARE = [ diff --git a/brutaldon/templates/base.html b/brutaldon/templates/base.html new file mode 100644 index 0000000..684f0b7 --- /dev/null +++ b/brutaldon/templates/base.html @@ -0,0 +1,26 @@ + + + + + + {% block title %}brutaldon{% endblock %} + + + + +
+
+ {% block content %} +

+ Title +

+

+ My first website with Bulma! +

+ {% endblock %} +
+
+ + diff --git a/brutaldon/templates/error.html b/brutaldon/templates/error.html new file mode 100644 index 0000000..94d9808 --- /dev/null +++ b/brutaldon/templates/error.html @@ -0,0 +1 @@ +{% extends "base.html" %} diff --git a/brutaldon/templates/main/timeline.html b/brutaldon/templates/main/timeline.html new file mode 100644 index 0000000..415be17 --- /dev/null +++ b/brutaldon/templates/main/timeline.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} +{% load humanize %} + +{% block content %} +{% for toot in toots %} +
+
+

+ +

+
+
+
+

+ {{ toot.account.display_name }} + @{{ toot.account.username }} + {{ toot.created_at |naturaltime }} +
+ {{ toot.content | safe }} +

+
+ +
+
+
+
+{% endfor %} +{% endblock %} diff --git a/brutaldon/templates/setup/login.html b/brutaldon/templates/setup/login.html new file mode 100644 index 0000000..7c703e2 --- /dev/null +++ b/brutaldon/templates/setup/login.html @@ -0,0 +1,53 @@ +{% extends "base.html" %} +{% load widget_tweaks %} + +{% block content %} +

Log in to your instance

+ +
+ {% csrf_token %} +
+ +
+ {% render_field form.instance class+="input" %} + + + +
+
+ +
+ +
+ {% render_field form.username class+="input" %} + + + +
+
+
+ +
+ {% render_field form.password class+="input" type="password" %} + + + +
+
+
+ +
+
+ +
+ +

+ 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. +

+
+ +{% endblock %} diff --git a/brutaldon/urls.py b/brutaldon/urls.py index b367ea4..dcdd61c 100644 --- a/brutaldon/urls.py +++ b/brutaldon/urls.py @@ -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), ] diff --git a/brutaldon/views.py b/brutaldon/views.py new file mode 100644 index 0000000..0547bb3 --- /dev/null +++ b/brutaldon/views.py @@ -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."}) diff --git a/requirements.txt b/requirements.txt index 9dbe603..18257c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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