##// END OF EJS Templates
Refactored post image
neko259 -
r931:197e8096 default
parent child Browse files
Show More
@@ -1,62 +1,83 b''
1 import hashlib
1 import hashlib
2 import os
2 import os
3 from random import random
3 from random import random
4 import time
4 import time
5 from django.db import models
5 from django.db import models
6 from boards import thumbs
6 from boards import thumbs
7 from boards.models.base import Viewable
7
8
8 __author__ = 'neko259'
9 __author__ = 'neko259'
9
10
10
11
11 IMAGE_THUMB_SIZE = (200, 150)
12 IMAGE_THUMB_SIZE = (200, 150)
12 IMAGES_DIRECTORY = 'images/'
13 IMAGES_DIRECTORY = 'images/'
13 FILE_EXTENSION_DELIMITER = '.'
14 FILE_EXTENSION_DELIMITER = '.'
15 HASH_LENGTH = 36
16
17 CSS_CLASS_IMAGE = 'image'
18 CSS_CLASS_THUMB = 'thumb'
14
19
15
20
16 class PostImage(models.Model):
21 class PostImage(models.Model, Viewable):
17 class Meta:
22 class Meta:
18 app_label = 'boards'
23 app_label = 'boards'
19 ordering = ('id',)
24 ordering = ('id',)
20
25
21 def _update_image_filename(self, filename):
26 def _update_image_filename(self, filename):
22 """
27 """
23 Gets unique image filename
28 Gets unique image filename
24 """
29 """
25
30
26 path = IMAGES_DIRECTORY
31 path = IMAGES_DIRECTORY
27 new_name = str(int(time.mktime(time.gmtime())))
32 new_name = str(int(time.mktime(time.gmtime())))
28 new_name += str(int(random() * 1000))
33 new_name += str(int(random() * 1000))
29 new_name += FILE_EXTENSION_DELIMITER
34 new_name += FILE_EXTENSION_DELIMITER
30 new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
35 new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
31
36
32 return os.path.join(path, new_name)
37 return os.path.join(path, new_name)
33
38
34 width = models.IntegerField(default=0)
39 width = models.IntegerField(default=0)
35 height = models.IntegerField(default=0)
40 height = models.IntegerField(default=0)
36
41
37 pre_width = models.IntegerField(default=0)
42 pre_width = models.IntegerField(default=0)
38 pre_height = models.IntegerField(default=0)
43 pre_height = models.IntegerField(default=0)
39
44
40 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
45 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
41 blank=True, sizes=(IMAGE_THUMB_SIZE,),
46 blank=True, sizes=(IMAGE_THUMB_SIZE,),
42 width_field='width',
47 width_field='width',
43 height_field='height',
48 height_field='height',
44 preview_width_field='pre_width',
49 preview_width_field='pre_width',
45 preview_height_field='pre_height')
50 preview_height_field='pre_height')
46 hash = models.CharField(max_length=36)
51 hash = models.CharField(max_length=HASH_LENGTH)
47
52
48 def save(self, *args, **kwargs):
53 def save(self, *args, **kwargs):
49 """
54 """
50 Saves the model and computes the image hash for deduplication purposes.
55 Saves the model and computes the image hash for deduplication purposes.
51 """
56 """
52
57
53 if not self.pk and self.image:
58 if not self.pk and self.image:
54 md5 = hashlib.md5()
59 md5 = hashlib.md5()
55 for chunk in self.image.chunks():
60 for chunk in self.image.chunks():
56 md5.update(chunk)
61 md5.update(chunk)
57 self.hash = md5.hexdigest()
62 self.hash = md5.hexdigest()
58 super(PostImage, self).save(*args, **kwargs)
63 super(PostImage, self).save(*args, **kwargs)
59
64
60 def __str__(self):
65 def __str__(self):
61 return self.image.url
66 return self.image.url
62
67
68 def get_view(self):
69 return '<div class="{}">' \
70 '<a class="{}" href="{}">' \
71 '<img' \
72 ' src="{}"' \
73 ' alt="{}"' \
74 ' width="{}"' \
75 ' height="{}"' \
76 ' data-width="{}"' \
77 ' data-height="{}" />' \
78 '</a>' \
79 '</div>'\
80 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB, self.image.url,
81 self.image.url_200x150,
82 str(self.hash), str(self.pre_width),
83 str(self.pre_height), str(self.width), str(self.height))
@@ -1,96 +1,97 b''
1 {% load i18n %}
1 {% load i18n %}
2 {% load board %}
2 {% load board %}
3 {% load cache %}
3 {% load cache %}
4
4
5 {% get_current_language as LANGUAGE_CODE %}
5 {% get_current_language as LANGUAGE_CODE %}
6
6
7 {% if thread.archived %}
7 {% if thread.archived %}
8 <div class="post archive_post" id="{{ post.id }}">
8 <div class="post archive_post" id="{{ post.id }}">
9 {% elif bumpable %}
9 {% elif bumpable %}
10 <div class="post" id="{{ post.id }}">
10 <div class="post" id="{{ post.id }}">
11 {% else %}
11 {% else %}
12 <div class="post dead_post" id="{{ post.id }}">
12 <div class="post dead_post" id="{{ post.id }}">
13 {% endif %}
13 {% endif %}
14
14
15 <div class="post-info">
15 <div class="post-info">
16 <a class="post_id" href="{% post_object_url post thread=thread %}"
16 <a class="post_id" href="{% post_object_url post thread=thread %}"
17 {% if not truncated and not thread.archived %}
17 {% if not truncated and not thread.archived %}
18 onclick="javascript:addQuickReply('{{ post.id }}'); return false;"
18 onclick="javascript:addQuickReply('{{ post.id }}'); return false;"
19 title="{% trans 'Quote' %}" {% endif %}>({{ post.id }})</a>
19 title="{% trans 'Quote' %}" {% endif %}>({{ post.id }})</a>
20 <span class="title">{{ post.title }}</span>
20 <span class="title">{{ post.title }}</span>
21 <span class="pub_time">{{ post.pub_time }}</span>
21 <span class="pub_time">{{ post.pub_time }}</span>
22 {% comment %}
22 {% comment %}
23 Thread death time needs to be shown only if the thread is alredy archived
23 Thread death time needs to be shown only if the thread is alredy archived
24 and this is an opening post (thread death time) or a post for popup
24 and this is an opening post (thread death time) or a post for popup
25 (we don't see OP here so we show the death time in the post itself).
25 (we don't see OP here so we show the death time in the post itself).
26 {% endcomment %}
26 {% endcomment %}
27 {% if thread.archived %}
27 {% if thread.archived %}
28 {% if is_opening %}
28 {% if is_opening %}
29 β€” {{ thread.bump_time }}
29 β€” {{ thread.bump_time }}
30 {% endif %}
30 {% endif %}
31 {% endif %}
31 {% endif %}
32 {% if is_opening and need_open_link %}
32 {% if is_opening and need_open_link %}
33 {% if thread.archived %}
33 {% if thread.archived %}
34 [<a class="link" href="{% url 'thread' post.id %}">{% trans "Open" %}</a>]
34 [<a class="link" href="{% url 'thread' post.id %}">{% trans "Open" %}</a>]
35 {% else %}
35 {% else %}
36 [<a class="link" href="{% url 'thread' post.id %}#form">{% trans "Reply" %}</a>]
36 [<a class="link" href="{% url 'thread' post.id %}#form">{% trans "Reply" %}</a>]
37 {% endif %}
37 {% endif %}
38 {% endif %}
38 {% endif %}
39
39
40 {% if moderator %}
40 {% if moderator %}
41 <span class="moderator_info">
41 <span class="moderator_info">
42 [<a href="{% url 'admin:boards_post_change' post.id %}">{% trans 'Edit' %}</a>]
42 [<a href="{% url 'admin:boards_post_change' post.id %}">{% trans 'Edit' %}</a>]
43 {% if is_opening %}
43 {% if is_opening %}
44 [<a href="{% url 'admin:boards_thread_change' thread.id %}">{% trans 'Edit thread' %}</a>]
44 [<a href="{% url 'admin:boards_thread_change' thread.id %}">{% trans 'Edit thread' %}</a>]
45 {% endif %}
45 {% endif %}
46 </span>
46 </span>
47 {% endif %}
47 {% endif %}
48 </div>
48 </div>
49 {% comment %}
50 Post images. Currently only 1 image can be posted and shown, but post model
51 supports multiple.
52 {% endcomment %}
49 {% if post.images.exists %}
53 {% if post.images.exists %}
50 {% with post.images.all.0 as image %}
54 {% with post.images.all.0 as image %}
51 <div class="image">
55 {% autoescape off %}
52 <a
56 {{ image.get_view }}
53 class="thumb"
57 {% endautoescape %}
54 href="{{ image.image.url }}"><img
55 src="{{ image.image.url_200x150 }}"
56 alt="{{ post.id }}"
57 width="{{ image.pre_width }}"
58 height="{{ image.pre_height }}"
59 data-width="{{ image.width }}"
60 data-height="{{ image.height }}"/>
61 </a>
62 </div>
63 {% endwith %}
58 {% endwith %}
64 {% endif %}
59 {% endif %}
60 {% comment %}
61 Post message (text)
62 {% endcomment %}
65 <div class="message">
63 <div class="message">
66 {% autoescape off %}
64 {% autoescape off %}
67 {% if truncated %}
65 {% if truncated %}
68 {{ post.get_text|truncatewords_html:50 }}
66 {{ post.get_text|truncatewords_html:50 }}
69 {% else %}
67 {% else %}
70 {{ post.get_text }}
68 {{ post.get_text }}
71 {% endif %}
69 {% endif %}
72 {% endautoescape %}
70 {% endautoescape %}
73 {% if post.is_referenced %}
71 {% if post.is_referenced %}
74 <div class="refmap">
72 <div class="refmap">
75 {% autoescape off %}
73 {% autoescape off %}
76 {% trans "Replies" %}: {{ post.refmap }}
74 {% trans "Replies" %}: {{ post.refmap }}
77 {% endautoescape %}
75 {% endautoescape %}
78 </div>
76 </div>
79 {% endif %}
77 {% endif %}
80 </div>
78 </div>
79 {% comment %}
80 Thread metadata: counters, tags etc
81 {% endcomment %}
81 {% if is_opening %}
82 {% if is_opening %}
82 <div class="metadata">
83 <div class="metadata">
83 {% if is_opening and need_open_link %}
84 {% if is_opening and need_open_link %}
84 {{ thread.get_reply_count }} {% trans 'messages' %},
85 {{ thread.get_reply_count }} {% trans 'messages' %},
85 {{ thread.get_images_count }} {% trans 'images' %}.
86 {{ thread.get_images_count }} {% trans 'images' %}.
86 {% endif %}
87 {% endif %}
87 <span class="tags">
88 <span class="tags">
88 {% for tag in thread.get_tags %}
89 {% for tag in thread.get_tags %}
89 {% autoescape off %}
90 {% autoescape off %}
90 {{ tag.get_view }}{% if not forloop.last %},{% endif %}
91 {{ tag.get_view }}{% if not forloop.last %},{% endif %}
91 {% endautoescape %}
92 {% endautoescape %}
92 {% endfor %}
93 {% endfor %}
93 </span>
94 </span>
94 </div>
95 </div>
95 {% endif %}
96 {% endif %}
96 </div>
97 </div>
General Comments 0
You need to be logged in to leave comments. Login now