<s> import copy <EOL> import decimal <EOL> import os <EOL> import re <EOL> import uuid <EOL> from datetime import datetime , date , time <EOL> from StringIO import StringIO <EOL> from urlparse import urlparse <EOL> import pygit2 <EOL> from gitmodel . utils import isodate , json <EOL> from gitmodel . exceptions import ValidationError , FieldError <EOL> INVALID_PATH_CHARS = ( '<STR_LIT:/>' , '<STR_LIT>' ) <EOL> class NOT_PROVIDED : <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' <EOL> class Field ( object ) : <EOL> """<STR_LIT>""" <EOL> creation_counter = <NUM_LIT:0> <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> serializable = True <EOL> empty_value = None <EOL> def __init__ ( self , name = None , id = False , default = NOT_PROVIDED , <EOL> required = True , readonly = False , unique = False , serialize = True , <EOL> autocreated = False , error_messages = None ) : <EOL> self . model = None <EOL> self . name = name <EOL> self . id = id <EOL> self . _default = default <EOL> self . required = required <EOL> self . readonly = readonly <EOL> self . value = self . empty_value <EOL> self . unique = unique <EOL> self . serializeable = self . serializable and serialize <EOL> self . autocreated = autocreated <EOL> messages = { } <EOL> for c in reversed ( type ( self ) . __mro__ ) : <EOL> messages . update ( getattr ( c , '<STR_LIT>' , { } ) ) <EOL> messages . update ( error_messages or { } ) <EOL> self . error_messages = messages <EOL> self . creation_counter = Field . creation_counter <EOL> Field . creation_counter += <NUM_LIT:1> <EOL> def contribute_to_class ( self , cls , name ) : <EOL> field = self <EOL> field . name = name <EOL> if field . model : <EOL> field = copy . copy ( field ) <EOL> field . model = cls <EOL> cls . _meta . add_field ( field ) <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 self . has_default ( ) : <EOL> if callable ( self . _default ) : <EOL> return self . _default ( ) <EOL> return self . _default <EOL> return <EOL> def empty ( self , value ) : <EOL> """<STR_LIT>""" <EOL> return value is None or value == self . empty_value <EOL> def __cmp__ ( self , other ) : <EOL> return cmp ( self . creation_counter , other . creation_counter ) <EOL> def to_python ( self , value ) : <EOL> """<STR_LIT>""" <EOL> return value <EOL> def get_raw_value ( self , model_instance ) : <EOL> """<STR_LIT>""" <EOL> return getattr ( model_instance , self . name ) <EOL> def validate ( self , value , model_instance ) : <EOL> """<STR_LIT>""" <EOL> if self . required and self . empty ( value ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> if self . id and any ( c in value for c in INVALID_PATH_CHARS ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> def clean ( self , value , model_instance ) : <EOL> """<STR_LIT>""" <EOL> value = self . to_python ( value ) <EOL> self . validate ( value , model_instance ) <EOL> return value <EOL> def serialize ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> value = getattr ( obj , self . name ) <EOL> return self . to_python ( value ) <EOL> def deserialize ( self , data , value ) : <EOL> """<STR_LIT>""" <EOL> return self . to_python ( value ) <EOL> def get_error_message ( self , error_code , default = '<STR_LIT>' , ** kwargs ) : <EOL> msg = self . error_messages . get ( error_code , default ) <EOL> kwargs [ '<STR_LIT>' ] = self <EOL> msg = msg . format ( ** kwargs ) <EOL> return '<STR_LIT>' . format ( name = self . name , err = msg ) <EOL> def post_save ( self , value , model_instance , commit = False ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class CharField ( Field ) : <EOL> """<STR_LIT>""" <EOL> empty_value = '<STR_LIT>' <EOL> def to_python ( self , value ) : <EOL> if value is None and not self . required : <EOL> return self . empty_value <EOL> if value is None : <EOL> return None <EOL> return unicode ( value ) <EOL> class SlugField ( CharField ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> } <EOL> def validate ( self , value , model_instance ) : <EOL> super ( SlugField , self ) . validate ( value , model_instance ) <EOL> slug_re = re . compile ( r'<STR_LIT>' ) <EOL> if not slug_re . match ( value ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class EmailField ( CharField ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def validate ( self , value , model_instance ) : <EOL> super ( EmailField , self ) . validate ( value , model_instance ) <EOL> email_re = re . compile ( <EOL> r"<STR_LIT>" <EOL> r"<STR_LIT>" <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' <EOL> r'<STR_LIT>' , <EOL> re . IGNORECASE ) <EOL> if not email_re . match ( value ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class URLField ( CharField ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def __init__ ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . schemes = kwargs . pop ( '<STR_LIT>' , None ) <EOL> super ( URLField , self ) . __init__ ( self , ** kwargs ) <EOL> def validate ( self , value , model_instance ) : <EOL> super ( URLField , self ) . validate ( value , model_instance ) <EOL> if self . empty ( value ) : <EOL> return <EOL> parsed = urlparse ( value ) <EOL> if not all ( ( parsed . scheme , parsed . hostname ) ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> if self . schemes and parsed . scheme . lower ( ) not in self . schemes : <EOL> schemes = '<STR_LIT:U+002CU+0020>' . join ( self . schemes ) <EOL> raise ValidationError ( '<STR_LIT>' , self , schemes = schemes ) <EOL> class BlobFieldDescriptor ( object ) : <EOL> def __init__ ( self , field ) : <EOL> self . field = field <EOL> self . data = None <EOL> def __get__ ( self , instance , instance_type = None ) : <EOL> if self . data is None : <EOL> workspace = instance . _meta . workspace <EOL> path = self . field . get_data_path ( instance ) <EOL> try : <EOL> blob = workspace . index [ path ] . oid <EOL> except KeyError : <EOL> return None <EOL> self . data = StringIO ( workspace . repo [ blob ] . data ) <EOL> return self . data <EOL> def __set__ ( self , instance , value ) : <EOL> if isinstance ( value , type ( self ) ) : <EOL> self . data = None <EOL> elif value is None : <EOL> self . data = None <EOL> elif hasattr ( value , '<STR_LIT>' ) : <EOL> self . data = StringIO ( value . read ( ) ) <EOL> else : <EOL> self . data = StringIO ( value ) <EOL> class BlobField ( Field ) : <EOL> """<STR_LIT>""" <EOL> serializable = False <EOL> def to_python ( self , value ) : <EOL> if hasattr ( value , '<STR_LIT>' ) : <EOL> return value <EOL> if value is None : <EOL> return None <EOL> return StringIO ( value ) <EOL> def post_save ( self , value , instance , commit = False ) : <EOL> if value is None : <EOL> return <EOL> workspace = instance . _meta . workspace <EOL> path = self . get_data_path ( instance ) <EOL> content = value . read ( ) <EOL> workspace . add_blob ( path , content ) <EOL> def get_data_path ( self , instance ) : <EOL> path = os . path . dirname ( instance . get_data_path ( ) ) <EOL> path = os . path . join ( path , self . name ) <EOL> return '<STR_LIT>' . format ( path ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( BlobField , self ) . contribute_to_class ( cls , name ) <EOL> setattr ( cls , name , BlobFieldDescriptor ( self ) ) <EOL> def deserialize ( self , data , value ) : <EOL> return BlobFieldDescriptor ( self ) <EOL> class IntegerField ( Field ) : <EOL> """<STR_LIT>""" <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> try : <EOL> value = float ( value ) <EOL> except ValueError : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> if value % <NUM_LIT:1> != <NUM_LIT:0> : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> return int ( value ) <EOL> class UUIDField ( CharField ) : <EOL> """<STR_LIT>""" <EOL> @ property <EOL> def default ( self ) : <EOL> return uuid . uuid4 ( ) . hex <EOL> class FloatField ( Field ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> try : <EOL> return float ( value ) <EOL> except ValueError : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class DecimalField ( Field ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def __init__ ( self , max_digits = None , decimal_places = None , ** kwargs ) : <EOL> self . max_digits = max_digits <EOL> self . decimal_places = decimal_places <EOL> super ( DecimalField , self ) . __init__ ( ** kwargs ) <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> if type ( value ) == float : <EOL> value = str ( value ) <EOL> try : <EOL> return decimal . Decimal ( value ) <EOL> except decimal . InvalidOperation : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class BooleanField ( Field ) : <EOL> def __init__ ( self , nullable = False , ** kwargs ) : <EOL> self . nullable = nullable <EOL> super ( BooleanField , self ) . __init__ ( ** kwargs ) <EOL> def to_python ( self , value ) : <EOL> if value is None and self . nullable : <EOL> return None <EOL> return bool ( value ) <EOL> class DateField ( Field ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return value <EOL> if isinstance ( value , datetime ) : <EOL> return value . date ( ) <EOL> if isinstance ( value , date ) : <EOL> return value <EOL> if isinstance ( value , basestring ) : <EOL> try : <EOL> return isodate . parse_iso_date ( value ) <EOL> except isodate . InvalidFormat : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> except isodate . InvalidDate : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class DateTimeField ( Field ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return value <EOL> if isinstance ( value , datetime ) : <EOL> return value <EOL> if isinstance ( value , date ) : <EOL> return datetime ( value . year , value . month , value . day ) <EOL> if isinstance ( value , basestring ) : <EOL> try : <EOL> return isodate . parse_iso_datetime ( value ) <EOL> except isodate . InvalidFormat : <EOL> try : <EOL> return isodate . parse_iso_date ( value ) <EOL> except isodate . InvalidFormat : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> except isodate . InvalidDate : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class TimeField ( Field ) : <EOL> default_error_messages = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' <EOL> } <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return value <EOL> if isinstance ( value , time ) : <EOL> return value <EOL> if isinstance ( value , basestring ) : <EOL> try : <EOL> return isodate . parse_iso_time ( value ) <EOL> except isodate . InvalidFormat : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> except isodate . InvalidDate : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> class RelatedFieldDescriptor ( object ) : <EOL> def __init__ ( self , field ) : <EOL> self . field = field <EOL> self . id = None <EOL> def __get__ ( self , instance , instance_type = None ) : <EOL> from gitmodel import models <EOL> if instance is None : <EOL> return self <EOL> value = instance . __dict__ [ self . field . name ] <EOL> if value is None or isinstance ( value , models . GitModel ) : <EOL> return value <EOL> return self . field . to_model . get ( value ) <EOL> def __set__ ( self , instance , value ) : <EOL> instance . __dict__ [ self . field . name ] = value <EOL> class RelatedField ( Field ) : <EOL> def __init__ ( self , model , ** kwargs ) : <EOL> self . _to_model = model <EOL> super ( RelatedField , self ) . __init__ ( ** kwargs ) <EOL> @ property <EOL> def to_model ( self ) : <EOL> if not self . workspace : <EOL> return self . _to_model <EOL> if isinstance ( self . _to_model , basestring ) : <EOL> if not self . workspace . models . get ( self . _to_model ) : <EOL> msg = "<STR_LIT>" . format ( self . _to_model ) <EOL> raise FieldError ( msg ) <EOL> return self . workspace . models [ self . _to_model ] <EOL> if hasattr ( self . _to_model , '<STR_LIT>' ) : <EOL> return self . _to_model <EOL> if self . workspace . models . get ( self . _to_model . __name__ ) : <EOL> return self . workspace . models [ self . _to_model . __name__ ] <EOL> return self . workspace . register_model ( self . to_model ) <EOL> def to_python ( self , value ) : <EOL> from gitmodel import models <EOL> if isinstance ( value , models . GitModel ) : <EOL> return value . get_id ( ) <EOL> return value <EOL> def serialize ( self , obj ) : <EOL> value = obj . __dict__ [ self . name ] <EOL> return self . to_python ( value ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( RelatedField , self ) . contribute_to_class ( cls , name ) <EOL> if hasattr ( cls , '<STR_LIT>' ) : <EOL> self . workspace = cls . _meta . workspace <EOL> setattr ( cls , name , RelatedFieldDescriptor ( self ) ) <EOL> class GitObjectFieldDescriptor ( object ) : <EOL> def __init__ ( self , field ) : <EOL> self . field = field <EOL> self . oid = None <EOL> def __get__ ( self , instance , instance_type = None ) : <EOL> if instance is None : <EOL> return self <EOL> value = instance . __dict__ [ self . field . name ] <EOL> if value is None or isinstance ( value , pygit2 . Object ) : <EOL> return value <EOL> return instance . _meta . workspace . repo [ value ] <EOL> def __set__ ( self , instance , value ) : <EOL> if isinstance ( value , pygit2 . Object ) : <EOL> value = value . oid . hex <EOL> elif isinstance ( value , pygit2 . Oid ) : <EOL> value = value . hex <EOL> instance . __dict__ [ self . field . name ] = value <EOL> class GitObjectField ( CharField ) : <EOL> """<STR_LIT>""" <EOL> default_error_messages = { <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> } <EOL> def __init__ ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> self . type = kwargs . pop ( '<STR_LIT:type>' , None ) <EOL> super ( GitObjectField , self ) . __init__ ( ** kwargs ) <EOL> def to_python ( self , value ) : <EOL> if not isinstance ( value , ( basestring , pygit2 . Oid , pygit2 . Object ) ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> if isinstance ( value , pygit2 . Oid ) : <EOL> return value . hex <EOL> return value <EOL> def clean ( self , value , model_instance ) : <EOL> raw_value = model_instance . __dict__ [ self . name ] <EOL> return super ( GitObjectField , self ) . clean ( raw_value , model_instance ) <EOL> def serialize ( self , obj ) : <EOL> value = obj . __dict__ [ self . name ] <EOL> return self . to_python ( value ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( GitObjectField , self ) . contribute_to_class ( cls , name ) <EOL> setattr ( cls , name , GitObjectFieldDescriptor ( self ) ) <EOL> def get_raw_value ( self , model_instance ) : <EOL> return model_instance . __dict__ [ self . name ] <EOL> def validate ( self , value , model_instance ) : <EOL> super ( GitObjectField , self ) . validate ( value , model_instance ) <EOL> oid = model_instance . __dict__ [ self . name ] <EOL> try : <EOL> obj = model_instance . _meta . workspace . repo [ oid ] <EOL> except ( ValueError , KeyError ) : <EOL> raise ValidationError ( '<STR_LIT>' , self ) <EOL> if self . type and not isinstance ( obj , self . type ) : <EOL> raise ValidationError ( '<STR_LIT>' , self , <EOL> type = self . type . __name__ ) <EOL> class JSONField ( CharField ) : <EOL> def to_python ( self , value ) : <EOL> if value is None : <EOL> return None <EOL> if isinstance ( value , dict ) : <EOL> return value <EOL> try : <EOL> return json . loads ( value ) <EOL> except ValueError , e : <EOL> raise ValidationError ( e ) </s>
