
    M@c<@                       d dl Z d dlmZ d dlmZ ddlmZ ddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZ ddlmZ d	d
lmZmZmZmZ d	dlmZmZmZmZmZ d	dlmZ ddlmZ ddl m!Z!  e!e"      Z#dZ$ G d de      Z%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3d Z4d!Z5d"Z6d#Z7d$Z8d%Z9d&Z:d'Z;d(Z<d)Z=d*Z>d+Z?d,Z@d-ZAd.ZBd/ZCd0ZDd1ZEd2ZFd3ZGe@eAeBeCeDeEeFeGgZHd4ZId5ZJg d6ZKg d7ZL G d8 d9eM      ZN G d: d;eN      ZO G d< d=eO      ZP G d> d?eO      ZQ G d@ dAeN      ZR G dB dCeR      ZS G dD dEeN      ZT G dF dGeN      ZU G dH dIeN      ZV G dJ dKeN      ZW G dL dMeN      ZX G dN dOeN      ZY G dP dQeN      ZZ G dR dSeN      Z[ G dT dUeM      Z\ G dV dWeNe\      Z] G dX dYe]      Z^ G dZ d[e]      Z_ G d\ d]eNe\      Z` G d^ d_eN      Za G d` daeN      Zb G db dceN      Zc edddedfg      Zd	  G dg dheN      Ze G di djef      Zgdk Zhdl Zidm Zjdn Zkdo Zldp Zmi dqdredfd!dseeUfdtduedfddvee^fdwdxedfd4dyeeafd5dzeeefd{d|edfd}d~edfddedfddedfddeeVfddedfddedfddedfd&deeXfddedfi ddedfd'deeWfd#deeYfd)deeZfddedfddedfddeecfddeebfddedfddedfddedfddedfddedfddeeOfd$deeOfddeeOfddeeOfi d+deeOfddeeQfddeeQfddeeOfddeeQfddeeQfddeeQfddeeQfd*deeOfddeeOfddeeOfddeeQfddeeOfddeeOfddeeOfddeeOfddeeOfi ddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeQfddeeOfddeeOfddeeOfddeeOfddeeOfd deeOfddeeOfi d%deeOfddeeOfddeeQfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeOfddeeQfddeePfddee[fd(dee`fddee_fdeeRfd eeRfdeeRfdeeRfdeeRfdeeRfdeeRfdeeRfdeeSfd	Znd	 Zoi d
dddddddddddܓddޓddddddœdddddddd ddddddi dddddd֓dd$dd˓d dd!d+d"d%d#d*d$dd%dǓd&dd'dd(dÓd)dϓd*dѓd+di d,dӓd-dd.d.d/d/d0d0d1d,d2d-d3d3d4d"d5dd6dd7dd8dd9d&d:dd;dd<di d=dd>dd?d}d@ddAd!dBddCd#dDd)dEddFdqdGddHdIdJddKddLddMdNdOdPddQdRdSdTdUdVZpd	dWlmqZq dXeeNfdYeeOfdZeeOfd[eeOfd\eeOfd]eeQfd^eeOfd_eeOfd`eeqj                  fdaeeqj                  fdbeeqj                  fdceeqj                  fddeeqj                  fdeeeOfdfeeqj                  fdgZxy(h      N)BytesIO)
namedtuple   )core)requireUnicoderequireBytes)	bin2bytesbin2dec	bytes2bindec2bin	bytes2dec	dec2bytessignedInt162bytesbytes2signedInt16)Error   )ID3_V2ID3_V2_2ID3_V2_3ID3_V2_4)LATIN1_ENCODINGUTF_8_ENCODINGUTF_16BE_ENCODINGUTF_16_ENCODINGDEFAULT_LANG)FrameHeader)b)	getLoggerz
iso-8859-1c                       e Zd Zy)FrameExceptionN)__name__
__module____qualname__     2/usr/lib/python3/dist-packages/eyed3/id3/frames.pyr    r       s    r%   r       TIT2s   TIT3s   TPE1s   TPE2s   TOPEs   TCOMs   TALBs   TRCKs   TCONs   COMMs   TXXXs   GEOBs   UFIDs   USLTs   TPOSs   APIC   WXXXs   PCNTs   TBPMs   TPUBs   MCDIs   PRIV   USERs   POPMs   TENCs   TCOP   WCOM   WCOP   WOAF   WOAR   WOAS   WORS   WPAY   WPUBs   CTOCs   CHAP)   TDAT   TYER   TIME   TORY   TRDA   XDOR)   TDEN   TDOR   TDRC   TDRL   TDTGc                   j   e Zd ZdZ ed      d        Zed        Zej                  d        Z ed      d        Z	d Z
d Zed	        Zed
        Zed        Zed        Z ed      d        Z ed      d        Zed        Zd Zed        Zej                  d        Zed        Zed        Zy)FrameTr   c                     || _         d | _        d| _        d | _        d | _        d | _        d| _        d | _        d| _        y )Nr   F)	idheaderdecompressed_sizegroup_idencrypt_methoddatadata_len	_encoding_unknown)selfr@   s     r&   __init__zFrame.__init__P   sC    !""	r%   c                     | j                   S N_headerrI   s    r&   rA   zFrame.header]       ||r%   c                     || _         y rL   rM   )rI   hs     r&   rA   zFrame.headera   s	    r%   c                 `    |j                   | _         || _        | j                  |      | _        y rL   )r@   rA   _disassembleFramerE   )rI   rE   frame_headers      r&   parsezFrame.parsee   s&    //"**40	r%   c                 8    | j                  | j                        S rL   )_assembleFramerE   rO   s    r&   renderzFrame.renderk   s    ""499--r%   c                 4    | j                   |j                   k  S rL   )r@   )rI   others     r&   __lt__zFrame.__lt__n   s    ww!!r%   c                     dd l }t        j                  dt        |       z         |j	                  | d      } t        j                  dt        |       z         | S )Nr   zbefore decompression: %d bytes   zafter decompression: %d bytes)zliblogdebuglen
decompressrE   r_   s     r&   rc   zFrame.decompressq   sF    		2SY>?tR(		1CI=>r%   c                     dd l }t        j                  dt        |       z         |j	                  |       } t        j                  dt        |       z         | S )Nr   zbefore compression: %d byteszafter compression: %d bytes)r_   r`   ra   rb   compressrd   s     r&   rf   zFrame.compressy   sD    		03t9<=}}T"		/#d);<r%   c                 0    t         j                  d       | S )Nz7Frame decryption not yet supported, leaving data as is.r`   warningrE   s    r&   decryptzFrame.decrypt       MNr%   c                 0    t         j                  d       | S )Nz7Frame encryption not yet supported, leaving data as is.rh   rj   s    r&   encryptzFrame.encrypt   rl   r%   c                 R   | j                   sJ | j                   }|j                  dk  r|j                  rCt        t	        |d d             | _        |dd  }t        j                  d| j
                  z         |j                  rCt        t	        |dd             | _	        |dd  }t        j                  d| j                  z         |j                  rrt        t	        |dd             | _        |dd  }t        j                  d| j                  z         n-|j                  rCt        t	        |dd             | _        t        j                  d| j                  z         |dd  }|j                  rCt        t	        |dd             | _	        |dd  }t        j                  d| j                  z         |j                  rt        t	        |d d d            | _        |dd  }t        j                  d	| j                  z         |j                  r3| j                  | _        t        j                  d| j
                  z         |j                  dk(  r|j                  rt        |      }|j                  r| j!                  |      }|j                  r| j#                  |      }|S )
N      zDecompressed Size: %dr   r   zEncryption Method: %dzGroup ID: %d   zData Length: %d)rA   minor_version
compressedr
   r   rB   r`   ra   	encryptedrD   groupedrC   data_length_indicatorrF   unsyncdeunsyncDatark   rc   )rI   rE   rA   s      r&   rT   zFrame._disassembleFrame   s2   {{{ 1$  )0481D)E&ABx		1D4J4JJK&-iQq	.B&C#ABx		1D4G4GGH~~ '	$q)(< =ABx		.4==89 ~~ '	$q)(< =		.4==89ABx&-iQq	.B&C#ABx		1D4G4GGH++ '	$r(A(> ?ABx		+dmm;<$$-1]]D*II58N8NNO1$%D<<%D??4(Dr%   c                    | j                   sJ | j                   }d|_        d}|j                  dk(  r|j                  r!|t	        t        t        |      d            z  }|j                  r"|t	        t        | j                  d            z  }|j                  r|t	        t        | j                  d            z  }n|j                  r"|t	        t        | j                  d            z  }|j                  r"|t	        t        | j                  d            z  }|j                  s|j                  r(d|_        |t	        t        t        |      d            z  }|j                  r| j                  |      }|j                  r| j                  |      }||z   | _        |j                  t        | j                              | j                  z   S )NFr%   rp          r   )rA   rx   rs   rt   r	   r   rb   ru   rD   rv   rC   rw   rf   rn   rE   rY   )rI   rE   rA   format_datas       r&   rX   zFrame._assembleFrame   so   {{{ 1$  yTB)?@@y1D1Da)HII~~y)BCC~~y)BCCy1D1Da)HII  F$@$@/0,yTB)?@@==&D<<%D$&	}}S^,tyy88r%   c                 V    | j                   J | j                   t        t        fv rdS dS )N         )encodingr   r   rO   s    r&   
text_delimzFrame.text_delim   s;    }}((("mm0A0C C{ 	PHO	Pr%   c                 n   | j                   j                  r"t        | j                   j                        dk(  sJ | j                  }| j                  c| j                   j                  d d dk  r| j                   j                  d   dk(  rt        | _        nz| j                  t
        kD  rgt
        | _        n[| j                   j                  d d dk  r4| j                   j                  d   dk(  rt
        | _        nt        | _        nt        | _        t        j                  d| d| j                          y )Nrp   r   )r   rq   r   r   z_initEncoding: was=z now=)	rA   versionrb   r   r   r   r   r`   ra   )rI   curr_encs     r&   _initEncodingzFrame._initEncoding   s    {{""s4;;+>+>'?1'DDD====${{""2A&/;;&&q)Q.$3DM}}6(7{{""2A&/;;&&q)Q.$3DM$3DM .		'zt}}oFGr%   c                     | j                   S rL   )rG   rO   s    r&   r   zFrame.encoding       ~~r%   c                     t        |t              st        d      t        |cxk  r	t        k  s,n t
        j                  dj                  |             t        }|| _        y )N(encoding argument must be a byte string.zUnknown encoding value {})	
isinstancebytes	TypeErrorr   r   r`   ri   formatrG   )rI   encs     r&   r   zFrame.encoding   sI    #u%FGG C9>9KK3::3?@!Cr%   c                     | j                   S rL   )_render_strictrO   s    r&   strict_renderingzFrame.strict_rendering  s    """r%   c                     | j                   S rL   )rH   rO   s    r&   unknownzFrame.unknown      }}r%   N)r!   r"   r#   r   r   rJ   propertyrA   setterrV   rY   r\   staticmethodrc   rf   rk   rn   rT   rX   r   r   r   r   r   r$   r%   r&   r>   r>   M   s]   N!_
 
   ]]  !_1 1
."         !_, ,\ !_9 9B P P
H0   __  # #  r%   r>   c                        e Zd ZdZ ed      d	 fd	       Zed        Zej                   ed      d               Z fdZ	 fdZ
 xZS )
	TextFramezDText frames.
    Data string format: encoding (one byte) + text
    textc                     t         t        |   |       | j                  dd dk(  s| j                  dv sJ |xs d| _        y )Nr   r      T)   XSOA   XSOP   XSOTr7      WFED   GRP1 )superr   rJ   r@   r   )rI   r@   r   	__class__s      r&   rJ   zTextFrame.__init__  sM    i'+wwq|t#tww 3N (N 	O NJB	r%   c                     | j                   S rL   _textrO   s    r&   r   zTextFrame.text      zzr%   r   c                     || _         y rL   r   rI   txts     r&   r   zTextFrame.text  s     
r%   c                 .   t         |   ||       	 | j                  dd | _        | j                  dd  }	 t        || j                        | _        t
        j                  d| j                  z         y # t        $ rT}t
        j                  dj                  || j                               t        | _        | j                  d d  }Y d }~d }~ww xY w# t        $ r6}t
        j                  d| j                   d|        d| _        Y d }~d }~ww xY w)	Nr   r   z&TextFrame[{fid}] - {err}; using latin1errfidzError decoding text frame z: r   zTextFrame text: %s)r   rV   rE   r   
ValueErrorr`   ri   r   r@   r   decodeUnicoder   UnicodeDecodeErrorra   )rI   rE   rU   	text_datar   r   s        r&   rV   zTextFrame.parse$  s    dL)	% IIaNDM		!"I	%i?DI 			&23  	%KK@CTWW57+DM		!I		% " 	KK4TWWIRuEFDII	s/   #A5 C 5	C>A
CC	D,DDc                     | j                          | j                  | j                  j                  t	        | j                              z   | _        t        | j
                        t        u sJ t        | %         S rL   )
