##// END OF EJS Templates
Search for image for every domain level starting from the lowest one. Cache this into memcached
Search for image for every domain level starting from the lowest one. Cache this into memcached

File last commit:

r1772:1342675d default
r1772:1342675d default
Show More
viewers.py
210 lines | 5.7 KiB | text/x-python | PythonLexer
import re
from django.contrib.staticfiles import finders
from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.files.images import get_image_dimensions
from django.template.defaultfilters import filesizeformat
from boards.utils import get_domain, cached_result
FILE_STUB_IMAGE = 'images/file.png'
FILE_STUB_URL = 'url'
FILE_TYPES_VIDEO = (
'webm',
'mp4',
'mpeg',
'ogv',
)
FILE_TYPE_SVG = 'svg'
FILE_TYPES_AUDIO = (
'ogg',
'mp3',
'opus',
)
FILE_TYPES_IMAGE = (
'jpeg',
'jpg',
'png',
'bmp',
'gif',
)
PLAIN_FILE_FORMATS = {
'pdf': 'pdf',
'djvu': 'djvu',
'txt': 'txt',
'tex': 'tex',
'xcf': 'xcf',
'zip': 'archive',
'tar': 'archive',
'gz': 'archive',
}
URL_PROTOCOLS = {
'magnet': 'magnet',
}
CSS_CLASS_IMAGE = 'image'
CSS_CLASS_THUMB = 'thumb'
def get_viewers():
return AbstractViewer.__subclasses__()
def get_static_dimensions(filename):
file_path = finders.find(filename)
return get_image_dimensions(file_path)
# TODO Move this to utils
def file_exists(filename):
return finders.find(filename) is not None
class AbstractViewer:
def __init__(self, file, file_type, hash, url):
self.file = file
self.file_type = file_type
self.hash = hash
self.url = url
@staticmethod
def supports(file_type):
return True
def get_view(self):
return '<div class="image">'\
'{}'\
'<div class="image-metadata"><a href="{}" download >{}, {}</a></div>'\
'</div>'.format(self.get_format_view(), self.file.url,
self.file_type, filesizeformat(self.file.size))
def get_format_view(self):
if self.file_type in PLAIN_FILE_FORMATS:
image = 'images/fileformats/{}.png'.format(
PLAIN_FILE_FORMATS[self.file_type])
else:
image = FILE_STUB_IMAGE
w, h = get_static_dimensions(image)
return '<a href="{}">'\
'<img class="url-image" src="{}" width="{}" height="{}"/>'\
'</a>'.format(self.file.url, static(image), w, h)
class VideoViewer(AbstractViewer):
@staticmethod
def supports(file_type):
return file_type in FILE_TYPES_VIDEO
def get_format_view(self):
return '<video width="200" height="150" controls src="{}"></video>'\
.format(self.file.url)
class AudioViewer(AbstractViewer):
@staticmethod
def supports(file_type):
return file_type in FILE_TYPES_AUDIO
def get_format_view(self):
return '<audio controls src="{}"></audio>'.format(self.file.url)
class SvgViewer(AbstractViewer):
@staticmethod
def supports(file_type):
return file_type == FILE_TYPE_SVG
def get_format_view(self):
return '<a class="thumb" href="{}">'\
'<img class="post-image-preview" width="200" height="150" src="{}" />'\
'</a>'.format(self.file.url, self.file.url)
class ImageViewer(AbstractViewer):
@staticmethod
def supports(file_type):
return file_type in FILE_TYPES_IMAGE
def get_format_view(self):
metadata = '{}, {}'.format(self.file.name.split('.')[-1],
filesizeformat(self.file.size))
width, height = get_image_dimensions(self.file.file)
preview_path = self.file.path.replace('.', '.200x150.')
pre_width, pre_height = get_image_dimensions(preview_path)
split = self.file.url.rsplit('.', 1)
w, h = 200, 150
thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1])
return '<a class="{}" href="{full}">' \
'<img class="post-image-preview"' \
' src="{}"' \
' alt="{}"' \
' width="{}"' \
' height="{}"' \
' data-width="{}"' \
' data-height="{}" />' \
'</a>' \
.format(CSS_CLASS_THUMB,
thumb_url,
self.hash,
str(pre_width),
str(pre_height), str(width), str(height),
full=self.file.url, image_meta=metadata)
class UrlViewer(AbstractViewer):
@staticmethod
def supports(file_type):
return file_type is None
def get_view(self):
return '<div class="image">' \
'{}' \
'<div class="image-metadata">{}</div>' \
'</div>'.format(self.get_format_view(), get_domain(self.url))
def get_format_view(self):
protocol = self.url.split('://')[0]
domain = get_domain(self.url)
if protocol in URL_PROTOCOLS:
url_image_name = URL_PROTOCOLS.get(protocol)
elif domain:
url_image_name = self._find_image_for_domains(domain) or FILE_STUB_URL
else:
url_image_name = FILE_STUB_URL
image_path = 'images/{}.png'.format(url_image_name)
image = static(image_path)
w, h = get_static_dimensions(image_path)
return '<a href="{}">' \
'<img class="url-image" src="{}" width="{}" height="{}"/>' \
'</a>'.format(self.url, image, w, h)
@cached_result()
def _find_image_for_domains(self, domain):
"""
Searches for the domain image for every domain level except top.
E.g. for l3.example.co.uk it will search for l3.example.co.uk, then
example.co.uk, then co.uk
"""
levels = domain.split('.')
while len(levels) > 1:
domain = '.'.join(levels)
filename = 'images/domains/{}.png'.format(domain)
if file_exists(filename):
return 'domains/' + domain
else:
del levels[0]