mirror of
http://git.carcosa.net/jmcbray/brutaldon.git
synced 2025-02-21 08:03:47 -05:00
Do a better job of validating post length
This still doesn't correctly handle the shorter "effective lengths" for handles and URLs. And it doesn't handle different per-server toot lengths. But it does catch posts that become too long because the length of the CW is counted as part of the length of the post body, and gives a validation error rather than throwing an exception.
This commit is contained in:
parent
c729956fab
commit
8fa5da1409
@ -1,10 +1,12 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
PRIVACY_CHOICES = (('public', 'Public'),
|
PRIVACY_CHOICES = (('public', 'Public'),
|
||||||
('unlisted', 'Unlisted'),
|
('unlisted', 'Unlisted'),
|
||||||
('private', 'Private'),
|
('private', 'Private'),
|
||||||
('direct', 'Direct'))
|
('direct', 'Direct'))
|
||||||
|
|
||||||
|
MAX_LENGTH = settings.TOOT_MAX_LENGTH
|
||||||
|
|
||||||
class LoginForm(forms.Form):
|
class LoginForm(forms.Form):
|
||||||
instance = forms.CharField(label="Instance",
|
instance = forms.CharField(label="Instance",
|
||||||
@ -27,27 +29,40 @@ class SettingsForm(forms.Form):
|
|||||||
|
|
||||||
class PostForm(forms.Form):
|
class PostForm(forms.Form):
|
||||||
"""def status_post(self, status, in_reply_to_id=None, media_ids=None,
|
"""def status_post(self, status, in_reply_to_id=None, media_ids=None,
|
||||||
sensitive=False, visibility=None, spoiler_text=None):"""
|
sensitive=False, visibility=None, spoiler_text=None):"""
|
||||||
status = forms.CharField(label="Toot", max_length=500, widget=forms.Textarea)
|
status = forms.CharField(label="Toot", max_length=MAX_LENGTH, widget=forms.Textarea)
|
||||||
visibility = forms.ChoiceField(label="Toot visibility", choices=PRIVACY_CHOICES,
|
visibility = forms.ChoiceField(label="Toot visibility", choices=PRIVACY_CHOICES,
|
||||||
required=False)
|
required=False)
|
||||||
spoiler_text = forms.CharField(label="CW or Subject", max_length=500,
|
spoiler_text = forms.CharField(label="CW or Subject", max_length=MAX_LENGTH,
|
||||||
required=False)
|
required=False)
|
||||||
media_file_1 = forms.FileField(label = "Media attachment 1",
|
media_file_1 = forms.FileField(label = "Media attachment 1",
|
||||||
required=False)
|
required=False)
|
||||||
media_text_1 = forms.CharField(label="Describe media attachment 1.", max_length=500,
|
media_text_1 = forms.CharField(label="Describe media attachment 1.",
|
||||||
|
max_length=MAX_LENGTH,
|
||||||
required=False)
|
required=False)
|
||||||
media_file_2 = forms.FileField(label = "Media attachment 2",
|
media_file_2 = forms.FileField(label = "Media attachment 2",
|
||||||
required=False)
|
required=False)
|
||||||
media_text_2 = forms.CharField(label="Describe media attachment 2.", max_length=500,
|
media_text_2 = forms.CharField(label="Describe media attachment 2.",
|
||||||
|
max_length=MAX_LENGTH,
|
||||||
required=False)
|
required=False)
|
||||||
media_file_3 = forms.FileField(label = "Media attachment 3",
|
media_file_3 = forms.FileField(label = "Media attachment 3",
|
||||||
required=False)
|
required=False)
|
||||||
media_text_3 = forms.CharField(label="Describe media attachment 3.", max_length=500,
|
media_text_3 = forms.CharField(label="Describe media attachment 3.",
|
||||||
|
max_length=MAX_LENGTH,
|
||||||
required=False)
|
required=False)
|
||||||
media_file_4 = forms.FileField(label = "Media attachment 4",
|
media_file_4 = forms.FileField(label = "Media attachment 4",
|
||||||
required=False)
|
required=False)
|
||||||
media_text_4 = forms.CharField(label="Describe media attachment 4.", max_length=500,
|
media_text_4 = forms.CharField(label="Describe media attachment 4.",
|
||||||
|
max_length=MAX_LENGTH,
|
||||||
required=False)
|
required=False)
|
||||||
media_sensitive = forms.BooleanField(label="Sensitive media?", required=False)
|
media_sensitive = forms.BooleanField(label="Sensitive media?", required=False)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super().clean()
|
||||||
|
status = cleaned_data.get("status")
|
||||||
|
spoiler_text = cleaned_data.get("spoiler_text")
|
||||||
|
|
||||||
|
if len(status) + len(spoiler_text) > MAX_LENGTH:
|
||||||
|
raise forms.ValidationError("Max length of toot exceeded: %(max_length)s",
|
||||||
|
code="too_long",
|
||||||
|
params={"max_length": MAX_LENGTH})
|
||||||
|
@ -187,3 +187,8 @@ FILE_UPLOAD_HANDLERS = ["django.core.files.uploadhandler.TemporaryFileUploadHand
|
|||||||
# Session serialization
|
# Session serialization
|
||||||
# Important: whatever you choose has to be able to serialize DateTime, so not JSON.
|
# Important: whatever you choose has to be able to serialize DateTime, so not JSON.
|
||||||
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
|
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
|
||||||
|
|
||||||
|
# Max length of toots
|
||||||
|
# Later this will be a user setting, but I am adding it here so that I don't
|
||||||
|
# write any magic numbers into the validation code
|
||||||
|
TOOT_MAX_LENGTH = 500
|
||||||
|
@ -75,6 +75,11 @@ span.account-locked
|
|||||||
margin-left: -16px;
|
margin-left: -16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.errorlist
|
||||||
|
{
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.media {
|
.media {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -282,3 +282,8 @@ label
|
|||||||
{
|
{
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.errorlist
|
||||||
|
{
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
<form method="post" id="post-form" action="{% url "toot" %}" enctype="multipart/form-data">
|
<form method="post" id="post-form" action="{% url "toot" %}" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field" >
|
<div class="field" >
|
||||||
<label class="label" >{{ form.status.label }}</label>
|
<label class="label" >{{ form.status.label }}</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
@ -9,10 +14,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
|
||||||
{{ form.errors }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="control level is-mobile">
|
<div class="control level is-mobile">
|
||||||
<img class="image avatar is-48x48 level-item" src="{{ own_acct.avatar_static }}" alt="">
|
<img class="image avatar is-48x48 level-item" src="{{ own_acct.avatar_static }}" alt="">
|
||||||
|
@ -5,153 +5,154 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<form method="post" action="{% url "toot" %}" enctype="multipart/form-data">
|
<form method="post" action="{% url "toot" %}" enctype="multipart/form-data">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<div class="field">
|
<div>
|
||||||
<label class="label"> {{ form.spoiler_text.label }}</label>
|
{{ form.non_field_errors }}
|
||||||
<div class="control">
|
<br>
|
||||||
{% render_field form.spoiler_text class+="input mousetrap" placeholder="Optional" %}
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label"> {{ form.spoiler_text.label }}</label>
|
||||||
|
<div class="control">
|
||||||
|
{% render_field form.spoiler_text class+="input mousetrap" placeholder="Optional" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field" >
|
||||||
|
<label class="label" >{{ form.status.label }}</label>
|
||||||
|
<div class="control">
|
||||||
|
{% render_field form.status class+="textarea mousetrap is-primary" rows="4" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" > {{ form.visibility.label }}</label>
|
||||||
|
<div class="control has-icons-left">
|
||||||
|
<div class="select">
|
||||||
|
{% render_field form.visibility class+="select"%}
|
||||||
|
<span class="icon is-small is-left" >
|
||||||
|
<i class="fa address-card"></i>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field" >
|
<div class="field has-addons">
|
||||||
<label class="label" >{{ form.status.label }}</label>
|
<div class="file">
|
||||||
<div class="control">
|
<label class="file-label">
|
||||||
{% render_field form.status class+="textarea mousetrap is-primary" rows="4" %}
|
{% render_field form.media_file_1 class+="file-input" %}
|
||||||
</div>
|
<span class="file-cta">
|
||||||
</div>
|
<span class="file-icon">
|
||||||
|
<i class="fa fa-upload"></i>
|
||||||
<div class="field">
|
|
||||||
<label class="label" > {{ form.visibility.label }}</label>
|
|
||||||
<div class="control has-icons-left">
|
|
||||||
<div class="select">
|
|
||||||
{% render_field form.visibility class+="select"%}
|
|
||||||
<span class="icon is-small is-left" >
|
|
||||||
<i class="fa address-card"></i>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
<span class="file-label" id="media_filename_1">
|
||||||
</div>
|
{{ form.media_file_1.label }}
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="file">
|
|
||||||
<label class="file-label">
|
|
||||||
{% render_field form.media_file_1 class+="file-input" %}
|
|
||||||
<span class="file-cta">
|
|
||||||
<span class="file-icon">
|
|
||||||
<i class="fa fa-upload"></i>
|
|
||||||
</span>
|
|
||||||
<span class="file-label" id="media_filename_1">
|
|
||||||
{{ form.media_file_1.label }}
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</span>
|
||||||
</div>
|
</label>
|
||||||
<div class="control is-expanded">
|
|
||||||
{% render_field form.media_text_1 class+="input mousetrap" placeholder="Describe attachment" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control is-expanded">
|
||||||
|
{% render_field form.media_text_1 class+="input mousetrap" placeholder="Describe attachment" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="file">
|
<div class="file">
|
||||||
<label class="file-label">
|
<label class="file-label">
|
||||||
{% render_field form.media_file_2 class+="file-input" %}
|
{% render_field form.media_file_2 class+="file-input" %}
|
||||||
<span class="file-cta">
|
<span class="file-cta">
|
||||||
<span class="file-icon">
|
<span class="file-icon">
|
||||||
<i class="fa fa-upload"></i>
|
<i class="fa fa-upload"></i>
|
||||||
</span>
|
|
||||||
<span class="file-label" id="media_filename_2">
|
|
||||||
{{ form.media_file_2.label }}
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
<span class="file-label" id="media_filename_2">
|
||||||
</div>
|
{{ form.media_file_2.label }}
|
||||||
<div class="control is-expanded">
|
|
||||||
{% render_field form.media_text_2 class+="input mousetrap" placeholder="Describe attachment" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="file">
|
|
||||||
<label class="file-label">
|
|
||||||
{% render_field form.media_file_3 class+="file-input" %}
|
|
||||||
<span class="file-cta">
|
|
||||||
<span class="file-icon">
|
|
||||||
<i class="fa fa-upload"></i>
|
|
||||||
</span>
|
|
||||||
<span class="file-label" id="media_filename_3">
|
|
||||||
{{ form.media_file_3.label }}
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</span>
|
||||||
</div>
|
</label>
|
||||||
<div class="control is-expanded">
|
|
||||||
{% render_field form.media_text_3 class+="input mousetrap" placeholder="Describe attachment" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="field has-addons">
|
<div class="control is-expanded">
|
||||||
<div class="file">
|
{% render_field form.media_text_2 class+="input mousetrap" placeholder="Describe attachment" %}
|
||||||
<label class="file-label">
|
</div>
|
||||||
{% render_field form.media_file_4 class+="file-input" %}
|
</div>
|
||||||
<span class="file-cta">
|
|
||||||
<span class="file-icon">
|
<div class="field has-addons">
|
||||||
<i class="fa fa-upload"></i>
|
<div class="file">
|
||||||
</span>
|
<label class="file-label">
|
||||||
<span class="file-label" id="media_filename_4">
|
{% render_field form.media_file_3 class+="file-input" %}
|
||||||
{{ form.media_file_4.label }}
|
<span class="file-cta">
|
||||||
</span>
|
<span class="file-icon">
|
||||||
|
<i class="fa fa-upload"></i>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
<span class="file-label" id="media_filename_3">
|
||||||
</div>
|
{{ form.media_file_3.label }}
|
||||||
<div class="control is-expanded">
|
</span>
|
||||||
{% render_field form.media_text_4 class+="input mousetrap" placeholder="Describe attachment" %}
|
</span>
|
||||||
</div>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control is-expanded">
|
||||||
|
{% render_field form.media_text_3 class+="input mousetrap" placeholder="Describe attachment" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="file">
|
||||||
|
<label class="file-label">
|
||||||
|
{% render_field form.media_file_4 class+="file-input" %}
|
||||||
|
<span class="file-cta">
|
||||||
|
<span class="file-icon">
|
||||||
|
<i class="fa fa-upload"></i>
|
||||||
|
</span>
|
||||||
|
<span class="file-label" id="media_filename_4">
|
||||||
|
{{ form.media_file_4.label }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="control is-expanded">
|
||||||
|
{% render_field form.media_text_4 class+="input mousetrap" placeholder="Describe attachment" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div class="field has-addons">
|
||||||
{{ form.errors }}
|
<div class="control level is-mobile">
|
||||||
</div>
|
<img class="image avatar is-48x48 level-item" src="{{ own_acct.avatar_static }}"
|
||||||
|
alt="">
|
||||||
<div class="field has-addons">
|
<input type="submit" class="button is-primary level-item"
|
||||||
<div class="control level is-mobile">
|
name="toot" value="Toot">
|
||||||
<img class="image avatar is-48x48 level-item" src="{{ own_acct.avatar_static }}"
|
|
||||||
alt="">
|
|
||||||
<input type="submit" class="button is-primary level-item"
|
|
||||||
name="toot" value="Toot">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if not fullbrutalism %}
|
{% if not fullbrutalism %}
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
var file1 = document.getElementById("id_media_file_1");
|
var file1 = document.getElementById("id_media_file_1");
|
||||||
file1.onchange = function(){
|
file1.onchange = function(){
|
||||||
if (file1.files.length > 0)
|
if (file1.files.length > 0)
|
||||||
{
|
{
|
||||||
document.getElementById('media_filename_1').innerHTML = file1.files[0].name;
|
document.getElementById('media_filename_1').innerHTML = file1.files[0].name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var file2 = document.getElementById("id_media_file_2");
|
var file2 = document.getElementById("id_media_file_2");
|
||||||
file2.onchange = function(){
|
file2.onchange = function(){
|
||||||
if (file2.files.length > 0)
|
if (file2.files.length > 0)
|
||||||
{
|
{
|
||||||
document.getElementById('media_filename_2').innerHTML = file2.files[0].name;
|
document.getElementById('media_filename_2').innerHTML = file2.files[0].name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var file3 = document.getElementById("id_media_file_3");
|
var file3 = document.getElementById("id_media_file_3");
|
||||||
file3.onchange = function(){
|
file3.onchange = function(){
|
||||||
if (file3.files.length > 0)
|
if (file3.files.length > 0)
|
||||||
{
|
{
|
||||||
document.getElementById('media_filename_3').innerHTML = file3.files[0].name;
|
document.getElementById('media_filename_3').innerHTML = file3.files[0].name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var file4 = document.getElementById("id_media_file_4");
|
var file4 = document.getElementById("id_media_file_4");
|
||||||
file4.onchange = function(){
|
file4.onchange = function(){
|
||||||
if (file4.files.length > 0)
|
if (file4.files.length > 0)
|
||||||
{
|
{
|
||||||
document.getElementById('media_filename_4').innerHTML = file4.files[0].name;
|
document.getElementById('media_filename_4').innerHTML = file4.files[0].name;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user