Skip to content

Commit

Permalink
Added docs, tests and fine tuned ROSETTA_LANGUAGE_GROUPS setting
Browse files Browse the repository at this point in the history
  • Loading branch information
mbi committed May 2, 2014
1 parent dc5a246 commit e963ca6
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -3,6 +3,7 @@ Version 0.7.5
* Fixed external JavaScript import to be url scheme independent (PR #101, thanks @tsouvarev)
* Fixed a test
* Added support for excluding certain locale paths from the list of PO catalogs (PR #102, thanks @elpaso)
* Added support for translator groups (PR #103, thanks @barklund)


Version 0.7.4
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -63,7 +63,7 @@ Rosetta can be configured via the following parameters, to be defined in your pr
* ``ROSETTA_POFILE_WRAP_WIDTH``: Sets the line-length of the edited PO file. Set this to ``0`` to mimic ``makemessage``'s ``--no-wrap`` option. Defaults to ``78``.
* ``ROSETTA_STORAGE_CLASS``: See the note below on Storages. Defaults to ``rosetta.storage.CacheRosettaStorage``
* ``ROSETTA_ACCESS_CONTROL_FUNCTION``: An alternative function that determines if a given user can access the translation views. This function receives a ``user`` as its argument, and returns a boolean specifying whether the passed user is allowed to use Rosetta or not.
* ``ROSETTA_LANGUAGE_GROUPS``: Set to ``True`` to enable language-specific groups, which can be used to give different translators access to different languages.
* ``ROSETTA_LANGUAGE_GROUPS``: Set to ``True`` to enable language-specific groups, which can be used to give different translators access to different languages. Instead of creating a global ``translators`` group, create individual per-language groups, e.g. ``translators-de``, ``translators-fr``, and assign users to these.
* ``ROSETTA_CACHE_NAME``: When using ``rosetta.storage.CacheRosettaStorage``, you can store the rosetta data in a specific cache. This is particularly useful when your ``default`` cache is a ``django.core.cache.backends.dummy.DummyCache`` (which happens on pre-production environments). If unset, it will default to ``rosetta`` if a cache with this name exists, or ``default`` if not.
* ``ROSETTA_POFILENAMES``: Defines which po filenames are exposed in the web interface. Defaults to ``('django.po', 'djangojs.po')``
* ``ROSETTA_EXCLUDE_PATHS``: Exclude paths defined in this list from being searched (usually ends with "locale"). Defaults to ``()``
Expand Down
28 changes: 13 additions & 15 deletions rosetta/access.py
@@ -1,26 +1,13 @@
from django.conf import settings
from rosetta.conf import settings as rosetta_settings

from django.utils import importlib


def can_translate(user):
return get_access_control_function()(user)


def can_translate_language(user, langid):

use_language_groups = getattr(settings, 'ROSETTA_LANGUAGE_GROUPS', False)

if not use_language_groups:
return can_translate(user)
elif not user.is_authenticated():
return False
elif user.is_superuser and user.is_staff:
return True
else:
return user.groups.filter(name='translators-%s' % langid).exists()



def get_access_control_function():
"""
Return a predicate for determining if a user can access the Rosetta views
Expand All @@ -44,3 +31,14 @@ def is_superuser_staff_or_in_translators_group(user):
return True
else:
return user.groups.filter(name='translators').exists()


def can_translate_language(user, langid):
if not rosetta_settings.ROSETTA_LANGUAGE_GROUPS:
return can_translate(user)
elif not user.is_authenticated():
return False
elif user.is_superuser and user.is_staff:
return True
else:
return user.groups.filter(name='translators-%s' % langid).exists()
6 changes: 6 additions & 0 deletions rosetta/conf/settings.py
Expand Up @@ -75,3 +75,9 @@

# Exclude paths defined in this list from being searched (usually ends with "locale")
ROSETTA_EXCLUDED_PATHS = getattr(settings, 'ROSETTA_EXCLUDED_PATHS', ())

# Set to True to enable language-specific groups, which can be used to give
# different translators access to different languages. Instead of creating a
# 'translators` group, create individual per-language groups, e.g.
# 'translators-de', 'translators-fr', ...
ROSETTA_LANGUAGE_GROUPS = getattr(settings, 'ROSETTA_LANGUAGE_GROUPS', False)
38 changes: 37 additions & 1 deletion rosetta/tests/tests.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.models import User, Group
from django.core.urlresolvers import reverse, resolve
from django.core.exceptions import ImproperlyConfigured
from django.core.cache import cache
Expand Down Expand Up @@ -633,6 +633,42 @@ def test_31_pr_102__exclude_paths(self):

rosetta_settings.ROSETTA_EXCLUDED_PATHS = ROSETTA_EXCLUDED_PATHS

def test_32_pr_103__language_groups(self):
ROSETTA_LANGUAGE_GROUPS = rosetta_settings.ROSETTA_LANGUAGE_GROUPS
rosetta_settings.ROSETTA_LANGUAGE_GROUPS = False

# Default behavior: non admins need to be in a translators group, they see
# all catalogs
translators = Group.objects.create(name='translators')
translators_xx = Group.objects.create(name='translators-xx')

user4 = User.objects.create_user('test_admin4', 'test@test3.com', 'test_password')
user4.groups.add(translators)
user4.is_superuser = False
user4.is_staff = True
user4.save()
self.client.login(username='test_admin4', password='test_password')

r = self.client.get(reverse('rosetta-pick-file') + '?filter=third-party')
r = self.client.get(reverse('rosetta-pick-file'))
self.assertTrue(os.path.normpath('rosetta/locale/xx/LC_MESSAGES/django.po') in str(r.content))

# Activate the option, user doesn't see the XX catalog
rosetta_settings.ROSETTA_LANGUAGE_GROUPS = True

r = self.client.get(reverse('rosetta-pick-file') + '?filter=third-party')
r = self.client.get(reverse('rosetta-pick-file'))
self.assertFalse(os.path.normpath('rosetta/locale/xx/LC_MESSAGES/django.po') in str(r.content))

# Now add them to the custom group
user4.groups.add(translators_xx)

r = self.client.get(reverse('rosetta-pick-file') + '?filter=third-party')
r = self.client.get(reverse('rosetta-pick-file'))
self.assertTrue(os.path.normpath('rosetta/locale/xx/LC_MESSAGES/django.po') in str(r.content))

rosetta_settings.ROSETTA_LANGUAGE_GROUPS = ROSETTA_LANGUAGE_GROUPS


# Stubbed access control function
def no_access(user):
Expand Down

0 comments on commit e963ca6

Please sign in to comment.