from django import template
from django.utils.http import urlquote
from telemeta import models
from django.core.urlresolvers import reverse
import telemeta.models.dublincore as dc
from django.utils import html
from django import template
from django.utils.text import capfirst
from django.utils.translation import ungettext
from docutils.core import publish_parts
from django.utils.encoding import smart_str, force_unicode
from django.utils.safestring import mark_safe
from django import db
import re
import os
import ast
import datetime
from django.conf import settings
from django.template.defaultfilters import stringfilter
from django.template import NodeList
from telemeta.views.core import get_item_access
register = template.Library()
@register.filter
def tolist(dict):
"Converts a simple dict into a list"
list = []
for k, v in dict.iteritems():
list.append({'name': k, 'value': v})
return list
@register.filter
def mul(value, arg):
"Multiply a numeric value"
return value * arg
class TelemetaVersionNode(template.Node):
def render(self, context):
from telemeta import __version__
return __version__
@register.tag
def telemeta_version(parser, token):
"Get Telemeta version number"
return TelemetaVersionNode()
class TelemetaUrlNode(template.Node):
def render(self, context):
from telemeta import __url__
return __url__
@register.tag
def telemeta_url(parser, token):
"Get Telemeta project homepage URL"
return TelemetaUrlNode()
_js_escapes = (
('\\', '\\\\'),
('"', '\\"'),
("'", "\\'"),
('\n', '\\n'),
('\r', '\\r'),
('\b', '\\b'),
('\f', '\\f'),
('\t', '\\t'),
('\v', '\\v'),
('</', '<\\/'),
)
@register.filter
def escapejs(value):
"""Backslash-escapes characters for use in JavaScript strings."""
for bad, good in _js_escapes:
value = value.replace(bad, good)
return value
@register.filter
def build_pattern_dict(query):
return ast.literal_eval(query.rstrip())
@register.filter
def build_query_string(vars):
"""Build an HTTP query string out of a dict"""
if type(vars) == dict:
import urllib
args = []
for k, v in vars.iteritems():
if isinstance(v, db.models.Model):
v = v.pk
elif not isinstance(v, basestring):
v = unicode(v)
args.append(urlquote(k) + '=' + urlquote(v))
return "&".join(args)
return ''
@register.filter
def with_no_sound(vars):
_vars = vars.copy()
if type(_vars) == dict:
if u'sound' in _vars:
del _vars[u'sound']
return _vars
@register.filter
def with_sound(vars):
_vars = vars.copy()
if type(_vars) == dict:
if not 'sound' in _vars:
_vars['sound'] = True
return _vars
@register.filter
def code_or_id(resource):
if resource.code:
return resource.code
else:
return resource.id
@register.filter
def is_item(resource):
return isinstance(resource, models.MediaItem)
@register.filter
def is_collection(resource):
return isinstance(resource, models.MediaCollection)
@register.filter
def is_corpus(resource):
return isinstance(resource, models.MediaCorpus)
@register.filter
def is_fonds(resource):
return isinstance(resource, models.MediaFonds)
@register.filter
def is_resource(resource):
return is_fonds(resource) or is_corpus(resource)
@register.filter
def to_dublincore(resource):
if isinstance(resource, models.MediaItem):
return dc.express_item(resource)
elif isinstance(resource, models.MediaCollection):
return dc.express_collection(resource)
else:
return dc.express_generic_resource(resource)
class DescriptionListFieldNode(template.Node):
def __init__(self, model, attr, join_with = None, show_empty = False):
self.model = model
self.member = attr
self.join_with = join_with
self.show_empty = show_empty
def render(self, context):
try:
model = self.model.resolve(context)
if isinstance(self.member, template.Variable):
member = self.member.resolve(context)
else:
member = self.member
label = html.escape(capfirst(unicode(model.field_label(member))))
try:
value = getattr(model, member)
except AttributeError:
value = '<ERROR: no such field>'
except template.VariableDoesNotExist:
label = unicode(self.model) + '.' + self.member
value = '<ERROR: can\'t find variable>'
try:
value = value()
except TypeError:
pass
if self.join_with:
value = self.join_with.join([unicode(v) for v in value])
if not value:
value = ''
if value or self.show_empty:
value = html.escape(unicode(value))
markup = '<dt>%s</dt><dd>%s</dd>' % (label, value)
return markup
return ''
@register.tag
def dl_field(parser, token):
cut = token.split_contents()
join_with = None
show_empty = False
if len(cut) == 3:
tag_name, model, attr = cut
elif len(cut) == 4:
tag_name, model, attr, arg3 = cut
if arg3 == 'placeholder':
show_empty = True
else:
raise ValueError()
elif len(cut) >= 6:
tag_name, model, attr, arg3, arg4, arg5 = cut[0:6]
if arg3 == 'join' and arg4 == 'with'and arg5[0] == arg5[-1] and arg5[0] in ('"', "'"):
join_with = arg5[1:-1]
else:
raise ValueError()
if len(cut) > 6:
if cut[6] == 'placeholder':
show_empty = True
else:
raise ValueError();
else:
raise template.TemplateSyntaxError("%r tag: invalid arguments"
% token.contents.split()[0])
if attr[0] == attr[-1] and attr[0] in ('"', "'"):
attr = attr[1:-1]
else:
attr = template.Variable(attr)
model = template.Variable(model)
return DescriptionListFieldNode(model, attr, join_with=join_with, show_empty=show_empty)
@register.filter
def prepend(str, prefix):
if str:
return prefix + unicode(str)
return ''
@register.simple_tag
def field_label(model, field=None):
if isinstance(model, basestring):
model = getattr(models, model)
if not field:
return capfirst(unicode(model._meta.verbose_name))
return capfirst(unicode(model.field_label(field)))
@register.simple_tag
def field_value(object, member):
value = getattr(object, member)
try:
value = value()
except TypeError:
pass
return value
@register.filter
def is_none(value):
return value is None
@register.filter
def resources_num(value):
model = value.model
count = value.count()
label = str(count)
if model == models.MediaItem:
label = ungettext('%(count)d item', '%(count)d items', count) % {
'count': count, }
elif model == models.MediaCollection:
label = ungettext('%(count)d collection', '%(count)d collections', count) % {
'count': count, }
return label
@register.filter
def split(value, sep=','):
return value.split(sep)
@register.simple_tag
def variable_link(object, url_name, url_key):
return reverse(url_name, args=[field_value(object, url_key)])
@register.filter
def equals(value1, value2):
return value1 == value2
@register.filter
def render_flatpage(content):
parsed = ""
path = getattr(content, 'path', '')
if isinstance(content, basestring):
content = content.split("\n")
for line in content:
match = re.match('^(\.\. *(?:_[^:]*:|(?:\|\w+\|)? *image::) *)([^ ]+) *$', line)
if match:
directive, urlname = match.groups()
line = directive
try:
i = urlname.index('telemeta-')
except ValueError:
i = -1
if i == 0:
line += reverse(urlname)
elif urlname[:1] != '/' and urlname[:4] != 'http':
line += reverse('telemeta-flatpage', args=[path + '/../' + urlname])
else:
line += urlname
parsed += line + "\n"
parts = publish_parts(source=smart_str(parsed), writer_name="html4css1", settings_overrides={})
return mark_safe('<div class="rst-content">\n' + force_unicode(parts["html_body"]) + '</div>')
render_flatpage.is_safe = True
@register.simple_tag
def organization():
return settings.TELEMETA_ORGANIZATION
@register.simple_tag
def description():
try:
description = settings.TELEMETA_OAI_REPOSITORY_NAME
except:
description = settings.TELEMETA_DESCRIPTION
pass
return description
class SetVarNode(template.Node):
def __init__(self, var_name, var_value):
self.var_name = var_name
self.var_value = var_value
def render(self, context):
try:
value = template.Variable(self.var_value).resolve(context)
except template.VariableDoesNotExist:
value = ""
context[self.var_name] = value
return u""
@register.tag
def set_var(parser, token):
"""
{% set <var_name> = <var_value> %}
"""
parts = token.split_contents()
if len(parts) < 4:
raise template.TemplateSyntaxError("'set' tag must be of the form: {% set <var_name> = <var_value> %}")
return SetVarNode(parts[1], parts[3])
@register.simple_tag
def current_year():
return datetime.datetime.now().strftime("%Y")
@register.filter
def html_line_break(text):
return text.replace('\n', '<br />')
@register.simple_tag
def profile(user):
return user.get_profile()
@register.filter
def to_string(list):
if len(list) != 0:
return list[0].encode('utf-8')
else:
return ''
@register.filter
def get_filename(object):
if isinstance(object, unicode):
return object.split('/')[-1]
elif hasattr(object, 'path'):
return object.path.split(os.sep)[-1]
else:
return ''
@register.filter
def get_youtube(link):
link = link.split('&')
if "=" in link[0]:
ref = link[0].split('=')[1]
else:
ref = link[0].split('/')[-1]
return 'http://www.youtube.com/embed/'+ref
@register.filter
def to_utf8(word):
return word.encode('utf-8')
@register.filter
@stringfilter
def capitalize(value):
return value.capitalize()
@register.filter
@stringfilter
def mime_to_ext(mime_type):
return mime_type.split('/')[1]
@register.filter
@stringfilter
def mime_to_media_type(mime_type):
if 'video' in mime_type:
return 'Video'
else:
return 'Audio'
@register.simple_tag
def is_installed(app):
return app in settings.INSTALLED_APPS
def do_ifloaded(parser, token):
bits = token.split_contents()[1:]
var = bits[0]
nodelist_true = parser.parse(('else', 'endifloaded'))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse(('endifloaded',))
parser.delete_first_token()
else:
nodelist_false = NodeList()
return IfLoadedNode(var, nodelist_true, nodelist_false)
register.tag('ifloaded', do_ifloaded)
class IfLoadedNode(template.Node):
def __init__(self, var, nodelist_true, nodelist_false=None):
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
self.var = var
def __repr__(self):
return '<IfLoaded node>'
def __iter__(self):
for node in self.nodelist_true:
yield node
for node in self.nodelist_false:
yield node
def get_nodes_by_type(self, nodetype):
nodes = []
if isinstance(self, nodetype):
nodes.append(self)
nodes.extend(self.nodelist_true.get_nodes_by_type(nodetype))
nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype))
return nodes
def render(self, context):
for app in settings.INSTALLED_APPS:
if str(app) == str(self.var):
return self.nodelist_true.render(context)
return self.nodelist_false.render(context)
@register.filter
def has_access(user, item):
return get_item_access(item, user)
@register.filter
def get_attr(obj, val):
return getattr(obj, val)
@register.simple_tag
def logo_url():
static_url = getattr(settings, 'STATIC_URL', '/static/')
return getattr(settings, 'TELEMETA_LOGO', static_url + '/telemeta/images/logo_telemeta_2.png')
@register.assignment_tag
def get_googletools():
return 'googletools' in settings.INSTALLED_APPS
@register.assignment_tag
def settings_value(name):
return getattr(settings, name, "")