cdb0519419ba9d5795cdebf7c92261a7f43d8e41
[redakcja.git] / apps / filebrowser / templatetags / fb_versions.py
1 # coding: utf-8
2
3 import os, re
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
8 import urllib
9
10 # filebrowser imports
11 from filebrowser.fb_settings import MEDIA_ROOT, MEDIA_URL, VERSIONS
12 from filebrowser.functions import _url_to_path, _path_to_url, _get_version_path, _version_generator
13 from filebrowser.base import FileObject
14
15 register = Library()
16
17 class VersionNode(Node):
18     def __init__(self, src, version_prefix):
19         self.src = Variable(src)
20         if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
21             self.version_prefix = version_prefix[1:-1]
22         else:
23             self.version_prefix = None
24             self.version_prefix_var = Variable(version_prefix)
25
26     def render(self, context):
27         try:
28             source = self.src.resolve(context)
29         except VariableDoesNotExist:
30             return None
31
32         if self.version_prefix:
33             version_prefix = self.version_prefix
34         else:
35             try:
36                 version_prefix = self.version_prefix_var.resolve(context)
37             except VariableDoesNotExist:
38                 return None
39
40         try:
41             version_path = _get_version_path(_url_to_path(str(source)), version_prefix)
42             if not os.path.isfile(os.path.join(MEDIA_ROOT, version_path)):
43                 # create version
44                 version_path = _version_generator(_url_to_path(str(source)), version_prefix)
45             elif os.path.getmtime(os.path.join(MEDIA_ROOT, _url_to_path(str(source)))) > os.path.getmtime(os.path.join(MEDIA_ROOT, version_path)):
46                 # recreate version if original image was updated
47                 version_path = _version_generator(_url_to_path(str(source)), version_prefix, force = True)
48             return _path_to_url(version_path)
49         except Exception, e:
50             import traceback, sys
51             print "FB VERSION ERROR"
52             traceback.print_exc(file = sys.stdout)
53             return u""
54
55
56
57 def version(parser, token):
58     """
59     Displaying a version of an existing Image according to the predefined VERSIONS settings (see fb_settings).
60     {% version field_name version_prefix %}
61     
62     Use {% version my_image 'medium' %} in order to display the medium-size
63     version of an Image stored in a field name my_image.
64     
65     version_prefix can be a string or a variable. if version_prefix is a string, use quotes.
66     """
67
68     try:
69         tag, src, version_prefix = token.split_contents()
70     except:
71         raise TemplateSyntaxError, "%s tag requires 2 arguments" % token.contents.split()[0]
72     if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
73         raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
74     return VersionNode(src, version_prefix)
75
76
77 class VersionObjectNode(Node):
78     def __init__(self, src, version_prefix, var_name):
79         self.var_name = var_name
80         self.src = Variable(src)
81         if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
82             self.version_prefix = version_prefix[1:-1]
83         else:
84             self.version_prefix = None
85             self.version_prefix_var = Variable(version_prefix)
86
87     def render(self, context):
88         try:
89             source = self.src.resolve(context)
90         except VariableDoesNotExist:
91             return None
92         if self.version_prefix:
93             version_prefix = self.version_prefix
94         else:
95             try:
96                 version_prefix = self.version_prefix_var.resolve(context)
97             except VariableDoesNotExist:
98                 return None
99         try:
100             version_path = _get_version_path(_url_to_path(str(source)), version_prefix)
101             if not os.path.isfile(os.path.join(MEDIA_ROOT, version_path)):
102                 # create version
103                 version_path = _version_generator(_url_to_path(str(source)), version_prefix)
104             elif os.path.getmtime(os.path.join(MEDIA_ROOT, _url_to_path(str(source)))) > os.path.getmtime(os.path.join(MEDIA_ROOT, version_path)):
105                 # recreate version if original image was updated
106                 version_path = _version_generator(_url_to_path(str(source)), version_prefix, force = True)
107             context[self.var_name] = FileObject(version_path)
108         except:
109             context[self.var_name] = ""
110         return ''
111
112
113 def version_object(parser, token):
114     """
115     Returns a context variable 'version_object'.
116     {% version_object field_name version_prefix %}
117     
118     Use {% version_object my_image 'medium' %} in order to retrieve the medium
119     version of an Image stored in a field name my_image.
120     Use {% version_object my_image 'medium' as var %} in order to use 'var' as
121     your context variable.
122     
123     version_prefix can be a string or a variable. if version_prefix is a string, use quotes.
124     """
125
126     try:
127         #tag, src, version_prefix = token.split_contents()
128         tag, arg = token.contents.split(None, 1)
129     except:
130         raise TemplateSyntaxError, "%s tag requires arguments" % token.contents.split()[0]
131     m = re.search(r'(.*?) (.*?) as (\w+)', arg)
132     if not m:
133         raise TemplateSyntaxError, "%r tag had invalid arguments" % tag
134     src, version_prefix, var_name = m.groups()
135     if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
136         raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
137     return VersionObjectNode(src, version_prefix, var_name)
138
139
140 class VersionSettingNode(Node):
141     def __init__(self, version_prefix):
142         if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")):
143             self.version_prefix = version_prefix[1:-1]
144         else:
145             self.version_prefix = None
146             self.version_prefix_var = Variable(version_prefix)
147
148     def render(self, context):
149         if self.version_prefix:
150             version_prefix = self.version_prefix
151         else:
152             try:
153                 version_prefix = self.version_prefix_var.resolve(context)
154             except VariableDoesNotExist:
155                 return None
156         context['version_setting'] = VERSIONS[version_prefix]
157         return ''
158
159
160 def version_setting(parser, token):
161     """
162     Get Information about a version setting.
163     """
164
165     try:
166         tag, version_prefix = token.split_contents()
167     except:
168         raise TemplateSyntaxError, "%s tag requires 1 argument" % token.contents.split()[0]
169     if (version_prefix[0] == version_prefix[-1] and version_prefix[0] in ('"', "'")) and version_prefix.lower()[1:-1] not in VERSIONS:
170         raise TemplateSyntaxError, "%s tag received bad version_prefix %s" % (tag, version_prefix)
171     return VersionSettingNode(version_prefix)
172
173
174 register.tag(version)
175 register.tag(version_object)
176 register.tag(version_setting)
177
178