
    ~+h,                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZ dZ G d d	e      Z G d
 d ej                    ed dd                  Zej$                  Z G d de      Z G d de      Z G d d ej                    ed d                  Zej$                  Z G d de      Z G d de      Z G d de      Z G d d e      Zy)!zSThis module defines the Version classes, and the related Manifest
implementations.
    )with_statementN)six)FileHunk)md5_constructorRegistryMetaclassis_url)get_versionerVersionIndeterminableErrorVersionTimestampVersionget_manifestHashVersionManifestFileManifestc                       e Zd Zy)r
   N)__name__
__module____qualname__     D/var/www/html/venv/lib/python3.12/site-packages/webassets/version.pyr
   r
      s    r   r
   c                       e Zd ZdZddZd Zy)r   aU  A Version class that can be assigned to the ``Environment.versioner``
    attribute.

    Given a bundle, this must determine its "version". This version can then
    be used in the output filename of the bundle, or appended to the url as a
    query string, in order to expire cached assets.

    A version could be a timestamp, a content hash, or a git revision etc.

    As a user, all you need to care about, in most cases, is whether you want
    to set the ``Environment.versioner`` attribute to ``hash`` or ``timestamp``.

    A single instance can be used with different environments.
    Nc                     t               )a  Return a string that represents the current version of the given
        bundle.

        This method is called on two separate occasions:

        1) After a bundle has been built and is about to be saved. If the
           output filename contains a placeholder, this method is asked for the
           version. This mode is indicated by the ``hunk`` argument being
           available.

        2) When a version is required for an already built file, either
           because:

              *) An URL needs to be constructed.
              *) It needs to be determined if a bundle needs an update.

           *This will only occur* if *no manifest* is used. If there is a
           manifest, it would be used to determine the version instead.

        Support for option (2) is optional. If not supported, then in those
        cases a manifest needs to be configured. ``VersionIndeterminableError``
        should be raised with a message why.
        NotImplementedError)selfbundlectxhunks       r   determine_versionzVersion.determine_version*   s    0 "##r   c                      y)z_Hook called after a bundle has been built. Some version classes
        may need this.
        Nr   r   r   r   filenameversions        r   set_versionzVersion.set_versionD   s    r   N)r   r   r   __doc__r    r%   r   r   r   r   r      s    $4r   r   c                      t         S r&   )r   r   r   r   <lambda>r)      s    ' r   r    za version implementation)clazz	attributedescc                   B    e Zd ZdZdZddZd Zed        Zed        Z	y)	r   zwUses the most recent 'last modified' timestamp of all source files
    as the version.

    Uses second-precision.
    	timestampNc                     |s8ddl m}  ||j                        s | j                  |j	                  |            S 	 | j                  ||      S # t        $ r |J t        d      w xY w)Nr   has_placeholderz<source files are missing and output target has a placeholder)webassets.bundler1   outputget_timestampresolve_outputfind_recent_most_timestampOSErrorr
   )r   r   r   r   r1   s        r   r    z"TimestampVersion.determine_versionV   sw    
 8"6==1))&*?*?*DEE
	2263?? 	 <<, 		s   A A'c                 4    t        j                  |d|f       y )N)osutimer"   s        r   r%   zTimestampVersion.set_versionm   s    
