
^Q\^U                 @   s|  d  Z  y d d l m Z Wn" e k
 r> d d l m Z Yn Xd d l Z d d l Z d d l m Z d d l m	 Z	 m
 Z
 d d l Z d d l m Z y d d l m Z m Z Wn( e k
 r d d l m Z d Z Yn Xd d	 l m Z d d
 l m Z m Z m Z d d l m Z d d l m Z m Z d d l m Z d d l  m! Z! y4 d d l" m# Z# d d l" m$ Z$ d d l% m& Z& WnH e e! f k
 rd d l' m# Z# d d l' m$ Z$ d d l( m& Z& Yn Xd d l) m* Z* d d l( m+ Z+ e j, e-  Z. d d   Z/ d d   Z0 Gd d   d e  Z1 e d d    Z2 Gd d   d e  Z d d    Z d! d"   Z3 d# d$   Z4 d S)%z

    This code mainly comes from @glenrobertson's django-geoson-tiles at:
    https://github.com/glenrobertson/django-geojson-tiles/

    Itself, adapted from @jeffkistler's geojson serializer at: https://gist.github.com/967274
    )StringION)contextmanager)string_types	iteritems)Model)QuerySetValuesQuerySet)r   )model_to_dict)
_get_model
SerializerDeserializer)DjangoJSONEncoder)SerializationErrorDeserializationError)
smart_text)ImproperlyConfigured)	WKBWriter)GEOSGeometry)GeometryField   )GEOJSON_DEFAULT_SRID)GeoJSONFieldc             C   s)   t  |  t  r | |  k S| t |   k S)N)
isinstancedictdir)objname r   J/var/www/dbchiro/venv/lib/python3.4/site-packages/djgeojson/serializers.pyhasattr_lazy5   s    
r   c             C   s!   t  j d k  r |  j S|  j Sd S)z" For Django 1.8/2.0 compatibility r   	   N)r   r    )djangoVERSIONrelremote_field)fieldr   r   r   get_field_remote_field;   s    r&   c                   s"   e  Z d  Z   f d d   Z   S)DjangoGeoJSONEncoderc                s9   t  | t  r t j | j  St t |   j |  Sd  S)N)r   r   jsonloadsZgeojsonsuperr'   default)selfo)	__class__r   r   r+   E   s    zDjangoGeoJSONEncoder.default)__name__
__module____qualname__r+   r   r   )r.   r   r'   C   s   r'   c             #   s   t  t j d  } zg  d k	 rt  f d d     | sU t j j }   t j _ qt G  f d d   d |  } n  | VWd  d k	 r | s | t j _ q n  Xd S)zE
    Context manager to set float precision during json encoding
    
FLOAT_REPRNc                s   t  |  d    S)Nz.%sf)format)r-   )	precisionr   r   
float_reprT   s    z/json_encoder_with_precision.<locals>.float_reprc                   s.   e  Z d  Z e j Z d   f d d  Z d S)z5json_encoder_with_precision.<locals>.JSONEncoderClassFc                s  |  j  r i  } n d } |  j r0 t j j } n t j j } |  j   t j j t j j d d  } | r t j j d k	 r |  j	 d k r t j j | |  j
 | |  j	 |  j |  j |  j |  j |  j 	 } n? t j j | |  j
 | |  j	 | |  j |  j |  j |  j | 
 } | | d  S)a(  Encode the given object and yield each string
                        representation as available.

                        For example::

                            for chunk in JSONEncoder().iterencode(bigobject):
                                mysocket.write(chunk)

                        Nc             S   sl   |  |  k r d } n4 |  | k r* d } n |  | k r? d } n
 | |   S| sh t  d t |     n  | S)NZNaNZInfinityz	-Infinityz2Out of range float values are not JSON compliant: )
ValueErrorrepr)r-   	allow_nanZ_reprZ_infZ_neginftextr   r   r   floatstrw   s    			
zRjson_encoder_with_precision.<locals>.JSONEncoderClass.iterencode.<locals>.floatstrr   )Zcheck_circularZensure_asciir(   encoderZencode_basestring_asciiZencode_basestringr8   ZINFINITYZc_make_encoderindentr+   Zkey_separatorZitem_separatorZ	sort_keysZskipkeysZ_make_iterencode)r,   r-   Z	_one_shotmarkersZ_encoderr:   Z_iterencode)r5   r   r   
iterencoded   s"    
			('		z@json_encoder_with_precision.<locals>.JSONEncoderClass.iterencodeN)r/   r0   r1   float__repr__r2   r>   r   )r5   r   r   JSONEncoderClass^   s   	rA   )hasattrr(   r;   r2   )r4   rA   Zneeds_class_hackZoriginal_float_reprr   )r5   r4   r   json_encoder_with_precisionL   s    9	rC   c               @   s   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z d  S)!r   Fc             C   st   i d d 6g  d 6|  _  |  j d k	 r< |  j   |  j  d <n  |  j j d d   } | rg | |  j  d <n  d  |  _ d  S)NZFeatureCollectiontypefeaturesFcrsbbox)feature_collectionrF   get_crsoptionspop_current)r,   rG   r   r   r   start_serialization   s    zSerializer.start_serializationc             C   s   i  } |  j  j d d   } i  } | d k rG d t |  j  | d <n' d } d t |  j  | d <d | d <| | d <| | d	 <| S)
