a
    |fE                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z
 ddlmZ zddlmZ W n eyz   dZY n0 ddlZddlmZ ddlmZ ddlmZ dd	lmZ ejjZd
ZdZedejZdZG dd de
Z G dd dej!Z"dd Z#dd Z$dd Z%dd Z&dd Z'dd Z(d@ddZ)d d! Z*d"d# Z+d$d% Z,d&d' Z-d(d) Z.d*d+ Z/d,d- Z0d.d/ Z1dAd1d2Z2dBd4d5Z3d6d7 Z4d8d9 Z5d:d; Z6d<d= Z7zdd>l8m9Z9 W n ey   e" Z9Y n0 ej:dj;e9d?Z<dS )Cz]Thread-local resource stack.

This module is not part of the public API surface of `gcloud`.
    N)local)timestamp_pb2)app_identity)HTTPConnection)configparser)PROJECT)CREDENTIALSz%Y-%m-%dT%H:%M:%S.%fZz%Y-%m-%dT%H:%M:%Sa  
    (?P<no_fraction>
        \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}  # YYYY-MM-DDTHH:MM:SS
    )
    \.                                       # decimal point
    (?P<nanos>\d{1,9})                       # nanoseconds, maybe truncated
    Z                                        # Zulu
z.~/.config/gcloud/configurations/config_defaultc                       sD   e Zd ZdZ fddZdd Zdd Zdd	 Zed
d Z	  Z
S )_LocalStackzManage a thread-local LIFO stack of resources.

    Intended for use in :class:`gcloud.datastore.batch.Batch.__enter__`,
    :class:`gcloud.storage.batch.Batch.__enter__`, etc.
    c                    s   t t|   g | _d S N)superr	   __init___stackself	__class__ ID:\Projects\storyit_web\backend\venv\Lib\site-packages\gcloud/_helpers.pyr   >   s    z_LocalStack.__init__c                 C   s   t t| jS )z)Iterate the stack in LIFO order.
        )iterreversedr   r   r   r   r   __iter__B   s    z_LocalStack.__iter__c                 C   s   | j | dS )z(Push a resource onto our stack.
        N)r   append)r   resourcer   r   r   pushG   s    z_LocalStack.pushc                 C   s
   | j  S )zPop a resource from our stack.

        :rtype: object
        :returns: the top-most resource, after removing it.
        :raises IndexError: if the stack is empty.
        )r   popr   r   r   r   r   L   s    z_LocalStack.popc                 C   s   t | jdkr| jd S dS )z~Get the top-most resource

        :rtype: object
        :returns: the top-most item, or None if the stack is empty.
        r   N)lenr   r   r   r   r   topU   s    z_LocalStack.top)__name__
__module____qualname____doc__r   r   r   r   propertyr   __classcell__r   r   r   r   r	   8   s   	r	   c                       sZ   e Zd ZdZedZdZeZdd Z	 fddZ
dd	 Zd
d Zdd Zdd Z  ZS )_UTCzeBasic UTC implementation.

    Implementing a small surface area to avoid depending on ``pytz``.
    r   UTCc                 C   s   | j S )zDaylight savings time offset.)_dstr   dtr   r   r   dstj   s    z_UTC.dstc                    s&   |j du r|j| dS tt| |S )z6Convert a timestamp from (naive) UTC to this timezone.Ntzinfo)r+   replacer   r$   fromutcr'   r   r   r   r-   n   s    
z_UTC.fromutcc                 C   s   | j S )zGet the name of this timezone._tznamer'   r   r   r   tznamet   s    z_UTC.tznamec                 C   s   | j S )zUTC offset of this timezone.)
_utcoffsetr'   r   r   r   	utcoffsetx   s    z_UTC.utcoffsetc                 C   s   d| j f S )Nz<%s>r.   r   r   r   r   __repr__|   s    z_UTC.__repr__c                 C   s   | j S r
   r.   r   r   r   r   __str__   s    z_UTC.__str__)r   r   r    r!   datetime	timedeltar&   r/   r1   r)   r-   r0   r2   r3   r4   r#   r   r   r   r   r$   `   s   
