Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / api / __init__.py @ 3902cfc6

History | View | Annotate | Download (7 kB)

1 6b03a847 Sofia Papagiannaki
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 6b03a847 Sofia Papagiannaki
#
3 6b03a847 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 6b03a847 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 6b03a847 Sofia Papagiannaki
# conditions are met:
6 6b03a847 Sofia Papagiannaki
#
7 6b03a847 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 6b03a847 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 6b03a847 Sofia Papagiannaki
#      disclaimer.
10 6b03a847 Sofia Papagiannaki
#
11 6b03a847 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 6b03a847 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 6b03a847 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 6b03a847 Sofia Papagiannaki
#      provided with the distribution.
15 6b03a847 Sofia Papagiannaki
#
16 6b03a847 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 6b03a847 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 6b03a847 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 6b03a847 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 6b03a847 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 6b03a847 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 6b03a847 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 6b03a847 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 6b03a847 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 6b03a847 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 6b03a847 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 6b03a847 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 6b03a847 Sofia Papagiannaki
#
29 6b03a847 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 6b03a847 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 6b03a847 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 6b03a847 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 6b03a847 Sofia Papagiannaki
34 14c5be5a Sofia Papagiannaki
from functools import wraps
35 14c5be5a Sofia Papagiannaki
from traceback import format_exc
36 14c5be5a Sofia Papagiannaki
from urllib import quote, unquote
37 14c5be5a Sofia Papagiannaki
38 6b03a847 Sofia Papagiannaki
from django.http import HttpResponse
39 6b03a847 Sofia Papagiannaki
from django.utils import simplejson as json
40 14c5be5a Sofia Papagiannaki
from django.conf import settings
41 14c5be5a Sofia Papagiannaki
from django.core.urlresolvers import reverse
42 3902cfc6 Kostas Papadimitriou
from django.utils.translation import ugettext as _
43 14c5be5a Sofia Papagiannaki
44 6a933a9c Sofia Papagiannaki
from astakos.im.models import AstakosUser, Service, Resource
45 aab4d540 Sofia Papagiannaki
from astakos.im.api.faults import Fault, ItemNotFound, InternalServerError, BadRequest
46 73fbaec4 Sofia Papagiannaki
from astakos.im.settings import (
47 73fbaec4 Sofia Papagiannaki
    INVITATIONS_ENABLED, COOKIE_NAME, EMAILCHANGE_ENABLED, QUOTAHOLDER_URL)
48 6b03a847 Sofia Papagiannaki
49 14c5be5a Sofia Papagiannaki
import logging
50 14c5be5a Sofia Papagiannaki
logger = logging.getLogger(__name__)
51 6b03a847 Sofia Papagiannaki
52 6b03a847 Sofia Papagiannaki
format = ('%a, %d %b %Y %H:%M:%S GMT')
53 6b03a847 Sofia Papagiannaki
54 a88d9ec1 Sofia Papagiannaki
absolute = lambda request, url: request.build_absolute_uri(url)
55 a88d9ec1 Sofia Papagiannaki
56 5ce3ce4f Sofia Papagiannaki
57 14c5be5a Sofia Papagiannaki
def render_fault(request, fault):
58 14c5be5a Sofia Papagiannaki
    if isinstance(fault, InternalServerError) and settings.DEBUG:
59 14c5be5a Sofia Papagiannaki
        fault.details = format_exc(fault)
60 14c5be5a Sofia Papagiannaki
61 14c5be5a Sofia Papagiannaki
    request.serialization = 'text'
62 14c5be5a Sofia Papagiannaki
    data = fault.message + '\n'
63 14c5be5a Sofia Papagiannaki
    if fault.details:
64 14c5be5a Sofia Papagiannaki
        data += '\n' + fault.details
65 14c5be5a Sofia Papagiannaki
    response = HttpResponse(data, status=fault.code)
66 14c5be5a Sofia Papagiannaki
    response['Content-Length'] = len(response.content)
67 14c5be5a Sofia Papagiannaki
    return response
68 14c5be5a Sofia Papagiannaki
69 5ce3ce4f Sofia Papagiannaki
70 14c5be5a Sofia Papagiannaki
def api_method(http_method=None):
71 14c5be5a Sofia Papagiannaki
    """Decorator function for views that implement an API method."""
72 14c5be5a Sofia Papagiannaki
    def decorator(func):
73 14c5be5a Sofia Papagiannaki
        @wraps(func)
