Skip to content
This repository was archived by the owner on Apr 21, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 66 additions & 27 deletions djangobb_forum/forms.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# coding: utf-8
from __future__ import unicode_literals

import os.path
from datetime import timedelta
import string
import os.path

from django import forms
from django.conf import settings
from django.template.defaultfilters import filesizeformat
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.text import get_valid_filename

from djangobb_forum import settings as forum_settings
from djangobb_forum.models import Topic, Post, Profile, Reputation, Report, \
Attachment, Poll, PollChoice
from djangobb_forum import settings as forum_settings
from djangobb_forum.util import convert_text_to_html, set_language
from djangobb_forum.user import User
from djangobb_forum.util import convert_text_to_html, set_language


SORT_USER_BY_CHOICES = (
Expand Down Expand Up @@ -45,13 +48,55 @@
('topic', _('Topic subject only')),
)

def format_filename(s):
"""Take a string and return a valid filename constructed from the string.
Uses a whitelist approach: any characters not present in valid_chars are
removed. Also spaces are replaced with underscores.

Note: this method may produce invalid filenames such as ``, `.` or `..`
When I use this method I prepend a date string like '2009_01_15_19_46_32_'
and append a file extension like '.txt', so I avoid the potential of using
an invalid filename.

see: https://gist.github.com/seanh/93666
"""
valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
filename = ''.join(c for c in s if c in valid_chars)
filename = filename.replace(' ','_') # I don't like spaces in filenames.
return filename


class BasePostForm(forms.ModelForm):
attachment = forms.FileField(label=_('Attachment'), required=False, widget=forms.FileInput(attrs={'multiple':'multiple'}))

class AddPostForm(forms.ModelForm):
def clean_attachment(self):
if not self.files:
return self.cleaned_data['attachment']
attachments = self.files.getlist('attachment')
for memfile in attachments:
if memfile.size > forum_settings.ATTACHMENT_SIZE_LIMIT:
msg = _('Attachment is too big')
msg += ' (max. %s)' % (filesizeformat(forum_settings.ATTACHMENT_SIZE_LIMIT))
raise forms.ValidationError(msg)
return attachments

def save_attachment(self, post, memfile):
if memfile:
obj = Attachment(size=memfile.size, content_type=memfile.content_type,
name=memfile.name, post=post)
dir = os.path.join(settings.MEDIA_ROOT, forum_settings.ATTACHMENT_UPLOAD_TO)
fname = '%d.%s' % (post.id, get_valid_filename(format_filename(memfile.name[:240])))
path = os.path.join(dir, fname)
open(path, 'wb').write(memfile.read())
obj.path = fname
obj.save()


class AddPostForm(BasePostForm):
FORM_NAME = "AddPostForm" # used in view and template submit button

name = forms.CharField(label=_('Subject'), max_length=255,
widget=forms.TextInput(attrs={'size':'115'}))
attachment = forms.FileField(label=_('Attachment'), required=False)
subscribe = forms.BooleanField(label=_('Subscribe'), help_text=_("Subscribe this topic."), required=False)

class Meta:
Expand Down Expand Up @@ -93,13 +138,6 @@ def clean(self):
del cleaned_data['body']
return cleaned_data

def clean_attachment(self):
if self.cleaned_data['attachment']:
memfile = self.cleaned_data['attachment']
if memfile.size > forum_settings.ATTACHMENT_SIZE_LIMIT:
raise forms.ValidationError(_('Attachment is too big'))
return self.cleaned_data['attachment']

def save(self):
if self.forum:
topic = Topic(forum=self.forum,
Expand All @@ -118,26 +156,16 @@ def save(self):
body=self.cleaned_data['body'])

post.save()
if forum_settings.ATTACHMENT_SUPPORT:
self.save_attachment(post, self.cleaned_data['attachment'])
if forum_settings.ATTACHMENT_SUPPORT and self.files:
for attachment in self.files.getlist('attachment'):
self.save_attachment(post, attachment)
return post


