##// END OF EJS Templates
Removed redundant viewers code
neko259 -
r2040:5608c1c3 default
parent child Browse files
Show More
@@ -1,249 +1,243 b''
1 from django.contrib.staticfiles import finders
1 from django.contrib.staticfiles import finders
2 from django.contrib.staticfiles.templatetags.staticfiles import static
2 from django.contrib.staticfiles.templatetags.staticfiles import static
3 from django.core.files.images import get_image_dimensions
3 from django.core.files.images import get_image_dimensions
4 from django.template.defaultfilters import filesizeformat
4 from django.template.defaultfilters import filesizeformat
5
5
6 from boards import settings
6 from boards import settings
7 from boards.abstracts.constants import THUMB_SIZES
7 from boards.abstracts.constants import THUMB_SIZES
8 from boards.settings import SECTION_EXTERNAL
8 from boards.settings import SECTION_EXTERNAL
9 from boards.utils import get_domain, cached_result, get_extension
9 from boards.utils import get_domain, cached_result, get_extension
10
10
11 URL_IMAGE_PATH = 'images/{}.png'
12
11 PROTOCOL_DELIMITER = ':'
13 PROTOCOL_DELIMITER = ':'
12 DOMAIN_DELIMITER = '.'
14 DOMAIN_DELIMITER = '.'
13
15
14 FILE_STUB_IMAGE = 'images/file.png'
16 FILE_STUB_IMAGE = 'images/file.png'
15 FILE_STUB_URL = 'url'
17 FILE_STUB_URL = 'url'
16 FILE_FILEFORMAT = 'images/fileformats/{}.png'
18 FILE_FILEFORMAT = 'images/fileformats/{}.png'
17
19
18
20
19 FILE_TYPES_VIDEO = (
21 FILE_TYPES_VIDEO = (
20 'video/webm',
22 'video/webm',
21 'video/mp4',
23 'video/mp4',
22 'video/mpeg',
24 'video/mpeg',
23 'video/ogv',
25 'video/ogv',
24 )
26 )
25 FILE_TYPE_SVG = 'image/svg+xml'
27 FILE_TYPE_SVG = 'image/svg+xml'
26 FILE_TYPES_AUDIO = (
28 FILE_TYPES_AUDIO = (
27 'audio/ogg',
29 'audio/ogg',
28 'audio/mpeg',
30 'audio/mpeg',
29 'audio/opus',
31 'audio/opus',
30 'audio/x-flac',
32 'audio/x-flac',
31 'audio/mpeg',
33 'audio/mpeg',
32 )
34 )
33 FILE_TYPES_IMAGE = (
35 FILE_TYPES_IMAGE = (
34 'image/jpeg',
36 'image/jpeg',
35 'image/jpg',
37 'image/jpg',
36 'image/png',
38 'image/png',
37 'image/bmp',
39 'image/bmp',
38 'image/gif',
40 'image/gif',
39 )
41 )
40
42
41 PLAIN_FILE_FORMATS = {
43 PLAIN_FILE_FORMATS = {
42 'zip': 'archive',
44 'zip': 'archive',
43 'tar': 'archive',
45 'tar': 'archive',
44 'gz': 'archive',
46 'gz': 'archive',
45 'mid' : 'midi',
47 'mid' : 'midi',
46 }
48 }
47
49
48 URL_PROTOCOLS = {
50 URL_PROTOCOLS = {
49 'magnet': 'magnet',
51 'magnet': 'magnet',
50 }
52 }
51
53
52 CSS_CLASS_IMAGE = 'image'
54 CSS_CLASS_IMAGE = 'image'
53 CSS_CLASS_THUMB = 'thumb'
54
55
55 ABSTRACT_VIEW = '<div class="image">'\
56 ABSTRACT_VIEW = '<div class="image">'\
56 '{}'\
57 '{}'\
57 '<div class="image-metadata"><a href="{}" download >{}, {}</a>'\
58 '<div class="image-metadata"><a href="{}" download >{}, {}</a>'\
58 ' <a class="file-menu" href="#" data-type="{}" data-search-url="{}" data-filename="{}" data-id="{}">&#8942; </a></div>'\
59 ' <a class="file-menu" href="#" data-type="{}" data-search-url="{}" data-filename="{}" data-id="{}">&#8942; </a></div>'\
59 '</div>'
60 '</div>'
60 URL_VIEW = '<div class="image">' \
61 URL_VIEW = '<div class="image">' \
61 '{}' \
62 '{}' \
62 '<div class="image-metadata">{}</div>' \
63 '<div class="image-metadata">{}</div>' \
63 '</div>'
64 '</div>'
64 ABSTRACT_FORMAT_VIEW = '<a href="{}">'\
65 ABSTRACT_FORMAT_VIEW = '<a href="{}">'\
65 '<img class="url-image" src="{}" width="{}" height="{}"/>'\
66 '<img class="url-image" src="{}" width="{}" height="{}"/>'\
66 '</a>'
67 '</a>'
67 VIDEO_FORMAT_VIEW = '<video width="200" height="150" controls src="{}"></video>'
68 VIDEO_FORMAT_VIEW = '<video width="200" height="150" controls src="{}"></video>'
68 AUDIO_FORMAT_VIEW = '<audio controls src="{}"></audio>'
69 AUDIO_FORMAT_VIEW = '<audio controls src="{}"></audio>'
69 IMAGE_FORMAT_VIEW = '<a class="{}" href="{full}">' \
70 IMAGE_FORMAT_VIEW = '<a class="thumb" href="{full}">' \
70 '<img class="post-image-preview"' \
71 '<img class="post-image-preview"' \
71 ' src="{}"' \
72 ' src="{}"' \
72 ' alt="{}"' \
73 ' alt="{}"' \
73 ' width="{}"' \
74 ' width="{}"' \
74 ' height="{}"' \
75 ' height="{}"' \
75 ' data-width="{}"' \
76 ' data-width="{}"' \
76 ' data-height="{}" />' \
77 ' data-height="{}" />' \
77 '</a>'
78 '</a>'
78 SVG_FORMAT_VIEW = '<a class="thumb" href="{}">'\
79 SVG_FORMAT_VIEW = '<a class="thumb" href="{}">'\
79 '<img class="post-image-preview" width="200" height="150" src="{}" />'\
80 '<img class="post-image-preview" width="200" height="150" src="{}" />'\
80 '</a>'
81 '</a>'
81 URL_FORMAT_VIEW = '<a href="{}">' \
82 URL_FORMAT_VIEW = '<a href="{}">' \
82 '<img class="url-image" src="{}" width="{}" height="{}"/>' \
83 '<img class="url-image" src="{}" width="{}" height="{}"/>' \
83 '</a>'
84 '</a>'
84
85
85
86
86 def get_viewers():
87 def get_viewers():
87 return AbstractViewer.__subclasses__()
88 return AbstractViewer.__subclasses__()
88
89
89
90
90
91
92 class AbstractViewer:
91 class AbstractViewer:
93 def __init__(self, file, file_type, id, url):
92 def __init__(self, file, file_type, id, url):
94 self.file = file
93 self.file = file
95 self.file_type = file_type
94 self.file_type = file_type
96 self.id = id
95 self.id = id
97 self.url = url
96 self.url = url
98 self.extension = get_extension(self.file.name).lower()
97 self.extension = get_extension(self.file.name).lower()
99
98
100 @staticmethod
99 @staticmethod
101 def supports(file_type):
100 def supports(file_type):
102 return True
101 return True
103
102
104 def get_view(self):
103 def get_view(self):
105 return ABSTRACT_VIEW.format(self.get_format_view(), self.file.url,
104 return ABSTRACT_VIEW.format(self.get_format_view(), self.file.url,
106 self.file_type, filesizeformat(self.file.size),
105 self.file_type, filesizeformat(self.file.size),
107 self.file_type, self._get_search_url(), self.file.name, self.id)
106 self.file_type, self._get_search_url(), self.file.name, self.id)
108
107
109 def _get_search_url(self):
108 def _get_search_url(self):
110 search_host = settings.get(SECTION_EXTERNAL, 'ImageSearchHost')
109 search_host = settings.get(SECTION_EXTERNAL, 'ImageSearchHost')
111 if search_host:
110 if search_host:
112 if search_host.endswith('/'):
111 if search_host.endswith('/'):
113 search_host = search_host[:-1]
112 search_host = search_host[:-1]
114 search_url = search_host + self.file.url
113 search_url = search_host + self.file.url
115 else:
114 else:
116 search_url = ''
115 search_url = ''
117 return search_url
116 return search_url
118
117
119 def get_format_view(self):
118 def get_format_view(self):
120 image_name = PLAIN_FILE_FORMATS.get(self.extension, self.extension)
119 image_name = PLAIN_FILE_FORMATS.get(self.extension, self.extension)
121 file_name = FILE_FILEFORMAT.format(image_name)
120 file_name = FILE_FILEFORMAT.format(image_name)
122
121
123 if self.file_exists(file_name):
122 if self.file_exists(file_name):
124 image = file_name
123 image = file_name
125 else:
124 else:
126 image = FILE_STUB_IMAGE
125 image = FILE_STUB_IMAGE
127
126
128 w, h = self.get_static_dimensions(image)
127 w, h = self.get_static_dimensions(image)
129
128
130 return ABSTRACT_FORMAT_VIEW.format(self.file.url, static(image), w, h)
129 return ABSTRACT_FORMAT_VIEW.format(self.file.url, static(image), w, h)
131
130
132 @cached_result()
131 @cached_result()
133 def get_static_dimensions(self, filename):
132 def get_static_dimensions(self, filename):
134 file_path = finders.find(filename)
133 file_path = finders.find(filename)
135 return get_image_dimensions(file_path)
134 return get_image_dimensions(file_path)
136
135
137
138 @cached_result()
136 @cached_result()
139 def file_exists(self, filename):
137 def file_exists(self, filename):
140 return finders.find(filename) is not None
138 return finders.find(filename) is not None
141
139
142
140
143 class VideoViewer(AbstractViewer):
141 class VideoViewer(AbstractViewer):
144 @staticmethod
142 @staticmethod
145 def supports(file_type):
143 def supports(file_type):
146 return file_type in FILE_TYPES_VIDEO
144 return file_type in FILE_TYPES_VIDEO
147
145
148 def get_format_view(self):
146 def get_format_view(self):
149 return VIDEO_FORMAT_VIEW.format(self.file.url)
147 return VIDEO_FORMAT_VIEW.format(self.file.url)
150
148
151
149
152 class AudioViewer(AbstractViewer):
150 class AudioViewer(AbstractViewer):
153 @staticmethod
151 @staticmethod
154 def supports(file_type):
152 def supports(file_type):
155 return file_type in FILE_TYPES_AUDIO
153 return file_type in FILE_TYPES_AUDIO
156
154
157 def get_format_view(self):
155 def get_format_view(self):
158 return AUDIO_FORMAT_VIEW.format(self.file.url)
156 return AUDIO_FORMAT_VIEW.format(self.file.url)
159
157
160
158
161 class SvgViewer(AbstractViewer):
159 class SvgViewer(AbstractViewer):
162 @staticmethod
160 @staticmethod
163 def supports(file_type):
161 def supports(file_type):
164 return file_type == FILE_TYPE_SVG
162 return file_type == FILE_TYPE_SVG
165
163
166 def get_format_view(self):
164 def get_format_view(self):
167 return SVG_FORMAT_VIEW.format(self.file.url, self.file.url)
165 return SVG_FORMAT_VIEW.format(self.file.url, self.file.url)
168
166
169
167
170 class ImageViewer(AbstractViewer):
168 class ImageViewer(AbstractViewer):
171 @staticmethod
169 @staticmethod
172 def supports(file_type):
170 def supports(file_type):
173 return file_type in FILE_TYPES_IMAGE
171 return file_type in FILE_TYPES_IMAGE
174
172
175 def get_format_view(self):
173 def get_format_view(self):
176 metadata = '{}, {}'.format(self.file.name.split('.')[-1],
177 filesizeformat(self.file.size))
178
179 try:
174 try:
180 width, height = get_image_dimensions(self.file.path)
175 width, height = get_image_dimensions(self.file.path)
181 except Exception:
176 except Exception:
182 # If the image is a decompression bomb, treat it as just a regular
177 # If the image is a decompression bomb, treat it as just a regular
183 # file
178 # file
184 return super().get_format_view()
179 return super().get_format_view()
185
180
186 preview_path = self.file.path.replace('.', '.200x150.')
181 preview_path = self.file.path.replace('.', '.200x150.')
187 try:
182 try:
188 pre_width, pre_height = get_image_dimensions(preview_path)
183 pre_width, pre_height = get_image_dimensions(preview_path)
189 except Exception:
184 except Exception:
190 return super().get_format_view()
185 return super().get_format_view()
191
186
192 split = self.file.url.rsplit('.', 1)
187 split = self.file.url.rsplit('.', 1)
193 w, h = THUMB_SIZES[0]
188 w, h = THUMB_SIZES[0]
194 thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1])
189 thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1])
195
190
196 return IMAGE_FORMAT_VIEW.format(CSS_CLASS_THUMB,
191 return IMAGE_FORMAT_VIEW.format(
197 thumb_url,
192 thumb_url,
198 self.id,
193 self.id,
199 str(pre_width),
194 pre_width, pre_height, width, height,
200 str(pre_height), str(width), str(height),
195 full=self.file.url)
201 full=self.file.url, image_meta=metadata)
202
196
203
197
204 class UrlViewer(AbstractViewer):
198 class UrlViewer(AbstractViewer):
205 @staticmethod
199 @staticmethod
206 def supports(file_type):
200 def supports(file_type):
207 return file_type is None
201 return file_type is None
208
202
209 def get_view(self):
203 def get_view(self):
210 return URL_VIEW.format(self.get_format_view(), get_domain(self.url))
204 return URL_VIEW.format(self.get_format_view(), get_domain(self.url))
211
205
212 def get_format_view(self):
206 def get_format_view(self):
213 protocol = self.url.split(PROTOCOL_DELIMITER)[0]
207 protocol = self.url.split(PROTOCOL_DELIMITER)[0]
214
208
215 domain = get_domain(self.url)
209 domain = get_domain(self.url)
216
210
217 image_path = 'images/{}.png'.format(self._get_image_name(protocol, domain))
211 image_path = URL_IMAGE_PATH.format(self._get_image_name(protocol, domain))
218 image = static(image_path)
212 image = static(image_path)
219 w, h = self.get_static_dimensions(image_path)
213 w, h = self.get_static_dimensions(image_path)
220
214
221 return URL_FORMAT_VIEW.format(self.url, image, w, h)
215 return URL_FORMAT_VIEW.format(self.url, image, w, h)
222
216
223 def _find_image_for_domains(self, domain):
217 def _find_image_for_domains(self, domain):
224 """
218 """
225 Searches for the domain image for every domain level except top.
219 Searches for the domain image for every domain level except top.
226 E.g. for l3.example.co.uk it will search for l3.example.co.uk, then
220 E.g. for l3.example.co.uk it will search for l3.example.co.uk, then
227 example.co.uk, then co.uk
221 example.co.uk, then co.uk
228 """
222 """
229 levels = domain.split(DOMAIN_DELIMITER)
223 levels = domain.split(DOMAIN_DELIMITER)
230 while len(levels) > 1:
224 while len(levels) > 1:
231 domain = DOMAIN_DELIMITER.join(levels)
225 domain = DOMAIN_DELIMITER.join(levels)
232
226
233 filename = 'images/domains/{}.png'.format(domain)
227 filename = 'images/domains/{}.png'.format(domain)
234 if self.file_exists(filename):
228 if self.file_exists(filename):
235 return 'domains/' + domain
229 return 'domains/' + domain
236 else:
230 else:
237 del levels[0]
231 del levels[0]
238
232
239 @cached_result()
233 @cached_result()
240 def _get_image_name(self, protocol, domain):
234 def _get_image_name(self, protocol, domain):
241 if protocol in URL_PROTOCOLS:
235 if protocol in URL_PROTOCOLS:
242 url_image_name = URL_PROTOCOLS.get(protocol)
236 url_image_name = URL_PROTOCOLS.get(protocol)
243 elif domain:
237 elif domain:
244 url_image_name = self._find_image_for_domains(domain) or FILE_STUB_URL
238 url_image_name = self._find_image_for_domains(domain) or FILE_STUB_URL
245 else:
239 else:
246 url_image_name = FILE_STUB_URL
240 url_image_name = FILE_STUB_URL
247
241
248 return url_image_name
242 return url_image_name
249
243
General Comments 0
You need to be logged in to leave comments. Login now