Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / templatetags / astakos_tags.py @ dd5f8f4d

History | View | Annotate | Download (7 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import urllib
35

    
36
from inspect import getargspec
37

    
38
from django import template
39
from django.core.urlresolvers import resolve
40
from django.conf import settings
41
from django.template import TemplateSyntaxError, Variable
42

    
43
register = template.Library()
44

    
45
MESSAGES_VIEWS_MAP = getattr(settings, 'ASTAKOS_MESSAGES_VIEWS_MAP', {
46
    'astakos.im.views.index': 'LOGIN_MESSAGES',
47
    'astakos.im.views.logout': 'LOGIN_MESSAGES',
48
    'astakos.im.views.login': 'LOGIN_MESSAGES',
49
    'astakos.im.views.signup': 'SIGNUP_MESSAGES',
50
    'astakos.im.views.edit_profile': 'PROFILE_MESSAGES',
51
    'astakos.im.views.change_password': 'PROFILE_MESSAGES',
52
    'astakos.im.views.invite': 'PROFILE_MESSAGES',
53
    'astakos.im.views.feedback': 'PROFILE_MESSAGES',
54
})
55

    
56

    
57
# helper tag decorator
58
# https://github.com/djblets/djblets/blob/master/djblets/util/decorators.py#L96
59
def basictag(takes_context=False):
60
    """
61
    A decorator similar to Django's @register.simple_tag that optionally
62
    takes a context parameter. This condenses many tag implementations down
63
    to a few lines of code.
64

65
    Example:
66
        @register.tag
67
        @basictag(takes_context=True)
68
        def printuser(context):
69
            return context['user']
70
    """
71
    class BasicTagNode(template.Node):
72
        def __init__(self, take_context, tag_name, tag_func, args):
73
            self.takes_context = takes_context
74
            self.tag_name = tag_name
75
            self.tag_func = tag_func
76
            self.args = args
77

    
78
        def render(self, context):
79
            args = [Variable(var).resolve(context) for var in self.args]
80

    
81
            if self.takes_context:
82
                return self.tag_func(context, *args)
83
            else:
84
                return self.tag_func(*args)
85

    
86
    def basictag_func(tag_func):
87
        def _setup_tag(parser, token):
88
            bits = token.split_contents()
89
            tag_name = bits[0]
90
            del(bits[0])
91

    
92
            params, xx, xxx, defaults = getargspec(tag_func)
93
            max_args = len(params)
94

    
95
            if takes_context:
96
                if params[0] == 'context':
97
                    max_args -= 1 # Ignore context
98
                else:
99
                    raise TemplateSyntaxError, \
100
                        "Any tag function decorated with takes_context=True " \
101
                        "must have a first argument of 'context'"
102

    
103
            min_args = max_args - len(defaults or [])
104

    
105
            if not min_args <= len(bits) <= max_args:
106
                if min_args == max_args:
107
                    raise TemplateSyntaxError, \
108
                        "%r tag takes %d arguments." % (tag_name, min_args)
109
                else:
110
                    raise TemplateSyntaxError, \
111
                        "%r tag takes %d to %d arguments, got %d." % \
112
                        (tag_name, min_args, max_args, len(bits))
113

    
114
            return BasicTagNode(takes_context, tag_name, tag_func, bits)
115

    
116
        _setup_tag.__name__ = tag_func.__name__
117
        _setup_tag.__doc__ = tag_func.__doc__
118
        _setup_tag.__dict__.update(tag_func.__dict__)
119
        return _setup_tag
120

    
121
    return basictag_func
122

    
123

    
124
@register.tag(name='display_messages')
125
def display_messages(parser, token):
126
    return MessagesNode()
127

    
128

    
129
class DummyMessage(object):
130
    def __init__(self, type, msg):
131
        self.message = msg
132
        self.tags = type
133

    
134
    def __repr__(self):
135
        return "%s: %s" % (self.tags, self.message)
136

    
137

    
138
class MessagesNode(template.Node):
139

    
140
    def get_view_messages(self, context):
141
        messages = list(context['GLOBAL_MESSAGES'])
142
        try:
143
            view = resolve(context['request'].get_full_path())[0]
144
            view_name = "%s.%s" % (view.__module__, view.func_name)
145
            messages += context[MESSAGES_VIEWS_MAP.get(view_name)]
146
            return messages
147
        except Exception, e:
148
            return messages
149

    
150
    def render(self, context):
151
        if self not in context.render_context:
152
            messages = list(context['messages'])
153
            if context['EXTRA_MESSAGES_SET']:
154
                view_messages = self.get_view_messages(context)
155
                for msg_object in view_messages:
156
                    messages.append(DummyMessage(msg_object[0], msg_object[1]))
157

    
158
            if not messages:
159
                return ""
160

    
161
            cls = messages[-1].tags
162
            content = '<div class="top-msg active %s">' % cls
163
            for msg in messages:
164
                content += '<div class="msg %s">%s</div>' % (
165
                    msg.tags, msg.message)
166

    
167
            content += '<a href="#" title="close" class="close">X</a>'
168
            content += '</div>'
169
            context.render_context[self] = content
170

    
171
        return context.render_context[self]
172

    
173

    
174
@register.simple_tag
175
def get_grant_value(rname, form):
176
    grants = form.instance.grants
177
    service_name, resource_name = rname.split('.',1)
178
    try:
179
        return form.instance.projectresourcegrant_set.get(resource__name=resource_name,
180
                                                           resource__service__name=service_name).member_capacity
181
    except:
182
        return ''
183

    
184
@register.tag(name="provider_login_url")
185
@basictag(takes_context=True)
186
def provider_login_url(context, provider):
187
    request = context['request'].REQUEST
188
    next = request.get('next', None)
189
    code = request.get('code', None)
190
    key = request.get('key', None)
191

    
192
    attrs = {}
193
    if next:
194
        attrs['next'] = next
195
    if code:
196
        attrs['code'] = code
197
    if key:
198
        attrs['key'] = key
199

    
200
    url = provider.add_url
201

    
202
    joinchar = "?"
203
    if "?" in url:
204
        joinchar = "&"
205

    
206
    return "%s%s%s" % (provider.add_url, joinchar, urllib.urlencode(attrs))
207