Package s3 :: Module s3export
[frames] | no frames]

Source Code for Module s3.s3export

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ Resource Export Tools 
  4   
  5      @see: U{B{I{S3XRC}} <http://eden.sahanafoundation.org/wiki/S3XRC>} 
  6   
  7      @requires: U{B{I{gluon}} <http://web2py.com>} 
  8   
  9      @copyright: 2009-2019 (c) Sahana Software Foundation 
 10      @license: MIT 
 11   
 12      Permission is hereby granted, free of charge, to any person 
 13      obtaining a copy of this software and associated documentation 
 14      files (the "Software"), to deal in the Software without 
 15      restriction, including without limitation the rights to use, 
 16      copy, modify, merge, publish, distribute, sublicense, and/or sell 
 17      copies of the Software, and to permit persons to whom the 
 18      Software is furnished to do so, subject to the following 
 19      conditions: 
 20   
 21      The above copyright notice and this permission notice shall be 
 22      included in all copies or substantial portions of the Software. 
 23   
 24      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 25      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 26      OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 27      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 28      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 29      WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 30      FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 31      OTHER DEALINGS IN THE SOFTWARE. 
 32  """ 
 33   
 34  __all__ = ("S3Exporter",) 
 35   
 36  from gluon import current 
 37   
 38  from s3codec import S3Codec 
 39   
 40  # ============================================================================= 
41 -class S3Exporter(object):
42 """ 43 Exporter toolkit 44 """ 45 46 # -------------------------------------------------------------------------
47 - def csv(self, resource):
48 """ 49 Export resource as CSV 50 51 @param resource: the resource to export 52 53 @note: export does not include components! 54 55 @todo: implement audit 56 """ 57 58 request = current.request 59 response = current.response 60 61 if response: 62 servername = request and "%s_" % request.env.server_name or "" 63 filename = "%s%s.csv" % (servername, resource.tablename) 64 from gluon.contenttype import contenttype 65 response.headers["Content-Type"] = contenttype(".csv") 66 response.headers["Content-disposition"] = "attachment; filename=%s" % filename 67 68 rows = resource.select(None, as_rows=True) 69 return str(rows)
70 71 # -------------------------------------------------------------------------
72 - def json(self, resource, 73 start=None, 74 limit=None, 75 fields=None, 76 orderby=None, 77 represent=False, 78 tooltip=None):
79 """ 80 Export a resource as JSON 81 82 @param resource: the resource to export from 83 @param start: index of the first record to export 84 @param limit: maximum number of records to export 85 @param fields: list of field selectors for fields to include in 86 the export (None for all fields) 87 @param orderby: ORDERBY expression 88 @param represent: whether values should be represented 89 @param tooltip: additional tooltip field, either a field selector 90 or an expression "f(k,v)" where f is a function 91 name that can be looked up from s3db, and k,v are 92 field selectors for the row, f will be called with 93 a list of tuples (k,v) for each row and is expected 94 to return a dict {k:tooltip} => used by 95 filterOptionsS3 to extract onhover-tooltips for 96 Ajax-update of options 97 """ 98 99 if fields is None: 100 # Use json_fields setting, or fall back to list_fields if 101 # not defined, or to all readable fields if list_fields is 102 # not defined either. 103 # Always include the ID field regardless whether it is 104 # configured or not => required for S3FilterOptions and 105 # similar Ajax lookups. 106 fields = resource.list_fields("json_fields", id_column=0) 107 108 if orderby is None: 109 orderby = resource.get_config("orderby", None) 110 111 tooltip_function = None 112 if tooltip: 113 if type(tooltip) is list: 114 tooltip = tooltip[-1] 115 import re 116 match = re.match(r"(\w+)\((\w+),(\w+)\)", tooltip) 117 if match: 118 function_name, kname, vname = match.groups() 119 # Try to resolve the function name 120 tooltip_function = current.s3db.get(function_name) 121 if tooltip_function: 122 if kname not in fields: 123 fields.append(kname) 124 if vname not in fields: 125 fields.append(vname) 126 else: 127 if tooltip not in fields: 128 fields.append(tooltip) 129 130 # Get the data 131 _rows = resource.select(fields, 132 start=start, 133 limit=limit, 134 orderby=orderby, 135 represent=represent).rows 136 137 # Simplify to plain fieldnames for fields in this table 138 tn = "%s." % resource.tablename 139 rows = [] 140 rappend = rows.append 141 for _row in _rows: 142 row = {} 143 for f in _row: 144 v = _row[f] 145 if tn in f: 146 f = f.split(tn, 1)[1] 147 row[f] = v 148 rappend(row) 149 150 if tooltip: 151 if tooltip_function: 152 # Resolve key and value names against the resource 153 try: 154 krfield = resource.resolve_selector(kname) 155 vrfield = resource.resolve_selector(vname) 156 except (AttributeError, SyntaxError): 157 import sys 158 current.log.error(sys.exc_info()[1]) 159 else: 160 # Extract key and value fields from each row and 161 # build options dict for function call 162 options = [] 163 items = {} 164 for row in rows: 165 try: 166 k = krfield.extract(row) 167 except KeyError: 168 break 169 try: 170 v = vrfield.extract(row) 171 except KeyError: 172 break 173 items[k] = row 174 options.append((k, v)) 175 # Call tooltip rendering function 176 try: 177 tooltips = tooltip_function(options) 178 except: 179 import sys 180 current.log.error(sys.exc_info()[1]) 181 else: 182 # Add tooltips as "_tooltip" to the corresponding rows 183 if isinstance(tooltips, dict): 184 from s3utils import s3_unicode 185 for k, v in tooltips.items(): 186 if k in items: 187 items[k]["_tooltip"] = s3_unicode(v) 188 189 else: 190 # Resolve the tooltip field name against the resource 191 try: 192 tooltip_rfield = resource.resolve_selector(tooltip) 193 except (AttributeError, SyntaxError): 194 import sys 195 current.log.error(sys.exc_info()[1]) 196 else: 197 # Extract the tooltip field from each row 198 # and add it as _tooltip 199 from s3utils import s3_unicode 200 for row in rows: 201 try: 202 value = tooltip_rfield.extract(row) 203 except KeyError: 204 break 205 if value: 206 row["_tooltip"] = s3_unicode(value) 207 208 # Return as JSON 209 response = current.response 210 if response: 211 response.headers["Content-Type"] = "application/json" 212 213 from gluon.serializers import json as jsons 214 return jsons(rows)
215 216 # -------------------------------------------------------------------------
217 - def pdf(self, *args, **kwargs):
218 219 codec = S3Codec.get_codec("pdf").encode 220 return codec(*args, **kwargs)
221 222 # -------------------------------------------------------------------------
223 - def pdfcard(self, *args, **kwargs):
224 225 codec = S3Codec.get_codec("card") 226 return codec.encode(*args, **kwargs)
227 228 # -------------------------------------------------------------------------
229 - def shp(self, *args, **kwargs):
230 231 codec = S3Codec.get_codec("shp").encode 232 return codec(*args, **kwargs)
233 234 # -------------------------------------------------------------------------
235 - def svg(self, *args, **kwargs):
236 237 codec = S3Codec.get_codec("svg").encode 238 return codec(*args, **kwargs)
239 240 # -------------------------------------------------------------------------
241 - def xls(self, *args, **kwargs):
242 243 codec = S3Codec.get_codec("xls").encode 244 return codec(*args, **kwargs)
245 246 # End ========================================================================= 247