r$   c                 C   s&   t |ttfstd| |f t|S )a  Ensures an input is a tuple or list.

    This effectively reduces the iterable types allowed to a very short
    whitelist: list and tuple.

    :type arg_name: str
    :param arg_name: Name of argument to use in error message.

    :type tuple_or_list: sequence of str
    :param tuple_or_list: Sequence to be verified.

    :rtype: list of str
    :returns: The ``tuple_or_list`` passed in cast to a ``list``.
    :raises TypeError: if the ``tuple_or_list`` is not a tuple or list.
    z.Expected %s to be a tuple or list. Received %r)
isinstancetuplelist	TypeError)arg_nameZtuple_or_listr   r   r   _ensure_tuple_or_list   s
    r<   c                   C   s   t du rdS t  S )zGets the App Engine application ID if it can be inferred.

    :rtype: str or ``NoneType``
    :returns: App Engine application ID if running in App Engine,
              else ``None``.
    N)r   Zget_application_idr   r   r   r   _app_engine_id   s    r=   c                  C   s^   t t} | rZt| d2}| }t|d}|dW  d   S 1 sP0    Y  dS )zGets the project id from the credentials file if one is available.

    :rtype: str or ``NoneType``
    :returns: Project-ID from JSON credentials file if value exists,
              else ``None``.
    rbutf-8Z
project_idN)	osgetenvr   openreadjsonloadsdecodeget)Zcredentials_file_pathZcredentials_fileZcredentials_jsoncredentialsr   r   r   _file_project_id   s    
rI   c                  C   s~   g } z|  tjt W n ty,   Y n0 tjtddddd}|  | t	 }|
|  |drz|ddS dS )	aT  Retrieves the project ID from the gcloud command line tool.

    Files that cannot be opened with configparser are silently ignored; this is
    designed so that you can specify a list of potential configuration file
    locations.

    :rtype: str or ``NoneType``
    :returns: Project-ID from default configuration file else ``None``
    APPDATA ZgcloudZconfigurationsZconfig_defaultcoreprojectN)r   r@   path
expanduserDEFAULT_CONFIGURATION_PATHImportErrorjoinrA   r   RawConfigParserrC   has_sectionrG   )Zsearch_pathsZwindows_config_pathconfigr   r   r   _default_service_project_id   s    



rV   c                  C   s   d} d}ddi}t | dd}z\z:|jd||d | }|jd	krV| W W |  S W n tjyl   Y n0 W |  n
|  0 d
S )aQ  Gets the Compute Engine project ID if it can be inferred.

    Uses 169.254.169.254 for the metadata server to avoid request
    latency from DNS lookup.

    See https://cloud.google.com/compute/docs/metadata#metadataserver
    for information about this IP address. (This IP is also used for
    Amazon EC2 instances, so the metadata flavor is crucial.)

    See https://github.com/google/oauth2client/issues/93 for context about
    DNS latency.

    :rtype: str or ``NoneType``
    :returns: Compute Engine project ID if the metadata service is available,
              else ``None``.
    z169.254.169.254z&/computeMetadata/v1/project/project-idzMetadata-FlavorZGoogleg?)timeoutGET)headers   N)r   requestgetresponsestatusrC   closesocketerror)hostZuri_pathrY   
connectionresponser   r   r   _compute_engine_id   s    

