pvl/verkko/table.py
author Tero Marttila <terom@paivola.fi>
Wed, 11 Sep 2013 14:06:16 +0300
changeset 251 d250f200dd7e
parent 242 088d68412650
permissions -rw-r--r--
fix process_generate for ZoneRecord.build
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
from pvl.web import html
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
from pvl.verkko import web, db
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
     4
import math
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
     5
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
import logging; log = logging.getLogger('pvl.verkko.table')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
class Column (object) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
        web.Table column spec, representing a property of an SQLAlchemy ORM model class.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
    def __init__ (self, attr, title, column, rowhtml=None, sort=True, filter=True, colcss=True, rowfilter=False, rowtitle=None, rowcss=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
            attr        - name of column value, used for http query arg, html css class, model getattr()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
            title       - title of column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
            column      - the model column property, used to build queries
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
            rowhtml     - function returning column value as HTML for model
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
            sort        - allow sorting by column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
            filter      - allow filtering by column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
            colcss      - apply css class for column; True -> attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
            rowfilter   - allow filtering by row value
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
            rowtitle    - function returning column title for model
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
            rowcss      - function returning column class for model
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
        if colcss is True :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
            colcss = attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
        self.attr = attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
        self.title = title
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
        self.column = column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
        # column attrs
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
        self.sort = sort
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
        self.filter = filter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
        self.colcss = colcss
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
        # row attrs
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
        self.rowhtml = rowhtml
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
        self.rowfilter = rowfilter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
        self.rowtitle = rowtitle
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
        self.rowcss = rowcss
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
    def render_header (self, sorturl) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
            Render <th> for <thead> in given Table.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
        header = self.title
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
        if self.sort :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
            header = html.a(href=sorturl)(header)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
        return html.th(header)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
    def render_filter_input (self, filters) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
            Render filter <input> in given Table.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
        value = filters.get(self.attr)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        if value :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            # XXX: multi-valued filters?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
            value = value[0]
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
            value = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
        return html.input(type='text', name=self.attr, value=value)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
    def render_header_filter (self, filters) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
            Render <td><input> for <thead> in given Table.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
        if self.filter :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
            input = self.render_filter_input(filters)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
        else  :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
            input = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        return html.td(class_=self.colcss)(input)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    84
    def cell_value (self, item) :
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    85
        """
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    86
            Return value for cell.
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    87
        """
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    88
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    89
        # XXX: this is sometimes broken, figure out how to index by column
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    90
        return getattr(item, self.attr)
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    91
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
    92
    def cell_html (self, item, value) :
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    93
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    94
            Render contents for <td>.
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    95
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    96
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    97
        if self.rowhtml :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    98
            return self.rowhtml(item)
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
    99
        else :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   100
            return value
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   101
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   102
    def cell_css (self, item, value=None, hilight=None) :
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   103
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   104
            Return CSS classes for <td>.
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   105
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   106
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   107
        if self.colcss :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   108
            yield self.colcss
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   109
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   110
        if self.rowcss :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   111
            yield self.rowcss(item)
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   112
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   113
        if hilight :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   114
            # lookup attr/value
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   115
            hilight = self.attr in hilight and value in hilight[self.attr]
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   116
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   117
        if hilight :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   118
            yield 'hilight'
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   119
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   120
    def cell_title (self, item, value=None) :
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   121
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   122
            Return title= for <td>
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   123
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   124
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   125
        if self.rowtitle :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   126
            return self.rowtitle(item)
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   127
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   128
    def render_cell (self, item, table, filters=None, hilight=None) :
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
            Render <td> for item in <tbody> in given Table.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
                hilight     - optionally higlight given { attr: value }'s using CSS.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   135
        value = self.cell_value(item)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   137
        if self.rowfilter and filters is not None :
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
            # filter-link by row-value
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
            filters = { self.attr: value }
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
            filters = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   143
        yield table.render_cell(self.cell_html(item, value),
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   144
                css         = tuple(self.cell_css(item, value, hilight=hilight)),
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
                filters     = filters,
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   146
                title       = self.cell_title(item),
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
        )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
class Table (object) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
        Render <table> with Columns from SQLAlchemy ORM model class.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   152
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
    COLUMNS = ()
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   155
    ITEMS = None
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
    
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
    # attr -> column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
    ATTRS = dict((col.attr, col) for col in COLUMNS)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
 
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
    # items per page
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
    PAGE = 10
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
    
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
    def __init__ (self, url, columns=None, table_url=None, item_url=None, caption=None, page=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
                url         - pvl.web.Handler.url()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
                table_url   - ListHandler, or self?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
                item_url    - ItemHandler, or self#id
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
                columns     - sequence of Columns
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
                caption     - optional <caption>
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
                page        - items per page
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
        self.url = url
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        self.columns = columns or self.COLUMNS
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
        self.table_url = table_url
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
        self.item_url = item_url
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
        self.caption = caption
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
        self.page = page or self.PAGE
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
    def tableurl (self, filters=None, **opts) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
            URL for table with given opts, keeping our sorting/filtering unless overriden.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   187
        args = dict()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   188
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   189
        # apply
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   190
        if filters :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   191
            args.update(filters)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   192
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   193
        if opts :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   194
            args.update(opts)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   195
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   196
        return self.url(self.table_url, **args)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
    def sorturl (self, attr, sort=None, **opts) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
            URL for table sorted by given column, reversing direction if already sorting by given column.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   202
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
        if not sort :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
            sort = attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
        elif sort.lstrip('+-') != attr :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
            sort = attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
        elif sort.startswith('-') :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
            sort = "+" + attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
            sort = "-" + attr
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
        return self.tableurl(sort=sort, **opts)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
    def itemurl (self, item) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
            URL for given item, by id.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
        if self.item_url :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
            # separate page
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
            return self.url(self.item_url, id=item.id)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
            # to our table
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
            return '#{id}'.format(id=item.id)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
    def render_head (self, filters=None, sort=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
            Yield header columns in table header.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
        # id
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
        yield html.th('#')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
        for column in self.columns :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
            yield column.render_header(sorturl=self.sorturl(column.attr, sort=sort, filters=filters))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
    def render_head_filters (self, filters=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
            Yield filter columns in table header.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
        # id
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
        yield html.td(html.input(type='submit', value=u'\u00BF'))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
        for column in self.columns :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
            yield column.render_header_filter(filters)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   248
    def render_cell (self, rowhtml, css=(), filters=None, title=None) :
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
            Render a single cell.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
                htmlvalue   - rendered value
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
                css         - css classes to apply
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
                filters     - render filter link for filter-values?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
                title       - mouseover title for cell
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   257
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   258
        if filters :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   259
            cell = html.a(href=self.tableurl(**filters))(rowhtml)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   261
            cell = rowhtml
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
        css = ' '.join(cls for cls in css if cls)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
        
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   265
        return html.td(class_=css, title=title)(cell)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
   
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
    def render_row (self, item, **opts) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
            Yield columns for row.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   270
        """
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   271
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   272
        yield html.th(
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   273
            html.a(href=self.itemurl(item))("#")
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   274
        ),
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   275
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
        for column in self.columns :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
            yield column.render_cell(item, self, **opts)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   278
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   279
    def render_body (self, rows, **opts) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   280
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   281
            Yield body rows.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   282
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   283
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   284
        for i, item in enumerate(rows) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   285
            yield html.tr(class_=('alternate' if i % 2 else None), id=item.id)(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
                self.render_row(item, **opts)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
            )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   289
    def render_pagination (self, page, count=None, **opts) :
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
            Render pagination links.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
        if count is not None :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   295
            pages = int(math.ceil(count / self.page))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   296
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   297
            pages = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   298
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   299
        if page > 0 :
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   300
            yield html.a(href=self.tableurl(page=0, **opts))(html("&laquo;&laquo; First"))
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   301
            yield html.a(href=self.tableurl(page=(page - 1), **opts))(html("&laquo; Prev"))
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   302
        
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   303
        if pages :
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   304
            yield html.span("Page {page} of {pages}".format(page=(page + 1), pages=pages))
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   305
        else :
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   306
            yield html.span("Page {page}".format(page=(page + 1)))
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   307
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   308
        yield html.a(href=self.tableurl(page=(page + 1), **opts))(html("&raquo; Next"))
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   309
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   310
    def render_foot (self, query, page, **opts) :
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   311
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   312
            Render pagination/host count in footer.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   313
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   314
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   315
        # XXX: does separate SELECT count()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   316
        count = query.count()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   317
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   318
        if page is None :
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   319
            return "{count} {items}".format(count=count, items=self.ITEMS)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   320
        else :
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   321
            # XXX: count is just the count we got..
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   322
            return self.render_pagination(page, count=None, **opts)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   323
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   324
    def render (self, query, filters=None, sort=None, page=None, hilight=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   325
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   326
            Return <table> element. Wrapped in <form> if filters.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   327
                query   - filter()'d sort()'d SELECT query()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   328
                filters - None for no filtering ui, dict of filters otherwise.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   329
                sort    - None for no sorting ui, sort-attr otherwise.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   330
                page    - display pagination for given page
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   331
                hilight - { attr: value } cells to hilight
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   332
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   333
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   334
        # render table
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   335
        table = html.table(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   336
            html.caption(self.caption) if self.caption else None,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   337
            html.thead(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   338
                html.tr(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   339
                    self.render_head(filters=filters, sort=sort)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   340
                ),
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   341
                (
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   342
                    html.tr(class_='filter')(self.render_head_filters(filters=filters))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   343
                ) if filters is not None else None,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   344
            ),
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   345
            html.tbody(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   346
                self.render_body(query,
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   347
                    filters = filters,
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   348
                    hilight = hilight,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   349
                )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   350
            ),
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   351
            html.tfoot(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   352
                html.tr(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   353
                    html.td(colspan=(1 + len(self.columns)))(
183
8fbaaf0564dc pvl.verkko.tables: fixfix
Tero Marttila <terom@paivola.fi>
parents: 180
diff changeset
   354
                        self.render_foot(query, page, filters=filters, sort=sort)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   355
                    )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   356
                )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   357
            )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   358
        )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   359
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   360
        # filters form?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   361
        if filters is None :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   362
            return table
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   363
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   364
            return html.form(method='get', action=self.tableurl())(
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   365
                html.input(type='hidden', name='sort', value=sort),
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   366
                table,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   367
            )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   368
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   369
    def json (self, item) :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   370
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   371
            Yield JSON params for given item.
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   372
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   373
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   374
        yield 'id', item.id
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   375
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   376
        for column in self.columns :
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   377
            value = column.cell_value(item)
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   378
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   379
            yield column.attr, dict(
206
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   380
                    html    = unicode(html(column.cell_html(item, value))),
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   381
                    css     = tuple(column.cell_css(item, value)),
079bf632442d pvl.verkko.table: fix Column.cell_* also requiring value
Tero Marttila <terom@paivola.fi>
parents: 204
diff changeset
   382
                    title   = column.cell_title(item, value),
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   383
            )
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   384
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   385
class TableHandler (object) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   386
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   387
        Mixin for handling Table args/rendering.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   388
    """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   389
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   390
    CSS = (
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   391
        "/static/dhcp/table.css", 
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   392
    )
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   393
    
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   394
    TABLE = None
242
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   395
    DB_TABLE = None
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   396
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   397
    # target Handlers for table links
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   398
    TABLE_URL = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   399
    TABLE_ITEM_URL = None
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   400
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   401
    def init (self) :
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   402
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   403
            Bind self.table
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   404
        """
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   405
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   406
        super(TableHandler, self).init()
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   407
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   408
        self.table = self.TABLE(self.url,
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   409
                table_url   = self.TABLE_URL,
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   410
                item_url    = self.TABLE_ITEM_URL,
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   411
        )
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   412
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   413
    def query (self) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   414
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   415
            Database SELECT query.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   416
        """
242
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   417
        
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   418
        if self.DB_CLASS is None :
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   419
            raise NotImplementedError()
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   420
242
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   421
        return self.db.query(self.DB_CLASS)
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   422
    
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   423
    def sort (self, query) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   424
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   425
            Apply ?sort= from requset args to query.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   426
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   427
            Return { attr: sort }, query
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   428
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   429
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   430
        sort = self.request.args.get('sort')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   431
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   432
        if sort :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   433
            name = sort.lstrip('+-')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   434
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   435
            name = None
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   436
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   437
        if name :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   438
            order_by = self.TABLE.ATTRS[name].column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   439
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   440
            order_by = self.TABLE.SORT # default
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   441
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   442
        # prefix -> ordering
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   443
        if not sort :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   444
            pass
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   445
        elif sort.startswith('+') :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   446
            order_by = order_by.asc()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   447
        elif sort.startswith('-') :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   448
            order_by = order_by.desc()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   449
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   450
            pass
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   451
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   452
        # apply
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   453
        log.debug("sort: %s", order_by)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   454
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   455
        query = query.order_by(order_by)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   456
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   457
        return sort, query
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   458
    
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   459
    def filter_attr (self, attr, value) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   460
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   461
            Return filter expression for given attr == value
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   462
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   463
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   464
        # preprocess
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   465
        like = False
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   466
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   467
        if value.endswith('*') :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   468
            like = value.replace('*', '%')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   469
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   470
        # filter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   471
        column = self.TABLE.ATTRS[attr].column
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   472
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   473
        if like :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   474
            return (column.like(like))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   475
        else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   476
            return (column == value)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   477
 
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   478
    def _filter (self, attr, values) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   479
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   480
            Apply filters for given attr -> (value, expression)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   481
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   482
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   483
        for value in values :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   484
            value = value.strip()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   485
            
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   486
            # ignore empty fields
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   487
            if not value :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   488
                continue
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   489
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   490
            # lookup attr-specific filter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   491
            filter = getattr(self, 'filter_{attr}'.format(attr=attr), None)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   492
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   493
            if filter :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   494
                filter = filter(value)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   495
            else :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   496
                # use generic
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   497
                filter = self.filter_attr(attr, value)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   498
            
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   499
            log.debug("%s: %s: %s", attr, value, filter)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   500
            
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   501
            yield value, filter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   502
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   503
    def filter (self, query) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   504
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   505
            Apply filters from request.args against given hosts.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   506
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   507
            Returns (filters, hosts).
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   508
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   509
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   510
        # filter?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   511
        filters = {}
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   512
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   513
        for attr in self.TABLE.ATTRS :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   514
            # from request args
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   515
            values = self.request.args.getlist(attr)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   516
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   517
            # lookup attr filters as expressions
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   518
            value_filters = list(self._filter(attr, values))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   519
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   520
            # ignore empty fields
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   521
            if not value_filters :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   522
                continue
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   523
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   524
            # filtering values, and filter expressions
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   525
            values, expressions = zip(*value_filters)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   526
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   527
            # apply
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   528
            query = query.filter(db.or_(*expressions))
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   529
            filters[attr] = values
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   530
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   531
        return filters, query
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   532
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   533
    def filters_title (self) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   534
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   535
            Return a string representing the applied filters.
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   536
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   537
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   538
        return ', '.join(value for values in self.filters.itervalues() for value in values)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   539
242
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   540
    def title (self) :
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   541
        if self.filters :
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   542
            return "{title}: {filters}".format(title=self.TABLE.ITEMS, filters=self.filters_title())
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   543
        else :
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   544
            return self.TABLE.ITEMS
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   545
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   546
    def process (self) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   547
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   548
            Process request args -> self.filters, self.sorts, self.page, self.query
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   549
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   550
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   551
        query = self.query()
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   552
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   553
        # filter
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   554
        self.filters, query = self.filter(query)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   555
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   556
        # sort
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   557
        # TODO: sort per filter column by default?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   558
        self.sorts, query = self.sort(query)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   559
        
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   560
        # page?
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   561
        self.page = self.request.args.get('page')
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   562
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   563
        if self.page :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   564
            self.page = int(self.page)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   565
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   566
            query = query.offset(self.page * self.TABLE.PAGE).limit(self.TABLE.PAGE)
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   567
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   568
        self.query = query
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   569
 
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   570
    def render_table (self, query, filters=None, sort=None, page=None, hilight=None) :
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   571
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   572
            Render table
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   573
                query       - SELECT query for rows
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   574
                filters     - applied filters
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   575
                sort        - applied sort
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   576
                page        - applied page
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   577
                hilight     - hilight given { attr: value } cells
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   578
        """
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   579
204
72304d66ecd1 pvl.verkko.table: implement Table.json(item)
Tero Marttila <terom@paivola.fi>
parents: 183
diff changeset
   580
        return self.table.render(query,
180
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   581
                filters = filters,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   582
                sort    = sort,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   583
                page    = page,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   584
                hilight = hilight,
e6bca452ce72 pvl.verkko: split table from hosts
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   585
        )
242
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   586
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   587
    def render (self) :
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   588
        return (
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   589
            self.render_table(self.query, filters=self.filters, sort=self.sorts, page=self.page),
088d68412650 pvl.verkko.table: better default handlers
Tero Marttila <terom@paivola.fi>
parents: 206
diff changeset
   590
        )