B=)r   c                 R    t        t        j                  |      j                        S r&   )intr:   statst_mtime)clsr#   s     r   r4   zTimestampVersion.get_timestampq   s    2778$--..r   c                     ddl m} d } |||      D ])  }t        |      r| j                  |      }|||kD  s(|}+ |S )Nr   )get_all_bundle_files)r2   rB   r   r4   )r@   r   r   rB   most_recentr#   r.   s          r   r6   z+TimestampVersion.find_recent_most_timestampu   sW    9 ,VS9 	(Hh))(3I"i+&='	( r   r&   )
r   r   r   r'   idr    r%   classmethodr4   r6   r   r   r   r   r   M   s@     
B.* / /  r   r   c                   :    e Zd ZdZdZedd       ZdefdZddZ	y)	r   a  Uses the MD5 hash of the content as the version.

    By default, only the first 8 characters of the hash are used, which
    should be sufficient. This can be changed by passing the appropriate
    ``length`` value to ``__init__`` (or ``None`` to use the full hash).

    You can also customize the hash used by passing the ``hash`` argument.
    All constructors from ``hashlib`` are supported.
    hashNc                 ,    |rt        |      gng } | | S r&   )r=   )r@   lengthargss      r   makezHashVersion.make   s     &F}BDzr      c                      || _         || _        y r&   )rI   hasher)r   rI   rG   s      r   __init__zHashVersion.__init__   s    r   c                 8   |s>ddl m}  ||j                        st        |j	                  |            }nt        d      | j                         }|j                  |j                         j                  d             |j                         d | j                   S )Nr   r0   zoutput target has a placeholderzutf-8)r2   r1   r3   r   r5   r
   rN   updatedataencode	hexdigestrI   )r   r   r   r   r1   rN   s         r   r    zHashVersion.determine_version   s    8"6==1 5 5c :; 157 7 diik((12!,4;;//r   r&   )
r   r   r   r'   rD   rE   rK   r   rO   r    r   r   r   r   r      s1     
B   o 0r   r   c                       e Zd ZdZd Zd Zy)r   av  Persists information about the versions bundles are at.

    The Manifest plays a role only if you insert the bundle version in your
    output filenames, or append the version as a querystring to the url (via
    the url_expire option). It serves two purposes:

        - Without a manifest, it may be impossible to determine the version
          at runtime. In a deployed app, the media files may be stored on
          a different server entirely, and be inaccessible from the application
          code. The manifest, if shipped with your application, is what still
          allows to construct the proper URLs.

        - Even if it were possible to determine the version at runtime without
          a manifest, it may be a costly process, and using a manifest may
          give you better performance. If you use a hash-based version for
          example, this hash would need to be recalculated every time a new
          process is started. (*)

    (*) It needs to happen only once per process, because Bundles are smart
        enough to cache their own version in memory.

    A special case is the ``Environment.auto_build`` option. A manifest
    implementation should re-read its data from its out-of-process data
    source on every request, if ``auto_build`` is enabled. Otherwise, if your
    application is served by multiple processes, then after an automatic
    rebuild in one process all other processes would continue to serve an old
    version of the file (or attach an old version to the query string).

    A manifest instance is currently not guaranteed to function correctly
    with multiple Environment instances.
    c                     t               r&   r   r   r   r   r$   s       r   rememberzManifest.remember       !##r   c                     t               r&   r   r   r   r   s      r   queryzManifest.query   rY   r   N)r   r   r   r'   rX   r\   r   r   r   r   r      s    @$$r   r   c                      t         S r&   )r   r   r   r   r)   r)      s    ( r   za manifest implementation)r*   r,   c                   D    e Zd ZdZdZed
d       Zd Zd Zd Z	d Z
d	 Zy)r   a  Stores version data in a single file.

    Uses Python's pickle module to store a dict data structure. You should
    only use this when the manifest is read-only in production, since it is
    not multi-process safe. If you use ``auto_build`` in production, use
    ``CacheManifest`` instead.

    By default, the file is named ".webassets-manifest" and stored in
    ``Environment.directory``.
    fileNc                 j    |sd} | t         j                  j                  |j                  |            S )Nz.webassets-manifest)r:   pathjoin	directory)r@   r   r#   s      r   rK   zFileManifest.make   s(    ,H277<<x899r   c                 2    || _         | j                          y r&   )r#   _load_manifest)r   r#   s     r   rO   zFileManifest.__init__   s     r   c                 V    || j                   |j                  <   | j                          y r&   )manifestr3   _save_manifestrW   s       r   rX   zFileManifest.remember   s     '.fmm$r   c                     |j                   r| j                          | j                  j                  |j                  d       S r&   )
