
    M@c8                     2   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Zd dlZddl	m
Z
 ddlmZ ddlmZmZmZ  ee d      r" ej$                  e j&                  d      Zd	 Zn! ej$                  e j,                  d
      Zd Z e
e      Z ej2                  dded      d)d       ZdedfdZ G d de      Zd Zd Zd Zd*dZ dZ!dZ"dZ#dZ$dZ%dZ&d)dZ'd  Z(d+d!Z) G d" d#ejT                        Z* G d$ d%ejV                        Z,d)d&Z-d,d'Z.d-d(Z/y).    N   )	getLogger)LOCAL_FS_ENCODING)__version____release_name____version_txt__fwalkT)follow_symlinksc                     | dd S )Nr       ws    6/usr/lib/python3/dist-packages/eyed3/utils/__init__.pyos_walk_unpackr      s    1v    )followlinksc                     | S Nr   r   s    r   r   r      s    r   z0.9a2z1.0z+Use eyed3.mimetype.guessMimetype() instead.)deprecated_in
removed_incurrent_versiondetailsFc                 x    ddl m} |j                  |       }|s|S t        j                  dt
        d       |d fS )Nr   )mimetypez9File character encoding no longer returned, value is None)
stacklevel) r   guessMimetypewarningswarnUserWarning)filenamewith_encodingr   retvals       r   r   r      s=     ##H-FQ!a	1t|r   c                    t        |t        j                        rt        |      }nt	        |      t        urt        ||      n|}|r|ng }g |D ]&  }j                  t        j                  |             ( fd}t        j                  j                  |      st        d|       t        j                  j                  |      r7 ||      s/| j                  t        j                  j                  |             yt        |      D cg c]  }t!        |       c}D ]  \  }}	}
t	        |      t        u r|nt        ||      }|	j#                          |
j#                          t%        |
      D ]  }|}t	        |      t        u r|nt        ||      }t        j                  j                  t        j                  j'                  ||            }t        j                  j                  |      r ||      r|
j)                  |       	 | j                  |        |
r| j-                  ||
       |r y yc c}w # t*        $ r Y   yw xY w)zvA wrapper around os.walk which handles exclusion patterns and multiple
    path types (str, pathlib.Path, bytes).
    c                 >    D ]  }|j                  |       }|s y y)NTF)match)_pexr'   excludes_res      r   _isExcludedzwalk.<locals>._isExcluded<   s*     	BHHRLE	 r   zfile not found: N)
isinstancepathlibPathstrtypeappendrecompileospathexistsIOErrorisfile
handleFileabspathos_walkr   sortlistjoinremoveStopIterationhandleDirectory)handlerr5   excludesfs_encoding	recursiveer+   r   rootdirsfilesff_keyr*   s                @r   walkrL   .   s    $%4y)-d3)>s4%D#xHK *2::a=)* 77>>$(/00		k$&7277??4019@GAnQ/G dEDzS(tc$.D		

e 	AE!W^Q)<AT1 56A77>>!$AU#""1%	 ##D%0-G ! s   I I	IIc                   "    e Zd ZdZd Zd Zd Zy)FileHandlerz;A handler interface for :func:`eyed3.utils.walk` callbacks.c                      y)zCalled for each file walked. The file ``f`` is the full path and
        the return value is ignored. If the walk should abort the method should
        raise a ``StopIteration`` exception.Nr   )selfrJ   s     r   r9   zFileHandler.handleFilef        	r   c                      y)zCalled for each directory ``d`` **after** ``handleFile`` has been
        called for each file in ``files``. ``StopIteration`` may be raised to
        halt iteration.Nr   )rP   drI   s      r   rA   zFileHandler.handleDirectoryl   rQ   r   c                      y)z.Called when there are no more files to handle.Nr   )rP   s    r   
