comparison render_datatable.py @ 0:d4690e65afcd draft

Uploaded
author bcclaywell
date Thu, 26 Feb 2015 18:16:36 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d4690e65afcd
1 #!/usr/bin/env python
2
3 import csv
4 import itertools
5 import string
6 import sys
7
8 input = sys.stdin
9 start_lines = input.readlines(10)
10 all_input = itertools.chain(iter(start_lines), input)
11
12 def detect_delimiter(iterable, char_set):
13 matches = (c for c in char_set if c in iterable)
14 return next(matches, None)
15
16 def detect_csv_dialect(sample):
17 try:
18 return csv.Sniffer().sniff(sample)
19 except:
20 return None
21
22 delimiter = detect_delimiter(start_lines[0], list('\t, '))
23 reader = None
24
25 if delimiter in list('\t,'):
26 # try to detect csv dialect, which should neatly handle quoted separators and stuff
27 dialect = detect_csv_dialect(''.join(start_lines))
28 if dialect:
29 reader = csv.reader(all_input, dialect)
30
31 if not reader:
32 if delimiter in list(string.whitespace):
33 # use str.split() with no arguments to split on arbitrary whitespace strings
34 reader = (line.strip().split() for line in all_input)
35 else:
36 reader = all_input
37
38 print """\
39 <!DOCTYPE html>
40 <html lang="en">
41 <head>
42 <meta http-equiv="content-type" content="text/html; charset=UTF-8"></meta>
43 <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.no-icons.min.css" rel="stylesheet">
44 <style>
45 div.dataTables_length label {
46 float: left;
47 text-align: left;
48 }
49
50 div.dataTables_length select {
51 width: 75px;
52 }
53
54 div.dataTables_filter label {
55 float: right;
56 }
57
58 div.dataTables_info {
59 padding-top: 8px;
60 }
61
62 div.dataTables_paginate {
63 float: right;
64 margin: 0;
65 }
66
67 table.table {
68 clear: both;
69 margin-bottom: 6px !important;
70 max-width: none !important;
71 }
72
73 table.table thead .sorting,
74 table.table thead .sorting_asc,
75 table.table thead .sorting_desc,
76 table.table thead .sorting_asc_disabled,
77 table.table thead .sorting_desc_disabled {
78 cursor: pointer;
79 *cursor: hand;
80 }
81
82
83 table.table thead .sorting { background: url('images/sort_both.png') no-repeat center right; }
84
85 //table.table thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; }
86 //table.table thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; }
87 table.table thead .sorting_asc { background: url('http://cdn3.iconfinder.com/data/icons/fatcow/16x16_0140/bullet_arrow_up.png') no-repeat center right; }
88 table.table thead .sorting_desc { background: url('http://cdn3.iconfinder.com/data/icons/fatcow/16x16_0140/bullet_arrow_down.png') no-repeat center right; }
89
90 table.table thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; }
91 table.table thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; }
92
93 table.dataTable th:active {
94 outline: none;
95 }
96
97 /* Scrolling */
98 div.dataTables_scrollHead table {
99 margin-bottom: 0 !important;
100 border-bottom-left-radius: 0;
101 border-bottom-right-radius: 0;
102 }
103
104 div.dataTables_scrollHead table thead tr:last-child th:first-child,
105 div.dataTables_scrollHead table thead tr:last-child td:first-child {
106 border-bottom-left-radius: 0 !important;
107 border-bottom-right-radius: 0 !important;
108 }
109
110 div.dataTables_scrollBody table {
111 border-top: none;
112 margin-bottom: 0 !important;
113 }
114
115 div.dataTables_scrollBody tbody tr:first-child th,
116 div.dataTables_scrollBody tbody tr:first-child td {
117 border-top: none;
118 }
119
120 div.dataTables_scrollFoot table {
121 border-top: none;
122 }
123
124
125
126
127 /*
128 * TableTools styles
129 */
130 .table tbody tr.active td,
131 .table tbody tr.active th {
132 background-color: #08C;
133 color: white;
134 }
135
136 .table tbody tr.active:hover td,
137 .table tbody tr.active:hover th {
138 background-color: #0075b0 !important;
139 }
140
141 .table-striped tbody tr.active:nth-child(odd) td,
142 .table-striped tbody tr.active:nth-child(odd) th {
143 background-color: #017ebc;
144 }
145
146 table.DTTT_selectable tbody tr {
147 cursor: pointer;
148 *cursor: hand;
149 }
150
151 div.DTTT .btn {
152 color: #333 !important;
153 font-size: 12px;
154 }
155
156 div.DTTT .btn:hover {
157 text-decoration: none !important;
158 }
159
160
161 ul.DTTT_dropdown.dropdown-menu a {
162 color: #333 !important; /* needed only when demo_page.css is included */
163 }
164
165 ul.DTTT_dropdown.dropdown-menu li:hover a {
166 background-color: #0088cc;
167 color: white !important;
168 }
169
170 /* TableTools information display */
171 div.DTTT_print_info.modal {
172 height: 150px;
173 margin-top: -75px;
174 text-align: center;
175 }
176
177 div.DTTT_print_info h6 {
178 font-weight: normal;
179 font-size: 28px;
180 line-height: 28px;
181 margin: 1em;
182 }
183
184 div.DTTT_print_info p {
185 font-size: 14px;
186 line-height: 20px;
187 }
188
189
190
191 /*
192 * FixedColumns styles
193 */
194 div.DTFC_LeftHeadWrapper table,
195 div.DTFC_LeftFootWrapper table,
196 table.DTFC_Cloned tr.even {
197 background-color: white;
198 }
199
200 div.DTFC_LeftHeadWrapper table {
201 margin-bottom: 0 !important;
202 border-top-right-radius: 0 !important;
203 border-bottom-left-radius: 0 !important;
204 border-bottom-right-radius: 0 !important;
205 }
206
207 div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,
208 div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {
209 border-bottom-left-radius: 0 !important;
210 border-bottom-right-radius: 0 !important;
211 }
212
213 div.DTFC_LeftBodyWrapper table {
214 border-top: none;
215 margin-bottom: 0 !important;
216 }
217
218 div.DTFC_LeftBodyWrapper tbody tr:first-child th,
219 div.DTFC_LeftBodyWrapper tbody tr:first-child td {
220 border-top: none;
221 }
222
223 div.DTFC_LeftFootWrapper table {
224 border-top: none;
225 }
226 </style>
227 <script type="text/javascript" language="javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.0.min.js"></script>
228 <script type="text/javascript" language="javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
229 <script type="text/javascript" charset="utf-8">
230 /* Set the defaults for DataTables initialisation */
231 $.extend( true, $.fn.dataTable.defaults, {
232 "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
233 "sPaginationType": "bootstrap",
234 "oLanguage": {
235 "sLengthMenu": "_MENU_ records per page"
236 }
237 } );
238
239
240 /* Default class modification */
241 $.extend( $.fn.dataTableExt.oStdClasses, {
242 "sWrapper": "dataTables_wrapper form-inline"
243 } );
244
245
246 /* API method to get paging information */
247 $.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
248 {
249 return {
250 "iStart": oSettings._iDisplayStart,
251 "iEnd": oSettings.fnDisplayEnd(),
252 "iLength": oSettings._iDisplayLength,
253 "iTotal": oSettings.fnRecordsTotal(),
254 "iFilteredTotal": oSettings.fnRecordsDisplay(),
255 "iPage": oSettings._iDisplayLength === -1 ?
256 0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
257 "iTotalPages": oSettings._iDisplayLength === -1 ?
258 0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
259 };
260 };
261
262
263 /* Bootstrap style pagination control */
264 $.extend( $.fn.dataTableExt.oPagination, {
265 "bootstrap": {
266 "fnInit": function( oSettings, nPaging, fnDraw ) {
267 var oLang = oSettings.oLanguage.oPaginate;
268 var fnClickHandler = function ( e ) {
269 e.preventDefault();
270 if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
271 fnDraw( oSettings );
272 }
273 };
274
275 $(nPaging).addClass('pagination').append(
276 '<ul>'+
277 '<li class="prev disabled"><a href="#">&larr; '+oLang.sPrevious+'</a></li>'+
278 '<li class="next disabled"><a href="#">'+oLang.sNext+' &rarr; </a></li>'+
279 '</ul>'
280 );
281 var els = $('a', nPaging);
282 $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
283 $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
284 },
285
286 "fnUpdate": function ( oSettings, fnDraw ) {
287 var iListLength = 5;
288 var oPaging = oSettings.oInstance.fnPagingInfo();
289 var an = oSettings.aanFeatures.p;
290 var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
291
292 if ( oPaging.iTotalPages < iListLength) {
293 iStart = 1;
294 iEnd = oPaging.iTotalPages;
295 }
296 else if ( oPaging.iPage <= iHalf ) {
297 iStart = 1;
298 iEnd = iListLength;
299 } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
300 iStart = oPaging.iTotalPages - iListLength + 1;
301 iEnd = oPaging.iTotalPages;
302 } else {
303 iStart = oPaging.iPage - iHalf + 1;
304 iEnd = iStart + iListLength - 1;
305 }
306
307 for ( i=0, ien=an.length ; i<ien ; i++ ) {
308 // Remove the middle elements
309 $('li:gt(0)', an[i]).filter(':not(:last)').remove();
310
311 // Add the new list items and their event handlers
312 for ( j=iStart ; j<=iEnd ; j++ ) {
313 sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
314 $('<li '+sClass+'><a href="#">'+j+'</a></li>')
315 .insertBefore( $('li:last', an[i])[0] )
316 .bind('click', function (e) {
317 e.preventDefault();
318 oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
319 fnDraw( oSettings );
320 } );
321 }
322
323 // Add / remove disabled classes from the static elements
324 if ( oPaging.iPage === 0 ) {
325 $('li:first', an[i]).addClass('disabled');
326 } else {
327 $('li:first', an[i]).removeClass('disabled');
328 }
329
330 if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
331 $('li:last', an[i]).addClass('disabled');
332 } else {
333 $('li:last', an[i]).removeClass('disabled');
334 }
335 }
336 }
337 }
338 } );
339
340
341 /*
342 * TableTools Bootstrap compatibility
343 * Required TableTools 2.1+
344 */
345 if ( $.fn.DataTable.TableTools ) {
346 // Set the classes that TableTools uses to something suitable for Bootstrap
347 $.extend( true, $.fn.DataTable.TableTools.classes, {
348 "container": "DTTT btn-group",
349 "buttons": {
350 "normal": "btn",
351 "disabled": "disabled"
352 },
353 "collection": {
354 "container": "DTTT_dropdown dropdown-menu",
355 "buttons": {
356 "normal": "",
357 "disabled": "disabled"
358 }
359 },
360 "print": {
361 "info": "DTTT_print_info modal"
362 },
363 "select": {
364 "row": "active"
365 }
366 } );
367
368 // Have the collection use a bootstrap compatible dropdown
369 $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
370 "collection": {
371 "container": "ul",
372 "button": "li",
373 "liner": "a"
374 }
375 } );
376 }
377
378
379 /* Table initialisation */
380 $(document).ready(function() {
381 $('#from_csv').dataTable( {
382 "sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
383 "sPaginationType": "bootstrap",
384 "oLanguage": {
385 "sLengthMenu": "_MENU_ records per page"
386 }
387 } );
388 } );
389 </script>
390 </head>
391 <body>
392 <div class="container" style="margin-top: 10px">
393 <table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="from_csv">
394 <thead>\
395 """
396
397 for i, row in enumerate(reader):
398 if i == 0:
399 print "<tr><th>" + "</th><th>".join(row) + "</th></tr>"
400 else:
401 print "<tr><td>" + "</td><td>".join(row) + "</td></tr>"
402
403 if i == 0:
404 print "</thead><tbody>"
405
406 print """\
407 </tbody>
408 </table>
409 </div>
410 </body>
411 </html>\
412 """