Ejemplo n.º 1
0
class Menu(models.Model):

    __metaclass__ = TransMeta

    name = models.CharField(
        verbose_name=_('name'),
        max_length=200,
    )

    slug = models.SlugField(
        verbose_name=_('slug'),
        max_length=200,
        blank=False,
        null=False,
    )

    help_text = models.CharField(
        verbose_name=_('help text'),
        help_text=
        _('text for describing the menu target, usually placed as link title attribute'
          ),
        max_length=200,
        blank=True,
        null=True,
    )

    parent = models.ForeignKey(
        'Menu',
        verbose_name=_('Parent'),
        blank=True,
        null=True,
        related_name='child_set',
    )

    url = models.URLField(
        verbose_name=_('url'),
        blank=True,
        null=True,
        editable=False,
    )

    status = models.CharField(
        verbose_name=_('status'),
        help_text=_('status of the menu element'),
        choices=(('public', _('public')), ('draft', _('draft'))),
        default='public',
        max_length=25,
    )

    visible_by_roles = models.ManyToManyField(
        Role,
        related_name='visible_menus',
        verbose_name=_('visible menus'),
        blank=True,
        null=True,
        help_text=_('The roles that will see this menu'))

    class Meta:
        verbose_name = _('menu')
        verbose_name_plural = _('menus')
        translate = (
            'name',
            'help_text',
        )

    def __unicode__(self):
        return unicode(self.name)

    def get_absolute_url(self):
        if self.url == None:
            self.update_url()
        return self.url

    @permalink
    def get_admin_absolute_url(self):
        """ Link to the admin page for editing the object """
        section = self.get_section()
        if section:
            section_content_type = ContentType.objects.get_for_model(section)
            return ('merengue.base.views.admin_link', [
                section_content_type.id, section.id,
                'mainmenu/%s/' % self.id
            ])
        else:
            menu_content_type = ContentType.objects.get_for_model(self)
            print menu_content_type.id
            print self.id
            return ('merengue.base.views.admin_link',
                    [menu_content_type.id, self.id, ''])

    @permalink
    def menu_public_link_without_section(self, ancestors_path):
        return self._menu_public_link_without_section(ancestors_path)

    def _menu_public_link_without_section(self, ancestors_path):
        return ('menu_view', (ancestors_path, self.slug))

    def public_link(self):
        menus_ancestors = [
            menu.slug for menu in self.get_ancestors()
        ][1:]  # first is a dummy root menu and we discard it
        ancestors_path = menus_ancestors and '/%s' % '/'.join(
            menus_ancestors) or ''
        section = self.get_section()
        if section:
            return section.get_real_instance().menu_public_link(
                ancestors_path, self)
        else:
            return self.menu_public_link_without_section(ancestors_path)

    def update_url(self, commit=True):
        try:
            _menu_sections_cache.reload_if_dirty()
            self.url = self.public_link()
        except BaseLink.DoesNotExist:
            self.url = ''
        if commit:
            self.save()
        return self.url

    def is_published(self):
        try:
            return self.baselink.is_published()
        except BaseLink.DoesNotExist:
            return True

    def _get_section(self):
        try:
            return getattr(self, 'main_menu_section')
        except BaseSection.DoesNotExist:
            pass

        if self.parent is not None:
            return self.parent.get_section()

    get_section = memoize(_get_section,
                          _menu_sections_cache,
                          1,
                          convert_args_func=_convert_cache_args)

    def get_breadcrumbs(self):
        """ Menu breadcrumbs (not included itself) """
        bc = []
        for parent in self.get_ancestors()[1:]:
            url = parent.get_absolute_url()
            bc.append((url, unicode(parent)))

        section = self.get_section()
        if section:
            bc.insert(0, (section.get_absolute_url(), unicode(section)))
        return bc

    def get_ancestors_by_user(self, user=None):
        from merengue.perms.utils import can_manage_site
        ancestors = self.get_ancestors().filter(
            status='public')  # uses mptt function
        if user and not can_manage_site(user):
            if not user.is_anonymous():
                roles = Role.objects.filter(principalrolerelation__user=user)
            else:
                roles = Role.objects.filter(slug='anonymous_user')
            ancestors = ancestors.filter(
                Q(visible_by_roles__isnull=True)
                | Q(visible_by_roles__in=roles))
        return ancestors

    def get_descendants_by_user(self, user=None):
        from merengue.perms.utils import can_manage_site
        descendants = self.get_descendants().filter(
            status='public')  # uses mptt function
        if user and not can_manage_site(user):
            if not user.is_anonymous():
                roles = Role.objects.filter(principalrolerelation__user=user)
            else:
                roles = Role.objects.filter(slug='anonymous_user')
            descendants = descendants.filter(
                Q(visible_by_roles__isnull=True)
                | Q(visible_by_roles__in=roles)).distinct()
        return descendants

    def can_edit(self, user):
        section = self.get_section()
        if section:
            return section.can_edit(user)
        else:
            return perms_api.can_manage_site(user)
