app/soc/views/sitemap/sidebar.py
author Lennard de Rijk <ljvderijk@gmail.com>
Thu, 05 Feb 2009 22:15:38 +0000
changeset 1225 1d5c58e24fd3
parent 1024 2a0ae6483825
child 1307 091a21cf3627
permissions -rw-r--r--
Org applications can now only be made by a user when a program allows it. To do this a new access_type has been added called apply. This ensures that users can only used the seeded version of create. Also the review_overview now has his own access type to ensure the separability of hosts for different sponsors in case of org app reviews. Note that the access checks for hosts are broken and only give access to developers at the moment. Patch by: Lennard de Rijk Reviewed by: to-be-reviewed

#!/usr/bin/python2.5
#
# Copyright 2008 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Module contains sidebar related functions.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]


import operator

from soc.views import out_of_band
from soc.views.helper import access

import soc.cache.sidebar


SIDEBAR = []
SIDEBAR_ACCESS_ARGS = ['SIDEBAR_CALLING']
SIDEBAR_ACCESS_KWARGS = {'SIDEBAR_CALLING': True}


def addMenu(callback):
  """Adds a callback to the menu builder.

  The callback should return a list of menu's when called.
  """

  global SIDEBAR
  SIDEBAR.append(callback)


@soc.cache.sidebar.cache
def getSidebar(id, user):
  """Constructs a sidebar for the current user.
  """

  sidebar = []

  for callback in SIDEBAR:
    menus = callback(id, user)

    for menu in (menus if menus else []):
      sidebar.append(menu)

  return sorted(sidebar, key=lambda x: x.get('group'))


def getSidebarItems(params):
  """Retrieves a list of sidebar entries for this view.

  Params usage:
    The params dictionary is provided to the menu_text's format.

    sidebar: The sidebar value is returned directly if non-False
    sidebar_defaults: The sidebar_defaults are used to construct the
      sidebar items for this View. It is expected to be a tuple of
      three items, the item's url, it's menu_text, and it's
      access_type, see getSidebarMenus on how access_type is used.
    sidebar_additional: The sidebar_additional values are appended
      to the list of items verbatim, and should be in the format
      expected by getSidebarMenus.

  Args:
    params: a dict with params for this View.
  """

  # Return the found result
  if params['sidebar']:
    default = params['sidebar']
    result = default[:]
    for item in params['sidebar_additional']:
      result.append(item)
    return result

  # Construct defaults manualy
  defaults = params['sidebar_defaults']

  result = []

  for item in params['sidebar_additional']:
    result.append(item)

  for url, menu_text, access_type in defaults:
    url = url % params['url_name'].lower()
    item = (url, menu_text % params, access_type)
    result.append(item)

  return result


def getSidebarMenu(id, user, items, params):
  """Returns an dictionary with one sidebar entry.

  Items is expected to be a tuple with an url, a menu_text, and an
  access_type. The access_type is then passed to checkAccess, if it
  raises out_of_band.Error, the item will not be added.

  Args:
    items: see above
    params: a dict with params for this View

  Params usage:
    The params dictionary is passed as argument to getSidebarItems,
    see the docstring of getSidebarItems on how it uses it.

    rights: The rights dictionary is used to check if the user has
      the required rights to see a sidebar item.
      See checkAccess for more details on how the rights dictionary
      is used to check access rights.
    sidebar_heading: The sidebar_heading value is used to set the
      heading variable in the result.
    name: The name value is used if sidebar_heading is not present.

  Returns: 
    A dictionary is returned with it's 'heading' value set as explained above.
    It's 'items' value is constructed by calling _getSidebarItems. It constists
    of dictionaries with a url and a title field.
  """

  rights = params['rights']

  submenus = []

  args = SIDEBAR_ACCESS_ARGS
  kwargs = SIDEBAR_ACCESS_KWARGS

  # reset and pre-fill the Checker's cache
  rights.setCurrentUser(id, user)

  for url, menu_text, access_type in items:
    try:
      rights.checkAccess(access_type, kwargs)
      submenus.append({'url': url, 'title': menu_text})
    except out_of_band.Error:
      pass

  return submenus


def getSidebarMenus(id, user, params=None):
  """Constructs the default sidebar menu for a View.

  Calls getSidebarItems to retrieve the items that should be in the
  menu. Then passes the result to getSidebarMenu. See the respective
  docstrings for an explanation on what they do.

  Args:
    params: a dict with params for this View
  """

  items = getSidebarItems(params)
  submenus = getSidebarMenu(id, user, items, params)

  if not submenus:
    return

  menu = {}

  if 'sidebar_heading' not in params:
    params['sidebar_heading'] = params['name']

  menu['heading'] = params['sidebar_heading']
  menu['items'] = submenus
  menu['group'] = params['sidebar_grouping']

  menus = [menu]

  return menus