Ncrs_typer   zEPSG:%slinkz(http://spatialreference.org/ref/epsg/%s/ZhrefZproj4rD   
properties)rJ   rK   strsrid)r,   rF   rN   rP   r   r   r   rI      s    


zSerializer.get_crsc             C   s   i d d 6i  d 6|  _  d  } |  j rJ t |  j d  rJ |  j |  } nj |  j r t |  j t  r t | t  r t | |  j  } q | |  j } n t | t  r | j } n  | r | |  j  d <n  d  S)NFeaturerD   rP   __call__id)rL   primary_keyrB   r   r   r   getattrpk)r,   r   rV   r   r   r   start_object   s    zSerializer.start_objectc                se  g  } t    j t  r=   f d d     j j   D } n7 t    j t t f  rt   f d d     j D } n  x0 | D]( } t | |  r{   j | |  q{ q{ W  j j	 d d  } t
 | d  r | r t | j    j d d <n  d	   j k rAt |   j  r1t |   j  }   j |  qAt j d
  n    j d j   j  d    _ d  S)Nc                s/   g  |  ]% \ } } |   j  d  k r |  q S)rP   )rL   ).0r%   r   )r,   r   r   
<listcomp>   s   	 	z)Serializer.end_object.<locals>.<listcomp>c                s)   g  |  ] } |   j  d  k r |  q S)rP   )rL   )rZ   r%   )r,   r   r   r[      s   	 with_modelnameT_metarP   modelgeometryz No GeometryField found in objectrE   )r   rP   r   itemslisttupler   handle_fieldrJ   rK   rB   r   r]   rL   geometry_fieldrW   _handle_geomloggerwarnrH   append)r,   r   extrasr%   r\   r_   r   )r,   r   
end_object   s$    %zSerializer.end_objectc             C   s7  |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d d   |  j  j d	 d   |  j  j d
 d   |  j  j d d   |  j  j d d   |  j  j d d   } t | t  ) } t j |  j |  j d | |  j  Wd  QXd  S)NstreamrP   rV   rd   use_natural_keysrF   rR   force2dsimplifyrG   	bbox_autor\   r4   cls)rJ   rK   rC   r'   r(   dumprH   rk   )r,   r4   rp   r   r   r   end_serialization   s    zSerializer.end_serializationc             C   sw  | d k r d } nQt  | t  r9 d | k r9 | } n-t  | t  rQ | } nD y t |  } Wn1 t k
 r d |  j | f } t |   Yn X|  j j d  r t   } d | _	 t | j
 |  d | j } n  |  j j d  } | d k	 r| j d | d	 d
  } n  | j rA| j |  j k rA| j |  j  n  |  j j d  rf| j |  j d <n  | |  j d <d S)z6 Geometry processing (in place), depending on options NrD   z>The field ["%s", "%s"] could not be parsed as a valid geometryrm      rR   rn   Z	toleranceZpreserve_topologyTro   rG   r_   )r   r   r   r6   rd   r   rJ   getr   ZoutdimwriterR   rn   	transformZextentrL   )r,   valuer_   Z	error_msgZwkb_wrn   r   r   r   re     s0    					!zSerializer._handle_geomc             C   s   t  | t  r! t | |  } n  t  | t  r= | | } n d  S| |  j k r` |  j |  n| |  j r | |  j k r t  |  j t  r |  j | } | |  j d | <q | |  j d | <n |  j s | |  j d | <n  d  S)NrP   )r   r   rW   r   rd   re   rP   rL   )r,   r   
field_namerw   Zproperty_namer   r   r   rc   +  s    	zSerializer.handle_fieldc             C   s,   t  t |  j d d    r( |  j j   Sd  S)Ngetvalue)callablerW   rk   ry   )r,   r   r   r   ry   B  s    zSerializer.getvaluec             C   s   t  | | j  } | d  k	 r |  j rE t | d  rE | j   } q t |  j | j j j k rr | j	   } q t
 t  | t |  j  d d } n  | |  j d | j <d  S)Nnatural_keystrings_onlyTrP   )rW   r   rl   rB   r{   r&   rx   r]   rX   _get_pk_valr   rL   )r,   r   r%   relatedr   r   r   handle_fk_fieldF  s    'zSerializer.handle_fk_fieldc                s   t  |  j j j r t  |  } t j d
 k  r< | j } n	 | j } |  j rl t	 | d  rl d d     n d d       f d d   t
 | | j  j   D |  j d	 | j <n  d  S)Nr   r    r{   c             S   s
   |  j    S)N)r{   )rw   r   r   r   	m2m_value\  s    z.Serializer.handle_m2m_field.<locals>.m2m_valuec             S   s   t  |  j   d d S)Nr|   T)r   r}   )rw   r   r   r   r   _  s    c                s   g  |  ] }   |   q Sr   r   )rZ   r~   )r   r   r   r[   a  s   	z/Serializer.handle_m2m_field.<locals>.<listcomp>rP   )r   r    )r&   Zthroughr]   Zauto_createdr!   r"   ZtoZrelated_modelrl   rB   rW   r   iteratorrL   )r,   r   r%   r$   Zremote_modelr   )r   r   handle_m2m_fieldT  s    	zSerializer.handle_m2m_fieldc                ss   |  j  r* t | j d  r* d d     n d d       f d d   t | |  j   D } | |  j d | <d  S)Nr{   c             S   s
   |  j    S)N)r{   )rw   r   r   r   reverse_valuef  s    z6Serializer.handle_reverse_field.<locals>.reverse_valuec             S   s   t  |  j   d d S)Nr|   T)r   r}   )rw   r   r   r   r   i  s    c                s   g  |  ] }   |   q Sr   r   )rZ   r~   )r   r   r   r[   k  s   	 z3Serializer.handle_reverse_field.<locals>.<listcomp>rP   )rl   rB   r^   rW   r   rL   )r,   r   r%   rx   valuesr   )r   r   handle_reverse_fieldd  s
    (zSerializer.handle_reverse_fieldc                s   t  |  d k r d  St | d t  s g  } x | D]   t    } |  j | k rs t   |  j  | |  j <n  |  j r   f d d   |  j D } x$ | D] } t   |  | | <q Wn  | j |  q6 W| } n  |  j |  d  S)Nr   c                s%   g  |  ] } t    |  r |  q Sr   )rB   )rZ   f)r   r   r   r[   {  s   	 z4Serializer.serialize_object_list.<locals>.<listcomp>)	lenr   r   r	   rd   rW   rP   rh   serialize_values_queryset)r,   objectsr   Zobjdictri   rx   r   )r   r   serialize_object_listn  s    		z Serializer.serialize_object_listc             C   s   x | D] } |  j  |  |  j | |  j  xQ | D]I } | | k rL q4 n  |  j d  k sj | |  j k r4 |  j | |  q4 q4 W|  j |  q Wd  S)N)rY   rc   rd   rP   rj   )r,   querysetr   rx   r   r   r   r     s    z$Serializer.serialize_values_querysetc       	      C   sT  | j  j } | j } | j } d d   t |  D } | d d   t |  D 7} x| D]} |  j |  |  j | |  j  x | D] } | j	 | j
 j	 k r |  j d  k s d |  j k r q n  t | t  r q n  | j s | j r t |  d  k r:|  j d  k s!| j |  j k rx|  j | | j	  qxq{|  j d  k se| j d  d  |  j k r{|  j | |  q{q q WxN | D]F } | j r|  j d  k s| j |  j k r|  j | |  qqqWxl | D]d } | j rt |  j p| j j   } |  j d  k s"| |  j k r;|  j | | |  q;qqW|  j |  q[ Wd  S)Nc             S   s   g  |  ] } | j   q Sr   )r%   )rZ   r   r   r   r   r[     s   	 z1Serializer.serialize_queryset.<locals>.<listcomp>c             S   s   g  |  ] } | j   q Sr   )r%   )rZ   r   r   r   r   r[     s   	 rU      )r^   r]   local_fieldsmany_to_manyget_all_related_objects$get_all_related_many_to_many_objectsrY   rc   rd   r   rX   rP   r   r   	serializerV   r&   Zattnamer   r   Zrelated_nameZobject_namelowerr   rj   )	r,   r   optsr   Zmany_to_many_fieldsZreversed_fieldsr   r%   rx   r   r   r   serialize_queryset  s<    		!+	!	zSerializer.serialize_querysetc             K   sM  | |  _  | j d t    |  _ | j d d  |  _ | j d  |  _ | j d d  |  _ | j d d  |  _ | j d	 d  |  _ | j d
 d  |  _	 | j d t
  |  _ | j d d  |  _ |  j   t d k	 r t | t  r |  j |  n> t | t  r|  j |  n t | t  r9|  j |  n  |  j   |  j   S)z'
        Serialize a queryset.
        rk   rV   NrP   rd   geomrl   FrG   ro   rR   rF   T)rJ   rt   r   rk   rV   rP   rd   rl   rG   ro   r   rR   rF   rM   r   r   r   ra   r   r   r   rr   ry   )r,   r   rJ   r   r   r   r     s&    	

zSerializer.serializeN)r/   r0   r1   Zinternal_use_onlyrM   rI   rY   rj   rr   re   rc   ry   r   r   r   r   r   r   r   r   r   r   r   r      s    '
.r   c             +   s    j  d d     f d d     t |  t  rE t |   } n |  } yO t j |  }   f d d   | d D } x t |   D] } | Vq WWnK t k
 r   Yn7 t k
 r } z t	 t
 |    WYd d } ~ Xn Xd S)	z6
    Deserialize a stream or string of JSON data.
    rd   r   c       
         s  |  d }  j  d  p% | j d  } t |  } d d   | j j D } i  } x3 t |  D]% \ } } | | k r` | | | <q` q` Wi | d 6|  j  d  p | j  d  d 6| d 6} t | j j    t  r |  d	 | d   <n* t	 t
 j |  d	   }	 |	 j | d   <| S)