Ejemplo n.º 2
0
    Gets content related blocks excluding the ones overwritten by blocks within the same content
    """
    from merengue.block.models import RegisteredBlock
    return RegisteredBlock.objects.actives().placed_in(place).with_content(
        content).exclude_overrided()


def _get_all_blocks_to_display(place=None, content=None, section=None):
    """
    Three block groups are fetched separately in increasing priority:
        - site blocks (no content)
        - section related blocks
        - content related blocks
    """
    all_blocks = get_blocks_to_display(place, content)
    if section:
        section_blocks = get_blocks_to_display(
            place, section).exclude_overrided(content)
        all_blocks = all_blocks | section_blocks
    sorted(all_blocks, key=lambda b: b.order)
    return all_blocks


get_all_blocks_to_display = memoize(_get_all_blocks_to_display,
                                    _blocks_lookup_cache, 3)


def clear_lookup_cache():
    global _blocks_lookup_cache
    _blocks_lookup_cache.clear()
Ejemplo n.º 3
0
        get_owners = getattr(obj, 'get_owners', None)
        get_participants = getattr(obj, 'get_participants', None)
        if get_owners and callable(get_owners) and user in obj.get_owners():
            role_ids.append(Role.objects.get(slug=OWNER_ROLE_SLUG).id)

        if get_participants and callable(get_participants) and user in obj.get_participants():
            role_ids.append(Role.objects.get(slug=PARTICIPANT_ROLE_SLUG).id)

        try:
            obj = obj.get_parent_for_permissions()
        except AttributeError:
            obj = None

    return Role.objects.filter(pk__in=role_ids)
get_roles = memoize(_get_roles, _roles_cache, 2)


def get_global_roles(principal):
    """Returns global roles of passed principal (user or group).
    """
    if isinstance(principal, AnonymousUser):
        return Role.objects.filter(slug=ANONYMOUS_ROLE_SLUG)
    if isinstance(principal, User):
        return [prr.role for prr in PrincipalRoleRelation.objects.filter(
            user=principal, content__isnull=True)]
    else:
        return [prr.role for prr in PrincipalRoleRelation.objects.filter(
            group=principal, content__isnull=True)]

Ejemplo n.º 4
0
def get_blocks_to_display(place=None, content=None):
    """
    Gets content related blocks excluding the ones overwritten by blocks within the same content
    """
    from merengue.block.models import RegisteredBlock

    return RegisteredBlock.objects.actives().placed_in(place).with_content(content).exclude_overrided()


def _get_all_blocks_to_display(place=None, content=None, section=None):
    """
    Three block groups are fetched separately in increasing priority:
        - site blocks (no content)
        - section related blocks
        - content related blocks
    """
    all_blocks = get_blocks_to_display(place, content)
    if section:
        section_blocks = get_blocks_to_display(place, section).exclude_overrided(content)
        all_blocks = all_blocks | section_blocks
    sorted(all_blocks, key=lambda b: b.order)
    return all_blocks


get_all_blocks_to_display = memoize(_get_all_blocks_to_display, _blocks_lookup_cache, 3)


def clear_lookup_cache():
    global _blocks_lookup_cache
    _blocks_lookup_cache.clear()
Ejemplo n.º 5
0
class RegisteredItemQuerySet(QuerySet):
    def all(self):
        return self.filter(broken=False)

    def actives(self, ordered=False):
        """ Retrieves active items for site """
        if not ordered:
            return self.filter(active=True)
        else:
            return self.filter(active=True).order_by('order')

    def inactives(self, ordered=False):
        """ Retrieves inactive items for site """
        if not ordered:
            return self.exclude(active=True)
        else:
            return self.exclude(active=True).order_by('order')

    def with_brokens(self):
        return self.filter()

    def get_items(self):
        """ Returns registrable items (not registered items) """
        for item in self.filter():
            yield item.get_registry_item()

    def get_item(self):
        """ Returns the registrable item (not registered items) """
        return self.get().get_registry_item()

    def get_by_item(self, item):
        """ obtain registered item passing by param a RegistrableItem """
        return self.get(id=item.reg_item.id)

    def _by_item_class_func(self, item_class):
        return self.all().filter(
            module=item_class.get_module(),
            class_name=item_class.get_class_name()).order_by('-active')

    _by_item_class = memoize(_by_item_class_func,
                             _registry_lookup_cache,
                             2,
                             offset=1,
                             convert_args_func=_convert_cache_args,
                             update_cache_if_empty=False)

    def get_by_item_class(self, item_class):
        """ obtain registered items passing by param a RegistrableItem class """
        try:
            return self._by_item_class(item_class)[0]
        except IndexError:
            raise self.model.DoesNotExist()

    def by_item_class(self, item_class):
        """ obtain registered items passing by param a RegistrableItem class """
        return FakeRegisteredItemQuerySet(self._by_item_class(item_class))

    def by_name(self, name):
        """ obtains registered items passing a full dotted name to RegistrableItem class """
        bits = name.split('.')
        module = '.'.join(bits[:-1])
        class_name = bits[-1]
        return self.filter(
            module=module,
            class_name=class_name,
        )
Ejemplo n.º 6
0
        if get_owners and callable(get_owners) and user in obj.get_owners():
            role_ids.append(Role.objects.get(slug=OWNER_ROLE_SLUG).id)

        if get_participants and callable(
                get_participants) and user in obj.get_participants():
            role_ids.append(Role.objects.get(slug=PARTICIPANT_ROLE_SLUG).id)

        try:
            obj = obj.get_parent_for_permissions()
        except AttributeError:
            obj = None

    return Role.objects.filter(pk__in=role_ids)


get_roles = memoize(_get_roles, _roles_cache, 2)


def get_global_roles(principal):
    """Returns global roles of passed principal (user or group).
    """
    if isinstance(principal, AnonymousUser):
        return Role.objects.filter(slug=ANONYMOUS_ROLE_SLUG)
    if isinstance(principal, User):
        return [
            prr.role for prr in PrincipalRoleRelation.objects.filter(
                user=principal, content__isnull=True)
        ]
    else:
        return [
            prr.role for prr in PrincipalRoleRelation.objects.filter(