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