##// END OF EJS Templates
Removed obsolete code. Added download link to files
neko259 -
r1308:ced75ab0 default
parent child Browse files
Show More
@@ -1,30 +1,26 b''
1 class Tripcode:
1 class Tripcode:
2 def __init__(self, code_str):
2 def __init__(self, code_str):
3 self.tripcode = code_str
3 self.tripcode = code_str
4
4
5 def get_color(self):
5 def get_color(self):
6 return self.tripcode[:6]
6 return self.tripcode[:6]
7
7
8 def get_background(self):
8 def get_background(self):
9 code = self.get_color()
9 code = self.get_color()
10 result = ''
10 result = ''
11
11
12 for i in range(0, len(code), 2):
12 for i in range(0, len(code), 2):
13 p = code[i:i+2]
13 p = code[i:i+2]
14 background = hex(255 - int(p, 16))[2:]
14 background = hex(255 - int(p, 16))[2:]
15 if len(background) < 2:
15 if len(background) < 2:
16 background = '0' + background
16 background = '0' + background
17 result += background
17 result += background
18
18
19 return result
19 return result
20
20
21 def get_short_text(self):
21 def get_short_text(self):
22 return self.tripcode[:8]
22 return self.tripcode[:8]
23
23
24 def get_full_text(self):
24 def get_full_text(self):
25 return self.tripcode
25 return self.tripcode
26
26
27 def get_view(self):
28 return '<span class="tripcode" title="{title}" style="border: solid 2px #{color}; border-left: solid 1ex #{color};">{text}</span>'\
29 .format(title=self.get_full_text(), color=self.get_color(),
30 text=self.get_short_text())
@@ -1,70 +1,70 b''
1 from django.template.defaultfilters import filesizeformat
1 from django.template.defaultfilters import filesizeformat
2 from django.contrib.staticfiles.templatetags.staticfiles import static
2 from django.contrib.staticfiles.templatetags.staticfiles import static
3
3
4 FILE_STUB_IMAGE = 'images/file.png'
4 FILE_STUB_IMAGE = 'images/file.png'
5
5
6 FILE_TYPES_VIDEO = (
6 FILE_TYPES_VIDEO = (
7 'webm',
7 'webm',
8 'mp4',
8 'mp4',
9 )
9 )
10 FILE_TYPE_SVG = 'svg'
10 FILE_TYPE_SVG = 'svg'
11 FILE_TYPES_AUDIO = (
11 FILE_TYPES_AUDIO = (
12 'ogg',
12 'ogg',
13 'mp3',
13 'mp3',
14 )
14 )
15
15
16
16
17 def get_viewers():
17 def get_viewers():
18 return AbstractViewer.__subclasses__()
18 return AbstractViewer.__subclasses__()
19
19
20
20
21 class AbstractViewer:
21 class AbstractViewer:
22 def __init__(self, file, file_type):
22 def __init__(self, file, file_type):
23 self.file = file
23 self.file = file
24 self.file_type = file_type
24 self.file_type = file_type
25
25
26 @staticmethod
26 @staticmethod
27 def supports(file_type):
27 def supports(file_type):
28 return True
28 return True
29
29
30 def get_view(self):
30 def get_view(self):
31 return '<div class="image">'\
31 return '<div class="image">'\
32 '{}'\
32 '{}'\
33 '<div class="image-metadata">{}, {}</div>'\
33 '<div class="image-metadata"><a href="{}" download >{}, {}</a></div>'\
34 '</div>'.format(self.get_format_view(),
34 '</div>'.format(self.get_format_view(), self.file.url,
35 self.file_type, filesizeformat(self.file.size))
35 self.file_type, filesizeformat(self.file.size))
36
36
37 def get_format_view(self):
37 def get_format_view(self):
38 return '<a href="{}">'\
38 return '<a href="{}">'\
39 '<img src="{}" width="200" height="150"/>'\
39 '<img src="{}" width="200" height="150"/>'\
40 '</a>'.format(self.file.url,static(FILE_STUB_IMAGE))
40 '</a>'.format(self.file.url, static(FILE_STUB_IMAGE))
41
41
42
42
43 class VideoViewer(AbstractViewer):
43 class VideoViewer(AbstractViewer):
44 @staticmethod
44 @staticmethod
45 def supports(file_type):
45 def supports(file_type):
46 return file_type in FILE_TYPES_VIDEO
46 return file_type in FILE_TYPES_VIDEO
47
47
48 def get_format_view(self):
48 def get_format_view(self):
49 return '<video width="200" height="150" controls src="{}"></video>'\
49 return '<video width="200" height="150" controls src="{}"></video>'\
50 .format(self.file.url)
50 .format(self.file.url)
51
51
52
52
53 class AudioViewer(AbstractViewer):
53 class AudioViewer(AbstractViewer):
54 @staticmethod
54 @staticmethod
55 def supports(file_type):
55 def supports(file_type):
56 return file_type in FILE_TYPES_AUDIO
56 return file_type in FILE_TYPES_AUDIO
57
57
58 def get_format_view(self):
58 def get_format_view(self):
59 return '<audio controls src="{}"></audio>'.format(self.file.url)
59 return '<audio controls src="{}"></audio>'.format(self.file.url)
60
60
61
61
62 class SvgViewer(AbstractViewer):
62 class SvgViewer(AbstractViewer):
63 @staticmethod
63 @staticmethod
64 def supports(file_type):
64 def supports(file_type):
65 return file_type == FILE_TYPE_SVG
65 return file_type == FILE_TYPE_SVG
66
66
67 def get_format_view(self):
67 def get_format_view(self):
68 return '<a class="thumb" href="{}">'\
68 return '<a class="thumb" href="{}">'\
69 '<img class="post-image-preview" width="200" height="150" src="{}" />'\
69 '<img class="post-image-preview" width="200" height="150" src="{}" />'\
70 '</a>'.format(self.file.url, self.file.url)
70 '</a>'.format(self.file.url, self.file.url)
@@ -1,112 +1,114 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
5
6 from django.db import models
6 from django.db import models
7 from django.template.defaultfilters import filesizeformat
7 from django.template.defaultfilters import filesizeformat
8
8
9 from boards import thumbs, utils
9 from boards import thumbs, utils
10 import boards
10 import boards
11 from boards.models.base import Viewable
11 from boards.models.base import Viewable
12
12
13 __author__ = 'neko259'
13 __author__ = 'neko259'
14
14
15
15
16 IMAGE_THUMB_SIZE = (200, 150)
16 IMAGE_THUMB_SIZE = (200, 150)
17 IMAGES_DIRECTORY = 'images/'
17 IMAGES_DIRECTORY = 'images/'
18 FILE_EXTENSION_DELIMITER = '.'
18 FILE_EXTENSION_DELIMITER = '.'
19 HASH_LENGTH = 36
19 HASH_LENGTH = 36
20
20
21 CSS_CLASS_IMAGE = 'image'
21 CSS_CLASS_IMAGE = 'image'
22 CSS_CLASS_THUMB = 'thumb'
22 CSS_CLASS_THUMB = 'thumb'
23
23
24
24
25 class PostImageManager(models.Manager):
25 class PostImageManager(models.Manager):
26 def create_with_hash(self, image):
26 def create_with_hash(self, image):
27 image_hash = utils.get_file_hash(image)
27 image_hash = utils.get_file_hash(image)
28 existing = self.filter(hash=image_hash)
28 existing = self.filter(hash=image_hash)
29 if len(existing) > 0:
29 if len(existing) > 0:
30 post_image = existing[0]
30 post_image = existing[0]
31 else:
31 else:
32 post_image = PostImage.objects.create(image=image)
32 post_image = PostImage.objects.create(image=image)
33
33
34 return post_image
34 return post_image
35
35
36 def get_random_images(self, count, include_archived=False, tags=None):
36 def get_random_images(self, count, include_archived=False, tags=None):
37 images = self.filter(post_images__thread__archived=include_archived)
37 images = self.filter(post_images__thread__archived=include_archived)
38 if tags is not None:
38 if tags is not None:
39 images = images.filter(post_images__threads__tags__in=tags)
39 images = images.filter(post_images__threads__tags__in=tags)
40 return images.order_by('?')[:count]
40 return images.order_by('?')[:count]
41
41
42
42
43 class PostImage(models.Model, Viewable):
43 class PostImage(models.Model, Viewable):
44 objects = PostImageManager()
44 objects = PostImageManager()
45
45
46 class Meta:
46 class Meta:
47 app_label = 'boards'
47 app_label = 'boards'
48 ordering = ('id',)
48 ordering = ('id',)
49
49
50 def _update_image_filename(self, filename):
50 def _update_image_filename(self, filename):
51 """
51 """
52 Gets unique image filename
52 Gets unique image filename
53 """
53 """
54
54
55 # TODO Use something other than random number in file name
55 # TODO Use something other than random number in file name
56 new_name = '{}{}.{}'.format(
56 new_name = '{}{}.{}'.format(
57 str(int(time.mktime(time.gmtime()))),
57 str(int(time.mktime(time.gmtime()))),
58 str(int(random() * 1000)),
58 str(int(random() * 1000)),
59 filename.split(FILE_EXTENSION_DELIMITER)[-1:][0])
59 filename.split(FILE_EXTENSION_DELIMITER)[-1:][0])
60
60
61 return os.path.join(IMAGES_DIRECTORY, new_name)
61 return os.path.join(IMAGES_DIRECTORY, new_name)
62
62
63 width = models.IntegerField(default=0)
63 width = models.IntegerField(default=0)
64 height = models.IntegerField(default=0)
64 height = models.IntegerField(default=0)
65
65
66 pre_width = models.IntegerField(default=0)
66 pre_width = models.IntegerField(default=0)
67 pre_height = models.IntegerField(default=0)
67 pre_height = models.IntegerField(default=0)
68
68
69 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
69 image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename,
70 blank=True, sizes=(IMAGE_THUMB_SIZE,),
70 blank=True, sizes=(IMAGE_THUMB_SIZE,),
71 width_field='width',
71 width_field='width',
72 height_field='height',
72 height_field='height',
73 preview_width_field='pre_width',
73 preview_width_field='pre_width',
74 preview_height_field='pre_height')
74 preview_height_field='pre_height')
75 hash = models.CharField(max_length=HASH_LENGTH)
75 hash = models.CharField(max_length=HASH_LENGTH)
76
76
77 def save(self, *args, **kwargs):
77 def save(self, *args, **kwargs):
78 """
78 """
79 Saves the model and computes the image hash for deduplication purposes.
79 Saves the model and computes the image hash for deduplication purposes.
80 """
80 """
81
81
82 if not self.pk and self.image:
82 if not self.pk and self.image:
83 self.hash = utils.get_file_hash(self.image)
83 self.hash = utils.get_file_hash(self.image)
84 super(PostImage, self).save(*args, **kwargs)
84 super(PostImage, self).save(*args, **kwargs)
85
85
86 def __str__(self):
86 def __str__(self):
87 return self.image.url
87 return self.image.url
88
88
89 def get_view(self):
89 def get_view(self):
90 metadata = '{}, {}'.format(self.image.name.split('.')[-1],
90 metadata = '{}, {}'.format(self.image.name.split('.')[-1],
91 filesizeformat(self.image.size))
91 filesizeformat(self.image.size))
92 return '<div class="{}">' \
92 return '<div class="{}">' \
93 '<a class="{}" href="{full}">' \
93 '<a class="{}" href="{full}">' \
94 '<img class="post-image-preview"' \
94 '<img class="post-image-preview"' \
95 ' src="{}"' \
95 ' src="{}"' \
96 ' alt="{}"' \
96 ' alt="{}"' \
97 ' width="{}"' \
97 ' width="{}"' \
98 ' height="{}"' \
98 ' height="{}"' \
99 ' data-width="{}"' \
99 ' data-width="{}"' \
100 ' data-height="{}" />' \
100 ' data-height="{}" />' \
101 '</a>' \
101 '</a>' \
102 '<div class="image-metadata">{image_meta}</div>' \
102 '<div class="image-metadata">'\
103 '<a href="{full}" download>{image_meta}</a>'\
104 '</div>' \
103 '</div>'\
105 '</div>'\
104 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB,
106 .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB,
105 self.image.url_200x150,
107 self.image.url_200x150,
106 str(self.hash), str(self.pre_width),
108 str(self.hash), str(self.pre_width),
107 str(self.pre_height), str(self.width), str(self.height),
109 str(self.pre_height), str(self.width), str(self.height),
108 full=self.image.url, image_meta=metadata)
110 full=self.image.url, image_meta=metadata)
109
111
110 def get_random_associated_post(self):
112 def get_random_associated_post(self):
111 posts = boards.models.Post.objects.filter(images__in=[self])
113 posts = boards.models.Post.objects.filter(images__in=[self])
112 return posts.order_by('?').first()
114 return posts.order_by('?').first()
General Comments 0
You need to be logged in to leave comments. Login now