def save_attachment(self, post, memfile):
if memfile:
obj = Attachment(size=memfile.size, content_type=memfile.content_type,
name=memfile.name, post=post)
dir = os.path.join(settings.MEDIA_ROOT, forum_settings.ATTACHMENT_UPLOAD_TO)
fname = '%d.0' % post.id
path = os.path.join(dir, fname)
open(path, 'wb').write(memfile.read())
obj.path = fname
obj.save()


class EditPostForm(forms.ModelForm):
class EditPostForm(BasePostForm):
name = forms.CharField(required=False, label=_('Subject'),
widget=forms.TextInput(attrs={'size':'115'}))
delete_attachments = forms.ModelMultipleChoiceField(None, required=False, widget=forms.CheckboxSelectMultiple())

class Meta:
model = Post
Expand All @@ -148,6 +176,8 @@ def __init__(self, *args, **kwargs):
super(EditPostForm, self).__init__(*args, **kwargs)
self.fields['name'].initial = self.topic
self.fields['body'].widget = forms.Textarea(attrs={'class':'markup'})
# initial selection of attachments
self.fields['delete_attachments'].queryset = Attachment.objects.filter(post=self.instance)

def save(self, commit=True):
post = super(EditPostForm, self).save(commit=False)
Expand All @@ -158,6 +188,15 @@ def save(self, commit=True):
if commit:
post.topic.save()
post.save()
if forum_settings.ATTACHMENT_SUPPORT:
# add new attachments
if self.files:
for attachment in self.files.getlist('attachment'):
self.save_attachment(post, attachment)
# delete existing attachments
delete_attachments = self.cleaned_data['delete_attachments']
for attachment in delete_attachments:
attachment.delete()
return post


Expand Down
33 changes: 32 additions & 1 deletion djangobb_forum/templates/djangobb_forum/edit_post.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<h2>{% trans "Edit post" %}</h2>

<div class="box">
<form method="post">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="inform">
<fieldset>
Expand All @@ -31,6 +31,37 @@ <h2>{% trans "Edit post" %}</h2>
</fieldset>
</div>

{% if forum_settings.ATTACHMENT_SUPPORT %}
<div class="inform">
<fieldset>
<legend>{% trans "Attachments" %}</legend>
<div class="infldset">

<p>
Note: Flag checkbox to delete an attachment
</p>

<p>
{% with post.attachments.all as attachments %}
{% if attachments %}
{% for attach in attachments %}
<input type="checkbox" id="id_delete_attachments_{{ forloop.counter0 }}" name="delete_attachments" value="{{ attach.pk }}" />
{{ attach|attachment_link }}<br />
{% endfor %}
{% endif %}
{% endwith %}
</p>

<br />
{{ form.attachment.errors }}
<div class="rbox">
{{ form.attachment }}
</div>
</div>
</fieldset>
</div>
{% endif %}

<p><input type="submit" value="{% trans "Save" %}" /><a href="javascript:history.go(-1)">{% trans "Go back" %}</a></p>
</form>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ <h2><span>{% if forum %}{% trans "New topic" %}{% else %}{% trans "New reply" %}
{% if forum_settings.ATTACHMENT_SUPPORT %}
<div class="inform">
<fieldset>
<legend>{% trans "Attachment" %}</legend>
<legend>{% trans "Attachments" %}</legend>
<div class="infldset">
{{ form.attachment.errors }}
<div class="rbox">
Expand Down
4 changes: 1 addition & 3 deletions djangobb_forum/templates/djangobb_forum/topic.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ <h3>{{ post.topic.name }}</h3>
{% endif %}
{% with post.attachments.all as attachments %}
{% if attachments %}
{% for attach in attachments %}
<p class="postedit"><em>{% trans "Attachments:" %} <br />{{ attach|attachment_link }}</em></p>
{% endfor %}
<p class="postedit"><em>{% trans "Attachments:" %} {% for attach in attachments %}<br />{{ attach|attachment_link }}{% endfor %}</em></p>
{% endif %}
{% endwith %}
</div>
Expand Down