add #18 file attach
This commit is contained in:
parent
ffc5e1c559
commit
7a45131368
8 changed files with 143 additions and 8 deletions
|
@ -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'))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Reference in a new issue