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