handleDonezFileHandler.handleDoner   s    r   N)__name__
__module____qualname____doc__r9   rA   rU   r   r   r   rN   rN   c   s    Er   rN   c                      g g |D ]6  }t        |      t        u rj                  |       &j                  |       8 ssJ  fd}|S )Nc                       fd}|S )Nc            
      B   D ]K  }|t        |       k\  r n;| |   t        | |         r)t        dj                  |t	              fz         D ]B  }||v s||   t        ||         rt        j                  d|dt	                      | i |S )Nz%s(argument %d) must be %sz
(argument z
) must be )lenr,   	TypeErrorrV   r/   )argskwargsinamearg_indicesarg_typefnkwarg_namess       r   
wrapped_fnz4_requireArgType.<locals>.wrapper.<locals>.wrapped_fn   s      ED	>7&z$q'8/L#$@%'[[!S]$C%D E EE $ HFNvd|'?&vd|X>#%'[[$H%G H HH
 t&v&&r   r   )re   rg   rc   rd   rf   s   ` r   wrapperz _requireArgType.<locals>.wrapper   s    	' r   )r0   intr1   )rd   r_   arh   rc   rf   s   `   @@r   _requireArgTyperk   w   s\    KK "7c>q!q!	"
 +&%  Nr   c                  "    t        t        g|  S )aw  Function decorator to enforce str/unicode argument types.
    ``None`` is a valid argument value, in all cases, regardless of not being
    unicode.  ``*args`` Positional arguments may be numeric argument index
    values (requireUnicode(1, 3) - requires argument 1 and 3 are unicode)
    or keyword argument names (requireUnicode("title")) or a combination
    thereof.
    )rk   r/   r_   s    r   requireUnicodern      s     3&&&r   c                  "    t        t        g|  S )z>Function decorator to enforce byte string argument types.
    )rk   bytesrm   s    r   requireBytesrq      s     5(4((r   c                 d   t        |       } d }|s( ||       \  }}}}|}|r ||      \  }}}}	|d|	z  z  }|S g d}
t        |       } | dk  rdj                  |       S t        t	        |
      dz
        D ]9  }|
|   \  }}|
|dz      \  }}| |k\  sdj                  | |z  || |z  |z  |      c S  y)	a  
    Format ``seconds`` (number of seconds) as a string representation.
    When ``short`` is False (the default) the format is:

        HH:MM:SS.

    Otherwise, the format is exacly 6 characters long and of the form:

        1w 3d
        2d 4h
        1h 5m
        1m 4s
        15s

    If ``total`` is not None it will also be formatted and
    appended to the result seperated by ' / '.
    c                     | | dk  rd} | dz  }| dz  dz  }| dz  dz  }d||fz  }t        |      rd||fz  }t        |      t        |      t        |      |fS )Nr     <   z	%02d:%02dz%02d:%s)ri   )tshoursminssecststrs        r   
time_tuplezformatTime.<locals>.time_tuple   su    :aBT	T	RT	RdD\)u:t},DE
CIs4y$77r   z / %s))yi )r   i:	 )rS   iQ )hrt   )mru   )s   ru   z   {0:02d}sr   z{0:02d}{1}{2:02d}{3}z  ~inf)roundri   formatranger]   )secondstotalshortr{   rw   rx   ry   curr_strr$   	total_strunitsra   unit1limit1unit2limit2s                   r   
formatTimer      s    $ GnG	8 &0&9#tT8+5e+<(E4yg	))F
 g,R< ''00s5zA~& 	9A!!HME6!!a%LME6& -44v%uv%&0%9 9		9 r   i   i   i   @KBMBGBc                    |sd}| t         k\  r"t        |       t        t               z  } t        }nU| t        k\  r"t        |       t        t              z  } t        }n*| t
        k\  r!t        |       t        t
              z  } t        }d| |fz  S d}| dk(  rd}nGt        t        j                  t        j                  |       t        j                  d      z              }|dkD  rd}n||   }t        t        j                  d|            }| |z  }t        |      }t        |      dk\  r|d	   d