rd   c                   C   s
   t tS )z2Gets the production project if it can be inferred.)r@   rA   r   r   r   r   r   _get_production_project   s    re   c                 C   sJ   | du rt  } | du rt } | du r*t } | du r8t } | du rFt } | S )a  Determine default project ID explicitly or implicitly as fall-back.

    In implicit case, supports three environments. In order of precedence, the
    implicit environments are:

    * GCLOUD_PROJECT environment variable
    * GOOGLE_APPLICATION_CREDENTIALS JSON file
    * Get default service project from
      ``$ gcloud beta auth application-default login``
    * Google App Engine application ID
    * Google Compute Engine project ID (from metadata server)

    :type project: str
    :param project: Optional. The project name to use as default.

    :rtype: str or ``NoneType``
    :returns: Default project if it can be determined.
    N)re   rI   rV   r=   rd   )rM   r   r   r   _determine_default_project   s    rf   c                 C   s   t | }|d S )zConvert a zone-aware datetime to integer milliseconds.

    :type when: :class:`datetime.datetime`
    :param when: the datetime to convert

    :rtype: int
    :returns: milliseconds since epoch for ``when``
      )_microseconds_from_datetime)whenmicrosr   r   r   _millis  s    	rk   c                 C   s   t tj| d S )zConvert timestamp to datetime, assuming UTC.

    :type value: float
    :param value: The timestamp to convert

    :rtype: :class:`datetime.datetime`
    :returns: The datetime object created from the value.
    )microseconds)_EPOCHr5   r6   valuer   r   r   _datetime_from_microseconds)  s    	rp   c                 C   s8   | j s| jtd} | t} tt|  d | j S )zConvert non-none datetime to microseconds.

    :type value: :class:`datetime.datetime`
    :param value: The timestamp to convert.

    :rtype: int
    :returns: The timestamp, in microseconds.
    r*   g    .A)	r+   r,   r%   
astimezoneintcalendartimegm	timetuplemicrosecondrn   r   r   r   rh   5  s    	
rh   c                 C   s   | durt | S dS )zConvert non-none datetime to timestamp, assuming UTC.

    :type value: :class:`datetime.datetime`, or None
    :param value: the timestamp

    :rtype: int, or ``NoneType``
    :returns: the timestamp, in milliseconds, or None
    N)rk   rn   r   r   r   _millis_from_datetimeF  s    	rw   c                 C   s&   | j d d d | j }|| jd  S )zBackport of timedelta.total_seconds() from python 2.7+.

    :type offset: :class:`datetime.timedelta`
    :param offset: A timedelta object.

    :rtype: int
    :returns: The total seconds (including microseconds) in the
              duration.
       <   gư>)dayssecondsrl   )offsetr{   r   r   r   _total_seconds_backportS  s    
r}   c                 C   s&   t jdd dk rt| S |  S dS )zVersion independent total seconds for a time delta.

    :type offset: :class:`datetime.timedelta`
    :param offset: A timedelta object.

    :rtype: int
    :returns: The total seconds (including microseconds) in the
              duration.
    N   )r~      )sysversion_infor}   total_seconds)r|   r   r   r   _total_secondsa  s    
r   c                 C   s   t j | tjtdS )zConvert a microsecond-precision timetamp to a native datetime.

    :type dt_str: str
    :param dt_str: The string to convert.

    :rtype: :class:`datetime.datetime`
    :returns: The datetime object created from the string.
    r*   )r5   strptime_RFC3339_MICROSr,   r%   )dt_strr   r   r   _rfc3339_to_datetimeq  s
    	r   c                 C   st   t | }|du r$td| t jf tj|dt}|d}dt| }t	|d|  }|d }|j
|tdS )	a  Convert a nanosecond-precision timestamp to a native datetime.

    .. note::

       Python datetimes do not support nanosecond precision;  this function
       therefore truncates such values to microseconds.

    :type dt_str: str
    :param dt_str: The string to convert.

    :rtype: :class:`datetime.datetime`
    :returns: The datetime object created from the string.
    :raises ValueError: If the timestamp does not match the RFC 3339
                        regular expression.
    Nz)Timestamp: %r, does not match pattern: %rZno_fractionnanos	   
   rg   )rv   r+   )_RFC3339_NANOSmatch
ValueErrorpatternr5   r   group_RFC3339_NO_FRACTIONr   rr   r,   r%   )r   Z
with_nanosZbare_secondsZfractionscaler   rj   r   r   r   _rfc3339_nanos_to_datetime~  s    


