web/views/__init__.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 08 Feb 2010 12:05:56 +0100
changeset 4494 ccb7fce7297b
parent 4252 6c4f109c2b03
child 5421 8167de96c523
permissions -rw-r--r--
AdaptedList -> SameETypeList *NO BW COMPAT*, benefit from cw 3.6 releasing of folder,file and blog which use it to get update at the same time. CMHN and PEGASE will need update (but won't go to 3.6 without update, so seem fine).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
     1
"""Views, forms, actions... for the CubicWeb web client
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
     4
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1719
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
     9
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    10
import os
3122
0e49d2679c5c fix open call to make cw happy /win32
Aurelien Campeas
parents: 2491
diff changeset
    11
import sys
2446
440cb4ea7e5c [refactor] #342855: replace uses of (deprecated) mktemp
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2230
diff changeset
    12
import tempfile
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
from rql import nodes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    15
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
def need_table_view(rset, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
    """return True if we think that a table view is more appropriate than a
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
    list or primary view to display the given result set
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
    rqlst = rset.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
    if len(rqlst.children) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
        # UNION query, use a table
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
    selected = rqlst.children[0].selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
        mainvar = selected[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    except AttributeError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
        # not a variable ref, using table view is probably a good option
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
    if not (isinstance(mainvar, nodes.VariableRef) or
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
            (isinstance(mainvar, nodes.Constant) and mainvar.uid)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    for i, etype in enumerate(rset.description[0][1:]):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
        # etype may be None on outer join
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
        if etype is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
            return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        # check the selected index node is a VariableRef (else we
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
        # won't detect aggregate function
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
        if not isinstance(selected[i+1], nodes.VariableRef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
            return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
        # if this is not a final entity
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3145
diff changeset
    42
        if not schema.eschema(etype).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
            return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
        # if this is a final entity not linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        var = selected[i+1].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        for vref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
            rel = vref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
            if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
            if mainvar.is_equivalent(rel.children[0]):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
                break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
            return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
2193
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    56
# FIXME: VID_BY_MIMETYPE is unfortunately a bit too naive since
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    57
#        some browsers (e.g. FF2) send a bunch of mimetypes in
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    58
#        the Accept header, for instance:
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    59
#          text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    60
#          text/plain;q=0.8,image/png,*/*;q=0.5
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    61
VID_BY_MIMETYPE = {
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    62
    #'text/xml': 'xml',
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    63
    # XXX rss, owl...
667b6340bfd4 [views] comment the naive content-negotiation algorithm, it breaks FF2 navigation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
    64
}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
def vid_from_rset(req, rset, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
    """given a result set, return a view id"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
    if rset is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
        return 'index'
1716
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
    69
    for mimetype in req.parse_accept_header('Accept'):
1719
bf26f32c8a72 wrong variable name
Graziella Toutoungis <graziella.toutoungis@logilab.fr>
parents: 1716
diff changeset
    70
        if mimetype in VID_BY_MIMETYPE:
bf26f32c8a72 wrong variable name
Graziella Toutoungis <graziella.toutoungis@logilab.fr>
parents: 1716
diff changeset
    71
            return VID_BY_MIMETYPE[mimetype]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
    nb_rows = len(rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
    # empty resultset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
    if nb_rows == 0 :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        return 'noresult'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
    # entity result set
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3145
diff changeset
    77
    if not schema.eschema(rset.description[0][0]).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        if need_table_view(rset, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
            return 'table'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        if nb_rows == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
            if req.search_state[0] == 'normal':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
                return 'primary'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
            return 'outofcontext-search'
2491
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2487
diff changeset
    84
        if len(rset.column_types(0)) == 1:
4494
ccb7fce7297b AdaptedList -> SameETypeList
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    85
            return 'sameetypelist'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        return 'list'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    return 'table'
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
    88
1716
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
    89
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
def linksearch_select_url(req, rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    """when searching an entity to create a relation, return an url to select
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    entities in the given rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    req.add_js( ('cubicweb.ajax.js', 'cubicweb.edition.js') )
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    95
    target, eid, r_type, searchedtype = req.search_state[1]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
    if target == 'subject':
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    97
        id_fmt = '%s:%s:%%s' % (eid, r_type)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    else:
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 0
diff changeset
    99
        id_fmt = '%%s:%s:%s' % (r_type, eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    triplets = '-'.join(id_fmt % row[0] for row in rset.rows)
631
99f5852f8604 major selector refactoring (mostly to avoid looking for select parameters on the target class), start accept / interface unification)
sylvain.thenault@logilab.fr
parents: 0
diff changeset
   101
    return "javascript: selectForAssociation('%s', '%s');" % (triplets, eid)
1716
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
   102
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
   103
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   104
class TmpFileViewMixin(object):
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   105
    binary = True
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   106
    content_type = 'application/octet-stream'
1716
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
   107
    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
   108
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   109
    def call(self):
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   110
        self.cell_call()
1716
b12d9e22bac3 basic support for http Accept header (untested)
sylvain.thenault@logilab.fr
parents: 1091
diff changeset
   111
1091
b5e253c0dd13 a bit of reorganisation inside web/views:
sylvain.thenault@logilab.fr
parents: 631
diff changeset
   112
    def cell_call(self, row=0, col=0):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3145
diff changeset
   113
        self.cw_row, self.cw_col = row, col # in case one needs it
3145
9b28545de60d avoid open file handler leak
Aurelien Campeas
parents: 3122
diff changeset
   114
        fd, tmpfile = tempfile.mkstemp('.png')
9b28545de60d avoid open file handler leak
Aurelien Campeas
parents: 3122
diff changeset
   115
        os.close(fd)
9b28545de60d avoid open file handler leak
Aurelien Campeas
parents: 3122
diff changeset
   116
        self._generate(tmpfile)
9b28545de60d avoid open file handler leak
Aurelien Campeas
parents: 3122
diff changeset
   117
        self.w(open(tmpfile, 'rb').read())
9b28545de60d avoid open file handler leak
Aurelien Campeas
parents: 3122
diff changeset
   118
        os.unlink(tmpfile)