##// END OF EJS Templates
Don't return posts with the same image in random view
neko259 -
r1249:93f2906a default
parent child Browse files
Show More
@@ -1,110 +1,120 b''
1 1 import hashlib
2 2 import os
3 3 from random import random
4 4 import time
5
5 6 from django.db import models
6 7 from django.template.defaultfilters import filesizeformat
8
7 9 from boards import thumbs
10 import boards
8 11 from boards.models.base import Viewable
9 12
10 13 __author__ = 'neko259'
11 14
12 15
13 16 IMAGE_THUMB_SIZE = (200, 150)
14 17 IMAGES_DIRECTORY = 'images/'
15 18 FILE_EXTENSION_DELIMITER = '.'
16 19 HASH_LENGTH = 36
17 20
18 21 CSS_CLASS_IMAGE = 'image'
19 22 CSS_CLASS_THUMB = 'thumb'
20 23
21 24
22 25 class PostImageManager(models.Manager):
23 26 def create_with_hash(self, image):
24 27 image_hash = self.get_hash(image)
25 28 existing = self.filter(hash=image_hash)
26 29 if len(existing) > 0:
27 30 post_image = existing[0]
28 31 else:
29 32 post_image = PostImage.objects.create(image=image)
30 33
31 34 return post_image
32 35
33 36 def get_hash(self, image):
34 37 """
35 38 Gets hash of an image.
36 39 """
37 40 md5 = hashlib.md5()
38 41 for chunk in image.chunks():
39 42 md5.update(chunk)
40 43 return md5.hexdigest()
41 44
45 def get_random_images(self, count):
46 return self.order_by('?')[:count]
47
42 48
43 49 class PostImage(models.Model, Viewable):
44 50 objects = PostImageManager()
45 51
46 52 class Meta:
47 53 app_label = 'boards'
48 54 ordering = ('id',)
49 55
50 56 def _update_image_filename(self, filename):
51 57 """
52 58 Gets unique image filename
53 59 """
54 60
55 61 path = IMAGES_DIRECTORY
56 62
57 63 # TODO Use something other than random number in file name
58 64 new_name = '{}{}.{}'.format(
59 65 str(int(time.mktime(time.gmtime()))),
60 66 str(int(random() * 1000)),
61 67 filename.split(FILE_EXTENSION_DELIMITER)[-1:][0])
62 68
63 69 return os.path.join(path, new_name)
64 70
65 71 width = models.IntegerField(default=0)
66 72 height = models.IntegerField(default=0)
67 73
68 74 pre_width = models.IntegerField(default=0)
69 75 pre_height = models.IntegerField(default=0)
70 76
71 77 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
72 78 blank=True, sizes=(IMAGE_THUMB_SIZE,),
73 79 width_field='width',
74 80 height_field='height',
75 81 preview_width_field='pre_width',
76 82 preview_height_field='pre_height')
77 83 hash = models.CharField(max_length=HASH_LENGTH)
78 84
79 85 def save(self, *args, **kwargs):
80 86 """
81 87 Saves the model and computes the image hash for deduplication purposes.
82 88 """
83 89
84 90 if not self.pk and self.image:
85 91 self.hash = PostImage.objects.get_hash(self.image)
86 92 super(PostImage, self).save(*args, **kwargs)
87 93
88 94 def __str__(self):
89 95 return self.image.url
90 96
91 97 def get_view(self):
92 98 metadata = '{}, {}'.format(self.image.name.split('.')[-1],
93 99 filesizeformat(self.image.size))
94 100 return '<div class="{}">' \
95 101 '<a class="{}" href="{full}">' \
96 102 '<img class="post-image-preview"' \
97 103 ' src="{}"' \
98 104 ' alt="{}"' \
99 105 ' width="{}"' \
100 106 ' height="{}"' \
101 107 ' data-width="{}"' \
102 108 ' data-height="{}" />' \
103 109 '</a>' \
104 110 '<div class="image-metadata">{image_meta}</div>' \
105 111 '</div>'\
106 112 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB,
107 113 self.image.url_200x150,
108 114 str(self.hash), str(self.pre_width),
109 115 str(self.pre_height), str(self.width), str(self.height),
110 116 full=self.image.url, image_meta=metadata)
117
118 def get_random_associated_post(self):
119 return boards.models.Post.objects.filter(images__in=[self])\
120 .order_by('?').first()
@@ -1,32 +1,32 b''
1 1 {% extends "boards/base.html" %}
2 2
3 3 {% load i18n %}
4 4
5 5 {% block head %}
6 6 <title>{% trans 'Random images' %} - {{ site_name }}</title>
7 7 {% endblock %}
8 8
9 9 {% block content %}
10 10
11 {% if posts %}
11 {% if images %}
12 12 <div class="random-images-table">
13 13 <div>
14 {% for post in posts %}
14 {% for image in images %}
15 15 <div class="gallery_image">
16 {% with post.get_first_image as image %}
17 16 {% autoescape off %}
18 17 {{ image.get_view }}
19 18 {% endautoescape %}
20 <a href="{{ post.get_absolute_url }}">>>{{ post.id }}</a>
21 {% endwith %}
19 {% with image.get_random_associated_post as post %}
20 <a href="{{ post.get_absolute_url }}">>>{{ post.id }}</a>
21 {% endwith %}
22 22 </div>
23 23 {% if forloop.counter|divisibleby:"3" %}
24 24 </div>
25 25 <div>
26 26 {% endif %}
27 27 {% endfor %}
28 28 </div>
29 29 </div>
30 30 {% endif %}
31 31
32 32 {% endblock %}
@@ -1,28 +1,22 b''
1 1 from django.shortcuts import render
2 from django.template import RequestContext
3 2 from django.views.generic import View
4 from django.db.models import Count
5 3
6 from boards.models import Post
7 from boards.mdx_neboard import Parser
4 from boards.models import PostImage
8 5
9 6 __author__ = 'neko259'
10 7
11 8 TEMPLATE = 'boards/random.html'
12 9
13 CONTEXT_POSTS = 'posts'
10 CONTEXT_IMAGES = 'images'
14 11
15 12 RANDOM_POST_COUNT = 9
16 13
17 14
18 15 class RandomImageView(View):
19 16 def get(self, request):
20 17 params = dict()
21 18
22 posts = Post.objects.annotate(images_count=Count(
23 'images')).filter(images_count__gt=0).order_by('?')\
24 [:RANDOM_POST_COUNT]
25
26 params[CONTEXT_POSTS] = posts
19 params[CONTEXT_IMAGES] = PostImage.objects.get_random_images(
20 RANDOM_POST_COUNT)
27 21
28 22 return render(request, TEMPLATE, params)
General Comments 0
You need to be logged in to leave comments. Login now