B
    `1                 @   sf   d dl Z d dlmZmZ ddlmZ dZeddZG dd	 d	ZG d
d dZG dd de	edZ
dS )    N)datetime	timedelta   )FilterableMetaclassz%Y-%m-%dT%H:%M:%S   )secondsc            	   @   s   e Zd ZdddZdS )PropertyFNc
       
      C   s:   || _ || _|| _|| _|| _|| _|| _|| _|	| _dS )a  
        A Property is an attribute returned from the API, and defines metadata
        about that value.  These are expected to be used as the values of a
        class-level dict named 'properties' in subclasses of Base.

        mutable - This Property should be sent in a call to save()
        identifier - This Property identifies the object in the API
        volatile - Re-query for this Property if the local value is older than the
            volatile refresh timeout
        relationship - The API Object this Property represents
        derived_class - The sub-collection type this Property represents
        is_datetime - True if this Property should be parsed as a datetime.datetime
        filterable - True if the API allows filtering on this property
        id_relationship - This Property should create a relationship with this key as the ID
            (This should be used on fields ending with '_id' only)
        slug_relationship - This property is a slug related for a given type.
        N)	mutable
identifiervolatilerelationshipderived_classis_datetime
filterableid_relationshipslug_relationship)
selfr	   r
   r   r   r   r   r   r   r    r   G/home/dcms/DCMS/lib/python3.7/site-packages/linode_api4/objects/base.py__init__   s    zProperty.__init__)	FFFNNFFFF)__name__
__module____qualname__r   r   r   r   r   r      s     r   c               @   s4   e Zd ZdZdd Zdd Zdd Zedd	 Zd
S )MappedObjectz
    Converts a dict into values accessible with the dot notation.

    object = {
        "this": "that"
    }

    becomes

    object.this # "that"
    c             K   s   | j | jf| d S )N)_expand_vals__dict__)r   valsr   r   r   r   8   s    zMappedObject.__init__c             K   sf   xV|D ]N}t || tkr.tf || ||< qt || tkrdd || D ||< qW || d S )Nc             S   s&   g | ]}t |tkrtf |n|qS r   )typedictr   ).0ir   r   r   
<listcomp>A   s    z-MappedObject._expand_vals.<locals>.<listcomp>)r   r   r   listupdate)r   targetr   vr   r   r   r   ;   s    
zMappedObject._expand_valsc             C   s   d t|  S )NzMapping containing {})formatvarskeys)r   r   r   r   __repr__D   s    zMappedObject.__repr__c             C   s
   t | jS )N)r   r   )r   r   r   r   r   G   s    zMappedObject.dictN)	r   r   r   __doc__r   r   r)   propertyr   r   r   r   r   r   ,   s
   	r   c               @   s   e Zd ZdZi Zi f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edd ZedddZed ddZdS )!Basez\
    The Base class knows how to look up api properties of a model, and lazy-load them.
    c             C   s   |  dd |  dtj |  d| |  dd  xt| jD ]}|  |d  q>W |  d| tt| dr|  tt| d| | | d S )N
_populatedF_last_updated_client	_raw_jsonidZid_attribute)_setr   minr   
propertieshasattrgetattr	_populate)r   clientr1   jsonpropr   r   r   r   Q   s    zBase.__init__c          
   C   sL  |t | j krt | j| jr$nt| |dkr:| jrrt | j| jsrt | j| jrt| dt	 t
 k rt | j| jr| |t | j| j| t| d n|   nd|t | j kr@t | jd| j}|r@t| d|sdS d|}t| |s4| ||| jt| d| t| |S t| |S )z
        Handles lazy-loading/refreshing an object from the server, and
        getting related objects, as defined in this object's 'properties'
        Nr.   r/   z{}_idz_{}_relcache)r   r4   r(   r
   object__getattribute__r-   r   r   volatile_refresh_timeoutr   nowr2   Z_api_get_derivedr6   _api_getr&   r   r5   r/   )r   nameZrelated_typeZrelcache_namer   r   r   r<   e   s,    


 zBase.__getattribute__c             C   s   d t| j| jS )z[
        Returns a safe representation of this object without accessing the server
        z{}: {})r&   r   r   r1   )r   r   r   r   r)      s    zBase.__repr__c             C   sH   |t | j kr8t | j| js8td|t | j| || dS )zQ
        Enforces allowing editing of only Properties defined as mutable
        z#'{}' is not a mutable field of '{}'N)r   r4   r(   r	   AttributeErrorr&   r   r2   )r   r@   valuer   r   r   __setattr__   s    "zBase.__setattr__c             C   s,   | j jt| j| |  d}d|kr(dS dS )zR
        Send this object's mutable values to the server in a PUT request
        )modeldataerrorFT)r/   putr   api_endpoint
_serialize)r   respr   r   r   save   s
    z	Base.savec             C   s.   | j jt| j| d}d|kr"dS |   dS )z8
        Sends a DELETE request for this object
        )rD   rF   FT)r/   deleter   rH   
invalidate)r   rJ   r   r   r   rL      s
    zBase.deletec                sB   x0 fddt  j D D ]} |d qW  dd dS )z
        Invalidates all non-identifier Properties this object has locally,
        causing the next access to re-fetch them from the server
        c                s    g | ]}t  j| js|qS r   )r   r4   r
   )r   k)r   r   r   r!      s    z#Base.invalidate.<locals>.<listcomp>Nr-   F)r   r4   r(   r2   )r   keyr   )r   r   rM      s    "zBase.invalidatec                s\    fddt  jD }x>| D ]2\}}t|tr@|j||< q"t|tr"|j||< q"W |S )zb
        A helper method to build a dict of all mutable Properties of
        this object
        c                s(   i | ] }t  j| jrt ||qS r   )r   r4   r	   r6   )r   a)r   r   r   
<dictcomp>   s    z#Base._serialize.<locals>.<dictcomp>)r   r4   items
isinstancer,   r1   r   r   )r   resultrN   r%   r   )r   r   rI      s    

zBase._serializec             C   s$   | j jt| j| d}| | dS )zD
        A helper method to GET this object from the server
        )rD   N)r/   getr   rH   r7   )r   r9   r   r   r   r?      s    zBase._api_getc       
   	      s  |sdS   d| xN|D ]D}| fddt j D krt j| jrT|| dk	rTt|| trg }xX|| D ]L}d|krq~t j| j}||d t d}|r|	| |
| q~W   || nvt|| tr|| d }n|| }t j| j}||t d}|rFt|| trF|	||    || qt j| jr|| dk	r  |t j|  j||  qt|| tkrĈ  |tf ||  qt|| tkrt|| d}  ||j qt j| jrRy,t|| t}	  |tt|	 W n     |||  Y nX q  |||  qW   dd	   d
t  dS )z
        A helper method that, given a JSON object representing this object,
        assigns values based on the properties dict and the attributes of
        its Properties.
        Nr0   c             3   s"   | ]}t  j| js|V  qd S )N)r   r4   r
   )r   rN   )r   r   r   	<genexpr>   s    z!Base._populate.<locals>.<genexpr>r1   r/   )_listr-   Tr.   )r2   r   r4   r(   r   rS   r"   make_instancer6   r7   appendr   r   r/   r   rW   r   timestrptimeDATE_FORMATr   fromtimestampmktimer>   )
r   r9   rO   objsd	new_classobjZ
related_idmappingtr   )r   r   r7      sX     

&zBase._populatec             C   s   t | || dS )zq
        A helper method to set values of Properties without invoking
        the overloaded __setattr__
        N)r;   rC   )r   r@   rB   r   r   r   r2     s    z	Base._setc             C   s   d | jddd S )zd
        Returns a URL that will produce a list of JSON objects
        of this class' type
        /N)joinrH   split)clsr   r   r   api_list  s    zBase.api_listNc             C   s4   ddl m} t||r$||| ||S ||| |S dS )a  
        Makes an api object based on an id and class.

        :param id: The id of the object to create
        :param client: The LinodeClient to give the new object
        :param cls: The class type to instantiate
        :param parent_id: The parent id for derived classes
        :param json: The JSON to use to populate the new class

        :returns: An instance of cls with the given id
        r   )DerivedBaseN)Zdbaserk   
issubclass)r1   r8   ri   	parent_idr9   rk   r   r   r   make   s    
z	Base.makec             C   s   t j||| ||dS )a  
        Makes an instance of the class this is called on and returns it.

        The intended usage is:
          instance = Linode.make_instance(123, client, json=response)

        :param cls: The class this was called on.
        :param id: The id of the instance to create
        :param client: The client to use for this instance
        :param parent_id: The parent id for derived classes
        :param json: The JSON to populate the instance with

        :returns: A new instance of this type, populated with json
        )rm   r9   )r,   rn   )ri   r1   r8   rm   r9   r   r   r   rX   4  s    zBase.make_instance)NN)NN)r   r   r   r*   r4   r   r<   r)   rC   rK   rL   rM   rI   r?   r7   r2   classmethodrj   staticmethodrn   rX   r   r   r   r   r,   K   s$   $	Ar,   )	metaclass)rZ   r   r   Z	filteringr   r\   r=   r   r   r;   r,   r   r   r   r   <module>   s   
