def __init__(self, bucket_name, dns_server=None): from boto.s3.connection import S3Connection from boto.utils import find_class from boto import config S3CompatibleStorage.__init__(self, bucket_name=bucket_name, host=S3Connection.DefaultHost, # The boto config can override the default calling format, and since # we don't use boto for get(), we need to use the right calling format. calling_format=S3Connection.DefaultCallingFormat, dns_server=dns_server ) # Allow to use a different host/calling format for GET requests by # adding the following boto config: # [get] # host = my.server.tld # calling_format = boto.s3.connection.TheCallingFormat get_host = config.get('get', 'host', S3Connection.DefaultHost) get_calling_format = config.get('get', 'calling_format', S3Connection.DefaultCallingFormat) if get_host != S3Connection.DefaultHost: if get_calling_format != S3Connection.DefaultCallingFormat: self._calling_format = find_class(get_calling_format)() self._host = self._calling_format.build_host(get_host, self._bucket_name)
def revive_object_from_id(id, manager): if not manager.domain: return None attrs = manager.domain.get_attributes(id, ['__module__', '__type__', '__lineage__']) try: cls = find_class(attrs['__module__'], attrs['__type__']) return cls(id, manager=manager) except ImportError: return None
def update(self, env): """ On an update, we have to remove all of our handlers and re-build our index handler """ self.env = env self.index_handler = IndexHandler(self.env, {}) self.robot_handler = RobotsHandler(self.env, {}) self.handlers = {} # Load up and verify all the handlers for route in self.env.config.get("botoweb", "handlers"): handler = find_class(route.get("handler")) if not handler: raise Exception("Handler not found: %s" % route.get('handler')) if route.get("db_class"): model_class = find_class(route.get("db_class").strip()) if model_class is None: raise Exception("DB Class not found: '%s'" % route.get('db_class'))
def decode_reference(self, value): if not value: return None try: value = value.childNodes[0] class_name = value.getAttribute("class") id = value.getAttribute("id") cls = find_class(class_name) return cls.get_by_ids(id) except: return None
def search_object(self, name, consistent_read=False): """Wrapper around the "search" function that returns Model objects instead of just a DynamoDB Item""" from boto.utils import find_class for item in self.search(name, consistent_read): if item.has_key("class_name") and item.has_key("module_name"): cls = find_class(item['module_name'], item['class_name']) if not cls: log.error("Could not find object class: %s %s" % (item['module_name'], item['class_name'])) else: yield cls.get_by_id(item['id'])
def getObj(ctx, nodes): """ Get this object and return it's XML format """ from StringIO import StringIO node = nodes[0] cls = find_class(node.get("class")) obj = cls.get_by_id(node.get('id')) doc = obj.to_xml().toxml() doc = etree.parse(StringIO(doc)) return doc.getroot().getchildren()
def __init__(self, id=None, domain_name=None, fnc=increment_by_one, init_val=None): """Create a new Sequence, using an optional function to increment to the next number, by default we just increment by one. Every parameter here is optional, if you don't specify any options then you'll get a new SequenceGenerator with a random ID stored in the default domain that increments by one and uses the default botoweb environment :param id: Optional ID (name) for this counter :type id: str :param domain_name: Optional domain name to use, by default we get this out of the environment configuration :type domain_name:str :param fnc: Optional function to use for the incrementation, by default we just increment by one There are several functions defined in this module. Your function must accept "None" to get the initial value :type fnc: function, str :param init_val: Initial value, by default this is the first element in your sequence, but you can pass in any value, even a string if you pass in a function that uses strings instead of ints to increment """ self._db = None self._value = None self.last_value = None self.domain_name = domain_name self.id = id if init_val == None: init_val = fnc(init_val) if self.id == None: import uuid self.id = str(uuid.uuid4()) self.item_type = type(fnc(None)) self.timestamp = None # Allow us to pass in a full name to a function if type(fnc) == str: from boto.utils import find_class fnc = find_class(fnc) self.fnc = fnc # Bootstrap the value last if not self.val: self.val = init_val
def get_url(obj_cls): """Get the URL for a given class""" from botoweb.encoder import url_map if url_map == None: import botoweb from boto.utils import find_class handlers = botoweb.env.config.get("botoweb", "handlers") url_map = {} for handler in handlers: if handler.has_key("db_class"): db_class = handler['db_class'] cls = find_class(db_class) url_map[cls.__name__] = handler['url'] return url_map.get(obj_cls.__name__)
def __init__(self, module, env=None): """Initialize the Environment object :param module: The Module that serves as the basis for this botoweb application :param env: Optional environment file that overrides any settings in our config """ self.module = module self._client_connection = None if not env: env = os.environ.get("BOTO_WEB_ENV") self.env = env # Config setup self.config = Config() self.config.env = self self.dist = get_provider(self.module) self.mgr = ResourceManager() if self.dist.has_resource("conf"): self.config.update(self.get_config("conf")) if env and os.path.exists(self.env): log.info("Loading environment: %s" % self.env) self.config.update(yaml.load(open(self.env, "r"))) # Set up the DB shortcuts if not self.config.has_key("DB"): self.config['DB'] = { "db_type": self.config.get("DB", "db_type", "SimpleDB"), "db_user": self.config.get("Credentials", "aws_access_key_id"), "db_passwd": self.config.get("Credentials", "aws_secret_access_key") } if self.config.has_key("auth_db"): self.config['DB']['User'] = {"db_name": self.config['auth_db']} if self.config.has_key("default_db"): self.config['DB']['db_name'] = self.config["default_db"] if self.config.has_key("session_db"): self.config['DB']['Session'] = {'db_name': self.config["session_db"]} # Bootstrap importing all db_classes for XMLize if self.config['botoweb'].has_key("handlers"): for handler in self.config['botoweb']['handlers']: if handler.has_key("db_class"): try: db_class = find_class(handler['db_class']) except: log.exception("Could not load class: %s" % handler['db_class']) db_class = None if db_class: xmlize.register(db_class)
def __init__(self, id=None, domain_name=None, fnc=increment_by_one, init_val=None): """Create a new Sequence, using an optional function to increment to the next number, by default we just increment by one. Every parameter here is optional, if you don't specify any options then you'll get a new SequenceGenerator with a random ID stored in the default domain that increments by one and uses the default botoweb environment :param id: Optional ID (name) for this counter :type id: str :param domain_name: Optional domain name to use, by default we get this out of the environment configuration :type domain_name:str :param fnc: Optional function to use for the incrementation, by default we just increment by one There are several functions defined in this module. Your function must accept "None" to get the initial value :type fnc: function, str :param init_val: Initial value, by default this is the first element in your sequence, but you can pass in any value, even a string if you pass in a function that uses strings instead of ints to increment """ self._db = None self._value = None self.last_value = None self.domain_name = domain_name self.id = id if init_val is None: init_val = fnc(init_val) if self.id is None: import uuid self.id = str(uuid.uuid4()) self.item_type = type(fnc(None)) self.timestamp = None # Allow us to pass in a full name to a function if isinstance(fnc, six.string_types): from boto.utils import find_class fnc = find_class(fnc) self.fnc = fnc # Bootstrap the value last if not self.val: self.val = init_val
def parse_path(self, req): """ Get the handler and object id (if given) for this path request. @return: (Handler, obj_id) @rtype: tuple """ path = req.path handler = None obj_id = None for handler_config in self.env.config.get("botoweb", "handlers"): match = re.match( "^(%s)(\.xml|\.json|\.csv)?(\/(.*))?$" % handler_config['url'], path) if match: # Allow for setting a custom content-type by URL if match.group(2): req.file_extension = match.group(2)[1:] else: req.file_extension = self.env.config.get("app", "format") log.debug("URL Mapping: %s" % handler_config) obj_id = match.group(4) if obj_id == "": obj_id = None if self.handlers.has_key(handler_config['url']): handler = self.handlers.get(handler_config['url']) else: if handler_config.has_key("handler"): class_name = handler_config['handler'] handler_class = find_class(class_name) handler = handler_class(self.env, handler_config) if handler: self.handlers[handler_config['url']] = handler if handler: req.script_name = match.group(1) if obj_id: obj_id = urllib.unquote(obj_id) return (handler, obj_id) if path == "/": return (self.index_handler, None) elif path == "/robots.txt": return (self.robot_handler, None) else: return (None, None)
def get_object(self, cls, id, a=None): if not a: a = self.domain.get_attributes(id) if not a.has_key('__type__'): return None if not cls: cls = find_class(a['__module__'], a['__type__']) obj = cls(id) for prop in obj.properties(hidden=False): if prop.data_type != Key: if a.has_key(prop.name): value = self.decode_value(prop, a[prop.name]) value = prop.make_value_from_datastore(value) setattr(obj, prop.name, value) return obj
def parse_path(self, req): """ Get the handler and object id (if given) for this path request. @return: (Handler, obj_id) @rtype: tuple """ path = req.path handler = None obj_id = None for handler_config in self.env.config.get("botoweb", "handlers"): match = re.match("^(%s)(\.xml|\.json|\.csv)?(\/(.*))?$" % handler_config['url'], path) if match: # Allow for setting a custom content-type by URL if match.group(2): req.file_extension = match.group(2)[1:] else: req.file_extension = self.env.config.get("app", "format") log.debug("URL Mapping: %s" % handler_config) obj_id = match.group(4) if obj_id == "": obj_id = None if self.handlers.has_key(handler_config['url']): handler = self.handlers.get(handler_config['url']) else: if handler_config.has_key("handler"): class_name = handler_config['handler'] handler_class = find_class(class_name) handler = handler_class(self.env, handler_config) if handler: self.handlers[handler_config['url']] = handler if handler: req.script_name = match.group(1) if obj_id: obj_id = urllib.unquote(obj_id) return (handler, obj_id) if path == "/": return (self.index_handler, None) elif path == "/robots.txt": return (self.robot_handler, None) else: return (None, None)
def update(self, env): """ On update, we have to re-build our entire filter list """ self.env = env self.filters = {} self.parser = etree.XMLParser() self.parser.resolvers.add(S3FilterResolver()) self.parser.resolvers.add(PythonFilterResolver()) self.external_functions = [] if self.env.config.has_key("xsltfunctions"): for func_path in self.env.config['xsltfunctions']: __import__(func_path) funcset = find_class(func_path) ns = etree.FunctionNamespace(funcset.uri) for fname in funcset.functions: ns[fname] = funcset.functions[fname]
def get_object(self, cls, id, a=None): if not a: a = self.domain.get_attributes(id) if not a.has_key('__type__'): raise SDBPersistenceError('object %s does not exist' % id) if not cls: cls = find_class(a['__module__'], a['__type__']) obj = cls(id) obj._auto_update = False for prop in obj.properties(hidden=False): if prop.data_type != Key: if a.has_key(prop.name): value = self.decode_value(prop, a[prop.name]) value = prop.make_value_from_datastore(value) setattr(obj, prop.name, value) obj._auto_update = True return obj
def _object_lister(self, cls, doc): for obj_node in doc.getElementsByTagName('object'): if not cls: class_name = obj_node.getAttribute('class') cls = find_class(class_name) id = obj_node.getAttribute('id') obj = cls(id) for prop_node in obj_node.getElementsByTagName('property'): prop_name = prop_node.getAttribute('name') prop = obj.find_property(prop_name) if prop: if hasattr(prop, 'item_type'): value = self.get_list(prop_node, prop.item_type) else: value = self.decode_value(prop, prop_node) value = prop.make_value_from_datastore(value) setattr(obj, prop.name, value) yield obj
def run_scripts(self): scripts = config.get('Pyami', 'scripts') if scripts: for script in scripts.split(','): script = script.strip(" ") try: pos = script.rfind('.') if pos > 0: mod_name = script[0:pos] cls_name = script[pos+1:] cls = find_class(mod_name, cls_name) boto.log.info('Running Script: %s' % script) s = cls() s.main() else: boto.log.warning('Trouble parsing script: %s' % script) except Exception: boto.log.exception('Problem Running Script: %s' % script)
def run_scripts(self): scripts = config.get('Pyami', 'scripts') if scripts: for script in scripts.split(','): script = script.strip(" ") try: pos = script.rfind('.') if pos > 0: mod_name = script[0:pos] cls_name = script[pos + 1:] cls = find_class(mod_name, cls_name) boto.log.info('Running Script: %s' % script) s = cls() s.main() else: boto.log.warning('Trouble parsing script: %s' % script) except Exception: boto.log.exception('Problem Running Script: %s' % script)
def get_object_from_doc(self, cls, id, doc): obj_node = doc.getElementsByTagName('object')[0] if not cls: class_name = obj_node.getAttribute('class') cls = find_class(class_name) if not id: id = obj_node.getAttribute('id') obj = cls(id) for prop_node in obj_node.getElementsByTagName('property'): prop_name = prop_node.getAttribute('name') prop = obj.find_property(prop_name) value = self.decode_value(prop, prop_node) value = prop.make_value_from_datastore(value) if value != None: try: setattr(obj, prop.name, value) except: pass return obj
def __init__(self, bucket_name, host=DefaultHost, calling_format=DefaultCallingFormat, dns_server=None): assert bucket_name self._bucket_name = bucket_name from boto.s3.connection import S3Connection from boto.utils import find_class from boto import config self._calling_format = find_class(calling_format)() self._host = self._calling_format.build_host(host, self._bucket_name) self._failed = False # Prepare the wrapper classes to use for urllib and boto. dns_query = dns_query_function(dns_server) self._http_connection_class = ConnectionWrapperFactory( httplib.HTTPConnection, dns_query) self._https_connection_class = ConnectionWrapperFactory( httplib.HTTPSConnection, dns_query) self._url_opener = OpenerFactory(self._http_connection_class, self._https_connection_class) # Get the boto S3 bucket instance if config.getbool('Boto', 'is_secure', True): s3_connection = S3Connection( host=host, port=443, https_connection_factory=(self._https_connection_class, ())) else: s3_connection = S3Connection( host=host, port=80, https_connection_factory=(self._http_connection_class, ())) self._bucket = s3_connection.get_bucket(self._bucket_name, validate=False) self.last_stats = {}
def get_object(self, cls, id, a=None): obj = None if not a: a = self.domain.get_attributes(id, consistent_read=self.consistent) if '__type__' in a: if not cls or a['__type__'] != cls.__name__: cls = find_class(a['__module__'], a['__type__']) if cls: params = {} for prop in cls.properties(hidden=False): if prop.name in a: value = self.decode_value(prop, a[prop.name]) value = prop.make_value_from_datastore(value) params[prop.name] = value obj = cls(id, **params) obj._loaded = True else: s = '(%s) class %s.%s not found' % (id, a['__module__'], a['__type__']) boto.log.info('sdbmanager: %s' % s) return obj
def get_object(self, cls, id, a=None): obj = None if not a: a = self.domain.get_attributes(id,consistent_read=self.consistent) if a.has_key('__type__'): if not cls or a['__type__'] != cls.__name__: cls = find_class(a['__module__'], a['__type__']) if cls: params = {} for prop in cls.properties(hidden=False): if a.has_key(prop.name): value = self.decode_value(prop, a[prop.name]) value = prop.make_value_from_datastore(value) params[prop.name] = value obj = cls(id, **params) obj._loaded = True else: s = '(%s) class %s.%s not found' % (id, a['__module__'], a['__type__']) boto.log.info('sdbmanager: %s' % s) return obj
def get_props_from_doc(self, cls, id, doc): """ Pull out the properties from this document Returns the class, the properties in a hash, and the id if provided as a tuple :return: (cls, props, id) """ obj_node = doc.getElementsByTagName('object')[0] if not cls: class_name = obj_node.getAttribute('class') cls = find_class(class_name) if not id: id = obj_node.getAttribute('id') props = {} for prop_node in obj_node.getElementsByTagName('property'): prop_name = prop_node.getAttribute('name') prop = cls.find_property(prop_name) value = self.decode_value(prop, prop_node) value = prop.make_value_from_datastore(value) if value != None: props[prop.name] = value return (cls, props, id)
def __init__(self, bucket_name, host=DefaultHost, calling_format=DefaultCallingFormat, dns_server=None): assert bucket_name self._bucket_name = bucket_name from boto.s3.connection import S3Connection from boto.utils import find_class from boto import config self._calling_format = find_class(calling_format)() self._host = self._calling_format.build_host(host, self._bucket_name) self._failed = False # Prepare the wrapper classes to use for urllib and boto. dns_query = dns_query_function(dns_server) self._http_connection_class = ConnectionWrapperFactory( httplib.HTTPConnection, dns_query) self._https_connection_class = ConnectionWrapperFactory( httplib.HTTPSConnection, dns_query) self._url_opener = OpenerFactory( self._http_connection_class, self._https_connection_class) # Get the boto S3 bucket instance if config.getbool('Boto', 'is_secure', True): s3_connection = S3Connection(host=host, port=443, https_connection_factory=(self._https_connection_class, ())) else: s3_connection = S3Connection(host=host, port=80, https_connection_factory=(self._http_connection_class, ())) self._bucket = s3_connection.get_bucket(self._bucket_name, validate=False) self.last_stats = {}
def revive_object_from_id(id): domain = get_domain() attrs = domain.get_attributes(id, ['__module__', '__type__', '__lineage__']) cls = find_class(attrs['__module__'], attrs['__type__']) return cls(id)
def to_dict(self, request): ret = {} if self.env.config.get("app", "version"): ret['__version__'] = self.env.config.get("app", "version") if request.user: ret["User"] = { "__id__": request.user.id, "name": request.user.name, "username": request.user.username, "email": request.user.email } ret['User']['auth_groups'] = [] for auth_group in request.user.auth_groups: ret['User']['auth_groups'].append(auth_group) ret['resources'] = {} for route in self.env.config.get("botoweb", "handlers"): if route.get("name"): route_dict = { "name": route.get("name"), "href": route['url'].strip('/'), "description": route.get("description") } # Handler info handler = find_class(route.get("handler")) if not handler: raise Exception("Handler not found: %s" % route.get('handler')) # Add in the Methods route_dict['methods'] = {} for method_name in handler.allowed_methods: method = getattr(handler, "_%s" % method_name) route_dict['methods'][method_name] = method.__doc__ # Info about the object returned if route.get("db_class"): model_class = find_class(route.get("db_class")) if model_class: # Class Info route_dict['class_name'] = model_class.__name__ if len(model_class.mro()) > 1: route_dict['parent_class'] = model_class.mro( )[1].__name__ # Property Info route_dict['properties'] = {} for prop in model_class.properties(): if prop.name.startswith("_"): continue route_dict['properties'][prop.name] = { "name": prop.name, "type": prop.__class__.__name__ } if hasattr(prop, "collection_name" ) and prop.collection_name: route_dict['properties'][prop.name][ 'reference_name'] = prop.collection_name if hasattr(prop, "reference_class"): route_dict['properties'][ prop.name]['type'] = "reference" route_dict['properties'][prop.name][ 'item_type'] = prop.reference_class.__name__ else: prop_type_name = prop.type_name.lower() if not prop_type_name: if hasattr(prop, "calculated_type"): if prop.calculated_type: prop_type_name = prop.calculated_type.__name__.lower( ) else: prop_type_name = "str" route_dict['properties'][ prop.name]['calculated'] = True else: prop_type_name = TYPE_NAMES.get( prop.data_type, "string") route_dict['properties'][ prop.name]['type'] = TYPE_CONVERSIONS.get( prop_type_name, prop_type_name) if prop.data_type in [str, unicode]: route_dict['properties'][ prop.name]['max_length'] = 1024 if prop.data_type == int: route_dict['properties'][ prop.name]['min'] = -2147483648 route_dict['properties'][ prop.name]['max'] = 2147483647 if hasattr(prop, "item_type"): if hasattr(prop.item_type, "__name__"): item_type = prop.item_type.__name__ else: item_type = TYPE_NAMES.get( prop.item_type, "string") route_dict['properties'][ prop.name]['item_type'] = item_type if hasattr(prop, "verbose_name" ) and prop.verbose_name != None: route_dict['properties'][ prop.name]['description'] = str( prop.verbose_name) if hasattr(prop, "default") and prop.default: route_dict['properties'][ prop.name]['default'] = prop.default if hasattr(prop, "choices") and prop.choices: route_dict['properties'][ prop.name]['choices'] = [] for choice in prop.choices: route_dict['properties'][ prop.name]['choices'].append(choice) ret['resources'][route.get("name")] = route_dict return ret
def to_xml(self, request, response): response.content_type = 'text/xml' doc = etree.Element("Index", name=self.env.config.get("app", "name", "botoweb application")) if self.env.config.get("app", "version"): doc.set("version", str(self.env.config.get("app", "version"))) if request.user: user_node = etree.SubElement(doc, "User", id=request.user.id) etree.SubElement(user_node, "name", type='string').text = request.user.name etree.SubElement(user_node, "username", type='string').text = request.user.username etree.SubElement(user_node, "email", type='string').text = request.user.email for auth_group in request.user.auth_groups: etree.SubElement(user_node, "auth_groups", type='string').text = auth_group for route in self.env.config.get("botoweb", "handlers"): if route.get("name"): model_name = route.get("name") href = route['url'].strip('/') api_node = etree.SubElement(doc, "api", name=model_name) etree.SubElement(api_node, "href").text = href if route.get("description"): etree.SubElement( api_node, "description").text = route.get("description") handler = find_class(route.get("handler")) if not handler: raise Exception("Handler not found: %s" % route.get('handler')) methods_node = etree.SubElement(api_node, "methods") for method_name in handler.allowed_methods: method = getattr(handler, "_%s" % method_name) etree.SubElement(methods_node, method_name).text = method.__doc__ if route.get("db_class"): model_class = find_class(route.get("db_class")) if model_class: if len(model_class.mro()) > 1: api_node.set("parentClass", model_class.mro()[1].__name__) props_node = etree.SubElement(api_node, "properties") for prop in model_class.properties(): if prop.name.startswith("_"): continue prop_node = etree.SubElement( props_node, "property") prop_node.set("name", prop.name) if hasattr(prop, "collection_name" ) and prop.collection_name: prop_node.set("reference_name", prop.collection_name) if hasattr(prop, "reference_class"): prop_node.set("type", "reference") prop_node.set("item_type", prop.reference_class.__name__) else: prop_type_name = prop.type_name.lower() if prop_type_name: prop_node.set( "type", TYPE_CONVERSIONS.get( prop_type_name, prop_type_name)) elif hasattr(prop, "calculated_type"): if prop.calculated_type: prop_type_name = prop.calculated_type.__name__.lower( ) else: prop_type_name = "str" prop_node.set( "type", TYPE_CONVERSIONS.get( prop_type_name, prop_type_name)) prop_node.set("calculated", "true") else: prop_node.set( "type", TYPE_NAMES.get(prop.data_type, "string")) if prop.data_type in [str, unicode]: prop_node.set("max_length", "1024") if prop.data_type == int: prop_node.set("min", "-2147483648") prop_node.set("max", "2147483647") if hasattr(prop, "item_type"): if hasattr(prop.item_type, "__name__"): item_type = prop.item_type.__name__ else: item_type = TYPE_NAMES.get( prop.item_type, "string") prop_node.set("item_type", item_type) if hasattr(prop, "verbose_name" ) and prop.verbose_name != None: etree.SubElement(prop_node, "description").text = str( prop.verbose_name) if hasattr(prop, "default") and prop.default: default_node = etree.SubElement( prop_node, "default") default_node.text = str(prop.default) if hasattr(prop, "choices") and prop.choices: choices_node = etree.SubElement( prop_node, "choices") for choice in prop.choices: etree.SubElement(choices_node, "choice", value=choice) response.write(etree.tostring(doc, encoding="utf-8", pretty_print=True)) return response
def to_dict(self, request): ret = {} if self.env.config.get("app", "version"): ret['__version__'] = self.env.config.get("app", "version") if request.user: ret["User"] = { "__id__": request.user.id, "name": request.user.name, "username": request.user.username, "email": request.user.email } ret['User']['auth_groups'] = [] for auth_group in request.user.auth_groups: ret['User']['auth_groups'].append(auth_group) ret['resources'] = {} for route in self.env.config.get("botoweb", "handlers"): if route.get("name"): route_dict = { "name": route.get("name"), "href": route['url'].strip('/'), "description": route.get("description") } # Handler info handler = find_class(route.get("handler")) if not handler: raise Exception("Handler not found: %s" % route.get('handler')) # Add in the Methods route_dict['methods' ] = {} for method_name in handler.allowed_methods: method = getattr(handler, "_%s" % method_name) route_dict['methods'][method_name] = method.__doc__ # Info about the object returned if route.get("db_class"): model_class = find_class(route.get("db_class")) if model_class: # Class Info route_dict['class_name'] = model_class.__name__ if len(model_class.mro()) > 1: route_dict['parent_class'] = model_class.mro()[1].__name__ # Property Info route_dict['properties'] = {} for prop in model_class.properties(): if prop.name.startswith("_"): continue route_dict['properties'][prop.name] = { "name": prop.name, "type": prop.__class__.__name__ } if hasattr(prop, "collection_name") and prop.collection_name: route_dict['properties'][prop.name]['reference_name'] = prop.collection_name if hasattr(prop, "reference_class"): route_dict['properties'][prop.name]['type'] = "reference" route_dict['properties'][prop.name]['item_type'] = prop.reference_class.__name__ else: prop_type_name = prop.type_name.lower() if not prop_type_name: if hasattr(prop, "calculated_type"): if prop.calculated_type: prop_type_name = prop.calculated_type.__name__.lower() else: prop_type_name = "str" route_dict['properties'][prop.name]['calculated'] = True else: prop_type_name = TYPE_NAMES.get(prop.data_type, "string") route_dict['properties'][prop.name]['type'] = TYPE_CONVERSIONS.get(prop_type_name, prop_type_name) if prop.data_type in [str, unicode]: route_dict['properties'][prop.name]['max_length'] = 1024 if prop.data_type == int: route_dict['properties'][prop.name]['min'] = -2147483648 route_dict['properties'][prop.name]['max'] = 2147483647 if hasattr(prop, "item_type"): if hasattr(prop.item_type, "__name__"): item_type = prop.item_type.__name__ else: item_type = TYPE_NAMES.get(prop.item_type, "string") route_dict['properties'][prop.name]['item_type'] = item_type if hasattr(prop, "verbose_name") and prop.verbose_name != None: route_dict['properties'][prop.name]['description'] = str(prop.verbose_name) if hasattr(prop, "default") and prop.default: route_dict['properties'][prop.name]['default'] = prop.default if hasattr(prop, "choices") and prop.choices: route_dict['properties'][prop.name]['choices'] = [] for choice in prop.choices: route_dict['properties'][prop.name]['choices'].append(choice) ret['resources'][route.get("name")] = route_dict return ret
def to_xml(self, request, response): response.content_type = 'text/xml' doc = etree.Element("Index", name=self.env.config.get("app", "name", "botoweb application")) if self.env.config.get("app", "version"): doc.set("version", str(self.env.config.get("app", "version"))) if request.user: user_node = etree.SubElement(doc, "User", id=request.user.id) etree.SubElement(user_node, "name", type='string').text = request.user.name etree.SubElement(user_node, "username", type='string').text = request.user.username etree.SubElement(user_node, "email", type='string').text = request.user.email for auth_group in request.user.auth_groups: etree.SubElement(user_node, "auth_groups", type='string').text = auth_group for route in self.env.config.get("botoweb", "handlers"): if route.get("name"): model_name = route.get("name") href = route['url'].strip('/') api_node = etree.SubElement(doc, "api", name=model_name) etree.SubElement(api_node, "href").text = href if route.get("description"): etree.SubElement(api_node, "description").text = route.get("description") handler = find_class(route.get("handler")) if not handler: raise Exception("Handler not found: %s" % route.get('handler')) methods_node = etree.SubElement(api_node, "methods") for method_name in handler.allowed_methods: method = getattr(handler, "_%s" % method_name) etree.SubElement(methods_node, method_name).text = method.__doc__ if route.get("db_class"): model_class = find_class(route.get("db_class")) if model_class: if len(model_class.mro()) > 1: api_node.set("parentClass", model_class.mro()[1].__name__) props_node = etree.SubElement(api_node, "properties") for prop in model_class.properties(): if prop.name.startswith("_"): continue prop_node = etree.SubElement(props_node, "property") prop_node.set("name", prop.name) if hasattr(prop, "collection_name") and prop.collection_name: prop_node.set("reference_name", prop.collection_name) if hasattr(prop, "reference_class"): prop_node.set("type", "reference") prop_node.set("item_type", prop.reference_class.__name__) else: prop_type_name = prop.type_name.lower() if prop_type_name: prop_node.set("type", TYPE_CONVERSIONS.get(prop_type_name, prop_type_name)) elif hasattr(prop, "calculated_type"): if prop.calculated_type: prop_type_name = prop.calculated_type.__name__.lower() else: prop_type_name = "str" prop_node.set("type", TYPE_CONVERSIONS.get(prop_type_name, prop_type_name)) prop_node.set("calculated", "true") else: prop_node.set("type", TYPE_NAMES.get(prop.data_type, "string")) if prop.data_type in [str, unicode]: prop_node.set("max_length", "1024") if prop.data_type == int: prop_node.set("min", "-2147483648") prop_node.set("max", "2147483647") if hasattr(prop, "item_type"): if hasattr(prop.item_type, "__name__"): item_type = prop.item_type.__name__ else: item_type = TYPE_NAMES.get(prop.item_type, "string") prop_node.set("item_type", item_type) if hasattr(prop, "verbose_name") and prop.verbose_name != None: etree.SubElement(prop_node, "description").text = str(prop.verbose_name) if hasattr(prop, "default") and prop.default: default_node = etree.SubElement(prop_node, "default") default_node.text = str(prop.default) if hasattr(prop, "choices") and prop.choices: choices_node = etree.SubElement(prop_node, "choices") for choice in prop.choices: etree.SubElement(choices_node, "choice", value=choice) response.write(etree.tostring(doc, encoding="utf-8", pretty_print=True)) return response
def __init__(self, env, config): RequestHandler.__init__(self, env, config) db_class_name = self.config.get('db_class', None) if db_class_name: self.db_class = find_class(db_class_name) xmlize.register(self.db_class)