abilian.web.tags.criterion — Abilian 0.1 documentation

# Source code for abilian.web.tags.criterion

    # coding=utf-8
    """
    """
    from __future__ import absolute_import

    import sqlalchemy as sa

    from abilian.i18n import _
    from abilian.core.models.tag import Tag, entity_tag_tbl
    from .extension import ENTITY_DEFAULT_NS_ATTR
    from ..search.criterion import BaseCriterion

    class TagCriterion(BaseCriterion):
      """
      Filter entities with selected tag(s).
      """
      form_default_value = u''

      def __init__(self, *args, **kwargs):
        if len(args) == 0:
          kwargs.setdefault('name', 'tags')

        if len(args) < 2:
          kwargs.setdefault('label', _(u'Tags'))

        super(TagCriterion, self).__init__(*args, **kwargs)

      @BaseCriterion.model.setter
      def model(self, model):
        BaseCriterion.model.fset(self, model)
        self.ns = getattr(model, ENTITY_DEFAULT_NS_ATTR)

      @property
      def valid_tags(self):
        join_clause = entity_tag_tbl.join(
          self.model,
          self.model.id == entity_tag_tbl.c.entity_id,
        )
        model_tags = sa.sql.select([entity_tag_tbl.c.tag_id], from_obj=join_clause)
        return Tag.query.filter(Tag.ns == self.ns,
                                Tag.id.in_(model_tags))\
                        .all()

      def get_request_values(self, request):
        tag_ids = []

        for val in request.values.getlist(self.name):
          try:
            tag_ids.append(int(val))
          except ValueError:
            pass

        valid_tags = set(self.valid_tags)
        tags = []
        for tid in tag_ids:
          t = Tag.query.get(tid)
          if t in valid_tags:
            tags.append(t)

        return tags

      def filter(self, query, module, request, searched_text, *args, **kwargs):
        """
        """
        tags = self.get_request_values(request)
        if not tags:
          return query

        cond = sa.sql.exists(
          sa.sql.select([1], entity_tag_tbl.c.entity_id == self.model.id)
        )
        return query.filter(cond)

      @property
      def form_filter_type(self):
        return "select"

      @property
      def form_unset_value(self):
        return []

      @property
      def form_filter_args(self):
        # expected value: [list of selectable items, is multiple?]
        return [
          [(unicode(t.id), t.label) for t in self.valid_tags],
          True,
        ]