r   r   r   encodeid3EncodingToStringrE   typer   r   rY   rI   r   s    r&   rY   zTextFrame.render7  s_    ]]YY%%&9$--&HIJ	DII%'''w~r%   rL   )r!   r"   r#   __doc__r   rJ   r   r   r   rV   rY   __classcell__r   s   @r&   r   r     si     F    
[[A  4&   r%   r   c                        e Zd Z edd      eddf fd	       Zed        Zej                   ed      d               Zd Z	d	 Z
 xZS )
UserTextFramedescriptionr   r   c                 >    t         t        |   ||       || _        y Nr   )r   r   rJ   r   )rI   r@   r   r   r   s       r&   rJ   zUserTextFrame.__init__@  s    mT+BT+:&r%   c                     | j                   S rL   _descriptionrO   s    r&   r   zUserTextFrame.descriptionE         r%   r   c                     || _         y rL   r   r   s     r&   r   zUserTextFrame.descriptionI        r%   c                    t         j                  | ||       	 | j                  dd | _        t	        | j                  dd | j                        \  }}t        || j                        | _        t        j                  d| j                  z         t        || j                        | _        t        j                  d| j                  z         y# t
        $ rk}t        j                  dj                  || j                               t        | _        t	        | j                  dd | j                        \  }}Y d}~d}~ww xY w)zLData string format:
        encoding (one byte) + description + b" " + text r   r   Nz*UserTextFrame[{fid}] - {err}; using latin1r   zUserTextFrame description: %szUserTextFrame text: %s)r>   rV   rE   r   splitUnicoder   r`   ri   r   r@   r   r   r   ra   r   )rI   rE   rU   dtr   s         r&   rV   zUserTextFrame.parseN  s    
 	D$-	? IIaNDM!$))AB-?FQ )DMM:		1D4D4DDE!!T]]3			*TYY67  	?KKDCTWW57+DM!$))A,>FQ		?s   :C 	EA!D==Ec                 H   | j                          | j                  | j                  j                  t	        | j                              z   | j
                  z   | j                  j                  t	        | j                              z   }|| _        t        j                  |       S rL   )
r   r   r   r   r   r   r   rE   r>   rY   rI   rE   s     r&   rY   zUserTextFrame.renderc  s      ''(;DMM(JKL  		  !4T]]!CDE 	||D!!r%   )r!   r"   r#   r   USERTEXT_FIDrJ   r   r   r   rV   rY   r   r   s   @r&   r   r   ?  sh    M6*&BR ' +' ! ! A    8*"r%   r   c                   d     e Zd Zd fd	Z fdZed        Zej                  d        Zd Z xZ	S )	DateFramec                     |t         v s
|t        v sJ t        |   |t	        |             | j
                  | _        t        | _        y r   )		DATE_FIDSDEPRECATED_DATE_FIDSr   rJ   strr   dater   r   )rI   r@   r   r   s      r&   rJ   zDateFrame.__init__o  s@    Y"(<"<=<#d),II	'r%   c                    t         |   ||       	 | j                  r*t        j                  j                  | j                        }y y # t
        $ r5 t        j                  t        d| j                                d| _        Y y w xY w)NzInvalid date: r   )r   rV   r   r   Dater   
parseErrorr    )rI   rE   rU   _r   s       r&   rV   zDateFrame.parseu  sj    dL)	yyIIOODII.  	OON^DII;+GHIDI	s   5A
 
;BBc                     | j                   r8t        j                  j                  | j                   j	                  d            S d S Nlatin1)r   r   r   rV   r   rO   s    r&   r   zDateFrame.date  s/    >Biityytyy//9:QTQr%   c                    |sd| _         y	 t        |      t        u r t        j                  j                  |      }nLt        |      t        u rt        j                  |      }n%t        |t        j                        st        d      t        |      | _         y# t        $ r" t        j                  d|        d| _         Y yw xY w)zLSet value with a either an ISO 8601 date string or a eyed3.core.Date object.r   Nz*str, int, or eyed3.core.Date type expectedzInvalid date text: )r   r   r   r   r   rV   intr   r   r   r`   ri   )rI   r   s     r&   r   zDateFrame.date  s     DI	DzS yyt,ds"yydii0 LMM I	  	KK-dV45DI	s   A=B (CCc                     t         | _        y rL   )r   r   rO   s    r&   r   zDateFrame._initEncoding  s	    'r%   r   )
r!   r"   r#   rJ   rV   r   r   r   r   r   r   s   @r&   r   r   n  s@    ( R R 
[[ *(r%   r   c                   h     e Zd Zd fd	Zed        Zej                  d        Z fdZ fdZ xZ	S )UrlFramec                 v    |t         v s|t        k(  sJ t        t        |   |       t
        | _        || _        y rL   )URL_FIDSUSERURL_FIDr   r   rJ   r   r   url)rI   r@   r   r   s      r&   rJ   zUrlFrame.__init__  s4    X~{!232h&r*'r%   c                     | j                   S rL   )_urlrO   s    r&   r   zUrlFrame.url      yyr%   c                     t        |t              rt        |t              }|| _        y |j	                  t               || _        y rL   )r   r   r   
ISO_8859_1r   r   )rI   r   s     r&   r   zUrlFrame.url  s6    c5!c:&C 	 JJz"	r%   c                     t         |   ||       	 | j                  | _        y # t        $ r t
        j                  d       d| _        Y y w xY w)NNon ascii url, clearing.r   )r   rV   rE   r   r   r`   ri   rI   rE   rU   r   s      r&   rV   zUrlFrame.parse  sD    dL)	yyDH! 	KK23DH	s   % %AAc                 p    | j                   j                  t              | _        t        t
        |          S rL   )r   r   r   rE   r   r   rY   r   s    r&   rY   zUrlFrame.render  s'    HHOOJ/	Xt+--r%   r   )
r!   r"   r#   rJ   r   r   r   rV   rY   r   r   s   @r&   r   r     sC       	ZZ . .r%   r   c                        e Zd ZdZ ed      eddfd       Zed        Zej                   ed      d               Z fdZ
d	 Z xZS )
UserUrlFramez]
    Data string format:
    encoding (one byte) + description + b" " + url (iso-8859-1)
    r   r   c                 l    t         j                  | ||       | j                  t        k(  sJ || _        y )N)r   )r   rJ   r@   r   r   )rI   r@   r   r   s       r&   rJ   zUserUrlFrame.__init__  s1    $,ww+%&%&r%   c                     | j                   S rL   r   rO   s    r&   r   zUserUrlFrame.description  r   r%   r   c                     || _         y rL   r   )rI   descs     r&   r   zUserUrlFrame.description  s     !r%   c                    t         |   ||       | j                  dd x| _        }t	        | j                  dd  |      \  }}t        ||      | _        t        j                  d| j                  z         	 t        |d      j                  d      | _        t        j                  d| j                  z         y # t        $ r t        j                  d       d| _        Y Jw xY w)Nr   r   zUserUrlFrame description: %sasciir   r   zUserUrlFrame text: %s)r   rV   rE   r   r   r   r   r`   ra   r   r   r   r   ri   )rI   rE   rU   r   r   ur   s         r&   rV   zUserUrlFrame.parse  s     	dL)#'99Qq>1diimX6A(H5		043C3CCD	1g--g6DH 			)DHH45 " 	KK23DH	s   8 B; ;%C#"C#c                 *   | j                          | j                  | j                  j                  t	        | j                              z   | j
                  z   | j                  j                  t              z   }|| _        t        j                  |       S rL   )r   r   r   r   r   r   r   r   rE   r>   rY   r   s     r&   rY   zUserUrlFrame.render  st      ''(;DMM(JKL "&((//*"=> 	||D!!r%   )r!   r"   r#   r   r   r   rJ   r   r   r   rV   rY   r   r   s   @r&   r   r     sm     M"%22 ' #' ! ! A!  !6""r%   r   c                   "     e Zd ZdZ fdZ xZS )UnknownFramezUnknown Frame.
    c                 ~    t         |   |       | j                  t        vr| j                  t        vsJ d| _        y )NT)r   rJ   r@   
ID3_FRAMESNONSTANDARD_ID3_FRAMESrH   )rI   r@   r   s     r&   rJ   zUnknownFrame.__init__  s5    wwj(TWW<R-RRRr%   )r!   r"   r#   r   rJ   r   r   s   @r&   r   r     s     r%   r   c                       e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZeZeZdZdZeefZ ed      edddddf fd	       Ze d        Z!e!jD                   ed      d               Z!e d        Z#e#jD                  d        Z#e d         Z$e$jD                  d!        Z$ fd"Z% fd#Z&e'd$        Z(e'd%        Z)d'd&Z* xZ+S )(
ImageFramer   r   r   rp   rq         rr   r|   	   
               r^                  s   -->z-->r   r   Nc                     |t         k(  sJ t        t        |   |       || _        || _        || _        || _        || _        y rL   )		IMAGE_FIDr   r  rJ   r   
image_data	image_urlpicture_type	mime_type)rI   r@   r   r  r  r  r  r   s          r&   rJ   zImageFrame.__init__   sG     Yj$(,&$" )"r%   c                     | j                   S rL   r   rO   s    r&   r   zImageFrame.description.  r   r%   c                     || _         y rL   r   )rI   r   s     r&   r   zImageFrame.description2  s     r%   c                 .    t        | j                  d      S Nr   r   
_mime_typerO   s    r&   r  zImageFrame.mime_type7      4??G,,r%   c                 l    |xs d}t        |t              r|| _        y |j                  d      | _        y Nr%   r   r   r   r   r  rI   ms     r&   r  zImageFrame.mime_type;  *    H)!U3!'9Jr%   c                     | j                   S rL   )	_pic_typerO   s    r&   r  zImageFrame.picture_type@  r   r%   c                 ~    |4|t         j                  k  s|t         j                  kD  rt        d|z        || _        y )NzInvalid picture_type: %d)r  MIN_TYPEMAX_TYPEr   r#  rI   r   s     r&   r  zImageFrame.picture_typeD  s:    =a*"5"55*"5"557!;<<r%   c                 \   t         
|   ||       t        | j                        }t        j                  dt        | j                        z         |j                  d      x| _        }d| _	        |j                  dk7  rG|j                  d      }|rJ|dk7  rE| xj                  |z  c_	        |j                  d      }|r|dk7  r.n|j                  d      | _	        t        j                  d| j                  z         | j                  st        j                  t        d             | j                  | j                  k7  r2| j                  j                  d	      d
k(  rd| j                  z   | _	        t!        |j                  d            }t        j                  d|z         || j"                  k  s|| j$                  kD  r3t        j                  t        d|z               | j&                  | _        n|| _        t        j                  d| j(                  z         d| _        |j                         }|j-                          t/        ||      \  }}	t        j                  dt        |      z         t        j                  dt        |	      z         t1        ||      | _        t        j                  d| j2                  z         | j                  j                  | j                        d
k7  rId | _        |	| _        t        j                  dt        | j6                  j9                  d            z         n9|	| _        d | _        t        j                  dt        | j4                        z         | j4                  s,| j6                  st        j                  t        d             y y y )NzAPIC frame data size: %dr   r%   r   r   rp   zAPIC mime type: %sz'APIC frame does not contain a mime type   /s   image/zInitial APIC picture type: %dInvalid APIC picture type: %dzAPIC picture type: %dr   zdescription len: %dzimage len: %dzAPIC description: %szAPIC image URL: %sr   zAPIC image data: %d bytesz*APIC frame does not contain image data/url)r   rV   r   rE   r`   ra   rb   readr   r  rs   r   r   r    URL_MIME_TYPEfindordr%  r&  OTHERr  
desciptioncloser   r   r   r  r  decode)rI   rE   rU   inputr   chptbufferr   imgr   s             r&   rV   zImageFrame.parseK  s   dL)		"		,s499~=>#(::a=0 %%*ABw2%ZZ] w
 $jjmDO		&89OON ,2 3 4OOt111$$T*b0'$//9DOA		1B67dmm!3OON+J+-,. / 0 $

D "D		)D,=,==> "684s		'#d)34		/CH,-(x8		(4+;+;;<?? 2 23r9"DO DNII*$..//89: ; "DO!DNII1C4HHIt~~OON ,6 7 8 (6r%   c                    | j                          | j                  s| j                  r| j                  | _        | j
                  | j                  z   dz   t        t        | j                  d            z   | j                  j                  t        | j
                              z   | j                  z   }| j                  r|| j                  z  }n| j                  r|| j                  z  }|| _        t        t        | C         S )Nr   r|   )r   r  r  r-  r  r   r	   r   r  r   r   r   r   rE   r   r  rY   rI   rE   r   s     r&   rY   zImageFrame.render  s     	4>>"00DO/'9'$"3"3Q789  ''(;DMM(JKL  
 ??DOO#D^^DNN"D	Z-//r%   c                 f   | t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j
                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry	| t         j                  k(  ry
| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                  k(  ry| t         j                   k(  ry| t         j"                  k(  ry| t         j$                  k(  ry| t         j&                  k(  ry| t         j(                  k(  ry| t         j*                  k(  ryt-        d| z        )Nr0  ICON
OTHER_ICONFRONT_COVER
BACK_COVERLEAFLETMEDIALEAD_ARTISTARTIST	CONDUCTORBANDCOMPOSERLYRICISTRECORDING_LOCATIONDURING_RECORDINGDURING_PERFORMANCEVIDEOBRIGHT_COLORED_FISHILLUSTRATION	BAND_LOGOPUBLISHER_LOGOr+  r  r0  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  rL  rM  rN  rO  r   )r   s    r&   picTypeToStringzImageFrame.picTypeToString  st   
   *//!*'''*((( *'''*$$$*"""*((( *###*&&&*//!*%%%*%%%*///'*---%*///'*"""*000(*)))!*&&&*+++#<q@AAr%   c                    | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j
                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | d	k(  rt         j                  S | d
k(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                  S | dk(  rt         j                   S | dk(  rt         j"                  S | dk(  rt         j$                  S | dk(  rt         j&                  S | dk(  rt         j(                  S | dk(  rt         j*                  S t-        d| z        )Nr0  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  rL  rM  rN  rO  zInvalid APIC picture type: %srP  ss    r&   stringToPicTypezImageFrame.stringToPicType  s   <###&[??",(((-))),((()^%%%'\###-)))(]$$$+'''&[??"*_&&&*_&&&&&000$$...&&000'\###''111. ***+'''"",,,<q@AAr%   c                     |st         j                  | j                        n|}| j                  j	                  d      d   }|dk(  rd}dj                  ||g      S )N/r   jpegjpg.)r  rQ  r  r  splitjoin)rI   nameexts      r&   makeFileNamezImageFrame.makeFileName  sX    DHz))$*;*;<BF 	nn""3'*&=Cxxs$$r%   rL   ),r!   r"   r#   r0  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  rL  rM  rN  rO  r%  r&  r-  URL_MIME_TYPE_STRURL_MIME_TYPE_VALUESr   r  rJ   r   r   r   r  r  rV   rY   r   rQ  rU  r_  r   r   s   @r&   r  r    s   EDJKJGEKFIDHHELINH(H M)+<=M"# D"d# ## ! ! A   - - K K    :8x0, ,B ,B\ ,B ,B\%r%   r  c                       e Zd Z edd      eddddf fd	       Zed        Zej                   ed      d               Zed	        Z	e	j                  d
        Z	ed        Z
e
j                   ed      d               Z
 fdZ fdZ xZS )ObjectFramer   filenamer   Nc                 \    t         |   |       || _        || _        || _        || _        y rL   )r   rJ   r   rd  r  object_data)rI   r   r   rd  rf  r  r   s         r&   rJ   zObjectFrame.__init__  s0     	& "&r%   c                     | j                   S rL   r   rO   s    r&   r   zObjectFrame.description  r   r%   r   c                     || _         y rL   r   r   s     r&   r   zObjectFrame.description  r   r%   c                 .    t        | j                  d      S r  r  rO   s    r&   r  zObjectFrame.mime_type  r  r%   c                 l    |xs d}t        |t              r|| _        y |j                  d      | _        y r  r  r  s     r&   r  zObjectFrame.mime_type  r!  r%   c                     | j                   S rL   	_filenamerO   s    r&   rd  zObjectFrame.filename   r   r%   c                     || _         y rL   rl  r   s     r&   rd  zObjectFrame.filename$  s     r%   c                    t         
|   ||       t        | j                        }t        j                  dt        t        | j                              z          |j                  d      x| _	        }d| _
        | j                  j                  dk7  rA|j                  d      }|dvrB| xj                  |z  c_
        |j                  d      }|dvr+n|j                  d      | _
        t        j                  d| j                  z         | j                  st        j                  t        d             | j                  j!                  d	      d
