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