74 14c5be5a Sofia Papagiannaki
        def wrapper(request, *args, **kwargs):
75 14c5be5a Sofia Papagiannaki
            try:
76 14c5be5a Sofia Papagiannaki
                if http_method and request.method != http_method:
77 14c5be5a Sofia Papagiannaki
                    raise BadRequest('Method not allowed.')
78 14c5be5a Sofia Papagiannaki
                response = func(request, *args, **kwargs)
79 14c5be5a Sofia Papagiannaki
                return response
80 14c5be5a Sofia Papagiannaki
            except Fault, fault:
81 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
82 14c5be5a Sofia Papagiannaki
            except BaseException, e:
83 14c5be5a Sofia Papagiannaki
                logger.exception('Unexpected error: %s' % e)
84 14c5be5a Sofia Papagiannaki
                fault = InternalServerError('Unexpected error')
85 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
86 14c5be5a Sofia Papagiannaki
        return wrapper
87 14c5be5a Sofia Papagiannaki
    return decorator
88 14c5be5a Sofia Papagiannaki
89 5ce3ce4f Sofia Papagiannaki
90 1ebea3d3 Kostas Papadimitriou
def get_services_dict():
91 14c5be5a Sofia Papagiannaki
    services = Service.objects.all()
92 5ce3ce4f Sofia Papagiannaki
    data = tuple({'id': s.pk, 'name': s.name, 'url': s.url, 'icon':
93 5ce3ce4f Sofia Papagiannaki
                 s.icon} for s in services)
94 1ebea3d3 Kostas Papadimitriou
    return data
95 1ebea3d3 Kostas Papadimitriou
96 1ebea3d3 Kostas Papadimitriou
@api_method(http_method=None)
97 1ebea3d3 Kostas Papadimitriou
def get_services(request):
98 1ebea3d3 Kostas Papadimitriou
    callback = request.GET.get('callback', None)
99 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
100 1ebea3d3 Kostas Papadimitriou
    data = json.dumps(get_services_dict())
101 14c5be5a Sofia Papagiannaki
102 14c5be5a Sofia Papagiannaki
    if callback:
103 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
104 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
105 14c5be5a Sofia Papagiannaki
106 14c5be5a Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
107 14c5be5a Sofia Papagiannaki
108 5ce3ce4f Sofia Papagiannaki
109 14c5be5a Sofia Papagiannaki
@api_method()
110 ed4a91be Olga Brani
def get_menu(request, with_extra_links=False, with_signout=True):
111 304acb60 Olga Brani
    user = request.user
112 3902cfc6 Kostas Papadimitriou
    from_location = request.GET.get('location')
113 c0b26605 Sofia Papagiannaki
    index_url = reverse('index')
114 3902cfc6 Kostas Papadimitriou
    if from_location:
115 3902cfc6 Kostas Papadimitriou
        index_url = "%s?next=%s" % (index_url, from_location)
116 3902cfc6 Kostas Papadimitriou
117 3902cfc6 Kostas Papadimitriou
    l = [{'url': absolute(request, index_url), 'name': _("Sign in")}]
118 c0b26605 Sofia Papagiannaki
    if user.is_authenticated():
119 14c5be5a Sofia Papagiannaki
        l = []
120 a88d9ec1 Sofia Papagiannaki
        append = l.append
121 a88d9ec1 Sofia Papagiannaki
        item = MenuItem
122 a88d9ec1 Sofia Papagiannaki
        item.current_path = absolute(request, request.path)
123 54213d7a Sofia Papagiannaki
        append(item(
124 9a06d96f Olga Brani
               url=absolute(request, reverse('index')),
125 9a06d96f Olga Brani
               name=user.email))
126 54213d7a Sofia Papagiannaki
        append(item(url=absolute(request, reverse('edit_profile')),
127 54213d7a Sofia Papagiannaki
               name="My account"))
128 14c5be5a Sofia Papagiannaki
        if with_extra_links:
129 14c5be5a Sofia Papagiannaki
            if EMAILCHANGE_ENABLED:
130 54213d7a Sofia Papagiannaki
                append(item(
131 9a06d96f Olga Brani
                       url=absolute(request, reverse('email_change')),
132 9a06d96f Olga Brani
                       name="Change email"))
133 14c5be5a Sofia Papagiannaki
            if INVITATIONS_ENABLED:
134 54213d7a Sofia Papagiannaki
                append(item(
135 9a06d96f Olga Brani
                       url=absolute(request, reverse('invite')),
136 9a06d96f Olga Brani
                       name="Invitations"))