k(  rt        j                  t        d             d| _        d| _        |j                         }|j'                          t)        ||      \  }}t)        ||      \  }}	t+        ||      | _        t        j                  d| j"                  z          t+        ||      | _        t        j                  d| j$                  z          |	| _        t        j                  dt        | j,                        z         | j,                  st        j                  t        d             yy)a  Parse the frame from ``data`` bytes using details from
        ``frame_header``.

        Data string format:
        <Header for 'General encapsulated object', ID: "GEOB">
        Text encoding          $xx
        MIME type              <text string> $00
        Filename               <text string according to encoding> $00 (00)
        Content description    <text string according to encoding> $00 (00)
        Encapsulated object    <binary data>
        zGEOB frame data size: r   r%   r   )r%   r   rp   zGEOB mime type: %sz'GEOB frame does not contain a mime typer)  r*  z-GEOB frame does not contain a valid mime typer   zGEOB filename: zGEOB description: zGEOB data: %d bytes z$GEOB frame does not contain any dataN)r   rV   r   rE   r`   ra   r   rb   r,  r   r  rA   rs   r   r   r    r.  rd  r   r2  r   r   rf  )rI   rE   rU   r4  r   r5  r7  rd  r   objr   s             r&   rV   zObjectFrame.parse)  s    	dL)		"		*STYY-@@A#(::a=0 ;;$$)ABL(2%ZZ] L(
 $jjmDO		&89OON ,7 8 9??%+OON ,= > ?  )&(;6"684s%h9		#dmm34(x8		&)9)99:		(3t/?/?+@@AOON ,2 3 4  r%   c                    | j                          | j                  | j                  z   dz   | j                  j	                  t        | j                              z   | j                  z   | j                  j	                  t        | j                              z   | j                  z   | j                  xs dz   }|| _	        t        t        | 3         S )Nr   r%   )r   r   r  rd  r   r   r   r   rf  rE   r   rc  rY   r:  s     r&   rY   zObjectFrame.renderb  s    /'9$$%8%GHI    ''(;DMM(JKL 	 
 !!(S* 	[$.00r%   )r!   r"   r#   r   
OBJECT_FIDrJ   r   r   r   r  rd  rV   rY   r   r   s   @r&   rc  rc    s    M:.%2!T' /' ! ! A     - - K K   __A  74r	1 	1r%   rc  c                   T     e Zd ZU dZeed<   eed<   eddf fd	Z fdZ fdZ	 xZ
S )PrivateFramePRIVowner_id
owner_datar%   c                     t         |   |       |t        k(  sJ ||fD ]  }t        |      t        ust        d       || _        || _        y )Nz$PRIV owner fields require bytes type)r   rJ   PRIVATE_FIDr   r   r   rv  rw  )rI   r@   rv  rw  argr   s        r&   rJ   zPrivateFrame.__init__s  s\    [   j) 	ICCy% !GHH	I !$r%   c                     t         |   ||       	 | j                  j                  dd      \  | _        | _        y # t        $ r | j                  | _        Y y w xY w)Nr   r   )r   rV   rE   r[  rv  rw  r   r   s      r&   rV   zPrivateFrame.parse}  sO    dL)	&-1YY__Wa-H*DM4? 	& !IIDM	&s   )= AAc                 j    | j                   dz   | j                  z   | _        t        t        |          S Nr   )rv  rw  rE   r   rt  rY   r   s    r&   rY   zPrivateFrame.render  s,    MMG+doo=	\4/11r%   )r!   r"   r#   r   r   __annotations__ry  rJ   rV   rY   r   r   s   @r&   rt  rt  n  s,    O% %&2 2r%   rt  c                   b     e Zd Zedf fd	Zed        Zej                  d        Z fdZ xZ	S )MusicCDIdFramer%   c                 P    t         t        |   |       |t        k(  sJ || _        y rL   )r   r  rJ   CDID_FIDtoc)rI   r@   r  r   s      r&   rJ   zMusicCDIdFrame.__init__  s%    nd,R0X~~r%   c                     | j                   S rL   rj   rO   s    r&   r  zMusicCDIdFrame.toc  r   r%   c                     || _         y rL   rj   )rI   r  s     r&   r  zMusicCDIdFrame.toc  s	    	r%   c                 H    t         |   ||       | j                  | _        y rL   )r   rV   rE   r  r   s      r&   rV   zMusicCDIdFrame.parse  s    dL)99r%   )
r!   r"   r#   r  rJ   r   r  r   rV   r   r   s   @r&   r  r    sC    " 
   	ZZ  r%   r  c                   8     e Zd Zedf fd	Z fdZ fdZ xZS )PlayCountFramer   c                     t         t        |   |       | j                  t        k(  sJ ||dk  rt        dt        |      z        || _        y Nr   zInvalid count value: %s)r   r  rJ   r@   PLAYCOUNT_FIDr   r   count)rI   r@   r  r   s      r&   rJ   zPlayCountFrame.__init__  sK    nd,R0ww-'('=EAI6UCDD
