Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / api / __init__.py @ 1ebea3d3

History | View | Annotate | Download (6.8 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 14c5be5a Sofia Papagiannaki
43 6a933a9c Sofia Papagiannaki
from astakos.im.models import AstakosUser, Service, Resource
44 aab4d540 Sofia Papagiannaki
from astakos.im.api.faults import Fault, ItemNotFound, InternalServerError, BadRequest
45 73fbaec4 Sofia Papagiannaki
from astakos.im.settings import (
46 73fbaec4 Sofia Papagiannaki
    INVITATIONS_ENABLED, COOKIE_NAME, EMAILCHANGE_ENABLED, QUOTAHOLDER_URL)
47 6b03a847 Sofia Papagiannaki
48 14c5be5a Sofia Papagiannaki
import logging
49 14c5be5a Sofia Papagiannaki
logger = logging.getLogger(__name__)
50 6b03a847 Sofia Papagiannaki
51 6b03a847 Sofia Papagiannaki
format = ('%a, %d %b %Y %H:%M:%S GMT')
52 6b03a847 Sofia Papagiannaki
53 a88d9ec1 Sofia Papagiannaki
absolute = lambda request, url: request.build_absolute_uri(url)
54 a88d9ec1 Sofia Papagiannaki
55 5ce3ce4f Sofia Papagiannaki
56 14c5be5a Sofia Papagiannaki
def render_fault(request, fault):
57 14c5be5a Sofia Papagiannaki
    if isinstance(fault, InternalServerError) and settings.DEBUG:
58 14c5be5a Sofia Papagiannaki
        fault.details = format_exc(fault)
59 14c5be5a Sofia Papagiannaki
60 14c5be5a Sofia Papagiannaki
    request.serialization = 'text'
61 14c5be5a Sofia Papagiannaki
    data = fault.message + '\n'
62 14c5be5a Sofia Papagiannaki
    if fault.details:
63 14c5be5a Sofia Papagiannaki
        data += '\n' + fault.details
64 14c5be5a Sofia Papagiannaki
    response = HttpResponse(data, status=fault.code)
65 14c5be5a Sofia Papagiannaki
    response['Content-Length'] = len(response.content)
66 14c5be5a Sofia Papagiannaki
    return response
67 14c5be5a Sofia Papagiannaki
68 5ce3ce4f Sofia Papagiannaki
69 14c5be5a Sofia Papagiannaki
def api_method(http_method=None):
70 14c5be5a Sofia Papagiannaki
    """Decorator function for views that implement an API method."""
71 14c5be5a Sofia Papagiannaki
    def decorator(func):
72 14c5be5a Sofia Papagiannaki
        @wraps(func)
73 14c5be5a Sofia Papagiannaki
        def wrapper(request, *args, **kwargs):
74 14c5be5a Sofia Papagiannaki
            try:
75 14c5be5a Sofia Papagiannaki
                if http_method and request.method != http_method:
76 14c5be5a Sofia Papagiannaki
                    raise BadRequest('Method not allowed.')
77 14c5be5a Sofia Papagiannaki
                response = func(request, *args, **kwargs)
78 14c5be5a Sofia Papagiannaki
                return response
79 14c5be5a Sofia Papagiannaki
            except Fault, fault:
80 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
81 14c5be5a Sofia Papagiannaki
            except BaseException, e:
82 14c5be5a Sofia Papagiannaki
                logger.exception('Unexpected error: %s' % e)
83 14c5be5a Sofia Papagiannaki
                fault = InternalServerError('Unexpected error')
84 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
85 14c5be5a Sofia Papagiannaki
        return wrapper
86 14c5be5a Sofia Papagiannaki
    return decorator
87 14c5be5a Sofia Papagiannaki
88 5ce3ce4f Sofia Papagiannaki
89 1ebea3d3 Kostas Papadimitriou
def get_services_dict():
90 14c5be5a Sofia Papagiannaki
    services = Service.objects.all()
91 5ce3ce4f Sofia Papagiannaki
    data = tuple({'id': s.pk, 'name': s.name, 'url': s.url, 'icon':
92 5ce3ce4f Sofia Papagiannaki
                 s.icon} for s in services)
93 1ebea3d3 Kostas Papadimitriou
    return data
94 1ebea3d3 Kostas Papadimitriou
95 1ebea3d3 Kostas Papadimitriou
@api_method(http_method=None)
96 1ebea3d3 Kostas Papadimitriou
def get_services(request):
97 1ebea3d3 Kostas Papadimitriou
    callback = request.GET.get('callback', None)
98 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
99 1ebea3d3 Kostas Papadimitriou
    data = json.dumps(get_services_dict())
100 14c5be5a Sofia Papagiannaki
101 14c5be5a Sofia Papagiannaki
    if callback:
102 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
103 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
104 14c5be5a Sofia Papagiannaki
105 14c5be5a Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
106 14c5be5a Sofia Papagiannaki
107 5ce3ce4f Sofia Papagiannaki
108 14c5be5a Sofia Papagiannaki
@api_method()
109 ed4a91be Olga Brani
def get_menu(request, with_extra_links=False, with_signout=True):
110 304acb60 Olga Brani
    user = request.user
111 c0b26605 Sofia Papagiannaki
    index_url = reverse('index')
112 c0b26605 Sofia Papagiannaki
    l = [{'url': absolute(request, index_url), 'name': "Sign in"}]
113 c0b26605 Sofia Papagiannaki
    if user.is_authenticated():
114 14c5be5a Sofia Papagiannaki
        l = []
115 a88d9ec1 Sofia Papagiannaki
        append = l.append
116 a88d9ec1 Sofia Papagiannaki
        item = MenuItem
117 a88d9ec1 Sofia Papagiannaki
        item.current_path = absolute(request, request.path)
118 54213d7a Sofia Papagiannaki
        append(item(
119 9a06d96f Olga Brani
               url=absolute(request, reverse('index')),
120 9a06d96f Olga Brani
               name=user.email))
121 54213d7a Sofia Papagiannaki
        append(item(url=absolute(request, reverse('edit_profile')),
122 54213d7a Sofia Papagiannaki
               name="My account"))
123 14c5be5a Sofia Papagiannaki
        if with_extra_links:
124 14c5be5a Sofia Papagiannaki
            if EMAILCHANGE_ENABLED:
125 54213d7a Sofia Papagiannaki
                append(item(
126 9a06d96f Olga Brani
                       url=absolute(request, reverse('email_change')),
127 9a06d96f Olga Brani
                       name="Change email"))
128 14c5be5a Sofia Papagiannaki
            if INVITATIONS_ENABLED:
129 54213d7a Sofia Papagiannaki
                append(item(
130 9a06d96f Olga Brani
                       url=absolute(request, reverse('invite')),
131 9a06d96f Olga Brani
                       name="Invitations"))
132 1ebea3d3 Kostas Papadimitriou
133 73fbaec4 Sofia Papagiannaki
            if QUOTAHOLDER_URL:
134 73fbaec4 Sofia Papagiannaki
                append(item(
135 73fbaec4 Sofia Papagiannaki
                       url=absolute(request, reverse('project_list')),
136 172ce682 Sofia Papagiannaki
                       name="Projects"))
137 2a965273 Sofia Papagiannaki
            append(item(
138 666c7490 Sofia Papagiannaki
                   url=absolute(request, reverse('resource_usage')),
139 666c7490 Sofia Papagiannaki
                   name="Usage"))
140 a3e77c69 Olga Brani
            append(item(
141 a3e77c69 Olga Brani
                   url=absolute(request, reverse('feedback')),
142 279d6e51 Olga Brani
                   name="Contact"))
143 14c5be5a Sofia Papagiannaki
        if with_signout:
144 54213d7a Sofia Papagiannaki
            append(item(
145 9a06d96f Olga Brani
                   url=absolute(request, reverse('logout')),
146 9a06d96f Olga Brani
                   name="Sign out"))
147 5ce3ce4f Sofia Papagiannaki
148 14c5be5a Sofia Papagiannaki
    callback = request.GET.get('callback', None)
149 14c5be5a Sofia Papagiannaki
    data = json.dumps(tuple(l))
150 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
151 14c5be5a Sofia Papagiannaki
152 14c5be5a Sofia Papagiannaki
    if callback:
153 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
154 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
155 14c5be5a Sofia Papagiannaki
156 a88d9ec1 Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
157 a88d9ec1 Sofia Papagiannaki
158 5ce3ce4f Sofia Papagiannaki
159 a88d9ec1 Sofia Papagiannaki
class MenuItem(dict):
160 a88d9ec1 Sofia Papagiannaki
    current_path = ''
161 5ce3ce4f Sofia Papagiannaki
162 a88d9ec1 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
163 a88d9ec1 Sofia Papagiannaki
        super(MenuItem, self).__init__(*args, **kwargs)
164 a88d9ec1 Sofia Papagiannaki
        if kwargs.get('url') or kwargs.get('submenu'):
165 a88d9ec1 Sofia Papagiannaki
            self.__set_is_active__()
166 5ce3ce4f Sofia Papagiannaki
167 a88d9ec1 Sofia Papagiannaki
    def __setitem__(self, key, value):
168 a88d9ec1 Sofia Papagiannaki
        super(MenuItem, self).__setitem__(key, value)
169 a88d9ec1 Sofia Papagiannaki
        if key in ('url', 'submenu'):
170 a88d9ec1 Sofia Papagiannaki
            self.__set_is_active__()
171 5ce3ce4f Sofia Papagiannaki
172 a88d9ec1 Sofia Papagiannaki
    def __set_is_active__(self):
173 2ef68a58 Sofia Papagiannaki
        if self.get('is_active'):
174 2ef68a58 Sofia Papagiannaki
            return
175 a88d9ec1 Sofia Papagiannaki
        if self.current_path == self.get('url'):
176 a88d9ec1 Sofia Papagiannaki
            self.__setitem__('is_active', True)
177 a88d9ec1 Sofia Papagiannaki
        else:
178 2ef68a58 Sofia Papagiannaki
            submenu = self.get('submenu', ())
179 2ef68a58 Sofia Papagiannaki
            current = (i for i in submenu if i.get('url') == self.current_path)
180 2ef68a58 Sofia Papagiannaki
            try:
181 2ef68a58 Sofia Papagiannaki
                current_node = current.next()
182 2ef68a58 Sofia Papagiannaki
                if not current_node.get('is_active'):
183 2ef68a58 Sofia Papagiannaki
                    current_node.__setitem__('is_active', True)
184 2ef68a58 Sofia Papagiannaki
                self.__setitem__('is_active', True)
185 2ef68a58 Sofia Papagiannaki
            except StopIteration:
186 2ef68a58 Sofia Papagiannaki
                return
187 5ce3ce4f Sofia Papagiannaki
188 2ef68a58 Sofia Papagiannaki
    def __setattribute__(self, name, value):
189 2ef68a58 Sofia Papagiannaki
        super(MenuItem, self).__setattribute__(name, value)
190 2ef68a58 Sofia Papagiannaki
        if name == 'current_path':
191 5ce3ce4f Sofia Papagiannaki
            self.__set_is_active__()