mirror of
http://git.carcosa.net/jmcbray/brutaldon.git
synced 2024-11-27 09:10:08 -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:
parent
f6d91ca88b
commit
73e105517c
9
brutaldon/forms.py
Normal file
9
brutaldon/forms.py
Normal 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())
|
||||
|
24
brutaldon/migrations/0001_initial.py
Normal file
24
brutaldon/migrations/0001_initial.py
Normal 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)),
|
||||
],
|
||||
),
|
||||
]
|
25
brutaldon/migrations/0002_account.py
Normal file
25
brutaldon/migrations/0002_account.py
Normal 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)),
|
||||
],
|
||||
),
|
||||
]
|
0
brutaldon/migrations/__init__.py
Normal file
0
brutaldon/migrations/__init__.py
Normal file
16
brutaldon/models.py
Normal file
16
brutaldon/models.py
Normal 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)
|
@ -37,6 +37,9 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'widget_tweaks',
|
||||
'django.contrib.humanize',
|
||||
'brutaldon',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
26
brutaldon/templates/base.html
Normal file
26
brutaldon/templates/base.html
Normal 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>
|
1
brutaldon/templates/error.html
Normal file
1
brutaldon/templates/error.html
Normal file
@ -0,0 +1 @@
|
||||
{% extends "base.html" %}
|
52
brutaldon/templates/main/timeline.html
Normal file
52
brutaldon/templates/main/timeline.html
Normal 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 %}
|
53
brutaldon/templates/setup/login.html
Normal file
53
brutaldon/templates/setup/login.html
Normal 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 %}
|
@ -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
61
brutaldon/views.py
Normal 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."})
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user