add #18 file attach

This commit is contained in:
alafin 2009-04-14 14:57:17 +03:00
parent ffc5e1c559
commit 7a45131368
8 changed files with 143 additions and 8 deletions

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import re
import os.path
from datetime import datetime
from django import forms
@ -9,8 +10,10 @@ from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from forum.models import Topic, Post, Profile, Reputation, Report, PrivateMessage, Forum
from forum.models import Topic, Post, Profile, Reputation, Report, PrivateMessage,\
Forum, Attachment
from forum.markups import mypostmarkup
from forum import settings as forum_settings
SORT_USER_BY_CHOICES = (
('username', _(u'Username')),
@ -42,8 +45,10 @@ SEARCH_IN_CHOICES = (
)
class AddPostForm(forms.ModelForm):
name = forms.CharField(label=_('Subject'),
name = forms.CharField(label=_('Subject'),
widget=forms.TextInput(attrs={'size':'115'}))
attachment = forms.FileField(label=_('Attachment'), required=False,
widget=forms.FileInput(attrs={'size':'115'}))
class Meta:
model = Post
@ -55,12 +60,25 @@ class AddPostForm(forms.ModelForm):
self.forum = kwargs.pop('forum', None)
self.ip = kwargs.pop('ip', None)
super(AddPostForm, self).__init__(*args, **kwargs)
if self.topic:
self.fields['name'].widget = forms.HiddenInput()
self.fields['name'].required = False
self.fields['body'].widget = forms.Textarea(attrs={'class':'bbcode', 'rows':'20', 'cols':'95'})
if not forum_settings.ATTACHMENT_SUPPORT:
self.fields['attachment'].widget = forms.HiddenInput()
self.fields['attachment'].required = False
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:
@ -75,11 +93,26 @@ class AddPostForm(forms.ModelForm):
markup='bbcode',
body=self.cleaned_data['body'])
post.save()
if forum_settings.ATTACHMENT_SUPPORT:
self.save_attachment(post, self.cleaned_data['attachment'])
profile = get_object_or_404(Profile, user=self.user)
profile.post_count += 1
profile.save()
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)
file(path, 'w').write(memfile.read())
obj.path = fname
obj.save()
class EssentialsProfileForm(forms.ModelForm):
username = forms.CharField(label=_('Username'))
email = forms.CharField(label=_('E-mail'))

View file

