4 from time import gmtime
5 from django.template import Library, Node, Variable, VariableDoesNotExist, TemplateSyntaxError
6 from django.conf import settings
7 from django.utils.encoding import force_unicode
10 from filebrowser.fb_settings import MEDIA_ROOT, MEDIA_URL, VERSIONS
11 from filebrowser.functions import _url_to_path, _path_to_url, _get_version_path, _version_generator
12 from filebrowser.base import FileObject
16 class VersionNode(Node):
17 def __init__(self, src, version_prefix):
18 self.src = Variable(src)
19 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
20 self.version_prefix = version_prefix[1:-1]
22 self.version_prefix = None
23 self.version_prefix_var = Variable(version_prefix)
25 def render(self, context):
27 source = self.src.resolve(context)
28 except VariableDoesNotExist:
30 if self.version_prefix:
31 version_prefix = self.version_prefix
34 version_prefix = self.version_prefix_var.resolve(context)
35 except VariableDoesNotExist:
38 version_path = _get_version_path(_url_to_path(str(source)), version_prefix)
39 if not os.path.isfile(os.path.join(MEDIA_ROOT, version_path)):
41 version_path = _version_generator(_url_to_path(str(source)), version_prefix)
42 elif os.path.getmtime(os.path.join(MEDIA_ROOT, _url_to_path(str(source)))) > os.path.getmtime(os.path.join(MEDIA_ROOT, version_path)):
43 # recreate version if original image was updated
44 version_path = _version_generator(_url_to_path(str(source)), version_prefix, force=True)
45 return _path_to_url(version_path)
50 def version(parser, token):
52 Displaying a version of an existing Image according to the predefined VERSIONS settings (see fb_settings).
53 {% version field_name version_prefix %}
55 Use {% version my_image 'medium' %} in order to display the medium-size
56 version of an Image stored in a field name my_image.
58 version_prefix can be a string or a variable. if version_prefix is a string, use quotes.
62 tag, src, version_prefix = token.split_contents()
64 raise TemplateSyntaxError, "%s tag requires 2 arguments" % token.contents.split()[0]
65 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
66 raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
67 return VersionNode(src, version_prefix)
70 class VersionObjectNode(Node):
71 def __init__(self, src, version_prefix, var_name):
72 self.var_name = var_name
73 self.src = Variable(src)
74 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
75 self.version_prefix = version_prefix[1:-1]
77 self.version_prefix = None
78 self.version_prefix_var = Variable(version_prefix)
80 def render(self, context):
82 source = self.src.resolve(context)
83 except VariableDoesNotExist:
85 if self.version_prefix:
86 version_prefix = self.version_prefix
89 version_prefix = self.version_prefix_var.resolve(context)
90 except VariableDoesNotExist:
93 version_path = _get_version_path(_url_to_path(str(source)), version_prefix)
94 if not os.path.isfile(os.path.join(MEDIA_ROOT, version_path)):
96 version_path = _version_generator(_url_to_path(str(source)), version_prefix)
97 elif os.path.getmtime(os.path.join(MEDIA_ROOT, _url_to_path(str(source)))) > os.path.getmtime(os.path.join(MEDIA_ROOT, version_path)):
98 # recreate version if original image was updated
99 version_path = _version_generator(_url_to_path(str(source)), version_prefix, force=True)
100 context[self.var_name] = FileObject(version_path)
102 context[self.var_name] = ""
106 def version_object(parser, token):
108 Returns a context variable 'version_object'.
109 {% version_object field_name version_prefix %}
111 Use {% version_object my_image 'medium' %} in order to retrieve the medium
112 version of an Image stored in a field name my_image.
113 Use {% version_object my_image 'medium' as var %} in order to use 'var' as
114 your context variable.
116 version_prefix can be a string or a variable. if version_prefix is a string, use quotes.
120 #tag, src, version_prefix = token.split_contents()
121 tag, arg = token.contents.split(None, 1)
123 raise TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
124 m = re.search(r'(.*?) (.*?) as (\w+)', arg)
126 raise TemplateSyntaxError, "%r tag had invalid arguments" % tag
127 src, version_prefix, var_name = m.groups()
128 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
129 raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
130 return VersionObjectNode(src, version_prefix, var_name)
133 class VersionSettingNode(Node):
134 def __init__(self, version_prefix):
135 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
136 self.version_prefix = version_prefix[1:-1]
138 self.version_prefix = None
139 self.version_prefix_var = Variable(version_prefix)
141 def render(self, context):
142 if self.version_prefix:
143 version_prefix = self.version_prefix
146 version_prefix = self.version_prefix_var.resolve(context)
147 except VariableDoesNotExist:
149 context['version_setting'] = VERSIONS[version_prefix]
153 def version_setting(parser, token):
155 Get Information about a version setting.
159 tag, version_prefix = token.split_contents()
161 raise TemplateSyntaxError, "%s tag requires 1 argument" % token.contents.split()[0]
162 if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
163 raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
164 return VersionSettingNode(version_prefix)
167 register.tag(version)
168 register.tag(version_object)
169 register.tag(version_setting)