k(  r|dd	 }n|dd }dj                  ||      S )aF  Format ``size`` (number of bytes) into string format doing KB, MB, or GB
    conversion where necessary.

    When ``short`` is False (the default) the format is smallest unit of
    bytes and largest gigabytes; '234 GB'.
    The short version is 2-4 characters long and of the form

        256b
        64k
        1.1G
    Bytesz%.2f %sz kMGTPEHr   i     ?r   r   .Nz
{0:>3s}{1})GB_BYTESfloatGB_UNITMB_BYTESMB_UNITKB_BYTESKB_UNITri   mathfloorlogpowr/   r]   r   )sizer   unitsuffixes	num_scalesuffixvalue	str_values           r   
formatSizer      s/    8;x0DDX;x0DDX;x0DDD$<''19IDJJtxx~'FGHIq=Fi(Fy12	y J	y>Q9Q<3#6!"1I!"1I""9f55r   c                     | j                   }| j                  dz  }| j                  dz  dz  }| j                  dz  dz  }d|||fz  }|rd||fz  }|S )z0Format a timedelta object ``td`` into a string. rt   ru   z%02d:%02d:%02dz
%d days %s)daysr   )tdr   rw   rx   ry   rz   s         r   formatTimeDeltar     sf    77DJJEJJ#DJJ#DudD11DtTl*Kr   c                 d    d}|s,| j                  |      }|r|j                  |       nd}~|s+yy)z?Copy ``src_fp`` to ``dest_fp`` in ``chunk_sz`` byte increments.FTN)readwrite)src_fpdest_fpchunk_szdonedatas        r   	chunkCopyr   )  s4    D{{8$MM$D r   c                   ,     e Zd ZdZ fdZ fdZ xZS )ArgumentParserzPSubclass of argparse.ArgumentParser that adds version and log level
    options.c                 b   ddl m} ddlm} ddlm} fd} |d|      } |d|      }|D 	cg c]%  }	t        j                  |	      j                         ' c}	| _        t        j                  }
t        t        | 6  |d|
i | j                  d	d|d
       | j                  dddd       | j                  d      }|j                  dddt         |ddj#                  d | j                  D              z         |j                  ddddd       |j                  dddd        y c c}	w )!Nr   )version)LEVELS)MAIN_LOGGERc                 B    | v rj                  |       xs |}|S |}|S r   )pop)rb   defaultr   r`   s      r   	pop_kwargz*ArgumentParser.__init__.<locals>.pop_kwarg>  s0    v~