@ -1,6 +1,8 @@
from datetime import datetime
import os
import os.path
import sha
from django.db import models
from django.contrib.auth.models import User, Group
@ -401,3 +403,37 @@ class Ban(models.Model):
def __unicode__(self):
return self.user
class Attachment(models.Model):
post = models.ForeignKey(Post, verbose_name=_('Post'), related_name='attachments')
size = models.IntegerField(_('Size'))
content_type = models.CharField(_('Content type'), max_length=255)
path = models.CharField(_('Path'), max_length=255)
name = models.TextField(_('Name'))
hash = models.CharField(_('Hash'), max_length=40, blank=True, default='', db_index=True)
def save(self, *args, **kwargs):
super(Attachment, self).save(*args, **kwargs)
if not self.hash:
self.hash = sha.new(str(self.id) + settings.SECRET_KEY).hexdigest()
super(Attachment, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
def get_absolute_url(self):
return reverse('forum_attachment', args=[self.hash])
def size_display(self):
size = self.size
if size < 1024:
return '%b' % size
elif size < 1024 * 1024:
return '%dKb' % int(size / 1024)
else:
return '%.2fMb' % (size / float(1024 * 1024))
def get_absolute_path(self):
return os.path.join(settings.MEDIA_ROOT, forum_settings.ATTACHMENT_UPLOAD_TO,
self.path)

View file

@ -49,7 +49,13 @@ AUTHORITY_STEP_9 = get('AUTHORITY_STEP_9', 500)
AUTHORITY_STEP_10 = get('AUTHORITY_STEP_10', 1000)
# REPUTATION Extension
REPUTATION_SUPPORT = get('REPUTATION_SUPPORT', True)
REPUTATION_SUPPORT = get('REPUTATION_SUPPORT', True)
# ATTACHMENT Extension
ATTACHMENT_SUPPORT = get('ATTACHMENT_SUPPORT', True)
ATTACHMENT_UPLOAD_TO = get('ATTACHMENT_UPLOAD_TO', 'forum/attachments')
ATTACHMENT_SIZE_LIMIT = get('ATTACHMENT_SIZE_LIMIT', 1024 * 1024)
# SMILE Extension
EMOTION_SMILE = get('EMOTION_SMILE', '<img src="%sforum/img/smilies/smile.png">' % settings.MEDIA_URL)

View file

@ -17,7 +17,7 @@
<div class="blockform">
<h2><span>{% if forum %}{% trans "New topic" %}{% else %}{% trans "New reply" %}{% endif %}</span></h2>
<div class="box">
<form id="post" action="{% if forum %}{% url add_topic forum.id %}{% else %}{% url add_post topic.id %}{% endif %}" method="post">
<form id="post" action="{% if forum %}{% url add_topic forum.id %}{% else %}{% url add_post topic.id %}{% endif %}" method="post" enctype="multipart/form-data">
<div class="inform">
<fieldset>
<legend>{% trans "Write your message and submit" %}</legend>
@ -29,6 +29,18 @@
</div>
</fieldset>
</div>
{% if "ATTACHMENT_SUPPORT"|forum_setting %}
<div class="inform">
<fieldset>
<legend><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>{% trans "Attachment" %}<7D><></legend>
<div class="infldset">
<div class="rbox">
{{ form.attachment }}
</div>
</div>
</fieldset>
</div>
{% endif %}
<p><input type="submit" value="{% trans "Submit" %}" /><a href="javascript:history.go(-1)">{% trans "Go back" %}</a></p>
</form>
@ -55,7 +67,6 @@
</div>
<div class="clearer"></div>
<div class="postfootright"><ul><li class="postquote"><a onmouseover="copyQ('{{ post.user }}');" href="javascript:pasteQ();">{% trans "Quote" %}</a></li></ul></div>
</div>
</div>
{% endfor %}

View file

@ -90,6 +90,12 @@
{% if post.updated %}
<p class="postedit"><em>{% trans "Edited" %} {{ post.user }} ({% forum_time post.updated %})</em></p>
{% endif %}
{% if post.attachments.all %}
{% for attach in post.attachments.all %}
<p class="postedit"><em>{% trans "Attachments:" %} <div>{{ attach|attachment_link }}</div></em></p>
{% endfor %}
{% endif %}
</div>
</div>
@ -143,7 +149,7 @@
<div class="blockform">
<h2><span>{% trans "Quick post" %}</span></h2>
<div class="box">
<form id="post" action="{% url add_post topic.id %}" method="post">
<form id="post" action="{% url add_post topic.id %}" method="post" enctype="multipart/form-data">
<div class="inform">
<fieldset>
@ -154,6 +160,18 @@
</fieldset>
</div>
{% if "ATTACHMENT_SUPPORT"|forum_setting %}
<div class="inform">
<fieldset>
<legend><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>{% trans "Attachment" %}<7D><></legend>
<div class="infldset">
<div class="rbox">
{{ form.attachment }}
</div>
</div>
</fieldset>
</div>
{% endif %}
<p><input type="submit" value="{% trans "Submit" %}" /></p>
</form>
</div>

View file

@ -262,6 +262,21 @@ def online(user):
def pm_unreads(user):
return PrivateMessage.objects.filter(dst_user=user, read=False).count()
@register.filter
def attachment_link(attach):
if attach.content_type in ['image/png', 'image/gif', 'image/jpeg']:
img = '<img src="%sforum/img/attachment/image.png" alt="attachment" >' % (settings.MEDIA_URL)
elif attach.content_type in ['application/x-tar', 'application/zip']:
img = '<img src="%sforum/img/attachment/compress.png" alt="attachment" >' % (settings.MEDIA_URL)
elif attach.content_type in ['text/plain']:
img = '<img src="%sforum/img/attachment/text.png" alt="attachment" >' % (settings.MEDIA_URL)
elif attach.content_type in ['application/msword']:
img = '<img src="%sforum/img/attachment/doc.png" alt="attachment" >' % (settings.MEDIA_URL)
else:
img = '<img src="%sforum/img/attachment/unknown.png" alt="attachment" >' % (settings.MEDIA_URL)
attachment = '%s <a href="%s">%s</a> (%s)' % (img, attach.get_absolute_url(), attach.name, attach.size_display())
return mark_safe(attachment)
@register.simple_tag
def new_reports():
return Report.objects.filter(zapped=False).count()

View file

@ -72,3 +72,10 @@ if (forum_settings.REPUTATION_SUPPORT):
url('^reputation/(?P<username>.*)/$', views.reputation, name='reputation'),
)
# ATTACHMENT Extension
if (forum_settings.ATTACHMENT_SUPPORT):
urlpatterns += patterns('',
url('^attachment/(?P<hash>\w+)/$', views.show_attachment, name='forum_attachment'),
)

View file

@ -15,7 +15,7 @@ from django.db.models import Q
from forum.util import render_to, paged, build_form, paginate, set_language
from forum.models import Category, Forum, Topic, Post, Profile, Read,\
Reputation, Report, PrivateMessage
Reputation, Report, PrivateMessage, Attachment
from forum.forms import AddPostForm, EditPostForm, UserSearchForm,\
PostSearchForm, ReputationForm, MailToForm, EssentialsProfileForm,\
PersonalProfileForm, MessagingProfileForm, PersonalityProfileForm,\
@ -25,6 +25,8 @@ from forum.templatetags import forum_extras
from forum import settings as forum_settings
from forum.util import urlize, smiles
from forum.index import post_indexer
from forum.orm import load_related
@render_to('forum/index.html')
def index(request, full=True):
@ -334,6 +336,7 @@ def show_topic(request, topic_id, full=True):
}
else:
pages, paginator, paged_list_name = paginate(posts, request, forum_settings.TOPIC_PAGE_SIZE)
load_related(page.object_list, Attachment.objects.all(), 'post')
return {'categories': Category.objects.all(),
'topic': topic,
#'last_post': last_post,
@ -365,7 +368,7 @@ def add_post(request, forum_id, topic_id):
return HttpResponseForbidden()
if topic and topic.closed:
return HttpResponseRedirect(topic.get_absolute_url())
ip = request.META.get('REMOTE_ADDR', '')
form = build_form(AddPostForm, request, topic=topic, forum=forum,
user=request.user, ip=ip,
@ -779,6 +782,12 @@ def add_subscription(request, topic_id):
topic.subscribers.add(request.user)
return HttpResponseRedirect(reverse('topic', args=[topic.id]))
@login_required
def show_attachment(request, hash):
attachment = get_object_or_404(Attachment, hash=hash)
file_obj = file(attachment.get_absolute_path())
return HttpResponse(file_obj, content_type=attachment.content_type)
#TODO: check markup
@render_to('forum/post_preview.html')
def post_preview(request):