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