auto_buildre   rg   getr3   r[   s      r   r\   zFileManifest.query   s0    >>!}}  55r   c                     t         j                  j                  | j                        r:t	        | j                  d      5 }t        j                  |      | _        d d d        y i | _        y # 1 sw Y   y xY w)Nrb)r:   ra   existsr#   openpickleloadrg   r   fs     r   re   zFileManifest._load_manifest   sX    77>>$--(dmmT* /a &A/ / DM/ /s    A,,A5c                     t        | j                  d      5 }t        j                  | j                  |d       d d d        y # 1 sw Y   y xY w)Nwb   )protocol)ro   r#   rp   dumprg   rr   s     r   rh   zFileManifest._save_manifest   s;    $--& 	6!KKq15	6 	6 	6s   #AAr&   )r   r   r   r'   rD   rE   rK   rO   rX   r\   re   rh   r   r   r   r   r      s9    	 
B: :
6
6r   r   c                   2     e Zd ZdZdZ fdZd Zd Z xZS )JsonManifestz:Same as ``FileManifest``, but uses JSON instead of pickle.jsonc                 j    	 dd l }|| _         t        t        |   |i | y # t        $ r dd l}Y *w xY w)Nr   )r{   ImportError
simplejsonsuperrz   rO   )r   akwr{   	__class__s       r   rO   zJsonManifest.__init__  s<    	& 	lD*A44  	&%	&s   " 22c                     t         j                  j                  | j                        r@t	        | j                  d      5 }| j
                  j                  |      | _        d d d        y i | _        y # 1 sw Y   y xY w)Nr)r:   ra   rn   r#   ro   r{   rq   rg   rr   s     r   re   zJsonManifest._load_manifest  s]    77>>$--(dmmS) 2Q $		q 12 2 DM2 2s    !A22A;c                     t        | j                  d      5 }| j                  j                  | j                  |dd       d d d        y # 1 sw Y   y xY w)Nw   T)indent	sort_keys)ro   r#   r{   rx   rg   rr   s     r   rh   zJsonManifest._save_manifest  sG    $--% 	GIINN4==!ANF	G 	G 	Gs   *A

A)	r   r   r   r'   rD   rO   re   rh   __classcell__)r   s   @r   rz   rz     s    D	B5Gr   rz   c                   &    e Zd ZdZdZd Zd Zd Zy)CacheManifestaw  Stores version data in the webassets cache.

    Since this has bad portability (you hardly want to copy your cache between
    machines), this only makes sense when you are building on the same machine
    where you're application code runs.

    When you are using ``auto_build`` in production, this is exactly what you
    want to use, since it is multi-process safe.
    cachec                 2    |j                   st        d      y )NzAYou are using the cache manifest, but have not enabled the cache.)r   EnvironmentError)r   r   s     r   _checkzCacheManifest._check)  s     yy"%& & r   c                 v    | j                  |       |j                  j                  d|j                  f|       y Nrg   )r   r   setr3   rW   s       r   rX   zCacheManifest.remember/  s)    C		z6==17;r   c                 r    | j                  |       |j                  j                  d|j                  f      S r   )r   r   rk   r3   r[   s      r   r\   zCacheManifest.query3  s*    Cyy}}j&--899r   N)r   r   r   r'   rD   r   rX   r\   r   r   r   r   r     s     
B&<:r   r   c                       e Zd ZdZd Zy)SymlinkManifestzcCreates a symlink to the actual file.

    E.g. compressed-current.js -> compressed-1ebcdc5.js
    c                     t               r&   r   )r   s    r   rO   zSymlinkManifest.__init__B  rY   r   N)r   r   r   r'   rO   r   r   r   r   r   8  s    $r   r   )r'   
__future__r   r:   rp   	webassetsr   webassets.merger   webassets.utilsr   r   r   __all__	Exceptionr
   with_metaclassr   resolver	   r   r   r   r   r   rz   r   r   r   r   r   <module>r      s    & 	   $ F FG
	 	/ c  !2
%8	#"% & /d 5w 5p"0' "0J&$!s!!"3
!<#> ? &$R *68 *6ZG< G2:H :8$h $r   