r%   c                     t         |   ||       t        | j                        dk  rt        j                  d       t        | j                        | _        y )Nrq   z,Fixing invalid PCNT frame: less than 32 bits)r   rV   rb   rE   r`   ri   r   r  r   s      r&   rV   zPlayCountFrame.parse  s>    dL)tyy>AKKFGtyy)
r%   c                 ^    t        | j                  d      | _        t        t        |          S )Nr{   )r   r  rE   r   r  rY   r   s    r&   rY   zPlayCountFrame.render  s%    djj"-	^T133r%   )r!   r"   r#   r  rJ   rV   rY   r   r   s   @r&   r  r    s    'q *4 4r%   r  c                        e Zd ZdZedddf fd	Zed        Zej                  d        Zed        Z	e	j                  d        Z	ed	        Z
e
j                  d
        Z
 fdZ fdZ xZS )PopularityFramezFrame type for 'POPM' frames; popularity.
    Frame format:
    <Header for 'Popularimeter', ID: "POPM">
    Email to user   <text string> $00
    Rating          $xx
    Counter         $xx xx xx xx (xx ...)
    r%   r   c                     t         t        |   |       | j                  t        k(  sJ || _        || _        ||dk  rt        dt        |      z        || _	        y r  )
r   r  rJ   r@   POPULARITY_FIDemailratingr   r   r  )rI   r@   r  r  r  r   s        r&   rJ   zPopularityFrame.__init__  sY    ot-b1ww.()(
=EAI6UCDD
r%   c                     | j                   S rL   )_ratingrO   s    r&   r  zPopularityFrame.rating  rP   r%   c                 <    |dk  s|dkD  rt        d      || _        y )Nr      z(Popularity rating must be >= 0 and <=255)r   r  )rI   r  s     r&   r  zPopularityFrame.rating  s"    A:#GHHr%   c                     | j                   S rL   )_emailrO   s    r&   r  zPopularityFrame.email      {{r%   c                     t        |t              r|j                  d      | _        y t        |t              r|j                  d      }|| _        y t        d      )Nr   z"bytes, str, unicode email required)r   r   r   r  r   r3  r   )rI   r  r   s      r&   r  zPopularityFrame.email  sI     eS!,,w/DKu%W%ADK@AAr%   c                     | j                   S rL   )_countrO   s    r&   r  zPopularityFrame.count  r  r%   c                 2    |dk  rt        d      || _        y )Nr   zPopularity count must be > 0)r   r  )rI   r  s     r&   r  zPopularityFrame.count  s    19;<<r%   c                    t         |   ||       | j                  }|j                  d      }	 |d | | _        ||dz   d  }t        |dd       | _
        |dd  }t        | j                        dk  rt        j                  t        d             t        |      | _        y # t
        $ r( t        j                  t        d             d| _        Y w xY w)Nr   z:Invalid (non-ascii) POPM email address. Setting to 'BOGUS's   BOGUSr   r   rq   z+Invalid POPM play count: less than 32 bits.)r   rV   rE   r.  r  r   r   r   r    r   r  rb   r  )rI   rE   rU   	null_byter   s       r&   rV   zPopularityFrame.parse  s    dL)yyIIg&		"jy)DJ
 IMN#Qq	*ABxtyy>AOON=? @t_
 " 	"OON ,I J K!DJ	"s   
B! !.CCc                     | j                   xs ddz   }|t        | j                        z  }|t        | j                  d      z  }|| _        t
        t        |          S )Nr%   r   r{   )r  r   r  r  rE   r   r  rY   r:  s     r&   rY   zPopularityFrame.render  sU    

!cW,	$++&&	$**b))	_d244r%   )r!   r"   r#   r   r  rJ   r   r  r   r  r  rV   rY   r   r   s   @r&   r  r    s     )AQ    ]] 
   \\B B   \\ 
%*5 5r%   r  c                        e Zd Zeddf fd	Zed        Zej                  d        Zed        Zej                  d        Z fdZ	 fdZ
 xZS )	UniqueFileIDFramer%   c                 j    t         |   |       | j                  t        k(  sJ || _        || _        y rL   )r   rJ   r@   UNIQUE_FILE_ID_FIDrv  uniq_id)rI   r@   rv  r  r   s       r&   rJ   zUniqueFileIDFrame.__init__	  s1    ww,,-, r%   c                     | j                   S rL   )	_owner_idrO   s    r&   rv  zUniqueFileIDFrame.owner_id  r   r%   c                 8    |rt        |      | _        y d| _        y Nr%   )r   r  )rI   oids     r&   rv  zUniqueFileIDFrame.owner_id  s    #&3Cr%   c                     | j                   S rL   )_uniq_idrO   s    r&   r  zUniqueFileIDFrame.uniq_id  r   r%   c                 8    |rt        |      | _        y d| _        y r  )r   r  )rI   uids     r&   r  zUniqueFileIDFrame.uniq_id  s    "%#3r%   c                 l   t         |   ||       | j                  j                  dd      }t	        |      dk(  r|\  | _        | _        n!ddj                  |dd       c| _        | _        t        j                  d| j
                  z         t        j                  d| j                  z         | j
                  s+d}|| _        t        j                  t        d	|z               ydt	        | j                        cxk  rd
kD  r/n yt        j                  t        d| j                  z               yy)z}
        Data format
        Owner identifier <text string> $00
        Identifier       up to 64 bytes binary data>
        r   r   r   r%   r   zUFID owner_id: %szUFID id: %sz"http://www.id3.org/dummy/ufid.htmlz0Invalid UFID, owner_id is empty. Setting to '%s'@   z)Invalid UFID, ID is empty or too long: %sN)r   rV   rE   r[  rb   rv  r  r\  r`   ra   r   r   r    )rI   rE   rU   
split_datadummy_owner_idr   s        r&   rV   zUniqueFileIDFrame.parse  s    	dL)YY__Wa0
z?a,6)T]DL*-sxx
1Q/H'DM4<		%56		-$,,./}}AN*DMOON ,=?M,N O P#dll#(b(OON ,68<,E F G )r%   c                     t        | j                  t              sJ t        | j                  t              sJ | j                  dz   | j                  z   | _        t
        |          S r}  )r   rv  r   r  rE   r   rY   r   s    r&   rY   zUniqueFileIDFrame.render6  sQ    $--///$,,...MMG+dll:	w~r%   )r!   r"   r#   r  rJ   r   rv  r   r  rV   rY   r   r   s   @r&   r  r    sw    ,sC    __0 0   ^^/ /G.   r%   r  c                   \    e Zd Zed        Zej
                   ed      d               Zd Zy)LanguageCodeMixinc                 6    | j                   J | j                   S rL   )_langrO   s    r&   langzLanguageCodeMixin.lang>  s    zz%%%zzr%   r   c                     |sd| _         y |j                  d      }|r|d d nt        }	 |t        k7  r|j                  d       t        |      dk  sJ || _         y # t        $ r	 t        }Y )w xY w)Nr%   r   rp   r   )r  stripr   r3  r   rb   rI   r  s     r&   r  zLanguageCodeMixin.langC  sv     DJzz&!tBQx\	 |#G$ 4yA~~
 " 	 D	 s   A A.-A.c                 b    | j                   }t        |      dk  r|ddt        |      z
  z  z   }|S )Nrp   r   )r  rb   r  s     r&   _renderLangzLanguageCodeMixin._renderLangT  s2    yyt9q=7a#d)m45Dr%   N)r!   r"   r#   r   r  r   r   r  r$   r%   r&   r  r  =  s=      