137 1ebea3d3 Kostas Papadimitriou
138 73fbaec4 Sofia Papagiannaki
            if QUOTAHOLDER_URL:
139 73fbaec4 Sofia Papagiannaki
                append(item(
140 73fbaec4 Sofia Papagiannaki
                       url=absolute(request, reverse('project_list')),
141 172ce682 Sofia Papagiannaki
                       name="Projects"))
142 2a965273 Sofia Papagiannaki
            append(item(
143 666c7490 Sofia Papagiannaki
                   url=absolute(request, reverse('resource_usage')),
144 666c7490 Sofia Papagiannaki
                   name="Usage"))
145 a3e77c69 Olga Brani
            append(item(
146 a3e77c69 Olga Brani
                   url=absolute(request, reverse('feedback')),
147 279d6e51 Olga Brani
                   name="Contact"))
148 14c5be5a Sofia Papagiannaki
        if with_signout:
149 54213d7a Sofia Papagiannaki
            append(item(
150 9a06d96f Olga Brani
                   url=absolute(request, reverse('logout')),
151 9a06d96f Olga Brani
                   name="Sign out"))
152 5ce3ce4f Sofia Papagiannaki
153 14c5be5a Sofia Papagiannaki
    callback = request.GET.get('callback', None)
154 14c5be5a Sofia Papagiannaki
    data = json.dumps(tuple(l))
155 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
156 14c5be5a Sofia Papagiannaki
157 14c5be5a Sofia Papagiannaki
    if callback:
158 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
159 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
160 14c5be5a Sofia Papagiannaki
161 a88d9ec1 Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
162 a88d9ec1 Sofia Papagiannaki
163 5ce3ce4f Sofia Papagiannaki
164 a88d9ec1 Sofia Papagiannaki
class MenuItem(dict):
165 a88d9ec1 Sofia Papagiannaki
    current_path = ''
166 5ce3ce4f Sofia Papagiannaki
167 a88d9ec1 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
168 a88d9ec1 Sofia Papagiannaki
        super(MenuItem, self).__init__(*args, **kwargs)
169 a88d9ec1 Sofia Papagiannaki
        if kwargs.get('url') or kwargs.get('submenu'):
170 a88d9ec1 Sofia Papagiannaki
            self.__set_is_active__()
171 5ce3ce4f Sofia Papagiannaki
172 a88d9ec1 Sofia Papagiannaki
    def __setitem__(self, key, value):
173 a88d9ec1 Sofia Papagiannaki
        super(MenuItem, self).__setitem__(key, value)
174 a88d9ec1 Sofia Papagiannaki
        if key in ('url', 'submenu'):
175 a88d9ec1 Sofia Papagiannaki
            self.__set_is_active__()
176 5ce3ce4f Sofia Papagiannaki
177 a88d9ec1 Sofia Papagiannaki
    def __set_is_active__(self):
178 2ef68a58 Sofia Papagiannaki
        if self.get('is_active'):
179 2ef68a58 Sofia Papagiannaki
            return
180 451f6175 Sofia Papagiannaki
        if self.current_path.startswith(self.get('url')):
181 a88d9ec1 Sofia Papagiannaki
            self.__setitem__('is_active', True)
182 a88d9ec1 Sofia Papagiannaki
        else:
183 2ef68a58 Sofia Papagiannaki
            submenu = self.get('submenu', ())
184 2ef68a58 Sofia Papagiannaki
            current = (i for i in submenu if i.get('url') == self.current_path)
185 2ef68a58 Sofia Papagiannaki
            try:
186 2ef68a58 Sofia Papagiannaki
                current_node = current.next()
187 2ef68a58 Sofia Papagiannaki
                if not current_node.get('is_active'):
188 2ef68a58 Sofia Papagiannaki
                    current_node.__setitem__('is_active', True)
189 2ef68a58 Sofia Papagiannaki
                self.__setitem__('is_active', True)
190 2ef68a58 Sofia Papagiannaki
            except StopIteration:
191 2ef68a58 Sofia Papagiannaki
                return
192 5ce3ce4f Sofia Papagiannaki
193 2ef68a58 Sofia Papagiannaki
    def __setattribute__(self, name, value):
194 2ef68a58 Sofia Papagiannaki
        super(MenuItem, self).__setattribute__(name, value)
195 2ef68a58 Sofia Papagiannaki
        if name == 'current_path':
196 5ce3ce4f Sofia Papagiannaki
            self.__set_is_active__()