r   Tc                 C   s,   |s"| j dur"| jdd|   } | tS )aw  Convert a timestamp to a string.

    :type value: :class:`datetime.datetime`
    :param value: The datetime object to be converted to a string.

    :type ignore_zone: boolean
    :param ignore_zone: If True, then the timezone (if any) of the datetime
                        object is ignored.

    :rtype: str
    :returns: The string representing the datetime stamp.
    Nr*   )r+   r,   r2   strftimer   )ro   Zignore_zoner   r   r   _datetime_to_rfc3339  s    r   asciic                 C   s<   t | tjr| |n| }t |tjr*|S td| f dS )a  Converts a string value to bytes, if necessary.

    Unfortunately, ``six.b`` is insufficient for this task since in
    Python2 it does not modify ``unicode`` objects.

    :type value: str / bytes or unicode
    :param value: The string/bytes value to be converted.

    :type encoding: str
    :param encoding: The encoding to use to convert unicode to bytes. Defaults
                     to "ascii", which will not allow any characters from
                     ordinals larger than 127. Other useful values are
                     "latin-1", which which will only allows byte ordinals
                     (up to 255) and "utf-8", which will encode any unicode
                     that needs to be.

    :rtype: str / bytes
    :returns: The original value converted to bytes (if unicode) or as passed
              in if it started out as bytes.
    :raises TypeError: if the value could not be converted to bytes.
    z"%r could not be converted to bytesN)r7   six	text_typeencodebinary_typer:   )ro   encodingresultr   r   r   	_to_bytes  s    
r   c                 C   s<   t | tjr| dn| }t |tjr*|S td| f dS )ac  Converts bytes to a unicode value, if necessary.

    :type value: bytes
    :param value: bytes value to attempt string conversion on.

    :rtype: str
    :returns: The original value converted to unicode (if bytes) or as passed
              in if it started out as unicode.

    :raises ValueError: if the value could not be converted to unicode.
    r?   z$%r could not be converted to unicodeN)r7   r   r   rF   r   r   )ro   r   r   r   r   _bytes_to_unicode  s    
r   c                 C   s   t tj| j| jd d S )a+  Convert a Timestamp protobuf to a datetime object.

    :type timestamp: :class:`google.protobuf.timestamp_pb2.Timestamp`
    :param timestamp: A Google returned timestamp protobuf.

    :rtype: :class:`datetime.datetime`
    :returns: A UTC datetime object converted from a protobuf timestamp.
    g     @@)r{   rl   )rm   r5   r6   r{   r   )	timestampr   r   r   _pb_timestamp_to_datetime  s    
r   c                 C   s,   t | }t|d\}}|d }tj||dS )a
  Convert a datetime object to a Timestamp protobuf.

    :type when: :class:`datetime.datetime`
    :param when: the datetime to convert

    :rtype: :class:`google.protobuf.timestamp_pb2.Timestamp`
    :returns: A timestamp protobuf corresponding to the object.
    i@B rg   )r{   r   )rh   divmodr   	Timestamp)ri   Zms_valuer{   rj   r   r   r   r   _datetime_to_pb_timestamp  s    	r   c                 C   sh   t |trt|}|| }|s4td| |jf |dur^|d}||kr^td||f |dS )a  Validate a URI path and get the leaf object's name.

    :type path: str
    :param path: URI path containing the name.

    :type project: str or NoneType
    :param project: The project associated with the request. It is
                    included for validation purposes.  If passed as None,
                    disables validation.

    :type template: str
    :param template: Template regex describing the expected form of the path.
                     The regex must have two named groups, 'project' and
                     'name'.

    :rtype: str
    :returns: Name parsed from ``path``.
    :raises ValueError: if the ``path`` is ill-formed or if the project from
                        the ``path`` does not agree with the ``project``
                        passed in.
    z-path "%s" did not match expected pattern "%s"NrM   zEProject from client (%s) should agree with project from resource(%s).name)r7   strrecompiler   r   r   r   )rN   rM   templater   Zfound_projectr   r   r   _name_from_project_path  s     



r   )r%   r*   )N)T)r   )=r!   rs   r5   rD   r@   r   r_   r   	threadingr   ZLocalZgoogle.protobufr   Zgoogle.appengine.apir   rQ   r   Zsix.moves.http_clientr   Z	six.movesr   Zgcloud.environment_varsr   r   utcnowZ_NOWr   r   r   VERBOSEr   rP   r	   r+   r$   r<   r=   rI   rV   rd   re   rf   rk   rp   rh   rw   r}   r   r   r   r   r   r   r   r   r   Zpytzr%   utcfromtimestampr,   rm   r   r   r   r   <module>   sj   
(#!
%

)