<s> import datetime <EOL> from dateutil . parser import parse <EOL> from decimal import Decimal <EOL> import re <EOL> from piecrust . bundle import Bundle <EOL> from piecrust . exceptions import ApiFieldError , NotFound <EOL> from piecrust . utils import dict_strip_unicode_keys <EOL> try : <EOL> import importlib <EOL> except ImportError : <EOL> from piecrust . utils import importlib <EOL> try : <EOL> from django . utils import datetime_safe <EOL> except ImportError : <EOL> datetime_safe = datetime <EOL> class NOT_PROVIDED : <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' <EOL> DATE_REGEX = re . compile ( '<STR_LIT>' ) <EOL> DATETIME_REGEX = re . compile ( '<STR_LIT>' ) <EOL> class ApiField ( object ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:string>' <EOL> help_text = '<STR_LIT>' <EOL> def __init__ ( self , attribute = None , default = NOT_PROVIDED , null = False , blank = False , readonly = False , unique = False , help_text = None ) : <EOL> """<STR_LIT>""" <EOL> self . instance_name = None <EOL> self . _resource = None <EOL> self . attribute = attribute <EOL> self . _default = default <EOL> self . null = null <EOL> self . blank = blank <EOL> self . readonly = readonly <EOL> self . value = None <EOL> self . unique = unique <EOL> if help_text : <EOL> self . help_text = help_text <EOL> def contribute_to_class ( self , cls , name ) : <EOL> self . instance_name = name <EOL> self . _resource = cls <EOL> def has_default ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _default is not NOT_PROVIDED <EOL> @ property <EOL> def default ( self ) : <EOL> """<STR_LIT>""" <EOL> if callable ( self . _default ) : <EOL> return self . _default ( ) <EOL> return self . _default <EOL> def dehydrate ( self , bundle ) : <EOL> """<STR_LIT>""" <EOL> if self . attribute is not None : <EOL> attrs = self . attribute . split ( '<STR_LIT>' ) <EOL> current_object = bundle . obj <EOL> for attr in attrs : <EOL> previous_object = current_object <EOL> current_object = getattr ( current_object , attr , None ) <EOL> if current_object is None : <EOL> if self . has_default ( ) : <EOL> current_object = self . _default <EOL> break <EOL> elif self . null : <EOL> current_object = None <EOL> break <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( previous_object , attr ) ) <EOL> if callable ( current_object ) : <EOL> current_object = current_object ( ) <EOL> return self . convert ( current_object ) <EOL> if self . has_default ( ) : <EOL> return self . convert ( self . default ) <EOL> else : <EOL> return None <EOL> def convert ( self , value ) : <EOL> """<STR_LIT>""" <EOL> return value <EOL> def hydrate ( self , bundle ) : <EOL> """<STR_LIT>""" <EOL> if self . readonly : <EOL> return None <EOL> if not bundle . data . has_key ( self . instance_name ) : <EOL> if getattr ( self , '<STR_LIT>' , False ) and not getattr ( self , '<STR_LIT>' , False ) : <EOL> if bundle . related_obj and bundle . related_name in ( self . attribute , self . instance_name ) : <EOL> return bundle . related_obj <EOL> if self . blank : <EOL> return None <EOL> elif self . attribute and getattr ( bundle . obj , self . attribute , None ) : <EOL> return getattr ( bundle . obj , self . attribute ) <EOL> elif self . instance_name and hasattr ( bundle . obj , self . instance_name ) : <EOL> return getattr ( bundle . obj , self . instance_name ) <EOL> elif self . has_default ( ) : <EOL> if callable ( self . _default ) : <EOL> return self . _default ( ) <EOL> return self . _default <EOL> elif self . null : <EOL> return None <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % self . instance_name ) <EOL> return bundle . data [ self . instance_name ] <EOL> class CharField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:string>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return unicode ( value ) <EOL> class FileField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:string>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> try : <EOL> return getattr ( value , '<STR_LIT:url>' , value ) <EOL> except ValueError : <EOL> return None <EOL> class IntegerField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return int ( value ) <EOL> class FloatField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:float>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return float ( value ) <EOL> class DecimalField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return Decimal ( value ) <EOL> class BooleanField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return bool ( value ) <EOL> class ListField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:list>' <EOL> help_text = "<STR_LIT>" <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return list ( value ) <EOL> class DictField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> help_text = "<STR_LIT>" <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> return dict ( value ) <EOL> class DateField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT:date>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> if isinstance ( value , basestring ) : <EOL> match = DATE_REGEX . search ( value ) <EOL> if match : <EOL> data = match . groupdict ( ) <EOL> return datetime_safe . date ( int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) ) <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( self . instance_name , value ) ) <EOL> return value <EOL> def hydrate ( self , bundle ) : <EOL> value = super ( DateField , self ) . hydrate ( bundle ) <EOL> if value and not hasattr ( value , '<STR_LIT>' ) : <EOL> try : <EOL> value = parse ( value ) <EOL> if hasattr ( value , '<STR_LIT>' ) : <EOL> value = value . date ( ) <EOL> except ValueError : <EOL> pass <EOL> return value <EOL> class DateTimeField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> help_text = '<STR_LIT>' <EOL> def convert ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> if isinstance ( value , basestring ) : <EOL> match = DATETIME_REGEX . search ( value ) <EOL> if match : <EOL> data = match . groupdict ( ) <EOL> return datetime_safe . datetime ( int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) , int ( data [ '<STR_LIT>' ] ) ) <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( self . instance_name , value ) ) <EOL> return value <EOL> def hydrate ( self , bundle ) : <EOL> value = super ( DateTimeField , self ) . hydrate ( bundle ) <EOL> if value and not hasattr ( value , '<STR_LIT>' ) : <EOL> try : <EOL> value = parse ( value ) <EOL> except ValueError : <EOL> pass <EOL> return value <EOL> class RelatedField ( ApiField ) : <EOL> """<STR_LIT>""" <EOL> dehydrated_type = '<STR_LIT>' <EOL> is_related = True <EOL> self_referential = False <EOL> help_text = '<STR_LIT>' <EOL> def __init__ ( self , to , attribute , related_name = None , default = NOT_PROVIDED , null = False , blank = False , readonly = False , full = False , unique = False , help_text = None ) : <EOL> """<STR_LIT>""" <EOL> self . instance_name = None <EOL> self . _resource = None <EOL> self . to = to <EOL> self . attribute = attribute <EOL> self . related_name = related_name <EOL> self . _default = default <EOL> self . null = null <EOL> self . blank = blank <EOL> self . readonly = readonly <EOL> self . full = full <EOL> self . api_name = None <EOL> self . resource_name = None <EOL> self . unique = unique <EOL> self . _to_class = None <EOL> if self . to == '<STR_LIT>' : <EOL> self . self_referential = True <EOL> self . _to_class = self . __class__ <EOL> if help_text : <EOL> self . help_text = help_text <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( RelatedField , self ) . contribute_to_class ( cls , name ) <EOL> if self . self_referential or self . to == '<STR_LIT>' : <EOL> self . _to_class = cls <EOL> def get_related_resource ( self , related_instance ) : <EOL> """<STR_LIT>""" <EOL> related_resource = self . to_class ( ) <EOL> if related_resource . _meta . api_name is None : <EOL> if self . _resource and not self . _resource . _meta . api_name is None : <EOL> related_resource . _meta . api_name = self . _resource . _meta . api_name <EOL> related_resource . instance = related_instance <EOL> return related_resource <EOL> @ property <EOL> def to_class ( self ) : <EOL> if self . _to_class : <EOL> return self . _to_class <EOL> if not isinstance ( self . to , basestring ) : <EOL> self . _to_class = self . to <EOL> return self . _to_class <EOL> if '<STR_LIT:.>' in self . to : <EOL> module_bits = self . to . split ( '<STR_LIT:.>' ) <EOL> module_path , class_name = '<STR_LIT:.>' . join ( module_bits [ : - <NUM_LIT:1> ] ) , module_bits [ - <NUM_LIT:1> ] <EOL> module = importlib . import_module ( module_path ) <EOL> else : <EOL> raise ImportError ( "<STR_LIT>" % self . to ) <EOL> self . _to_class = getattr ( module , class_name , None ) <EOL> if self . _to_class is None : <EOL> raise ImportError ( "<STR_LIT>" % ( module_path , class_name ) ) <EOL> return self . _to_class <EOL> def dehydrate_related ( self , bundle , related_resource ) : <EOL> """<STR_LIT>""" <EOL> if not self . full : <EOL> return related_resource . get_resource_uri ( bundle ) <EOL> else : <EOL> bundle = related_resource . build_bundle ( obj = related_resource . instance , request = bundle . request ) <EOL> return related_resource . full_dehydrate ( bundle ) <EOL> def resource_from_uri ( self , fk_resource , uri , request = None , related_obj = None , related_name = None ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> obj = fk_resource . get_via_uri ( uri , request = request ) <EOL> bundle = fk_resource . build_bundle ( obj = obj , request = request ) <EOL> return fk_resource . full_dehydrate ( bundle ) <EOL> except NotFound : <EOL> raise ApiFieldError ( "<STR_LIT>" % uri ) <EOL> def resource_from_data ( self , fk_resource , data , request = None , related_obj = None , related_name = None ) : <EOL> """<STR_LIT>""" <EOL> data = dict_strip_unicode_keys ( data ) <EOL> fk_bundle = fk_resource . build_bundle ( data = data , request = request ) <EOL> if related_obj : <EOL> fk_bundle . related_obj = related_obj <EOL> fk_bundle . related_name = related_name <EOL> if not fk_resource . can_update ( ) : <EOL> return fk_resource . full_hydrate ( fk_bundle ) <EOL> try : <EOL> return fk_resource . obj_update ( fk_bundle , ** data ) <EOL> except NotFound : <EOL> try : <EOL> lookup_kwargs = dict ( ( k , v ) for k , v in data . iteritems ( ) if getattr ( fk_resource , k ) . unique ) <EOL> if not lookup_kwargs : <EOL> raise NotFound ( ) <EOL> return fk_resource . obj_update ( fk_bundle , ** lookup_kwargs ) <EOL> except NotFound : <EOL> return fk_resource . full_hydrate ( fk_bundle ) <EOL> except : <EOL> return fk_resource . full_hydrate ( fk_bundle ) <EOL> def resource_from_pk ( self , fk_resource , obj , request = None , related_obj = None , related_name = None ) : <EOL> """<STR_LIT>""" <EOL> bundle = fk_resource . build_bundle ( obj = obj , request = request ) <EOL> return fk_resource . full_dehydrate ( bundle ) <EOL> def build_related_resource ( self , value , request = None , related_obj = None , related_name = None ) : <EOL> """<STR_LIT>""" <EOL> self . fk_resource = self . to_class ( ) <EOL> kwargs = { <EOL> '<STR_LIT>' : request , <EOL> '<STR_LIT>' : related_obj , <EOL> '<STR_LIT:related_name>' : related_name , <EOL> } <EOL> if isinstance ( value , basestring ) : <EOL> return self . resource_from_uri ( self . fk_resource , value , ** kwargs ) <EOL> elif hasattr ( value , '<STR_LIT>' ) : <EOL> return self . resource_from_data ( self . fk_resource , value , ** kwargs ) <EOL> elif hasattr ( value , '<STR_LIT>' ) : <EOL> return self . resource_from_pk ( self . fk_resource , value , ** kwargs ) <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( self . instance_name , value ) ) <EOL> class ToOneField ( RelatedField ) : <EOL> """<STR_LIT>""" <EOL> help_text = '<STR_LIT>' <EOL> def __init__ ( self , to , attribute , related_name = None , default = NOT_PROVIDED , <EOL> null = False , blank = False , readonly = False , full = False , <EOL> unique = False , help_text = None ) : <EOL> super ( ToOneField , self ) . __init__ ( <EOL> to , attribute , related_name = related_name , default = default , <EOL> null = null , blank = blank , readonly = readonly , full = full , <EOL> unique = unique , help_text = help_text <EOL> ) <EOL> self . fk_resource = None <EOL> def dehydrate ( self , bundle ) : <EOL> try : <EOL> foreign_obj = getattr ( bundle . obj , self . attribute ) <EOL> except : <EOL> foreign_obj = None <EOL> if not foreign_obj : <EOL> if not self . null : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( bundle . obj , self . attribute ) ) <EOL> return None <EOL> self . fk_resource = self . get_related_resource ( foreign_obj ) <EOL> fk_bundle = Bundle ( obj = foreign_obj , request = bundle . request ) <EOL> return self . dehydrate_related ( fk_bundle , self . fk_resource ) <EOL> def hydrate ( self , bundle ) : <EOL> value = super ( ToOneField , self ) . hydrate ( bundle ) <EOL> if value is None : <EOL> return value <EOL> return self . build_related_resource ( value , request = bundle . request ) <EOL> class ForeignKey ( ToOneField ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class OneToOneField ( ToOneField ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class ToManyField ( RelatedField ) : <EOL> """<STR_LIT>""" <EOL> is_m2m = True <EOL> help_text = '<STR_LIT>' <EOL> def __init__ ( self , to , attribute , related_name = None , default = NOT_PROVIDED , <EOL> null = False , blank = False , readonly = False , full = False , <EOL> unique = False , help_text = None ) : <EOL> super ( ToManyField , self ) . __init__ ( <EOL> to , attribute , related_name = related_name , default = default , <EOL> null = null , blank = blank , readonly = readonly , full = full , <EOL> unique = unique , help_text = help_text <EOL> ) <EOL> self . m2m_bundles = [ ] <EOL> def dehydrate ( self , bundle ) : <EOL> if not bundle . obj or not bundle . obj . pk : <EOL> if not self . null : <EOL> raise ApiFieldError ( "<STR_LIT>" % bundle . obj ) <EOL> return [ ] <EOL> the_m2ms = None <EOL> if isinstance ( self . attribute , basestring ) : <EOL> the_m2ms = getattr ( bundle . obj , self . attribute ) <EOL> elif callable ( self . attribute ) : <EOL> the_m2ms = self . attribute ( bundle ) <EOL> if not the_m2ms : <EOL> if not self . null : <EOL> raise ApiFieldError ( "<STR_LIT>" % ( bundle . obj , self . attribute ) ) <EOL> return [ ] <EOL> self . m2m_resources = [ ] <EOL> m2m_dehydrated = [ ] <EOL> for m2m in the_m2ms . all ( ) : <EOL> m2m_resource = self . get_related_resource ( m2m ) <EOL> m2m_bundle = Bundle ( obj = m2m , request = bundle . request ) <EOL> self . m2m_resources . append ( m2m_resource ) <EOL> m2m_dehydrated . append ( self . dehydrate_related ( m2m_bundle , m2m_resource ) ) <EOL> return m2m_dehydrated <EOL> def hydrate ( self , bundle ) : <EOL> pass <EOL> def hydrate_m2m ( self , bundle ) : <EOL> if self . readonly : <EOL> return None <EOL> if bundle . data . get ( self . instance_name ) is None : <EOL> if self . blank : <EOL> return [ ] <EOL> elif self . null : <EOL> return [ ] <EOL> else : <EOL> raise ApiFieldError ( "<STR_LIT>" % self . instance_name ) <EOL> m2m_hydrated = [ ] <EOL> for value in bundle . data . get ( self . instance_name ) : <EOL> if value is None : <EOL> continue <EOL> kwargs = { <EOL> '<STR_LIT>' : bundle . request , <EOL> } <EOL> if self . related_name : <EOL> kwargs [ '<STR_LIT>' ] = bundle . obj <EOL> kwargs [ '<STR_LIT:related_name>' ] = self . related_name <EOL> m2m_hydrated . append ( self . build_related_resource ( value , ** kwargs ) ) <EOL> return m2m_hydrated <EOL> class ManyToManyField ( ToManyField ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class OneToManyField ( ToManyField ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class TimeField ( ApiField ) : <EOL> dehydrated_type = '<STR_LIT:time>' <EOL> help_text = '<STR_LIT>' <EOL> def dehydrate ( self , obj ) : <EOL> return self . convert ( super ( TimeField , self ) . dehydrate ( obj ) ) <EOL> def convert ( self , value ) : <EOL> if isinstance ( value , basestring ) : <EOL> return self . to_time ( value ) <EOL> return value <EOL> def to_time ( self , s ) : <EOL> try : <EOL> dt = parse ( s ) <EOL> except ValueError , e : <EOL> raise ApiFieldError ( str ( e ) ) <EOL> else : <EOL> return datetime . time ( dt . hour , dt . minute , dt . second ) <EOL> def hydrate ( self , bundle ) : <EOL> value = super ( TimeField , self ) . hydrate ( bundle ) <EOL> if value and not isinstance ( value , datetime . time ) : <EOL> value = self . to_time ( value ) <EOL> return value </s>