[[!_  r%   r  c                        e Zd Z edd       edd       fd              Zed        Zej                   ed      d               Zed        Z	e	j                   ed      d	               Z	 fd
Z
 fdZ xZS )DescriptionLangTextFramer   rp   r   rq   c                 N    t         |   |       || _        || _        || _        y rL   )r   rJ   r  r   r   rI   r@   r   r  r   r   s        r&   rJ   z!DescriptionLangTextFrame.__init__\  s(     		&	r%   c                     | j                   S rL   r   rO   s    r&   r   z$DescriptionLangTextFrame.descriptiond  r   r%   c                     || _         y rL   r   )rI   r   s     r&   r   z$DescriptionLangTextFrame.descriptionh  s     (r%   c                     | j                   S rL   r   rO   s    r&   r   zDescriptionLangTextFrame.textm  r   r%   c                     || _         y rL   r   rI   r   s     r&   r   zDescriptionLangTextFrame.textq       
r%   c                    t         |   ||       | j                  dd | _        | j                  dd | _        t
        j                  | j                  d| j                         	 t        | j                  dd  | j                        \  }}t        || j                        | _
        t
        j                  | j                  d| j                         t        || j                        | _        t
        j                  | j                  d| j                         y # t        $ r3 t
        j                  d| j                  z         d| _
        d| _        Y y w xY w)	Nr   r   rq    lang: z description:  text: z%Invalid %s frame; no description/textr   )r   rV   rE   r   r  r`   ra   r@   r   r   r   r   r   ri   )rI   rE   rU   r   r   r   s        r&   rV   zDescriptionLangTextFrame.parsev  s    dL)		!AIIaN			477DII67		!$))AB-?FQ,Q>DIIdggt7G7GHI%a7DIIItww		:; 	KK?$''IJ!DDI	s   )B8D" "9EEc                 j   | j                         }| j                          | j                  |z   | j                  j	                  t        | j                              z   | j                  z   | j                  j	                  t        | j                              z   }|| _        t        t        | /         S rL   )r  r   r   r   r   r   r   r   rE   r   r  rY   )rI   r  rE   r   s      r&   rY   zDescriptionLangTextFrame.render  s    !$  ''(;DMM(JKL  		  !4T]]!CDE 	-t;==r%   )r!   r"   r#   r   r   rJ   r   r   r   r   rV   rY   r   r   s   @r&   r  r  [  s    !QAq   ! ! A(  (   
[[A  $	> 	>r%   r  c                   (     e Zd Zededf fd	Z xZS )CommentFramer   c                 \    t         t        |   ||||       | j                  t        k(  sJ y rL   )r   r  rJ   r@   COMMENT_FIDr  s        r&   rJ   zCommentFrame.__init__  s*    lD*2{D$Gww+%&%r%   )r!   r"   r#   r  r   rJ   r   r   s   @r&   r  r    s    %2L' 'r%   r  c                   (     e Zd Zededf fd	Z xZS )LyricsFramer   c                 \    t         t        |   ||||       | j                  t        k(  sJ y rL   )r   r  rJ   r@   
LYRICS_FIDr  s        r&   rJ   zLyricsFrame.__init__  s*    k4)"k4Fww*$%$r%   )r!   r"   r#   r  r   rJ   r   r   s   @r&   r  r    s    $"<& &r%   r  c                        e Zd Z ed      ddef fd	       Zed        Zej                   ed      d               Z fdZ	 fd	Z
 xZS )
TermsOfUseFramer   r)   r   c                 H    t         t        |   |       || _        || _        y rL   )r   r  rJ   r  r   )rI   r@   r   r  r   s       r&   rJ   zTermsOfUseFrame.__init__  s     ot-b1		r%   c                     | j                   S rL   r   rO   s    r&   r   zTermsOfUseFrame.text  r   r%   r   c                     || _         y rL   r   r  s     r&   r   zTermsOfUseFrame.text  r  r%   c                 n   t         |   ||       | j                  dd x| _        }| j                  dd | _        t
        j                  | j                  d| j                         t        | j                  dd  |      | _	        t
        j                  | j                  d| j                         y )Nr   r   rq   r  r  )
r   rV   rE   r   r  r`   ra   r@   r   r   )rI   rE   rU   r   r   s       r&   rV   zTermsOfUseFrame.parse  s    dL)#'99Qq>1IIaN			477DII67!$))AB-:			477DII67r%   c                     | j                         }| j                          | j                  |z   | j                  j	                  t        | j                              z   | _        t        t        | '         S rL   )
r  r   r   r   r   r   rE   r   r  rY   )rI   r  r   s     r&   rY   zTermsOfUseFrame.render  s_    !]]T)YY%%&9$--&HIJ	_d244r%   )r!   r"   r#   r   r   rJ   r   r   r   rV   rY   r   r   s   @r&   r  r    si    F!  
   
[[A  85 5r%   r  c                   d     e Zd ZdZdZdZ edd      edddddf fd	       Z fd	Z	 fd
Z
 xZS )TocFramea   Table of content frame. There may be more than one, but only one may
    have the top-level flag set.

    Data format:
    Element ID: <string> 
    TOC flags:  %000000ab
    Entry count: %xx
    Child elem IDs: <string>  (... num entry count)
    Description: TIT2 frame (optional)
    r  rr   r   r   NTc                     |t         k(  sJ t        | 	  |       || _        || _        || _        |xs g | _        || _        y rL   )TOC_FIDr   rJ   
element_idtoplevelordered	child_idsr   )rI   r@   r  r  r  r  r   r   s          r&   rJ   zTocFrame.__init__  sF     W}}$ "b&r%   c                 Z   t         |   ||       | j                  }t        j	                  dt        |      z         |j                  d      }|d| | _        ||dz   d  }t        |dd       }t        || j                           | _        t        || j                           | _        t        |dd       }|dd  }g | _        t!        |      D ]9  }|j                  d      }| j                  j#                  |d |        ||dz   d  }; d | _        |r|d d dk7  rt        j'                  d       y |rxt)        |      }t+        j                  || j,                  j.                        }|j1                         }t3        t4              }|j                  ||       |j6                  | _        y y )	NCTOC frame data size: %dr   r   r   r   rq   r'   z%Invalid toc data, TIT2 frame expected)r   rV   rE   r`   ra   rb   r.  r  r   boolTOP_LEVEL_FLAG_BITr  ORDERED_FLAG_BITr  r   r  rangeappendr   ri   r   r   rA   r   r,  r   	TITLE_FIDr   )	rI   rE   rU   r  	flag_bitsentry_countr   description_framer   s	           r&   rV   zTocFrame.parse  s   dL)yy		,s4y89IIg&	q+IMN#d1Qi(	Yt'>'>?@Id&;&;<=Qq	*ABx{# 	(A		'*INN!!$z	"23	A'D	(  D!H'KK?@4=D&,,T4;;3F3FGL99;D )) 4##D,7055D r%   c                    dgdz  }| j                   rd|| j                  <   | j                  rd|| j                  <   | j                  dz   t        |      z   t        t        | j                              z   }| j                  D ]
  }||dz   z  } | j                  Vt        t        | j                        }t        t        | j                  j                        |_        ||j                         z  }|| _        t"        | =         S )Nr   r|   r   r   )r  r  r  r  r  r	   r   rb   r  r   r   r  r   rA   r   rY   rE   r   )rI   flagsrE   cid
