[views/secondary] Add HTML table aggregated view (closes #3316011).
authorVladimir Popescu <vladimir.popescu@logilab.fr>
Mon, 25 Nov 2013 13:23:53 +0000
changeset 500 12633f30d0bc
parent 499 257f29128208
child 501 fe6d699ca8e8
[views/secondary] Add HTML table aggregated view (closes #3316011).
views/secondary.py
--- a/views/secondary.py	Mon Nov 25 13:52:58 2013 +0000
+++ b/views/secondary.py	Mon Nov 25 13:23:53 2013 +0000
@@ -15,6 +15,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with this program. If not, see <http://www.gnu.org/licenses/>.
+from collections import defaultdict
 from logilab.mtconverter import xml_escape
 
 from cubicweb.predicates import is_instance
@@ -71,7 +72,59 @@
             self.wview('list', rset=rset)
 
 
+###############################################################################
+### AGGREGATED VIEW ###########################################################
+###############################################################################
+class BrainomicsAggregatedView(EntityView):
+    __regid__ = 'aggregated-view'
+
+    def call(self, rset=None):
+        rset = rset or self.cw_rset
+        row_types = list(set(row[0] for row in rset.description))
+        if len(row_types) > 1 or not row_types:
+            raise RQLException('Wrong result set query: %s' % rset.rql)
+        row_type = row_types[0]
+        table = defaultdict(dict)
+        for row in rset:
+            table.setdefault(row[0], {})
+            table[row[0]].update({row[1]: row[2]})
+        return self._html_table_from_data(table, row_type)
+
+    def _html_table_from_data(self, table_data, row_type):
+        """Build html table out of a Python dictionary with eids and values.
+
+           `table_data` is a dictionary with one key for each table row.
+           The value of each such key is a dictionary, with one key for each column.
+           The value of such a key is the value one wishes to put in the table cell.
+
+           `row_type` is a string holding the yams entity type of the entities
+           which occupy the first cell on each row.
+        """
+        # header first
+        self.w(u'<table><tr><th>%s</th>' % xml_escape(self._cw._(row_type)))
+        # Empty td first to leave room for first column
+        header_content = ''.join(u'<th><a href="%s">%s</a></th>'
+                                 % (ent.absolute_url(), ent.dc_title())
+                                 for ent in map(self._cw.entity_from_eid,
+                                                set(kcol for krow in table_data
+                                                    for kcol in table_data[krow])))
+        self.w(header_content)
+        self.w(u'</tr>')
+        # now the rows
+        for row in table_data:
+            self.w(u'<tr>')
+            # first row element:
+            row_ent = self._cw.entity_from_eid(row)
+            self.w(u'<td align="center"><a href="%s">%s</td>'
+                   % (row_ent.absolute_url(), row_ent.dc_title()))
+            row_content = ''.join(u'<td align="center">%s</td>'
+                                  % table_data[row][col]
+                                  for col in table_data[row])
+            self.w(row_content)
+            self.w(u'</tr>')
+        self.w(u'</table>')
+
+
 def registration_callback(vreg):
     vreg.register_all(globals().values(), __name__, (BrainomicsListView,))
     vreg.register_and_replace(BrainomicsListView, ListView)
-