NrP   
model_namer^   c             S   s   g  |  ] } | j   q Sr   )r   )rZ   r   r   r   r   r[     s   	 z9Deserializer.<locals>.FeatureToPython.<locals>.<listcomp>rU   rX   fieldsr_   )rt   rK   r
   r]   r   r   r   	get_fieldr   r   r(   dumpsZwkt)
ZdictobjrP   r   r^   field_namesr   kvr   shape)rd   rJ   r   r   FeatureToPython  s"    

z%Deserializer.<locals>.FeatureToPythonc                s   g  |  ] }   |   q Sr   r   )rZ   r   )r   r   r   r[     s   	 z Deserializer.<locals>.<listcomp>rE   N)rt   r   r   r   r(   loadPythonDeserializerGeneratorExit	Exceptionr   r7   )stream_or_stringrJ   rk   Z
collectionr   r   er   )r   rd   rJ   r   r     s    r   c             C   s1   t  j d k  r |  j   Sd d   |  j D Sd S)a  
    Django 1.8 changed meta api, see
    https://docs.djangoproject.com/en/1.8/ref/models/meta/#migrating-old-meta-api
    https://code.djangoproject.com/ticket/12663
    https://github.com/django/django/pull/3848
    Initially from Django REST Framework:
    https://github.com/tomchristie/django-rest-framework/blob/3.3.2/rest_framework/compat.py
    :param opts: Options instance
    :return: list of relations except many-to-many ones
    r      c             S   s"   g  |  ] } | j  j s |  q Sr   )r%   r   )rZ   rr   r   r   r[     s   	 z+get_all_related_objects.<locals>.<listcomp>N)r   r   )r!   r"   r   related_objects)r   r   r   r   r     s    
r   c             C   s1   t  j d k  r |  j   Sd d   |  j D Sd S)z
    Django 1.8 changed meta api, see docstr in get_all_related_objects()

    :param opts: Options instance
    :return: list of many-to-many relations
    r   r   c             S   s"   g  |  ] } | j  j r |  q Sr   )r%   r   )rZ   r   r   r   r   r[   '  s   	 z8get_all_related_many_to_many_objects.<locals>.<listcomp>N)r   r   )r!   r"   r   r   )r   r   r   r   r     s    
r   )5__doc__	cStringIOr   ImportErrorsixr(   logging
contextlibr   r   r   r!   Zdjango.db.models.baser   Zdjango.db.models.queryr   r   Zdjango.forms.modelsr	   Zdjango.core.serializers.pythonr
   r   ZPythonSerializerr   r   Zdjango.core.serializers.jsonr   Zdjango.core.serializers.baser   r   Zdjango.utils.encodingr   Zdjango.core.exceptionsr   Zdjango.contrib.gis.geosr   r   Z#django.contrib.gis.db.models.fieldsr   Znogeosr    r   r   	getLoggerr/   rf   r   r&   r'   rC   r   r   r   r   r   r   <module>   sR   	S A-