desc_framer   s        r&   rY   zTocFrame.render  s    a==-.E$))*<<+,E$''(')% !#,S-@#AB >> 	"CC'M!D	" '"9d.>.>?J +It{{7J7J KJJ%%''D	w~r%   )r!   r"   r#   r   r  r  r   r  rJ   rV   rY   r   r   s   @r&   r  r    sM    	 !Q!dT4T	' 	'"6H   r%   r  c                   ,    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zed        Zej                  d        Zed        Zej                  d        Zed        Zej                  d        Zed        Zej                  d        Zd fd	Z fdZ fdZ xZS )RelVolAdjFrameV24r   r   r   rp   rq   r  r  rr   r|   Fc                 .    t        | j                  d      S r   )r   _identifierrO   s    r&   
identifierzRelVolAdjFrameV24.identifier#  s    4##X..r%   c                 X    t        |      t        k7  r|j                  d      }|| _        y r   )r   r   r   r  )rI   idents     r&   r  zRelVolAdjFrameV24.identifier'  s$    ;%LL*E r%   c                     | j                   S rL   )_channel_typerO   s    r&   channel_typezRelVolAdjFrameV24.channel_type-  s    !!!r%   c                 F    d|cxk  rdk  r	|| _         y  t        d|       )Nr   r|   zInvalid type )r  r   r'  s     r&   r  zRelVolAdjFrameV24.channel_type1  s.    ;Q;!"D  }QC011r%   c                 (    | j                   xs ddz  S )Nr      _adjustmentrO   s    r&   
adjustmentzRelVolAdjFrameV24.adjustment8  s      %A,,r%   c                     |dz  | _         y )Nr   r  )rI   adjs     r&   r  zRelVolAdjFrameV24.adjustment<  s    9r%   c                     | j                   S rL   _peakrO   s    r&   peakzRelVolAdjFrameV24.peak@  r   r%   c                     || _         y rL   r  )rI   vs     r&   r	  zRelVolAdjFrameV24.peakD  s	    
r%   c                     |dk(  sJ t         |   |       |xs d| _        |xs | j                  | _        |xs d| _        |xs d| _        y )N   RVA2r   r   )r   rJ   r  CHANNEL_TYPE_OTHERr  r  r	  )rI   r   r  r  r  r	  r   s         r&   rJ   zRelVolAdjFrameV24.__init__H  sQ    g~~$*(CD,C,C$/IA	r%   c                 4   t         |   ||       | j                  j                  t        k7  r"t        d| j                  j                         | j                  }|j                  dd      \  | _        }|d   | _	        t        |dd       | _        t        |      dkD  r |d   }|rt        |dd|dz  z          | _        t        j!                  d	| j                   d
| j                   d| j"                   d| j                   d| j$                   
       y )NzInvalid frame version: r   r   )maxsplitr   rp   rq   r|   zParsed RVA2: identifier=z channel_type=z adjustment=z _adjustment=z peak=)r   rV   rA   r   r   r    rE   r[  r  r  r   r  rb   r   r  r`   ra   r  r	  )rI   rE   rU   bits_per_peakr   s       r&   rV   zRelVolAdjFrameV24.parseQ  s   dL);;(* #:4;;;N;N:O!PQQyy $

7Q
 ? G,T!AY7t9q= GM&tAa=A3E.F'GH
		,T__,=^DL]L]K^ _  $0d>N>N=OvVZV_V_U`b 	cr%   c                 v   | j                   J | j                  t        | j                  t              | _        | j                  j
                  t        k(  sJ | j                  dz   t        | j                         z   t        | j                  xs d      z   | _
        | j                  rd}t        t        | j                              }dD ]/  }||kD  r	|t        |d      t        | j                  |      z   z  } n |st        d| j                         | xj                  |z  c_
        t        | A         S )Nr   r   r%   )r|   r
  r{   r|   zPeak value out of range: )r  rA   r   r@   r   r   r  r   r   r  rE   r  rb   r   r   r   rY   )rI   	peak_datanum_pk_bitsszr   s       r&   rY   zRelVolAdjFrameV24.renderc  s!   !!---;;%dggx8DK{{""h... w&d(()*d..3!45 		
 ::Igdjj12K! #Yr1-	$**b0III		  #<TZZL!IJJII"Iw~r%   )r  NNNN)r!   r"   r#   r  CHANNEL_TYPE_MASTERCHANNEL_TYPE_FRONT_RIGHTCHANNEL_TYPE_FRONT_LEFTCHANNEL_TYPE_BACK_RIGHTCHANNEL_TYPE_BACK_LEFTCHANNEL_TYPE_FRONT_CENTERCHANNEL_TYPE_BACK_CENTERCHANNEL_TYPE_BASSr   r   r  r   r  r  r	  rJ   rV   rY   r   r   s   @r&   r  r    s     ! N/ / ! !
 " " 2 2 - - % %   
[[ c$   r%   r  c                        e Zd ZdZdZdZdZdZdZdefdefd	d
defdefdddefddefdgZ	e
j                   G d d             Zd fd	ZdefdZ fdZ fdZ xZS )RelVolAdjFrameV23r   r   r   rp   rq   r  front_right
front_left)front_right_peakN)front_left_peakN
back_right	back_left)back_right_peakN)back_left_peakNfront_center)front_center_peakNbass)	bass_peakNc                      e Zd ZU dZeed<   dZeed<   dZeed<   dZeed<   dZ	eed<   dZ
eed<   dZeed<   dZeed	<   dZeed
<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   ej0                  dej2                  dej4                  dej6                  dej8                  dej:                  d	ej<                  dej>                  dej@                  di	Z!e"de#fd       Z$e"de#fd       Z%e"de#fd       Z&e"de#fd       Z'e"de#fd       Z(e"de#fd       Z)e"de#fd       Z*d Z+d Z,d Z-y) #RelVolAdjFrameV23.VolumeAdjustmentsr   mastermaster_peakr   r!  r"  r#  r$  r%  r&  r'  r(  r)  back_centerback_center_peakr*  r+  r[   
other_peakreturnc                 H    t        | j                  xs | j                        S rL   )r  r.  r/  rO   s    r&   has_master_channelz6RelVolAdjFrameV23.VolumeAdjustments.has_master_channel  s    7t'7'788r%   c                     t        | j                  xs( | j                  xs | j                  xs | j                        S rL   )r  r   r!  r"  r#  rO   s    r&   has_front_channelz5RelVolAdjFrameV23.VolumeAdjustments.has_front_channel  s8      dDOOdt7L7LdPTPdPd r%   c                     t        | j                  xs( | j                  xs | j                  xs | j                        S rL   )r  r$  r%  r&  r'  rO   s    r&   has_back_channelz4RelVolAdjFrameV23.VolumeAdjustments.has_back_channel  s5    `4>>`T5I5I`TM`M` r%   c                 H    t        | j                  xs | j                        S rL   )r  r(  r)  rO   s    r&   has_front_center_channelz<RelVolAdjFrameV23.VolumeAdjustments.has_front_center_channel  s    ))CT-C-CDDr%   c                 H    t        | j                  xs | j                        S rL   )r  r0  r1  rO   s    r&   has_back_center_channelz;RelVolAdjFrameV23.VolumeAdjustments.has_back_center_channel  s    ((AD,A,ABBr%   c                 H    t        | j                  xs | j                        S rL   )r  r*  r+  rO   s    r&   has_bass_channelz4RelVolAdjFrameV23.VolumeAdjustments.has_bass_channel  s    		3T^^44r%   c                 H    t        | j                  xs | j                        S rL   )r  r[   r2  rO   s    r&   has_other_channelz5RelVolAdjFrameV23.VolumeAdjustments.has_other_channel  s    

5doo66r%   c                     g }t        j                  |       j                         D ]!  \  }}|dkD  s|dk  s|j                  |       # |rt	        ddj                  |             y )Ni   i  zInvalid RVAD channel values: ,)dataclassesasdictitemsr  r   r\  )rI   invalidsr]  values       r&   boundsCheckz/RelVolAdjFrameV23.VolumeAdjustments.boundsCheck  sn    H*11$7==? *e5=EFNOOD)*  #@(AS@T!UVV r%   c                 8    t        | | j                  |   |       y rL   setattr_channel_maprI   	chan_typerH  s      r&   setChannelAdjz1RelVolAdjFrameV23.VolumeAdjustments.setChannelAdj  s    D$++I6>r%   c                 >    t        | | j                  |    d|       y )Nr  rK  rN  s      r&   setChannelPeakz2RelVolAdjFrameV23.VolumeAdjustments.setChannelPeak  s!    DT..y9:%@%Hr%   N).r!   r"   r#   r.  r   r~  r/  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r0  r1  r*  r+  r[   r2  r  r  r  r  r  r  r  r  r  r  rM  r   r  r5  r7  r9  r;  r=  r?  rA  rI  rP  rR  r$   r%   r&   VolumeAdjustmentsr-    s   SS
C !#!  
C	3  c!"3"S !#!c	3s
C 11800'6655|55|44k7766//

 
	9 	9 
	9 
	t 	 
	
 
	d 	 
	
 
	Ed 	E 
	E 
	CT 	C 
	C 
	5d 	5 
	5 
	7t 	7 
	7	W	?	Ir%   rS  c                 @    |dk(  sJ t         |   |       d | _        y )N   RVAD)r   rJ   adjustments)rI   r   r   s     r&   rJ   zRelVolAdjFrameV23.__init__  s$    g~~r%   r3  c                     g fd}dD ]\  }t        t        d|j                                }t        | j                  |      }t        | j                  | d      } ||||       ^ S )zReturn a list of RVA2 framesc                 P    |s|sy j                  t        | |dz  |             y )Nr   )r  r  r	  )r  r  )ch_typech_adjch_peak	converteds      r&   r  z'RelVolAdjFrameV23.toV24.<locals>.append  s*    '!w6C<V]^r%   )r   r!  r$  r%  r(  r*  CHANNEL_TYPE_r  )getattrr  upperrV  )rI   r  channelchtyper  pkr\  s         @r&   toV24zRelVolAdjFrameV23.toV24  sx    		0 	$G.-?P0QRF$**G4C))gYe+<=B63#	$ r%   c                    t         	|   ||       | j                  j                  t        t
        fvrt        d      | j                  }t        t        |d   g            }|j                          |d   dz  }|dkD  rt        d      | j                         | _        d}| j                  D ]Q  \  }}|t        |      k\  r n>t        ||||z          }||z  }||r||   dk(  r| }t!        | j                  ||       S 	 t"        j%                  d| j                          | j                  j'                          y # t(        $ r	 d | _         w xY w)NzInvalid v2.4 frame: RVADr   r   r|   r   zRVAD volume adj out of boundsz Parsed RVAD frames adjustments: )r   rV   rA   r   r   r   r    rE   r   r   reverserS  rV  CHANNEL_DEFNrb   r   rL  r`   ra   rI  r   )
rI   rE   rU   inc_dec_bit_listbytes_per_voloffsetadj_nameinc_dec_bitadj_valr   s
            r&   rV   zRelVolAdjFrameV23.parse  sZ   dL);;x&:: !;<<yy$UDG9%56  "Q11 !@AA113%)%6%6 	9!HkT"VF],B CDGm#F'(5:"(D$$h8	9	II89I9I8JKL((* 	#D	s   <E   Ec                 v   d}dgdz  }| j                   t        | j                  t              | _         | j                   j                  t        k(  sJ | j
                  j                          | j
                  j                  dkD  rdnd|| j                  <   | j
                  j                  dkD  rdnd|| j                  <   |t        t        | j
                  j                        d      z  }|t        t        | j
                  j                        d      z  }|t        t        | j
                  j                        d      z  }|t        t        | j
                  j                        d      z  }d| j
                  j                  | j
                  j                   | j
                  j"                  fv r| j
                  j$                  dkD  rdnd|| j&                  <   | j
                  j(                  dkD  rdnd|| j*                  <   |t        t        | j
                  j$                        d      z  }|t        t        | j
                  j(                        d      z  }|t        t        | j
                  j,                        d      z  }|t        t        | j
                  j.                        d      z  }d| j
                  j                  | j
                  j                   fv r| j
                  j0                  dkD  rdnd|| j2                  <   |t        t        | j
                  j0                        d      z  }|t        t        | j
                  j4                        d      z  }| j
                  j                  r| j
                  j6                  dkD  rdnd|| j8                  <   |t        t        | j
                  j6                        d      z  }|t        t        | j
                  j:                        d      z  }t=        t?        |            dz   |z   | _         tB        |          S )	Nr%   r   r|   r   r
  )pT   )#rA   r   r@   r   r   rV  rI  r   FRONT_CHANNEL_RIGHT_BITr!  FRONT_CHANNEL_LEFT_BITr   absr"  r#  r?  r;  r9  r$  BACK_CHANNEL_RIGHT_BITr%  BACK_CHANNEL_LEFT_BITr&  r'  r(  FRONT_CENTER_CHANNEL_BITr)  r*  BASS_CHANNEL_BITr+  r	   reversedrE   r   rY   )rI   rE   inc_dec_bitsr   s      r&   rY   zRelVolAdjFrameV23.render(  sy   sQw;;%dggx8DK{{""h...$$& ;?:J:J:V:VYZ:ZQ`aT1129=9I9I9T9TWX9XA^_T001	#d..::;rBB	#d..99:bAA	#d..??@BGG	#d..>>?2FF D$$55t7G7G7`7`$$557 7=A=M=M=X=X[\=\bcL445<@<L<L<V<VYZ<Zq`aL334Ic$"2"2"="=>"EEDIc$"2"2"<"<=DDDIc$"2"2"B"BCrJJDIc$"2"2"A"ABbIID D$$55t7G7G7`7`aa?C?O?O?\?\_`?`!AB 667Ic$"2"2"?"?@BGGDIc$"2"2"D"DELLD ,,7;7G7G7L7Lq7P!VWL../Ic$"2"2"7"78B??DIc$"2"2"<"<=DDDh|45?$F	w~r%   )rU  )r!   r"   r#   rp  rq  rs  rt  ru  rv  rf  rD  	dataclassrS  rJ   listrc  rV   rY   r   r   s   @r&   r  r  ~  s     "$;<!#9:.-!#9: "78-,#%=>/-.'L SI SI SIj 