4(3G L  Lr   main_loggerr   formatter_classz	--versionz$Display version information and exit)actionr   helpz--about
store_trueabout_eyed3z=Display full version, release name, additional info, and exit)r   destr   	Debuggingz-lz--log-levelzLEVEL[:LOGGER]zSet a log level. This option may be specified multiple times. If a logger name is specified than the level applies only to that logger, otherwise the level is set on the top-level logger. Acceptable levels are %s. z, c              3   &   K   | ]	  }d |z    yw)z'%s'Nr   ).0ls     r   	<genexpr>z*ArgumentParser.__init__.<locals>.<genexpr>Z  s     Dq
Ds   )metavarr   r   r   z	--profileFdebug_profilezRun using python profiler.)r   r   r   r   z--pdb	debug_pdbz"Drop into 'pdb' when errors occur.)eyed3r   eyed3.utils.logr   r   logginggetLevelNamelower
log_levelsargparseRawDescriptionHelpFormattersuperr   __init__add_argumentadd_argument_groupLoggingActionr>   )rP   r_   r`   VERSIONr   r   r   r   r   r   	formatterdebug_group	__class__s     `         r   r   zArgumentParser.__init__9  sU   ,*/	  {;Iw/DJKq7//288:K88	nd,d 	7I 	7/5	7 	+iE 	 	G)L}^ 	 	` --k:  m-=$+K iiDDOODD	F 	! 	G 	  \)._8 	! 	: 	  K&J 	! 	L/ Ls   *D,c                 H   t        |   |i |}d|v r|j                  r|| j                  D cg c]  }t	        |t
        j                        s|! c}d   }|j                  }t        r	dt         nd}t        | | dt                | j                          y |S c c}w )Nr   r    r   z

)r   
parse_argsr   _actionsr,   r   _VersionActionr   r   printr   exit)rP   r_   r`   rj   r   r   release_namer   s          r   r   zArgumentParser.parse_argsa  s    w!4262D T%5%5!%YA*Q@W@W2XaYZ[\FnnG5EQ/012LWIl^4/@ABIIKK Zs   BB)rV   rW   rX   rY   r   r   __classcell__r   s   @r   r   r   5  s    &LP	 	r   r   c                   *     e Zd Z fdZd fd	Z xZS )r   c                 X    |j                  d      | _        t        t        |   |i | y )Nr   )r   r   r   r   r   )rP   r_   r`   r   s      r   r   zLoggingAction.__init__n  s(    !::m4mT+T<V<r   c                    |j                  d      }t        |      dkD  r|n|d   | j                  f\  }}t        j                  |      }	 |j                  t        j                  |j                                   t        t        | ;  ||||       y # t        $ r* d| d|j                   d}t        j                  | |      w xY w)N:r   r   zinvalid level choice: z (choose from ))splitr]   r   r   r   setLevel_nameToLevelupperKeyErrorr   r   ArgumentErrorr   r   __call__)	rP   parser	namespacevaluesoption_stringlevelloggermsgr   s	           r   r   zLoggingAction.__call__r  s    c""%f+/q	8<8H8H8Jv ""6*	4OOG00?@
 	mT+FIv}U	  	4*5'@Q@Q?RRSTC((s33	4s   0B 3Cr   )rV   rW   rX   r   r   r   r   s   @r   r   r   m  s    =V Vr   r   c                     |s(| j                   xs | j                  xs | j                  S | j                  xs | j                   xs | j                  S )a  This function returns a date of some sort, amongst all the possible
    dates (members called release_date, original_release_date,
    and recording_date of type eyed3.core.Date).

    The order of preference is:
    1) date of original release
    2) date of this versions release
    3) the recording date.

    Unless ``prefer_recording_date`` is ``True`` in which case the order is
    3, 1, 2.

    ``None`` will be returned if no dates are available.)original_release_daterelease_daterecording_date)thingprefer_recording_dates     r   
datePickerr    s]     !++ %""%$$	& $$ #++#""	$r   c                 t   t         j                  j                  |       }t         j                  j                  |       }t         j                  j	                  |      \  }}d}t         j                  j                  t         j                  j                  ||            rz|r|d|}dj                  ||g      }d}ndj                  |d||g      }|dz  }t         j                  j                  t         j                  j                  ||            rzt         j                  j                  ||      S )a  The ``file_path`` is the desired file name, and it is returned if the
    file does not exist. In the case that it already exists the path is
    adjusted to be unique. First, the ``uniq`` string is added, and then
    a counter is used to find a unique name.r   _r   )r4   r5   dirnamebasenamesplitextr6   r>   )	file_pathuniqr5   filerb   extcounts          r   makeUniqueFileNamer    s     77??9%D77I&D  &ID#E
''..dD1
2"D)D77D#;'DD77tU3S9:DQJE ''..dD1
2 77<<d##r   c                 d    t        | t              r| S ddl}|xs |j                  } ||       d   S )a  Converts `x` to a bytes string if not already.

    :param x: The string.
    :param encoder: Optional codec encoder to perform the conversion. The default is
                    `codecs.latin_1_encode`.
    :return: The byte string if conversion was needed.
    r   N)r,   rp   codecslatin_1_encode)xencoderr  s      r   br    s4     !U2V22qz!}r   )F)NF)i   )r   r   )0r4   r2   r   r-   r   r   r   	functoolsdeprecation	utils.logr   r   r   	__about__r   r   r   hasattrpartialr	   r;   r   rL   rV   r   
deprecatedr   objectrN   rk   rn   rq   r   r   r   r   r   r   r   r   r   r   r   _AppendActionr   r  r  r  r   r   r   <module>r     sC   	 	        !   F F
2wi$?G  iT:G  g%Q\ MO
O
 "&3DPU 2j& (:');~ 


)6X		5X,, 5pVH** V($0$*r   