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

Source Code for Module s3.s3codec

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ S3 Encoder/Decoder Base Class 
  4   
  5      @copyright: 2011-2019 (c) Sahana Software Foundation 
  6      @license: MIT 
  7   
  8      Permission is hereby granted, free of charge, to any person 
  9      obtaining a copy of this software and associated documentation 
 10      files (the "Software"), to deal in the Software without 
 11      restriction, including without limitation the rights to use, 
 12      copy, modify, merge, publish, distribute, sublicense, and/or sell 
 13      copies of the Software, and to permit persons to whom the 
 14      Software is furnished to do so, subject to the following 
 15      conditions: 
 16   
 17      The above copyright notice and this permission notice shall be 
 18      included in all copies or substantial portions of the Software. 
 19   
 20      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 21      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 22      OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 23      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 24      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 25      WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 26      FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 27      OTHER DEALINGS IN THE SOFTWARE. 
 28  """ 
 29   
 30  __all__ = ("S3Codec",) 
 31   
 32  import json 
 33   
 34  from xml.sax.saxutils import escape, unescape 
 35   
 36  from gluon import current 
 37   
 38  from s3utils import s3_str 
39 40 # ============================================================================= 41 -class S3Codec(object):
42 """ 43 Base class for converting S3Resources into/from external 44 data formats, for use with S3Importer/S3Exporter 45 """ 46 47 # A list of fields which should be skipped from PDF/XLS exports 48 indices = ["id", "pe_id", "site_id", "sit_id", "item_entity_id"] 49 50 CODECS = {"pdf": "S3RL_PDF", 51 "shp": "S3SHP", 52 "svg": "S3SVG", 53 "xls": "S3XLS", 54 "card": "S3PDFCard", 55 } 56 57 # ------------------------------------------------------------------------- 58 @classmethod
59 - def get_codec(cls, fmt):
60 """ 61 Get a codec by representation format 62 63 @param fmt: the representation format (string) 64 """ 65 66 codec = cls 67 68 name = cls.CODECS.get(fmt) 69 if name: 70 package = "applications.%s.modules.s3.codecs.%s" % \ 71 (current.request.application, fmt) 72 try: 73 codec = getattr(__import__(package, fromlist=[name]), name) 74 except (ImportError, AttributeError): 75 current.log.error("Codec not available: %s" % name) 76 else: 77 current.log.error("No codec found for '%s' format" % fmt) 78 79 return codec()
80 81 # ------------------------------------------------------------------------- 82 # API 83 #--------------------------------------------------------------------------
84 - def encode(self, resource, **attr):
85 """ 86 API Method to encode a resource in the target format, 87 to be implemented by the subclass (mandatory) 88 89 @param resource: the S3Resource 90 91 @return: a handle to the output 92 """ 93 raise NotImplementedError
94
95 - def decode(self, resource, source, **attr):
96 """ 97 API Method to decode a source into an S3XML ElementTree, 98 to be implemented by the subclass (if the class does decode) 99 100 @param resource: the S3Resource 101 @param source: the source 102 103 @return: an S3XML ElementTree 104 """ 105 return current.xml.tree()
106 107 # ------------------------------------------------------------------------- 108 # Utilities 109 #-------------------------------------------------------------------------- 110 PY2XML = {"'": "'", '"': """} 111 @classmethod
112 - def xml_encode(cls, s):
113 """ 114 XML-escape a string 115 116 @param s: the string 117 """ 118 if s: 119 s = escape(s, cls.PY2XML) 120 return s
121 122 #-------------------------------------------------------------------------- 123 XML2PY = {"'": "'", """: '"'} 124 @classmethod
125 - def xml_decode(cls, s):
126 """ 127 XML-unescape a string 128 129 @param s: the string 130 """ 131 if s: 132 s = unescape(s, cls.XML2PY) 133 return s
134 135 # ------------------------------------------------------------------------- 136 @staticmethod
137 - def crud_string(tablename, name):
138 """ 139 Get a CRUD string 140 141 @param tablename: the table name 142 @param name: the name of the CRUD string 143 """ 144 145 crud_strings = current.response.s3.crud_strings 146 # CRUD strings for this table 147 _crud_strings = crud_strings.get(tablename, crud_strings) 148 return _crud_strings.get(name, 149 # Default fallback 150 crud_strings.get(name, None))
151 152 # ------------------------------------------------------------------------- 153 # Error handling 154 # ------------------------------------------------------------------------- 155 @staticmethod
156 - def json_message(success=True, 157 statuscode=None, 158 message=None, 159 **kwargs):
160 """ 161 Provide a nicely-formatted JSON Message 162 163 @param success: action succeeded or failed 164 @param status_code: the HTTP status code 165 @param message: the message text 166 @param kwargs: other elements for the message 167 168 @keyword tree: error tree to include as JSON object (rather 169 than as string) for easy decoding 170 """ 171 172 if statuscode is None: 173 statuscode = success and 200 or 404 174 175 status = success and "success" or "failed" 176 code = str(statuscode) 177 178 output = {"status": status, "statuscode": str(code)} 179 180 tree = kwargs.get("tree", None) 181 if message: 182 output["message"] = s3_str(message) 183 for k, v in kwargs.items(): 184 if k != "tree": 185 output[k] = v 186 output = json.dumps(output) 187 if message and tree: 188 output = output[:-1] + ', "tree": %s}' % tree 189 return output
190 191 # End ========================================================================= 192