t *"H*  * r%   r  StartEndTuplestartendc                        e Zd ZdZdZ	 eddddf fd	Z fdZ fdZe	d        Z
e
j                  d        Z
e	d	        Zej                  d
        Ze	d        Zej                  d        Z xZS )ChapterFrameaJ  Frame type for chapter/section of the audio file.
    <ID3v2.3 or ID3v2.4 frame header, ID: "CHAP">           (10 bytes)
    Element ID      <text string> $00
    Start time      $xx xx xx xx
    End time        $xx xx xx xx
    Start offset    $xx xx xx xx
    End offset      $xx xx xx xx
    <Optional embedded sub-frames>
    l    Nc                     |t         k(  sJ t        t        |   |       || _        |xs t        d d       | _        |xs t        d d       | _        |xs
 t               | _	        y rL   )
CHAPTER_FIDr   r  rJ   r  r{  timesoffsetsFrameSet
sub_frames)rI   r@   r  r  r  r  r   s         r&   rJ   zChapterFrame.__init__g  s[    [ ! lD*2.$7mD$7
;-d";$2
r%   c                    ddl m}m} t        
|   ||       | j
                  }t        j                  dt        |      z         |j                  d      }|d| | _
        ||dz   d  }t        |d d       }|dd  }t        |d d       }|dd  }t        ||      | _        t        |d d       }|dd  }t        |d d       }|dd  }t        || j                  k7  r|nd || j                  k7  r|nd       | _        |rX || j                   j"                        }t        |      |_        | j&                  j	                  t)        |      | |             }	y t+               | _        y )Nr   )	TagHeaderExtendedTagHeaderr  r   r   rq   )headersr  r  r   rV   rE   r`   ra   rb   r.  r  r   r{  r  	NO_OFFSETr  rA   r   tag_sizer  r   r  )rI   rE   rU   r  r  r  r|  r}  dummy_tag_headerr   r   s             r&   rV   zChapterFrame.parsep  s[   9dL)yy		,s4y89IIg&	q+IMN#$r(#ABxRa!ABx"5#.
$r(#ABxRa!ABx$et~~.EU4,/4>>,AStM ()<)<=(+D	%%%gdm5E,=,?AA 'jDOr%   c                    | j                   dz   }| j                  | j                  z   D ]  }||t        |d      z  }|dz  } | j                  j                         D ]D  }t        |j                  | j                  j                        |_        ||j                         z  }F || _        t        t        | +         S )Nr   r{   s   )r  r  r  r   r  getAllFramesr   r@   rA   r   rY   rE   r   r  )rI   rE   nfr   s       r&   rY   zChapterFrame.render  s    (dll* 	,A}	!R((++		, --/ 	A"144)<)<=AHAHHJD	 	\4/11r%   c                 h    t         | j                  v r | j                  t            d   j                  S y Nr   )r  r  r   rO   s    r&   titlezChapterFrame.title  s+    '??9-a0555r%   c                 D    | j                   j                  t        |       y rL   )r  setTextFramer  )rI   r  s     r&   r  zChapterFrame.title  s    $$Y6r%   c                 h    t         | j                  v r | j                  t            d   j                  S y r  )SUBTITLE_FIDr  r   rO   s    r&   subtitlezChapterFrame.subtitle  s+    4??*??<03888r%   c                 D    | j                   j                  t        |       y rL   )r  r  r  )rI   r  s     r&   r  zChapterFrame.subtitle  s    $$\8<r%   c                 l    t         | j                  v r"| j                  t            d   }|j                  S y r  )r   r  r   )rI   frames     r&   user_urlzChapterFrame.user_url  s0    $//)OOK03E 99r%   c                     d}|| j                   t        = y t        | j                   v r0| j                   t           D ]  }|j                  |k(  s||_         y  t	        t        ||      | j                   t        <   y )Nzchapter url)r  r   r   r   r   )rI   r   DESCRIPTIONr  s       r&   r  zChapterFrame.user_url  sq    #;,doo-!__[9 E((K7$'	
 ,88CS,JDOOK(r%   )r!   r"   r#   r   r  r  rJ   rV   rY   r   r  r   r  r  r   r   s   @r&   r  r  Y  s     I1%$d$3)B2   
 \\7 7  
 __= =   __J Jr%   r  c                       e Zd Zd Zd Z ed      d        Z ed      d        Zed        Z	d Z
 ed       ed      d	               Z ed      d
        Zy)r  c                 L    t         j                  |        t               | _        y rL   )dictrJ   set_unknown_frame_idsrO   s    r&   rJ   zFrameSet.__init__  s    d"%%r%   c                 N   | j                          | j                  j                          d}|j                  |j                  z
  }d}|j	                  |      }|j
                  ro|j                  t        k  r\t        j                  dt        |      z         t        |      }t        |      }t        |      }t        j                  d||fz         d}	|	d|j                  z  z  }	t        |	|z         }
|
j                  t        |	             d}|dkD  rt        j                  dt        |      z          |dk  rt        j                  d       |}	 |S t        j                  d	       t        j                  d
t        |dz         z          t        j                   |
|j                        }|st        j                  d|z         |}	 |S |j"                  rt        j                  d|j"                  |j"                  |
j%                         |
j%                         fz         |
j	                  |j"                        }t        j                  dt        |      z         ||j                  |j"                  z   z  }	 t'        |||      }|| |j(                  <   |dz  }|j*                  r&| j                  j-                  |j(                         	 ||j                  |j"                  z   z  }|dkD  r|S # t.        $ r"}t        j1                  d|        Y d}~Kd}~ww xY w)zRead frames starting from the current read position of the file
        object. Returns the amount of padding which occurs after the tag, but
        before the audio content.  A return value of 0 does not mean error.r   z+De-unsynching %d bytes at once (<= 2.3 tag)z6De-unsynch'd %d bytes at once (<= 2.3 tag) to %d bytess
             r   zsize_left: r  z2FrameSet: Implied padding (size_left<minFrameSize)z1+++++++++++++++++++++++++++++++++++++++++++++++++zFrameSet: Reading Frame #r   z+No frame found, implied padding of %d byteszAFrameSet: Reading %d (0x%X) bytes of data from byte pos %d (0x%X)zFrameSet: %d bytes of data readzFrame error:  N)clearr  r  sizer,  rx   r   r   r`   ra   rb   ry   r   seekr   r   rV   	data_sizetellcreateFramer@   r   addr    ri   )rI   r  
tag_headerextended_headerpadding_size	size_leftconsumed_sizetag_dataog_size
prepadding
tag_bufferframe_countrU   rE   r  frame_exs                   r&   rV   zFrameSet.parse  s    	

