web/facet.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 01 Oct 2010 16:53:35 +0200
changeset 6380 63d5dbaef999
parent 6336 ae80aed607f2
child 6582 8eb7883b4223
permissions -rw-r--r--
[facets] support for `no_relation` on RelationFacet e.g. to filter en entities *without* a given relation as well as with a particular relation. Proposed or not by default according to relation cardinality. Also, try to guess i18nable properly from the schema by default.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    18
"""
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    19
The :mod:`cubicweb.web.facet` module contains a set of abstract classes to use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    20
as bases to build your own facets
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    21
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    22
All facet classes inherits from the :class:`AbstractFacet` class, though you'll
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    23
usually find some more handy class that do what you want.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    24
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    25
Let's see available classes.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    26
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    27
Classes you'll want to use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    28
--------------------------
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    29
.. autoclass:: cubicweb.web.facet.RelationFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    30
.. autoclass:: cubicweb.web.facet.RelationAttributeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    31
.. autoclass:: cubicweb.web.facet.HasRelationFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    32
.. autoclass:: cubicweb.web.facet.AttributeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    33
.. autoclass:: cubicweb.web.facet.RangeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    34
.. autoclass:: cubicweb.web.facet.DateRangeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    35
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    36
Classes for facets implementor
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    37
------------------------------
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    38
Unless you didn't find the class that does the job you want above, you may want
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    39
to skip those classes...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    40
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    41
.. autoclass:: cubicweb.web.facet.AbstractFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    42
.. autoclass:: cubicweb.web.facet.VocabularyFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    43
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    44
.. comment: XXX widgets
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5618
diff changeset
    45
"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
from copy import deepcopy
2152
Florent <florent@secondweb.fr>
parents: 2149
diff changeset
    50
from datetime import date, datetime, timedelta
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
    52
from logilab.mtconverter import xml_escape
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
from logilab.common.graph import has_path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
from logilab.common.decorators import cached
4719
aaed3f813ef8 kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4701
diff changeset
    55
from logilab.common.date import datetime2ticks
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
from logilab.common.compat import all
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
    58
from rql import parse, nodes, utils
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
from cubicweb import Unauthorized, typed_eid
2305
8f6dbe884700 import display_name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2152
diff changeset
    61
from cubicweb.schema import display_name
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4333
diff changeset
    62
from cubicweb.utils import make_uid
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 782
diff changeset
    63
from cubicweb.selectors import match_context_prop, partial_relation_possible
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    64
from cubicweb.appobject import AppObject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
from cubicweb.web.htmlwidgets import HTMLWidget
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    67
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    68
def rtype_facet_title(facet):
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    69
    ptypes = facet.cw_rset.column_types(0)
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    70
    if len(ptypes) == 1:
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    71
        return display_name(facet._cw, facet.rtype, form=facet.role,
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    72
                            context=iter(ptypes).next())
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    73
    return display_name(facet._cw, facet.rtype, form=facet.role)
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    74
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
## rqlst manipulation functions used by facets ################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
def prepare_facets_rqlst(rqlst, args=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    """prepare a syntax tree to generate facet filters
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
    79
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
    * remove ORDERBY clause
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    * cleanup selection (remove everything)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    * undefine unnecessary variables
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
    * set DISTINCT
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    * unset LIMIT/OFFSET
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    if len(rqlst.children) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        raise NotImplementedError('FIXME: union not yet supported')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
    select = rqlst.children[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    mainvar = filtered_variable(select)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
    select.set_limit(None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    select.set_offset(None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    baserql = select.as_string(kwargs=args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    # cleanup sort terms
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    select.remove_sort_terms()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
    # selection: only vocabulary entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
    for term in select.selection[:]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        select.remove_selected(term)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    # remove unbound variables which only have some type restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    for dvar in select.defined_vars.values():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        if not (dvar is mainvar or dvar.stinfo['relations']):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
            select.undefine_variable(dvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    # global tree config: DISTINCT, LIMIT, OFFSET
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    select.set_distinct(True)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
    return mainvar, baserql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
def filtered_variable(rqlst):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    vref = rqlst.selection[0].iget_nodes(nodes.VariableRef).next()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    return vref.variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
def get_facet(req, facetid, rqlst, mainvar):
4333
7add8a73a168 [vreg] object_by_id should not have been deprecated. Fix facets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   112
    return req.vreg['facets'].object_by_id(facetid, req, rqlst=rqlst,
7add8a73a168 [vreg] object_by_id should not have been deprecated. Fix facets.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   113
                                           filtered_variable=mainvar)
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   114
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
def filter_hiddens(w, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
    for key, val in kwargs.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
        w(u'<input type="hidden" name="%s" value="%s" />' % (
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
   119
            key, xml_escape(val)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
def _may_be_removed(rel, schema, mainvar):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
    """if the given relation may be removed from the tree, return the variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
    on the other side of `mainvar`, else return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
    Conditions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
    * the relation is an attribute selection of the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    * the relation is optional relation linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
    * the relation is a mandatory relation linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
      without any restriction on the other variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    lhs, rhs = rel.get_variable_parts()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
    rschema = schema.rschema(rel.r_type)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
    if lhs.variable is mainvar:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
            ovar = rhs.variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
        except AttributeError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
            # constant restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
            # XXX: X title LOWER(T) if it makes sense?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
            return None
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3333
diff changeset
   140
        if rschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
            if len(ovar.stinfo['relations']) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
                # attribute selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
                return ovar
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
            return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
        opt = 'right'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        cardidx = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
    elif getattr(rhs, 'variable', None) is mainvar:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        ovar = lhs.variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        opt = 'left'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        cardidx = 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        # not directly linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
    if rel.optional in (opt, 'both'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
        # optional relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        return ovar
4073
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3720
diff changeset
   157
    if all(rdef.cardinality[cardidx] in '1+'
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3720
diff changeset
   158
           for rdef in rschema.rdefs.values()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        # mandatory relation without any restriction on the other variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        for orel in ovar.stinfo['relations']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
            if rel is orel:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
            if _may_be_removed(orel, schema, ovar) is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
                return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        return ovar
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
    return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   168
def _make_relation(rqlst, mainvar, rtype, role):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   169
    newvar = rqlst.make_variable()
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   170
    if role == 'object':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   171
        rel = nodes.make_relation(newvar, rtype, (mainvar,), nodes.VariableRef)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   172
    else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   173
        rel = nodes.make_relation(mainvar, rtype, (newvar,), nodes.VariableRef)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   174
    return newvar, rel
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   175
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
def _add_rtype_relation(rqlst, mainvar, rtype, role):
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   177
    """add a relation relying `mainvar` to entities linked by the `rtype`
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   178
    relation (where `mainvar` has `role`)
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   179
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   180
    return the inserted variable for linked entities.
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   181
    """
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   182
    newvar, newrel = _make_relation(rqlst, mainvar, rtype, role)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   183
    rqlst.add_restriction(newrel)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   184
    return newvar, newrel
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   185
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   186
def _add_eid_restr(rel, restrvar, value):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   187
    rrel = nodes.make_constant_restriction(restrvar, 'eid', value, 'Int')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   188
    rel.parent.replace(rel, nodes.And(rel, rrel))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   190
def _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role,
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   191
                              select_target_entity=True):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
    """prepare a syntax tree to generate a filter vocabulary rql using the given
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    relation:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
    * create a variable to filter on this relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    * add the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
    * add the new variable to GROUPBY clause if necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
    * add the new variable to the selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
    """
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   199
    newvar = _add_rtype_relation(rqlst, mainvar, rtype, role)[0]
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   200
    if select_target_entity:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   201
        if rqlst.groupby:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   202
            rqlst.add_group_var(newvar)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   203
        rqlst.add_selected(newvar)
5618
24cc5d495fdf [facet] we must add type restriction for attribute facets as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5526
diff changeset
   204
    # add is restriction if necessary
24cc5d495fdf [facet] we must add type restriction for attribute facets as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5526
diff changeset
   205
    if mainvar.stinfo['typerel'] is None:
24cc5d495fdf [facet] we must add type restriction for attribute facets as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5526
diff changeset
   206
        etypes = frozenset(sol[mainvar.name] for sol in rqlst.solutions)
24cc5d495fdf [facet] we must add type restriction for attribute facets as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5526
diff changeset
   207
        rqlst.add_type_restriction(mainvar, etypes)
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   208
    return newvar
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   209
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
def _remove_relation(rqlst, rel, var):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
    """remove a constraint relation from the syntax tree"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    # remove the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
    rqlst.remove_node(rel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
    # remove relations where the filtered variable appears on the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
    # lhs and rhs is a constant restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
    extra = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
    for vrel in var.stinfo['relations']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
        if vrel is rel:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        if vrel.children[0].variable is var:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
            if not vrel.children[1].get_nodes(nodes.Constant):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
                extra.append(vrel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
            rqlst.remove_node(vrel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
    return extra
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
def _set_orderby(rqlst, newvar, sortasc, sortfuncname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
    if sortfuncname is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        rqlst.add_sort_var(newvar, sortasc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
        vref = nodes.variable_ref(newvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        vref.register_reference()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        sortfunc = nodes.Function(sortfuncname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        sortfunc.append(vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        term = nodes.SortTerm(sortfunc, sortasc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
        rqlst.add_sort_term(term)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
def insert_attr_select_relation(rqlst, mainvar, rtype, role, attrname,
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   238
                                sortfuncname=None, sortasc=True,
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   239
                                select_target_entity=True):
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   240
    """modify a syntax tree to :
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   241
    * link a new variable to `mainvar` through `rtype` (where mainvar has `role`)
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   242
    * retrieve only the newly inserted variable and its `attrname`
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   243
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   244
    Sorting:
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   245
    * on `attrname` ascendant (`sortasc`=True) or descendant (`sortasc`=False)
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   246
    * on `sortfuncname`(`attrname`) if `sortfuncname` is specified
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   247
    * no sort if `sortasc` is None
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   248
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
    _cleanup_rqlst(rqlst, mainvar)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   250
    var = _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role,
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   251
                                    select_target_entity)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
    attrvar = rqlst.make_variable()
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   253
    rqlst.add_relation(var, attrname, attrvar)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
    # if query is grouped, we have to add the attribute variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
    if rqlst.groupby:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
        if not attrvar in rqlst.groupby:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
            rqlst.add_group_var(attrvar)
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   258
    if sortasc is not None:
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   259
        _set_orderby(rqlst, attrvar, sortasc, sortfuncname)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    # add attribute variable to selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
    rqlst.add_selected(attrvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
    return var
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
def _cleanup_rqlst(rqlst, mainvar):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    """cleanup tree from unnecessary restriction:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
    * attribute selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
    * optional relations linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
    * mandatory relations linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
    if rqlst.where is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
    schema = rqlst.root.schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
    toremove = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
    vargraph = deepcopy(rqlst.vargraph) # graph representing links between variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
    for rel in rqlst.where.get_nodes(nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        ovar = _may_be_removed(rel, schema, mainvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        if ovar is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
            toremove.add(ovar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
    removed = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
    while toremove:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        trvar = toremove.pop()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
        trvarname = trvar.name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
        # remove paths using this variable from the graph
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
        linkedvars = vargraph.pop(trvarname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        for ovarname in linkedvars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
            vargraph[ovarname].remove(trvarname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
        # remove relation using this variable
5004
4cc020ee70e2 le patch rql26 a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   288
        for rel in trvar.stinfo['relations']:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
            if rel in removed:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
                # already removed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
            rqlst.remove_node(rel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
            removed.add(rel)
5004
4cc020ee70e2 le patch rql26 a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   294
        rel = trvar.stinfo['typerel']
4cc020ee70e2 le patch rql26 a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   295
        if rel is not None and not rel in removed:
4cc020ee70e2 le patch rql26 a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   296
            rqlst.remove_node(rel)
4cc020ee70e2 le patch rql26 a été importé
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   297
            removed.add(rel)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
        # cleanup groupby clause
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
        if rqlst.groupby:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
            for vref in rqlst.groupby[:]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
                if vref.name == trvarname:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
                    rqlst.remove_group_var(vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
        # we can also remove all variables which are linked to this variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
        # and have no path to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
        for ovarname in linkedvars:
408
a8814ff6824e reactivate tests and fix bug triggering removal of undesired relation (eg type restriction) in some cases
sylvain.thenault@logilab.fr
parents: 407
diff changeset
   306
            if ovarname == mainvar.name:
a8814ff6824e reactivate tests and fix bug triggering removal of undesired relation (eg type restriction) in some cases
sylvain.thenault@logilab.fr
parents: 407
diff changeset
   307
                continue
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
            if not has_path(vargraph, ovarname, mainvar.name):
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   309
                toremove.add(rqlst.defined_vars[ovarname])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   311
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   312
## base facet classes ##########################################################
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   313
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   314
class AbstractFacet(AppObject):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   315
    """Abstract base class for all facets. Facets are stored in their own
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   316
    'facets' registry. They are similar to contextual components since the use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   317
    the following configurable properties:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   318
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   319
    * `visible`, boolean flag telling if a facet should be displayed or not
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   320
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   321
    * `order`, integer to control facets display order
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   322
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   323
    * `context`, telling if a facet should be displayed in the table form filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   324
      (context = 'tablefilter') or in the facet box (context = 'facetbox') or in
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   325
      both (context = '')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   326
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   327
    The following methods define the facet API:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   328
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   329
    .. automethod:: cubicweb.web.facet.AbstractFacet.get_widget
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   330
    .. automethod:: cubicweb.web.facet.AbstractFacet.add_rql_restrictions
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   331
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   332
    Facets will have the following attributes set (beside the standard
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   333
    :class:`~cubicweb.appobject.AppObject` ones):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   334
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   335
    * `rqlst`, the rql syntax tree being facetted
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   336
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   337
    * `filtered_variable`, the variable node in this rql syntax tree that we're
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   338
      interested in filtering
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   339
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   340
    Facets implementors may also be interested in the following properties /
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   341
    methods:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   342
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   343
    .. automethod:: cubicweb.web.facet.AbstractFacet.operator
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   344
    .. automethod:: cubicweb.web.facet.AbstractFacet.rqlexec
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   345
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
    __abstract__ = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
    __registry__ = 'facets'
2799
b703639614e7 refactor property handling to avoid name conflicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
   348
    cw_property_defs = {
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
        _('visible'): dict(type='Boolean', default=True,
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   350
                           help=_('display the facet or not')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
        _('order'):   dict(type='Int', default=99,
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   352
                           help=_('display order of the facet')),
496
e25a3c2f5393 set default to empty string, not None
sylvain.thenault@logilab.fr
parents: 467
diff changeset
   353
        _('context'): dict(type='String', default='',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
                           # None <-> both
446
3a3ab6bbccc5 use empty string instead of None as possible context value to avoid getting an <optgroup> tag in associated widget
sylvain.thenault@logilab.fr
parents: 408
diff changeset
   355
                           vocabulary=(_('tablefilter'), _('facetbox'), ''),
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   356
                           help=_('context where this facet should be displayed, '
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   357
                                  'leave empty for both')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
        }
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    visible = True
446
3a3ab6bbccc5 use empty string instead of None as possible context value to avoid getting an <optgroup> tag in associated widget
sylvain.thenault@logilab.fr
parents: 408
diff changeset
   360
    context = ''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
    needs_update = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
    start_unfolded = True
4701
3acd198a66c9 [facet] before 3.6 we were sure to have a cw_rset attribute. Restore this for facets
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4615
diff changeset
   363
    cw_rset = None # ensure facets have a cw_rset attribute
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   364
4614
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   365
    def __init__(self, req, rqlst=None, filtered_variable=None,
2658
5535857eeaa5 [appobject selection process] drop the need for the .selected method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
   366
                 **kwargs):
4614
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   367
        super(AbstractFacet, self).__init__(req, **kwargs)
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   368
        assert rqlst is not None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        assert filtered_variable
4614
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   370
        # take care: facet may be retreived using `object_by_id` from an ajax call
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   371
        # or from `select` using the result set to filter
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   372
        self.rqlst = rqlst
2658
5535857eeaa5 [appobject selection process] drop the need for the .selected method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
   373
        self.filtered_variable = filtered_variable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
    def operator(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   377
        """Return the operator (AND or OR) to use for this facet when multiple
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   378
        values are selected.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   379
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        # OR between selected values by default
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   381
        return self._cw.form.get(self.__regid__ + '_andor', 'OR')
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   382
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   383
    def rqlexec(self, rql, args=None):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   384
        """Utility method to execute some rql queries, and simply returning an
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   385
        empty list if :exc:`Unauthorized` is raised.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   386
        """
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   387
        try:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   388
            return self._cw.execute(rql, args)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   389
        except Unauthorized:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   390
            return []
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   391
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
    def get_widget(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   393
        """Return the widget instance to use to display this facet, or None if
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   394
        the facet can't do anything valuable (only one value in the vocabulary
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   395
        for instance).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   398
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
    def add_rql_restrictions(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   400
        """When some facet criteria has been updated, this method is called to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   401
        add restriction for this facet into the rql syntax tree. It should get
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   402
        back its value in form parameters, and modify the syntax tree
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   403
        (`self.rqlst`) accordingly.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   404
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   406
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
class VocabularyFacet(AbstractFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   409
    """This abstract class extend :class:`AbstractFacet` to use the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   410
    :class:`FacetVocabularyWidget` as widget, suitable for facets that may
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   411
    restrict values according to a (usually computed) vocabulary.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   412
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   413
    A class which inherits from VocabularyFacet must define at least these methods:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   414
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   415
    .. automethod:: cubicweb.web.facet.VocabularyFacet.vocabulary
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   416
    .. automethod:: cubicweb.web.facet.VocabularyFacet.possible_values
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   417
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
    needs_update = True
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   419
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
    def get_widget(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   421
        """Return the widget instance to use to display this facet.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   423
        This implementation expects a .vocabulary method on the facet and
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   424
        return a combobox displaying this vocabulary.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        vocab = self.vocabulary()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
        if len(vocab) <= 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   428
            return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
        wdg = FacetVocabularyWidget(self)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   430
        selected = frozenset(typed_eid(eid) for eid in self._cw.list_form_param(self.__regid__))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
        for label, value in vocab:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
            if value is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
                wdg.append(FacetSeparator(label))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
            else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   435
                wdg.append(FacetItem(self._cw, label, value, value in selected))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        return wdg
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   437
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
    def vocabulary(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   439
        """Return vocabulary for this facet, eg a list of 2-uple (label, value).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   442
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
    def possible_values(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   444
        """Return a list of possible values (as string since it's used to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   445
        compare to a form value in javascript) for this facet.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
        raise NotImplementedError
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
    def support_and(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
        return False
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   451
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
class RelationFacet(VocabularyFacet):
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   454
    """Base facet to filter some entities according to other entities to which
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   455
    they are related. Create concret facet by inheriting from this class an then
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   456
    configuring it by setting class attribute described below.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   457
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   458
    The relation is defined by the `rtype` and `role` attributes.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   459
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   460
    The `no_relation` boolean flag tells if a special 'no relation' value should be
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   461
    added (allowing to filter on entities which *do not* have the relation set).
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   462
    Default is computed according the relation's cardinality.
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   463
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   464
    The values displayed for related entities will be:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   465
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   466
    * result of calling their `label_vid` view if specified
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   467
    * else their `target_attr` attribute value if specified
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   468
    * else their eid (you usually want something nicer...)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   469
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   470
    When no `label_vid` is set, you will get translated value if `i18nable` is
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   471
    set. By default, `i18nable` will be set according to the schema, but you can
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   472
    force its value by setting it has a class attribute.
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   473
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   474
    You can filter out target entity types by specifying `target_type`
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   475
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   476
    By default, vocabulary will be displayed sorted on `target_attr` value in an
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   477
    ascending way. You can control sorting with:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   478
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   479
    * `sortfunc`: set this to a stored procedure name if you want to sort on the
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   480
      result of this function's result instead of direct value
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   481
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   482
    * `sortasc`: boolean flag to control ascendant/descendant sorting
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   483
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   484
    To illustrate this facet, let's take for example an *excerpt* of the schema
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   485
    of an office location search application:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   486
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   487
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   488
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   489
      class Office(WorkflowableEntityType):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   490
          price = Int(description='euros / m2 / HC / HT')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   491
          surface = Int(description='m2')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   492
          has_address = SubjectRelation('PostalAddress',
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   493
                                        cardinality='1?',
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   494
                                        composite='subject')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   495
          proposed_by = SubjectRelation('Agency')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   496
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   497
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   498
    We can simply define a facet to filter offices according to the agency
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   499
    proposing it:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   500
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   501
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   502
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   503
      class AgencyFacet(RelationFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   504
          __regid__ = 'agency'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   505
          # this facet should only be selected when visualizing offices
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   506
          __select__ = RelationFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   507
          # this facet is a filter on the 'Agency' entities linked to the office
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   508
          # through the 'proposed_by' relation, where the office is the subject
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   509
          # of the relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   510
          rtype = 'has_address'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   511
          # 'subject' is the default but setting it explicitly doesn't hurt...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   512
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   513
          # we want to display the agency's name
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   514
          target_attr = 'name'
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   515
    """
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 782
diff changeset
   516
    __select__ = partial_relation_possible() & match_context_prop()
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   517
    # class attributes to configure the relation facet
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
    rtype = None
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   519
    role = 'subject'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
    target_attr = 'eid'
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   521
    target_type = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
    # set this to a stored procedure name if you want to sort on the result of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
    # this function's result instead of direct value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
    sortfunc = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
    # ascendant/descendant sorting
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
    sortasc = True
3328
76888cd23d83 facets enhancement: can now set label_vid to use a view instead of a simple attribute as label
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   527
    # if you want to call a view on the entity instead of using `target_attr`
76888cd23d83 facets enhancement: can now set label_vid to use a view instead of a simple attribute as label
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   528
    label_vid = None
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   529
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   530
    # internal purpose
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   531
    _select_target_entity = True
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   532
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
   533
    title = property(rtype_facet_title)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   534
    no_relation_label = '<no relation>'
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   535
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   536
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   537
    def i18nable(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   538
        """should label be internationalized"""
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   539
        if self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   540
            eschema = self._cw.vreg.schema.eschema(self.target_type)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   541
        elif self.role == 'subject':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   542
            eschema = self._cw.vreg.schema.rschema(self.rtype).objects()[0]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   543
        else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   544
            eschema = self._cw.vreg.schema.rschema(self.rtype).subjects()[0]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   545
        return eschema.rdef(self.target_attr).internationalizable
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   546
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   547
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   548
    def no_relation(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   549
        return (not self._cw.vreg.schema.rschema(self.rtype).final
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   550
                and self._search_card('?*'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
6251
afc757568492 [facet] add missing @property making subsequent access always true
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6152
diff changeset
   552
    @property
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   553
    def rql_sort(self):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   554
        """return true if we can handle sorting in the rql query. E.g.  if
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   555
        sortfunc is set or if we have not to transform the returned value (eg no
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   556
        label_vid and not i18nable)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   557
        """
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   558
        return self.sortfunc is not None or (self.label_vid is None
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   559
                                             and not self.i18nable)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   560
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
    def vocabulary(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
        """return vocabulary for this facet, eg a list of 2-uple (label, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
        rqlst.save_state()
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   566
        if self.rql_sort:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   567
            sort = self.sortasc
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   568
        else:
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   569
            sort = None # will be sorted on label
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
            mainvar = self.filtered_variable
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   572
            var = insert_attr_select_relation(
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   573
                rqlst, mainvar, self.rtype, self.role, self.target_attr,
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   574
                self.sortfunc, sort, self._select_target_entity)
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   575
            if self.target_type is not None:
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   576
                rqlst.add_type_restriction(var, self.target_type)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   577
            try:
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5016
diff changeset
   578
                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   579
            except:
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   580
                self.exception('error while getting vocabulary for %s, rql: %s',
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   581
                               self, rqlst.as_string())
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   582
                return ()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
        finally:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
            rqlst.recover()
5225
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   585
        # don't call rset_vocabulary on empty result set, it may be an empty
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   586
        # *list* (see rqlexec implementation)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   587
        values = rset and self.rset_vocabulary(rset) or []
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   588
        if self._include_no_relation():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   589
            values.insert(0, (self._cw._(self.no_relation_label), ''))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   590
        return values
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   591
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
    def possible_values(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   593
        """return a list of possible values (as string since it's used to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
        compare to a form value in javascript) for this facet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
        rqlst.save_state()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   598
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   599
            _cleanup_rqlst(rqlst, self.filtered_variable)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   600
            if self._select_target_entity:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   601
                _prepare_vocabulary_rqlst(rqlst, self.filtered_variable, self.rtype,
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   602
                                          self.role, select_target_entity=True)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   603
            else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   604
                insert_attr_select_relation(
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   605
                    rqlst, self.filtered_variable, self.rtype, self.role, self.target_attr,
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   606
                    select_target_entity=False)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   607
            values = [str(x) for x, in self.rqlexec(rqlst.as_string())]
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   608
        except:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   609
            self.exception('while computing values for %s', self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   610
        finally:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   611
            rqlst.recover()
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   612
        if self._include_no_relation():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   613
            values.append('')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   614
        return values
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   615
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   616
    def rset_vocabulary(self, rset):
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   617
        if self.i18nable:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   618
            _ = self._cw._
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   619
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   620
            _ = unicode
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   621
        if self.rql_sort:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   622
            values = [(_(label), eid) for eid, label in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   623
        else:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   624
            if self.label_vid is None:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   625
                values = [(_(label), eid) for eid, label in rset]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   626
            else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   627
                values = [(entity.view(self.label_vid), entity.eid)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   628
                          for entity in rset.entities()]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   629
            values = sorted(values)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   630
            if not self.sortasc:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   631
                values = list(reversed(values))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   632
        return values
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   633
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   634
    def support_and(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   635
        return self._search_card('+*')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   636
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   637
    def add_rql_restrictions(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   638
        """add restriction for this facet into the rql syntax tree"""
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   639
        value = self._cw.form.get(self.__regid__)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   640
        if value is None:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   641
            return
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   642
        mainvar = self.filtered_variable
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   643
        restrvar, rel = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   644
                                            self.role)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   645
        if isinstance(value, basestring):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   646
            # only one value selected
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   647
            if value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   648
                self.rqlst.add_eid_restriction(restrvar, value)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   649
            else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   650
                rel.parent.replace(rel, nodes.Not(rel))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   651
        elif self.operator == 'OR':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   652
            # set_distinct only if rtype cardinality is > 1
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   653
            if self.support_and():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   654
                self.rqlst.set_distinct(True)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   655
            # multiple ORed values: using IN is fine
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   656
            if '' in value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   657
                value.remove('')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   658
                self._add_not_rel_restr(rel)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   659
            _add_eid_restr(rel, restrvar, value)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   660
        else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   661
            # multiple values with AND operator
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   662
            if '' in value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   663
                value.remove('')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   664
                self._add_not_rel_restr(rel)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   665
            _add_eid_restr(rel, restrvar, value.pop())
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   666
            while value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   667
                restrvar, rtrel = _make_relation(self.rqlst, mainvar,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   668
                                                 self.rtype, self.role)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   669
                _add_eid_restr(rel, restrvar, value.pop())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   670
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   671
    @cached
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   672
    def _search_card(self, cards):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   673
        for rdef in self._iter_rdefs():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   674
            if rdef.role_cardinality(self.role) in cards:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   675
                return True
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   676
        return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   677
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   678
    def _iter_rdefs(self):
3456
1a63a252601f [facets] typo fix
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   679
        rschema = self._cw.vreg.schema.rschema(self.rtype)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   680
        # XXX when called via ajax, no rset to compute possible types
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   681
        possibletypes = self.cw_rset and self.cw_rset.column_types(0)
4087
2b8bc4cfd6ee api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4074
diff changeset
   682
        for rdef in rschema.rdefs.itervalues():
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   683
            if possibletypes is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   684
                if self.role == 'subject':
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   685
                    if rdef.subject not in possibletypes:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   686
                        continue
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   687
                elif rdef.object not in possibletypes:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   688
                    continue
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   689
            if self.target_type is not None:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   690
                if self.role == 'subject':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   691
                    if rdef.object != self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   692
                        continue
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   693
                elif rdef.subject != self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   694
                    continue
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   695
            yield rdef
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   696
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   697
    def _include_no_relation(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   698
        if not self.no_relation:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   699
            return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   700
        if self._cw.vreg.schema.rschema(self.rtype).final:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   701
            return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   702
        if self.role == 'object':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   703
            subj = utils.rqlvar_maker(defined=self.rqlst.defined_vars,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   704
                                      aliases=self.rqlst.aliases).next()
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   705
            obj = self.filtered_variable.name
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   706
        else:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   707
            subj = self.filtered_variable.name
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   708
            obj = utils.rqlvar_maker(defined=self.rqlst.defined_vars,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   709
                                     aliases=self.rqlst.aliases).next()
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   710
        rql = 'Any %s LIMIT 1 WHERE NOT %s %s %s, %s' % (
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   711
            self.filtered_variable.name, subj, self.rtype, obj,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   712
            self.rqlst.where.as_string())
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   713
        return bool(self.rqlexec(rql, self.cw_rset and self.cw_rset.args))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   714
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   715
    def _add_not_rel_restr(self, rel):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   716
        nrrel = nodes.Not(_make_relation(self.rqlst, self.filtered_variable,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   717
                                         self.rtype, self.role)[1])
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   718
        rel.parent.replace(rel, nodes.Or(nrrel, rel))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   719
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   720
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   721
class RelationAttributeFacet(RelationFacet):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   722
    """Base facet to filter some entities according to an attribute of other
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   723
    entities to which they are related. Most things work similarly as
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   724
    :class:`RelationFacet`, except that:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   725
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   726
    * `label_vid` doesn't make sense here
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   727
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   728
    * you should specify the attribute type using `attrtype` if it's not a
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   729
      String
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   730
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   731
    * you can specify a comparison operator using `comparator`
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   732
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   733
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   734
    Back to our example... if you want to search office by postal code and that
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   735
    you use a :class:`RelationFacet` for that, you won't get the expected
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   736
    behaviour: if two offices have the same postal code, they've however two
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   737
    different addresses.  So you'll see in the facet the same postal code twice,
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   738
    though linked to a different address entity. There is a great chance your
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   739
    users won't understand that...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   740
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   741
    That's where this class come in ! It's used to said that you want to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   742
    according to the *attribute value* of a relatied entity, not to the entity
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   743
    itself. Now here is the source code for the facet:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   744
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   745
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   746
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   747
      class PostalCodeFacet(RelationAttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   748
          __regid__ = 'postalcode'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   749
          # this facet should only be selected when visualizing offices
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   750
          __select__ = RelationAttributeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   751
          # this facet is a filter on the PostalAddress entities linked to the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   752
          # office through the 'has_address' relation, where the office is the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   753
          # subject of the relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   754
          rtype = 'has_address'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   755
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   756
          # we want to search according to address 'postal_code' attribute
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   757
          target_attr = 'postalcode'
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   758
    """
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   759
    _select_target_entity = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
    # attribute type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
    attrtype = 'String'
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   762
    # type of comparison: default is an exact match on the attribute value
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   763
    comparator = '=' # could be '<', '<=', '>', '>='
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   764
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   765
    def rset_vocabulary(self, rset):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   766
        if self.i18nable:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   767
            _ = self._cw._
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   768
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   769
            _ = unicode
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   770
        if self.rql_sort:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   771
            return [(_(value), value) for value, in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   772
        values = [(_(value), value) for value, in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   773
        if self.sortasc:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   774
            return sorted(values)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   775
        return reversed(sorted(values))
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   776
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   777
    def add_rql_restrictions(self):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   778
        """add restriction for this facet into the rql syntax tree"""
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   779
        value = self._cw.form.get(self.__regid__)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   780
        if not value:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   781
            return
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   782
        mainvar = self.filtered_variable
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   783
        restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   784
                                       self.role)[0]
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   785
        self.rqlst.set_distinct(True)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   786
        if isinstance(value, basestring) or self.operator == 'OR':
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   787
            # only one value selected or multiple ORed values: using IN is fine
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   788
            self.rqlst.add_constant_restriction(
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   789
                restrvar, self.target_attr, value,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   790
                self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   791
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   792
            # multiple values with AND operator
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   793
            self.rqlst.add_constant_restriction(
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   794
                restrvar, self.target_attr, value.pop(),
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   795
                self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   796
            while value:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   797
                restrvar = _add_rtype_relation(self.rqlst, mainvar, self.rtype,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   798
                                               self.role)[0]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   799
                self.rqlst.add_constant_restriction(
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   800
                    restrvar, self.target_attr, value.pop(),
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   801
                    self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   802
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   803
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   804
class AttributeFacet(RelationAttributeFacet):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   805
    """Base facet to filter some entities according one of their attribute.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   806
    Configuration is mostly similarly as :class:`RelationAttributeFacet`, except that:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   807
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   808
    * `target_attr` doesn't make sense here (you specify the attribute using `rtype`
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   809
    * `role` neither, it's systematically 'subject'
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   810
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   811
    So, suppose that in our office search example you want to refine search according
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   812
    to the office's surface. Here is a code snippet achieving this:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   813
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   814
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   815
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   816
      class SurfaceFacet(AttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   817
          __regid__ = 'surface'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   818
          __select__ = AttributeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   819
          # this facet is a filter on the office'surface
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   820
          rtype = 'surface'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   821
          # override the default value of operator since we want to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   822
          # according to a minimal value, not an exact one
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   823
          comparator = '>='
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   824
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   825
          def vocabulary(self):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   826
              '''override the default vocabulary method since we want to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   827
              hard-code our threshold values.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   828
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   829
              Not overriding would generate a filter containing all existing
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   830
              surfaces defined in the database.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   831
              '''
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   832
              return [('> 200', '200'), ('> 250', '250'),
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   833
                      ('> 275', '275'), ('> 300', '300')]
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   834
    """
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   835
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   836
    _select_target_entity = True
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   837
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   838
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   839
    def i18nable(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   840
        """should label be internationalized"""
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   841
        for rdef in self._iter_rdefs():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   842
            # no 'internationalizable' property for rdef whose object is not a
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   843
            # String
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   844
            if not getattr(rdef, 'internationalizable', False):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   845
                return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   846
        return True
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   847
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   848
    def vocabulary(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   849
        """return vocabulary for this facet, eg a list of 2-uple (label, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   850
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   851
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   852
        rqlst.save_state()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   853
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   854
            mainvar = self.filtered_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   855
            _cleanup_rqlst(rqlst, mainvar)
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   856
            newvar = _prepare_vocabulary_rqlst(rqlst, mainvar, self.rtype, self.role)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   857
            _set_orderby(rqlst, newvar, self.sortasc, self.sortfunc)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   858
            try:
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5016
diff changeset
   859
                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   860
            except:
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   861
                self.exception('error while getting vocabulary for %s, rql: %s',
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   862
                               self, rqlst.as_string())
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   863
                return ()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   864
        finally:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   865
            rqlst.recover()
5225
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   866
        # don't call rset_vocabulary on empty result set, it may be an empty
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   867
        # *list* (see rqlexec implementation)
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   868
        return rset and self.rset_vocabulary(rset)
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   869
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   870
    def support_and(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   871
        return False
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   872
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   873
    def add_rql_restrictions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   874
        """add restriction for this facet into the rql syntax tree"""
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   875
        value = self._cw.form.get(self.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   876
        if not value:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   877
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   878
        mainvar = self.filtered_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   879
        self.rqlst.add_constant_restriction(mainvar, self.rtype, value,
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   880
                                            self.attrtype, self.comparator)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   881
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   882
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   883
class RangeFacet(AttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   884
    """This class allows to filter entities according to an attribute of
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   885
    numerical type.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   886
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   887
    It displays a slider using `jquery`_ to choose a lower bound and an upper
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   888
    bound.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   889
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   890
    The example below provides an alternative to the surface facet seen earlier,
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   891
    in a more powerful way since
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   892
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   893
    * lower/upper boundaries are computed according to entities to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   894
    * user can specify lower/upper boundaries, not only the lower one
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   895
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   896
    .. sourcecode:: python
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   897
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   898
      class SurfaceFacet(RangeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   899
          __regid__ = 'surface'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   900
          __select__ = RangeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   901
          # this facet is a filter on the office'surface
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   902
          rtype = 'surface'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   903
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   904
    All this with even less code!
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   905
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   906
    The image below display the rendering of the slider:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   907
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   908
    .. image:: ../images/facet_range.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   909
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   910
    .. _jquery: http://www.jqueryui.com/
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   911
    """
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   912
    attrtype = 'Float' # only numerical types are supported
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   913
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   914
    @property
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   915
    def wdgclass(self):
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   916
        return FacetRangeWidget
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   917
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   918
    def get_widget(self):
4546
f8ac61376b2b provides a fallback_on_none_attribute field attribute, allowing to specify default value for attributes of *existing* entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   919
        """return the widget instance to use to display this facet"""
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   920
        values = set(value for _, value in self.vocabulary() if value is not None)
4615
d69d7ccbe046 Fix: RangeFacet is selected (valid rset) but without any values
Charles Hébert <charles.hebert@logilab.fr>
parents: 4614
diff changeset
   921
        # Rset with entities (the facet is selected) but without values
d69d7ccbe046 Fix: RangeFacet is selected (valid rset) but without any values
Charles Hébert <charles.hebert@logilab.fr>
parents: 4614
diff changeset
   922
        if len(values) == 0:
d69d7ccbe046 Fix: RangeFacet is selected (valid rset) but without any values
Charles Hébert <charles.hebert@logilab.fr>
parents: 4614
diff changeset
   923
            return None
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   924
        return self.wdgclass(self, min(values), max(values))
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   925
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   926
    def infvalue(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   927
        return self._cw.form.get('%s_inf' % self.__regid__)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   928
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   929
    def supvalue(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   930
        return self._cw.form.get('%s_sup' % self.__regid__)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   931
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   932
    def formatvalue(self, value):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
   933
        """format `value` before in order to insert it in the RQL query"""
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   934
        return unicode(value)
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   935
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   936
    def add_rql_restrictions(self):
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   937
        infvalue = self.infvalue()
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   938
        if infvalue is None: # nothing sent
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   939
            return
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   940
        supvalue = self.supvalue()
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   941
        self.rqlst.add_constant_restriction(self.filtered_variable,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   942
                                            self.rtype,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   943
                                            self.formatvalue(infvalue),
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   944
                                            self.attrtype, '>=')
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   945
        self.rqlst.add_constant_restriction(self.filtered_variable,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   946
                                            self.rtype,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   947
                                            self.formatvalue(supvalue),
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   948
                                            self.attrtype, '<=')
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   949
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   950
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   951
class DateRangeFacet(RangeFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   952
    """This class works similarly as the :class:`RangeFacet` but for attribute
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   953
    of date type.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   954
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   955
    The image below display the rendering of the slider for a date range:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   956
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   957
    .. image:: ../images/facet_date_range.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   958
    """
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   959
    attrtype = 'Date' # only date types are supported
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   960
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   961
    @property
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   962
    def wdgclass(self):
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   963
        return DateFacetRangeWidget
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   964
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   965
    def formatvalue(self, value):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
   966
        """format `value` before in order to insert it in the RQL query"""
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   967
        return '"%s"' % date.fromtimestamp(float(value) / 1000).strftime('%Y/%m/%d')
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   968
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
   969
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   970
class HasRelationFacet(AbstractFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   971
    """This class simply filter according to the presence of a relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   972
    (whatever the entity at the other end). It display a simple checkbox that
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   973
    lets you refine your selection in order to get only entities that actually
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   974
    have this relation. You simply have to define which relation using the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   975
    `rtype` and `role` attributes.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   976
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   977
    Here is an example of the rendering of thos facet to filter book with image
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   978
    and the corresponding code:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   979
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   980
    .. image:: ../images/facet_has_image.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   981
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   982
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   983
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   984
      class HasImageFacet(HasRelationFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   985
          __regid__ = 'hasimage'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   986
          __select__ = HasRelationFacet.__select__ & is_instance('Book')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   987
          rtype = 'has_image'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   988
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   989
    """
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   990
    rtype = None # override me in subclass
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   991
    role = 'subject' # role of filtered entity in the relation
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   992
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
   993
    title = property(rtype_facet_title)
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   994
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   995
    def support_and(self):
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   996
        return False
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   997
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
   998
    def get_widget(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   999
        return CheckBoxFacetWidget(self._cw, self,
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1000
                                   '%s:%s' % (self.rtype, self),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1001
                                   self._cw.form.get(self.__regid__))
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1002
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1003
    def add_rql_restrictions(self):
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1004
        """add restriction for this facet into the rql syntax tree"""
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1005
        self.rqlst.set_distinct(True) # XXX
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1006
        value = self._cw.form.get(self.__regid__)
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1007
        if not value: # no value sent for this facet
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1008
            return
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1009
        var = self.rqlst.make_variable()
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1010
        if self.role == 'subject':
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1011
            self.rqlst.add_relation(self.filtered_variable, self.rtype, var)
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1012
        else:
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1013
            self.rqlst.add_relation(var, self.rtype, self.filtered_variable)
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1014
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1015
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1016
## html widets ################################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1017
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1018
class FacetVocabularyWidget(HTMLWidget):
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1019
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1020
    def __init__(self, facet):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1021
        self.facet = facet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1022
        self.items = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1023
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1024
    def append(self, item):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1025
        self.items.append(item)
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1026
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1027
    def _render(self):
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1028
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1029
        facetid = xml_escape(self.facet.__regid__)
949
1fba39d6ee70 fix in facets (avoid to have an horizontal space between facets when facets are unfold)
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 536
diff changeset
  1030
        self.w(u'<div id="%s" class="facet">\n' % facetid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1031
        self.w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1032
               (xml_escape(facetid), title))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1033
        if self.facet.support_and():
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1034
            _ = self.facet._cw._
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1035
            self.w(u'''<select name="%s" class="radio facetOperator" title="%s">
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1036
  <option value="OR">%s</option>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1037
  <option value="AND">%s</option>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1038
</select>''' % (facetid + '_andor', _('and/or between different values'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1039
                _('OR'), _('AND')))
368
84a5106840fa facet widgets css cleanup
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 346
diff changeset
  1040
        cssclass = ''
84a5106840fa facet widgets css cleanup
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 346
diff changeset
  1041
        if not self.facet.start_unfolded:
84a5106840fa facet widgets css cleanup
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 346
diff changeset
  1042
            cssclass += ' hidden'
949
1fba39d6ee70 fix in facets (avoid to have an horizontal space between facets when facets are unfold)
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 536
diff changeset
  1043
        if len(self.items) > 6:
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 985
diff changeset
  1044
            cssclass += ' overflowed'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1045
        self.w(u'<div class="facetBody%s">\n' % cssclass)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1046
        for item in self.items:
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1933
diff changeset
  1047
            item.render(w=self.w)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1048
        self.w(u'</div>\n')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1049
        self.w(u'</div>\n')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1050
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1051
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1052
class FacetStringWidget(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1053
    def __init__(self, facet):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1054
        self.facet = facet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1055
        self.value = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1056
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1057
    def _render(self):
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1058
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1059
        facetid = xml_escape(self.facet.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1060
        self.w(u'<div id="%s" class="facet">\n' % facetid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1061
        self.w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1062
               (facetid, title))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1063
        self.w(u'<input name="%s" type="text" value="%s" />\n' % (facetid, self.value or u''))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1064
        self.w(u'</div>\n')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1065
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1066
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1067
class FacetRangeWidget(HTMLWidget):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1068
    formatter = 'function (value) {return value;}'
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1069
    onload = u'''
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1070
    var _formatter = %(formatter)s;
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1071
    jQuery("#%(sliderid)s").slider({
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1072
        range: true,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1073
        min: %(minvalue)s,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1074
        max: %(maxvalue)s,
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1075
        values: [%(minvalue)s, %(maxvalue)s],
1933
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1076
        stop: function(event, ui) { // submit when the user stops sliding
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1077
           var form = $('#%(sliderid)s').closest('form');
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1078
           buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs')));
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1079
        },
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1080
        slide: function(event, ui) {
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1081
            jQuery('#%(sliderid)s_inf').html(_formatter(ui.values[0]));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1082
            jQuery('#%(sliderid)s_sup').html(_formatter(ui.values[1]));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1083
            jQuery('input[name=%(facetid)s_inf]').val(ui.values[0]);
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1084
            jQuery('input[name=%(facetid)s_sup]').val(ui.values[1]);
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1085
        }
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1086
   });
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1087
   // use JS formatter to format value on page load
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1088
   jQuery('#%(sliderid)s_inf').html(_formatter(jQuery('input[name=%(facetid)s_inf]').val()));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1089
   jQuery('#%(sliderid)s_sup').html(_formatter(jQuery('input[name=%(facetid)s_sup]').val()));
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1090
'''
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1091
    #'# make emacs happier
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1092
    def __init__(self, facet, minvalue, maxvalue):
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1093
        self.facet = facet
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1094
        self.minvalue = minvalue
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1095
        self.maxvalue = maxvalue
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1096
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1097
    def _render(self):
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1098
        facet = self.facet
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1099
        facet._cw.add_js('ui.slider.js')
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1100
        facet._cw.add_css('ui.all.css')
3333
c61a526b530e [widgets] change make_uid() seed to make slider ids xhtml-valid
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3329
diff changeset
  1101
        sliderid = make_uid('theslider')
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1102
        facetid = xml_escape(self.facet.__regid__)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1103
        facet._cw.html_headers.add_onload(self.onload % {
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1104
            'sliderid': sliderid,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1105
            'facetid': facetid,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1106
            'minvalue': self.minvalue,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1107
            'maxvalue': self.maxvalue,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1108
            'formatter': self.formatter,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1109
            })
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1110
        title = xml_escape(self.facet.title)
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1111
        self.w(u'<div id="%s" class="facet">\n' % facetid)
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1112
        self.w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1113
               (facetid, title))
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1114
        self.w(u'<span id="%s_inf"></span> - <span id="%s_sup"></span>'
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1115
               % (sliderid, sliderid))
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1116
        self.w(u'<input type="hidden" name="%s_inf" value="%s" />'
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1117
               % (facetid, self.minvalue))
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1118
        self.w(u'<input type="hidden" name="%s_sup" value="%s" />'
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1119
               % (facetid, self.maxvalue))
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1120
        self.w(u'<div id="%s"></div>' % sliderid)
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1121
        self.w(u'</div>\n')
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1122
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1123
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1124
class DateFacetRangeWidget(FacetRangeWidget):
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1125
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1126
    formatter = 'function (value) {return (new Date(parseFloat(value))).strftime(DATE_FMT);}'
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1127
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1128
    def round_max_value(self, d):
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1129
        'round to upper value to avoid filtering out the max value'
2152
Florent <florent@secondweb.fr>
parents: 2149
diff changeset
  1130
        return datetime(d.year, d.month, d.day) + timedelta(days=1)
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1131
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1132
    def __init__(self, facet, minvalue, maxvalue):
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1133
        maxvalue = self.round_max_value(maxvalue)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1134
        super(DateFacetRangeWidget, self).__init__(facet,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1135
                                                   datetime2ticks(minvalue),
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1136
                                                   datetime2ticks(maxvalue))
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1137
        fmt = facet._cw.property_value('ui.date-format')
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1138
        facet._cw.html_headers.define_var('DATE_FMT', fmt)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1139
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1140
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1141
class FacetItem(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1142
203
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1143
    selected_img = "black-check.png"
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1144
    unselected_img = "no-check-no-border.png"
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1145
203
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1146
    def __init__(self, req, label, value, selected=False):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1147
        self._cw = req
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1148
        self.label = label
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1149
        self.value = value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1150
        self.selected = selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1151
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1152
    def _render(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1153
        if self.selected:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1154
            cssclass = ' facetValueSelected'
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1155
            imgsrc = self._cw.datadir_url + self.selected_img
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1156
            imgalt = self._cw._('selected')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1157
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1158
            cssclass = ''
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1159
            imgsrc = self._cw.datadir_url + self.unselected_img
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1160
            imgalt = self._cw._('not selected')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1161
        self.w(u'<div class="facetValue facetCheckBox%s" cubicweb:value="%s">\n'
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1162
               % (cssclass, xml_escape(unicode(self.value))))
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2658
diff changeset
  1163
        self.w(u'<img src="%s" alt="%s"/>&#160;' % (imgsrc, imgalt))
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1164
        self.w(u'<a href="javascript: {}">%s</a>' % xml_escape(self.label))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1165
        self.w(u'</div>')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1166
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1167
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1168
class CheckBoxFacetWidget(HTMLWidget):
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1169
    selected_img = "black-check.png"
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1170
    unselected_img = "black-uncheck.png"
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1171
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1172
    def __init__(self, req, facet, value, selected):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1173
        self._cw = req
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1174
        self.facet = facet
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1175
        self.value = value
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1176
        self.selected = selected
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1177
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1178
    def _render(self):
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1179
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1180
        facetid = xml_escape(self.facet.__regid__)
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1181
        self.w(u'<div id="%s" class="facet">\n' % facetid)
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1182
        if self.selected:
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1183
            cssclass = ' facetValueSelected'
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1184
            imgsrc = self._cw.datadir_url + self.selected_img
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1185
            imgalt = self._cw._('selected')
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1186
        else:
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1187
            cssclass = ''
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1188
            imgsrc = self._cw.datadir_url + self.unselected_img
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1189
            imgalt = self._cw._('not selected')
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1190
        self.w(u'<div class="facetValue facetCheckBox%s" cubicweb:value="%s">\n'
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1191
               % (cssclass, xml_escape(unicode(self.value))))
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1192
        self.w(u'<div class="facetCheckBoxWidget">')
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2658
diff changeset
  1193
        self.w(u'<img src="%s" alt="%s" cubicweb:unselimg="true" />&#160;' % (imgsrc, imgalt))
2130
caa5acbecc08 [javascript] provide a simple function to limit textarea size (+minor cosmetic changes)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2020
diff changeset
  1194
        self.w(u'<label class="facetTitle" cubicweb:facetName="%s"><a href="javascript: {}">%s</a></label>' % (facetid, title))
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1195
        self.w(u'</div>\n')
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1196
        self.w(u'</div>\n')
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1197
        self.w(u'</div>\n')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1198
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1199
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1200
class FacetSeparator(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1201
    def __init__(self, label=None):
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2658
diff changeset
  1202
        self.label = label or u'&#160;'
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1203
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1204
    def _render(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1205
        pass
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1206
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1207
# other classes ################################################################
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1208
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1209
class FilterRQLBuilder(object):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1210
    """called by javascript to get a rql string from filter form"""
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1211
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1212
    def __init__(self, req):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1213
        self._cw = req
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1214
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1215
    def build_rql(self):#, tablefilter=False):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1216
        form = self._cw.form
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1217
        facetids = form['facets'].split(',')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1218
        # XXX Union unsupported yet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1219
        select = self._cw.vreg.parse(self._cw, form['baserql']).children[0]
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1220
        mainvar = filtered_variable(select)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1221
        toupdate = []
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1222
        for facetid in facetids:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1223
            facet = get_facet(self._cw, facetid, select, mainvar)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1224
            facet.add_rql_restrictions()
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1225
            if facet.needs_update:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1226
                toupdate.append(facetid)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1227
        return select.as_string(), toupdate