Compare commits

..

No commits in common. "335467a30df1c15bc3d4028d53839d8039232769" and "6117fbe1e7be80e18fe830d1304a64f05845f005" have entirely different histories.

35 changed files with 320 additions and 216 deletions

View File

@ -5,7 +5,7 @@ By popular demand, I'm building a better anonkun. It doesn't do much right now t
Python 3.6+
PostgreSQL 10.4+
Redis 4.0.10+
Python packages: `django psycopg2 channels channels_redis jinja2 argon2-cffi bleach`
Python packages: `django psycopg2 channels channels_redis jinja2 argon2-cffi`
## Install
```

View File

@ -6,14 +6,13 @@ from django.contrib import messages
from django.shortcuts import redirect, render
from .forms import QuestForm, PostForm
from quest.models import Quest, Post, PageTitle
from quest.models import Quest, Post
def index(request):
"""
The index page for creating new quests.
"""
if request.method == 'POST':
# TODO: clean the post body
quest = Quest(owner=request.user)
quest_form = QuestForm(request.POST, instance=quest)
post = Post(post_type='text', page_num=1)
@ -22,12 +21,6 @@ def index(request):
quest.save()
post.quest = quest
post.save()
page = PageTitle(
quest=quest,
page_num=1,
title="Page 1"
)
page.save()
return redirect('quest:quest', quest_id=quest.id)
else:
quest_form = QuestForm()

View File

@ -1,31 +0,0 @@
{% extends "base.html" %}
{% block title %}Edit {{ quest.title }}{% endblock %}
{% block content %}
<center><h1>{{ quest.title }}</h1></center>
<form method="post" action="{{ url('quest:edit_quest', args=[quest_id]) }}">
{{ csrf_input }}
<table>
<tr>
<td>Quest Title:</td>
<td><input type="text" name="quest_title" value="{{ quest.title }}"></td>
</tr>
<tr>
<td>Visible:</td>
<td><input type="checkbox" name="visible" value="on"></td>
</tr>
<tr>
<td>Anonymous Name:</td>
<td><input type="text" name="anon_name" value="Anonymous"></td>
</tr>
<tr>
<td>Live:</td>
<td><input type="checkbox" name="live" value="off"></td>
</tr>
<tr>
<td>Live In:</td>
<td>Placeholder</td>
</tr>
</table>
<input type="submit">
</form>
{% endblock %}

View File

@ -15,13 +15,13 @@
{% endblock %}
{% block header %}
{% if request.user == quest.owner %}
<li><a href="{{ url('quest:edit_quest', args=[quest_id]) }}">Edit Quest</a></li>
<li><a href="{# url('edit_quest:index', quest_id=quest_id) #}">Edit Quest</a></li>
{% endif %}
<li>
<select onChange="window.location.href=this.value">
{% for page in pages %}
<option value="{{ url('quest:quest', args=[quest_id, page.page_num]) }}"{% if page.page_num == page_num %} selected="yes"{% endif %}>{{ page.title }}</option>
{% endfor %}
{# for page in pages %}
<option value="{{ url_for('.quest', quest_id=quest_id, page_num=page[1]) }}"{% if page[1] == page_num %} selected="yes"{% endif %}>{{ page[2] }}</option>
{% endfor #}
</select>
</li>
{% endblock %}

View File

@ -1,6 +1,6 @@
# Generated by Django 2.1.1 on 2018-09-05 17:44
# Generated by Django 2.1 on 2018-08-12 20:09
import django.core.validators
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
@ -10,17 +10,10 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Message',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField(auto_now=True)),
('message', models.TextField(max_length=512)),
],
),
migrations.CreateModel(
name='PageTitle',
fields=[
@ -29,20 +22,6 @@ class Migration(migrations.Migration):
('title', models.CharField(max_length=200)),
],
),
migrations.CreateModel(
name='PollOption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.CharField(max_length=200)),
],
),
migrations.CreateModel(
name='PollVote',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ip_address', models.GenericIPAddressField()),
],
),
migrations.CreateModel(
name='Post',
fields=[
@ -57,36 +36,19 @@ class Migration(migrations.Migration):
name='Quest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('quest_name', models.CharField(max_length=200)),
('open_post_id', models.IntegerField(null=True)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='DiceCall',
fields=[
('post', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Post')),
('dice_roll', models.CharField(max_length=9)),
('strict', models.BooleanField()),
('dice_challenge', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(999), django.core.validators.MinValueValidator(1)])),
('rolls_taken', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(99), django.core.validators.MinValueValidator(1)])),
('open', models.BooleanField()),
],
migrations.AddField(
model_name='post',
name='quest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest'),
),
migrations.CreateModel(
name='DiceRoll',
fields=[
('message', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Message')),
('roll', models.CharField(max_length=9)),
('results', models.TextField()),
('total', models.IntegerField()),
],
),
migrations.CreateModel(
name='Poll',
fields=[
('post', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Post')),
('multi_choice', models.BooleanField()),
('allow_writein', models.BooleanField()),
('open', models.BooleanField()),
],
migrations.AddField(
model_name='pagetitle',
name='quest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1 on 2018-08-12 20:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('quest', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='quest',
old_name='quest_name',
new_name='title',
),
]

View File

@ -1,67 +0,0 @@
# Generated by Django 2.1.1 on 2018-09-05 17:44
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('quest', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='quest',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='post',
name='quest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest'),
),
migrations.AddField(
model_name='pollvote',
name='option',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.PollOption'),
),
migrations.AddField(
model_name='pollvote',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='pagetitle',
name='quest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest'),
),
migrations.AddField(
model_name='message',
name='quest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest'),
),
migrations.AddField(
model_name='message',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='pollvote',
unique_together={('option', 'ip_address')},
),
migrations.AddField(
model_name='polloption',
name='poll',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Poll'),
),
migrations.AddField(
model_name='diceroll',
name='dicecall',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.DiceCall'),
),
]

View File

@ -0,0 +1,26 @@
# Generated by Django 2.1 on 2018-08-17 11:19
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),
('quest', '0002_auto_20180812_1612'),
]
operations = [
migrations.CreateModel(
name='Message',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(auto_now=True)),
('message', models.TextField(max_length=512)),
('quest', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Quest')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 2.1 on 2018-08-17 11:24
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0003_message'),
]
operations = [
migrations.AlterField(
model_name='message',
name='user',
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 2.1 on 2018-08-17 11:39
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0004_auto_20180817_0724'),
]
operations = [
migrations.AlterField(
model_name='message',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1 on 2018-08-17 13:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('quest', '0005_auto_20180817_0739'),
]
operations = [
migrations.RenameField(
model_name='message',
old_name='date',
new_name='timestamp',
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 2.1 on 2018-08-23 15:46
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0006_auto_20180817_0921'),
]
operations = [
migrations.CreateModel(
name='DiceCall',
fields=[
('post', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Post')),
('dice_roll', models.CharField(max_length=9)),
('strict', models.BooleanField()),
('dice_challenge', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(999), django.core.validators.MinValueValidator(1)])),
('rolls_taken', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(99), django.core.validators.MinValueValidator(1)])),
],
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 2.1 on 2018-08-24 12:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('quest', '0007_dicecall'),
]
operations = [
migrations.RemoveField(
model_name='quest',
name='open_post_id',
),
migrations.AddField(
model_name='dicecall',
name='open',
field=models.BooleanField(default=False),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 2.1 on 2018-08-25 01:06
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0008_auto_20180824_0855'),
]
operations = [
migrations.CreateModel(
name='DiceRoll',
fields=[
('message', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Message')),
('roll', models.CharField(max_length=9)),
('results', models.TextField()),
('total', models.IntegerField()),
('dicecall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.DiceCall')),
],
),
]

View File

@ -0,0 +1,47 @@
# Generated by Django 2.1 on 2018-08-29 17:08
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),
('quest', '0009_diceroll'),
]
operations = [
migrations.CreateModel(
name='Poll',
fields=[
('post', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='quest.Post')),
('multi_choice', models.BooleanField()),
('allow_writein', models.BooleanField()),
('open', models.BooleanField()),
],
),
migrations.CreateModel(
name='PollOption',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.CharField(max_length=200)),
('poll', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.Poll')),
],
),
migrations.CreateModel(
name='PollVote',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ip_address', models.GenericIPAddressField()),
('option', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='quest.PollOption')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterField(
model_name='dicecall',
name='open',
field=models.BooleanField(),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 2.1 on 2018-09-03 00:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('quest', '0010_auto_20180829_1308'),
]
operations = [
migrations.AlterField(
model_name='pollvote',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 2.1 on 2018-09-04 11:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('quest', '0011_auto_20180902_2007'),
]
operations = [
migrations.AlterUniqueTogether(
name='pollvote',
unique_together={('option', 'ip_address')},
),
]

View File

@ -11,6 +11,4 @@ urlpatterns = [
path('', views.index, name='index'),
path('<int:quest_id>', views.quest, name='quest'),
path('<int:quest_id>/<int:page_num>', views.quest, name='quest'),
path('<int:quest_id>/edit_quest', views.edit_quest, name='edit_quest'),
path('<int:quest_id>/<int:page_num>/edit_quest', views.edit_quest, name='edit_quest'),
]

View File

@ -2,15 +2,16 @@
"""
Quest and quest accessory views.
"""
from django.shortcuts import render, redirect
from django.shortcuts import render
from django.http import HttpResponse
from .models import Quest, DiceRoll, PollOption, PollVote, PageTitle
from .models import Quest, DiceRoll, PollOption, PollVote
def index(request):
"""
/quest page index. Possibly not needed.
"""
#return render(request, "Hello, world. You're at the quest index.", {})
return HttpResponse("Hello, world. You're at the quest index.")
@ -19,27 +20,11 @@ def quest(request, quest_id, page_num=1):
Arbituary quest page view.
"""
quest = Quest.objects.get(id=quest_id)
pages = PageTitle.objects.filter(quest=quest).order_by('page_num')
messages = quest.message_set.all()
posts = quest.post_set.all()
dice_rolls = DiceRoll.objects.filter(dicecall__post__quest=quest)
poll_options = PollOption.objects.filter(poll__post__quest=quest)
poll_votes = PollVote.objects.filter(option__poll__post__quest=quest)
dice_rolls = DiceRoll.objects.filter(dicecall__post__quest__id=quest_id)
poll_options = PollOption.objects.filter(poll__post__quest__id=quest_id)
poll_votes = PollVote.objects.filter(option__poll__post__quest__id=quest_id)
ip_address = request.META['REMOTE_ADDR']
context = locals()
return render(request, 'quest/quest.html', context)
def edit_quest(request, quest_id, page_num=1):
"""
Edit quest page. Only available to the QM.
"""
quest = Quest.objects.get(id=quest_id)
if quest.owner != request.user:
return redirect('quest:quest', quest_id=quest_id, page_num=page_num)
if request.method == 'POST':
pass
else:
pass
context = locals()
return render(request, 'quest/edit_quest.html', context)

View File

@ -5,7 +5,7 @@ Form(s) for the signup app.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from user.models import User
from users.models import User
class SignupForm(UserCreationForm):
"""

View File

@ -32,7 +32,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'user.apps.UserConfig',
'users.apps.UsersConfig',
'homepage.apps.HomepageConfig',
'create_quest.apps.CreateQuestConfig',
'quest.apps.QuestConfig',
@ -107,7 +107,7 @@ AUTH_PASSWORD_VALIDATORS = [
}
},
{
'NAME': 'user.validators.MaximumLengthValidator',
'NAME': 'users.validators.MaximumLengthValidator',
'OPTIONS': {
'max_length': 1024,
}
@ -138,7 +138,7 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
AUTH_USER_MODEL = 'user.User'
AUTH_USER_MODEL = 'users.User'
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.Argon2PasswordHasher',

3
todo
View File

@ -31,5 +31,6 @@ Adjust quote preview postioning
Port from old code:
Edit post
Edit quest
Pages
Images
User page

Binary file not shown.

View File

@ -1,5 +0,0 @@
from django.apps import AppConfig
class UserConfig(AppConfig):
name = 'user'

View File

@ -1,16 +0,0 @@
#!/usr/bin/env python3
"""
/user app views.
"""
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.core.exceptions import ObjectDoesNotExist
from .models import User
from quest.models import Quest
def index(request):
"""
The user index page.
"""
return HttpResponse("Hello, world. You're at the user index.")

5
users/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'

View File

@ -1,10 +1,9 @@
# Generated by Django 2.1.1 on 2018-09-05 17:44
# Generated by Django 2.0.7 on 2018-08-10 20:30
import django.contrib.auth.models
import django.core.validators
import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone
import user.validators
class Migration(migrations.Migration):
@ -26,7 +25,7 @@ class Migration(migrations.Migration):
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Must be between 3 and 20 characters. Letters and digits only.', max_length=20, unique=True, validators=[user.validators.CharValidator('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 'Username must only contain alphanumeric characters.'), django.core.validators.MinLengthValidator(3, 'Username must contain more than 3 characters.'), django.core.validators.MaxLengthValidator(20, 'Username must contain less than 20 characters.')], verbose_name='username')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 20 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=20, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('email', models.EmailField(max_length=254, verbose_name='email address')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),

View File

@ -0,0 +1,20 @@
# Generated by Django 2.1 on 2018-08-12 20:09
import django.core.validators
from django.db import migrations, models
import users.validators
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='user',
name='username',
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Must be between 3 and 20 characters. Letters and digits only.', max_length=20, unique=True, validators=[users.validators.CharValidator('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 'Username must only contain alphanumeric characters.'), django.core.validators.MinLengthValidator(3, 'Username must contain more than 3 characters.'), django.core.validators.MaxLengthValidator(20, 'Username must contain less than 20 characters.')], verbose_name='username'),
),
]

3
users/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.