%%'''/*>*>>	 66)$ !3!3x!?IIC(m$ %(mG#H-HHIIIN	*+ ,
 "
g 4 444
Z(23
J(!mIImc)n45F#		NO(J G IIIJII1Ca4HHI&,,Z9K9KLL		G#$ %(8 3 %%		 *-9-C-C-9-C-C-7__->-7__->-@@ A
 "|'='=>		;c$iGH,"3"3"."8"8#9 :>'
L$GE &+DN1$K}}//33EHH= ,++&001 2IO !mT  & =KK.
 ;<<=s   K9 9	L$LL$r   c                 8    || v rt         j                  | |      S y rL   )r  __getitem__rI   r   s     r&   r  zFrameSet.__getitem__#  s    $;##D#..r%   c                     ||j                   k(  sJ || v r| |   j                  |       y t        j                  | ||g       y rL   )r@   r  r  __setitem__)rI   r   r  s      r&   r  zFrameSet.__setitem__*  s?    ehh$;IU#T30r%   c                     | j                   S rL   )r  rO   s    r&   unknown_frame_idszFrameSet.unknown_frame_ids3  s    &&&r%   c                 p    g }t        | j                               D ]  }||z  }	 |j                          |S )zlReturn all the frames in the set as a list. The list is sorted
        in an arbitrary but consistent order.)rz  valuessort)rI   framesflists      r&   r  zFrameSet.getAllFrames7  s:     $++-( 	EeOF	r%   r   c                     |t         vr|t        vrt        d|       || v r|| |   d   _        y|t        t
        z   v rt        ||      | |<   yt        ||      | |<   y)zSet a text frame value.
        Text frame IDs must be unique.  If a frame with
        the same Id is already in the list it's value is changed, otherwise
        the frame is added.
        zInvalid frame ID: r   )r   r   N)r   r   r   r   r   r   r   r   )rI   r   r   s      r&   r  zFrameSet.setTextFrame@  sl     j S0F%F1#788$; $DIaLy#778%c5S	%c5S	r%   c                 .    t         j                  | |      S rL   )r  __contains__r  s     r&   r  zFrameSet.__contains__S  s      s++r%   N)r!   r"   r#   rJ   rV   r   r  r  r   r  r  r   r  r  r$   r%   r&   r  r    s    (L\ !_  !_1 1 ' ' !_A6  6" !_, ,r%   r  c                     g }d}| D cg c]  }t        |g       c}D ]3  }|r|j                  |       |dk7  }|dk7  r|j                  |       d}5 dj                  |      S c c}w )NT   r   r%   )r   r  r\  )rE   outputsafer   vals        r&   ry   ry   X  sr    FD$()qqc
) MM#7NDg~c"D 88F *s   A&c                 D   |j                   }|t        v rt        |   \  }}}nP|t        v r&t        j	                  d|z         t        |   \  }}}n"t        j                  d|        dd t        }}}t        j                  d| d| d|        |s.t        j                  d|j                  d       d	       t        }t        j                  d
| d| d       | j                  d d t        k(  r| j                  rd|_         ||      }|j                  ||       |S )Nz#Non standard frame '%s' encounteredzUnknown ID3 frame ID: UnknownzcreateFrame (desc:z) - z - zFrame 'r   z0' is not yet supported, using raw Frame to parsezcreateFrame 'z' with class ''r   T)r@   r   r   r`   verboseri   r   ra   r3  r>   r   r   rx   rV   )r  rU   rE   r   r   ver
FrameClassr  s           r&   r  r  g  s   
//C
j",S/sJ	&	&9C?@"8"=sJ,SE23#,dLJsII"4&SEZLAB gcjj122bcd
IIcU.A>?"1)j.?.?"sOE	KKl#Lr%   c                 b   | df|dffD ]#  \  }}t        |t              rt        d|z         t        |      }t        j                  d|z         |j                  d      r3t        |       dz  dk7  r"| dd  d	k(  rt        j                  d
       | d d } t        | |      j                  d      S )Nbitesr   z"%s argument must be a byte string.zUnicode encoding: %sutf_16r   r   r*  r   z'Fixing utf16 data with extra zero bytes )r   r   r   r   r`   ra   
startswithrb   ri   r   rstrip)r  r   rp  obj_namecodecs        r&   r   r     s     '*Xz,BC MX#u%@8KLLM  )EII$u,-"JNaE"#J'$9=>cr
ue##F++r%   c                    	 |t         k(  s	|t        k(  r| j                  dd      \  }}na|t        k(  s	|t        k(  rA| j                  dd      \  }}t        |      dz  dk7  r)| j                  dd      \  }}|dz  }nt        d|       ||fS # t        $ r)}t        j                  d|        | d	}}Y d }~||fS d }~ww xY w)
Nr   r   r   r   r   s      zUnknown ID3 encoding: z Invalid 2-tuple ID3 frame data: r%   )
r   r   r[  r   r   rb   NotImplementedErrorr   r`   ri   )rE   r   r   r   exs        r&   r   r     s    &(n*DZZ+FQ(H8I,I ZZQ/FQA
q OQ7AW%(>xj&IJJ
 a4K	  6rd;<S1a4K	s   B	B 	CB<<Cc                     t        | t              st        d      | t        k(  ry| t        k(  ry| t
        k(  ry| t        k(  ryt        d| z        )Nr   latin_1utf_8r  	utf_16_beEncoding unknown: %s)r   r   r   r   r   r   r   r   )r   s    r&   r   r     sV    h&BCC?"	^	#	_	$	&	&/(:;;r%   c                     | j                  dd      } | dv rt        S | dv rt        S | dv rt        S | dv rt        S t        d| z        )N-r   )r  r   )r  utf8)r  utf16)r  utf16_ber  )replacer   r   r   r   r   rS  s    r&   stringToEncodingr    s_    			#sA!!	
		
!	!	
'	'  /!344r%   s   AENCzAudio encryptionzAttached pictures   ASPIzAudio seek point indexCommentss   COMRzCommercial framezTable of contentsChapters   ENCRzEncryption method registrations   EQUAEqualisations   EQU2zEqualisation (2)s   ETCOzEvent timing codeszGeneral encapsulated objects   GRIDz!Group identification registrations   IPLSzInvolved people lists   LINKzLinked informationzMusic CD identifiers   MLLTzMPEG location lookup tables   OWNEzOwnership framezPrivate framezPlay counterPopularimeters   POSSzPosition synchronisation frames   RBUFzRecommended buffer sizerU  zRelative volume adjustmentr  zRelative volume adjustment (2)s   RVRBReverbs   SEEKz
Seek frames   SIGNzSignature frames   SYLTzSynchronised lyric/texts   SYTCzSynchronised tempo codeszAlbum/Movie/Show titlezBPM (beats per minute)ComposerzContent typezCopyright messager2   r   r8   zEncoding times   TDLYzPlaylist delayr9   zOriginal release timer:   zRecording timer;   zRelease timer<   zTagging timez
Encoded bys   TEXTzLyricist/Text writers   TFLTz	File typer4   Times   TIPLs   TIT1zContent group descriptionz"Title/songname/content descriptionzSubtitle/Description refinements   TKEYzInitial keys   TLANzLanguage(s)s   TLENLengths   TMCLzMusician credits lists   TMEDz
Media types   TMOOMoods   TOALzOriginal album/movie/show titles   TOFNzOriginal filenames   TOLYz#Original lyricist(s)/text writer(s)zOriginal artist(s)/performer(s)r5   zOriginal release years   TOWNzFile owner/licenseezLead performer(s)/Soloist(s)zBand/orchestra/accompaniments   TPE3zConductor/performer refinements   TPE4z.Interpreted, remixed, or otherwise modified byzPart of a sets   TPROzProduced notice	PublisherzTrack number/Position in setr6   zRecording datess   TRSNzInternet radio station names   TRSOzInternet radio station owners   TSOAzAlbum sort orders   TSOPzPerformer sort orders   TSOTzTitle sort orders   TSIZSizes   TSRCz,ISRC (international standard recording code)s   TSSEz0Software/Hardware and settings used for encodings   TSSTzSet subtitler3   Yearz#User defined text information framezUnique file identifierzTerms of usez'Unsynchronised lyric/text transcriptionzCommercial informationzCopyright/Legal informationzOfficial audio file webpagez!Official artist/performer webpagezOfficial audio source webpagez(Official Internet radio station homepagePaymentzPublishers official webpagezUser defined URL link frame)	r*   r+   r,   r-   r.   r/   r0   r1   r(   c                 (    | t         vr| S t         |    S rL   )TAGS2_2_TO_TAGS_2_3_AND_4)orig_ids    r&   map2_2FrameIdr  A  s    //$W--r%   s   TT1s   TT2s   TT3s   TP1s   TP2s   TP3s   TP4s   TCMs   TXTs   TLAs   TCOs   TALs   TRKs   TPAs   TRCs   TDAs   TYEs   TIMs   TRDs   TORs   TBPs   TMTs   TFTs   TCRs   TPBs   TENs   TSSs   TLEs   TSIs   TDYs   TKEs   TOTs   TOFs   TOAs   TOLs   TXXs   WAFs   WARs   WASs   WCMs   WCPs   WPBs   WXXs   IPLs   ULTs   COMs   UFIs   MCIs   ETCs   MLLs   STCs   SLTs   RVAs   EQUs   REVs   PICs   GEOs   CNTs   POPs   BUFs   CRAs   LNKs   TCP   TCMPs   TSTs   TSPs   TSAs   TS2   TSO2s   TSC   TSOC   TDES   TGIDr   s   CM1    PCST)s   TDRs   TDSs   TIDs   WFDs   CM1s   PCS)applezUndefined MusicMatch extensionz"iTunes complilation flag extensionz*Album sort-order string extension for v2.3z.Performer sort-order string extension for v2.3z*Title sort-order string extension for v2.3z2MusicBrainz release date (full) extension for v2.3z1Album artist sort-order used in iTunes and Picardz-Composer sort-order used in iTunes and Picardz-iTunes extension; marks the file as a podcastz#iTunes extension; podcast keywords?z&iTunes extension; podcast description?ziTunes extension; podcast ?????z#iTunes extension; podcast feed URL?z#iTunes extension; podcast category.ziTunes extension; grouping.)s   NCONr  r   r   r   r7   r  r  r  s   TKWDr  r  r   s   TCATr   )yrD  ior   collectionsr   r   r   utilsr   r   utils.binfuncsr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   	utils.logr   r!   r`   r   r    r  r  
ARTIST_FIDALBUM_ARTIST_FIDORIG_ARTIST_FIDCOMPOSER_FID	ALBUM_FIDTRACKNUM_FID	GENRE_FIDr  r   rr  r  r  DISCNUM_FIDr  r   r  BPM_FIDPUBLISHER_FIDr  ry  TOS_FIDr  ENCODED_BY_FIDCOPYRIGHT_FIDURL_COMMERCIAL_FIDURL_COPYRIGHT_FIDURL_AUDIOFILE_FIDURL_ARTIST_FIDURL_AUDIOSRC_FIDURL_INET_RADIO_FIDURL_PAYMENT_FIDURL_PUBLISHER_FIDr   r  r  r   r   objectr>   r   r   r   r   r   r   r  rc  rt  r  r  r  r  r  r  r  r  r  r  r  r  r{  r  r  r  ry   r  r   r   r   r  r   r  r  r  PCSTTKWDTDESTGIDWFEDGRP1r   r$   r%   r&   <module>r!     s     "  0    2 2. .    !
	U 	 	
 		
 
	      (*;'9I(/')
   :	@F @F,  , ^,"I ,"^-(	 -(`!.u !.H-"8 -"`5 "~% ~%Bg1% g1T25 2:U (4U 4,P5e P5f2  2 j <6>u&7 6>r'+ '&* &5e. 5BQ u Q hd  d NT  T n ?We,<= .sJ5 sJnE,t E,P6,(< 5zg* z *"$z 0 z 
FL9z *FD9z +VX>z 	6<8z  8&$G!z" $7#z$ *Hd;%z& ,fd;'z* 5v{K+z, ;VTJ-z0 .$?1z4 ,fd;5z8 -v~F9z: 4fdC;z> )648?zB >CzD ?EzF AGzH 8&$GIzL 164@MzN 4h@QROzP 8(DUVQzR &$/SzV h5WzX )8T:YzZ 164@[z\ 2FDA]z` 0&)Dazb 0&)Dczd 
FI6ezf 	:gzh +VY?izj )4kzl 9=mzn (&)<ozp /9Eqzr ((I>szt )<uzv )<wzx fi8yzz .	B{z| VY7}z~ )4z@ .)DAzB 3VYGCzD <f!#EzH 969MIzJ vy9KzL vy9MzN &)4OzP /9EQzR fi8SzT )4UzV 969MWzX +VY?YzZ =v!#[z^ 969M_z` /9Eazb -vyAczd 6	Jezf 6	Jgzh 8&)Lizj H	+kzn ;ozp )8Y?qzr VY7szt 6	Juzv )8Y?wzx 5vyIyzz 6	J{z| *Hi@}z~ .)Dz@ *Hi@AzB )4CzD F!#EzH J	+IzL )<MzN )4OzP =v%'QzV 0&:KLWzX @YzZ A6#%[z` 1&(C5vxH5vxH;VXN7JBF "!6845vxH5v|Lsz
z.M
GM
GM GM G	M
 GM GM GM GM GM GM GM GM GM GM GM  G!M" G#M$ G%M& G'M( G)M* G+M, G-M. G/M0 G1M2 G3M4 G5M6 G7M8 G9M: G;M< G=M> G?M@ GAMB GCMD GEMF GGMH GIMJ GKML GMMN GOMP GQMR GSMT GUMV GWMX GYMZ G[M\ G]M^ G_M` GaMb GcMd GeMf GgMh GiMj GkMl GmMn GoMp GqMr GsMt GuMv GwMx GyMz G{M| G}M@ GAMB GCMD GEMF GGMH GIMJ GKML YM ^ .>2FIF:	#>	#:	#B	# Bi!=i! >ejj"3ejj"6ejj"/ejj"3ejj"3i!+ejj"; r%   