a
    Dc``O@                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZ dd ZG dd dZG dd	 d	ZG d
d dZG dd dZG dd dZG dd dZG dd dZd	dgZdS )    N)_)reducec                 C   s    dddddd}| |  dS )N            )ZcriticalZ	emergencyZhighZmediumlowc   )getlower)uZurgency_map r   )/usr/share/apt-listchanges/DebianFiles.py_numeric_urgency-   s    r   c                   @   s>   e Zd ZedZg dZdd Zdd Zdd Z	d	d
 Z
dS )ControlStanzaz^\S+ \((?P<version>.*)\).*)PackageSourceVersionArchitectureStatusc                 C   s|   d }| dD ]h}|s qx|d dv rF|rvt| |t| |d |  q| dd\}}|| jv rrt| ||  qd }qd S )N
r   ) 	:r   )splitsetattrgetattrfields_to_readlstrip)selfsfieldlinevaluer   r   r   __init__;   s    
zControlStanza.__init__c                 C   s   t | d| jdd S )Nr   r   r   )r   r   r   r   r   r   r   sourceL   s    zControlStanza.sourcec                 C   s   t | do| jdd dkS )Nr   r   r   	installed)hasattrr   r   r%   r   r   r   r'   O   s    zControlStanza.installedc                 C   s>   | j }t| dr:| j| j}|r:|d}||s:|S |S )a  
        This function returns the version of the package. One would like it to
        be the "binary" version, though we have the tough case of source
        package whose binary packages versioning scheme is different from the
        source one (see OOo, linux-source, ...).

        This code does the following, if the Source field is set with a
        specified version, then we use the binary version if and only if the
        source version is a prefix. We must do that because of binNMUs.
        r   version)r   r(   source_version_rematchr   group
startswith)r   vr+   Zsvr   r   r   r)   R   s    


zControlStanza.versionN)__name__
__module____qualname__recompiler*   r   r$   r&   r'   r)   r   r   r   r   r   7   s   
r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )ControlParserc                 C   s   g | _ i | _d S N)stanzasindexr%   r   r   r   r$   h   s    zControlParser.__init__c                 C   s.   i | j |< | jD ]}|| j | t||< qd S r5   )r7   r6   r   )r   r!   stanzar   r   r   	makeindexl   s    

zControlParser.makeindexc              
   C   s   zTt |ddd2}|  jdd | dD 7  _W d    n1 sH0    Y  W n@ ty } z(ttd|t|d |W Y d }~n
d }~0 0 d S )	Nutf-8replace)encodingerrorsc                 S   s   g | ]}|rt |qS r   )r   .0xr   r   r   
<listcomp>t       z*ControlParser.readfile.<locals>.<listcomp>

'Error processing '%(what)s': %(errmsg)sZwhaterrmsg)openr6   readr   	ExceptionRuntimeErrorr   str)r   filefexr   r   r   readfileq   s    DzControlParser.readfilec              
   C   s|   z6dd|gt j }t|}| jt |dd W n@ tyv } z(tt	d|t
|d |W Y d }~n
d }~0 0 d S )Nzdpkg-debz-fr:   r;   rD   rE   )r   r   
subprocessZcheck_outputr6   appenddecoderI   rJ   r   rK   )r   ZdebcommandoutputrN   r   r   r   readdeby   s    
zControlParser.readdebc                 C   s\   || j v r,|| j | v r&| j | | S d S n,| jD ]$}t||r2t|||kr2|  S q2d S r5   )r7   r6   r(   r   )r   r!   r#   r8   r   r   r   find   s    


zControlParser.findN)r/   r0   r1   r$   r9   rO   rU   rV   r   r   r   r   r4   g   s
   	r4   c                   @   sz   e Zd ZdddZdd Zdd Zedd	 Zed
d Zedd Z	edd Z
edd Zedd Zdd ZeZdS )ChangelogEntryFc                 C   s0   |  | _|| _t|| _d| _d| _|| _d S )N )strip_header_versionr   _trailer_content_binnmu)r   headerr)   urgencybinnmur   r   r   r$      s    

zChangelogEntry.__init__c                 C   s   |  | _d S r5   )rstripr\   )r   trailerr   r   r   set_trailer   s    zChangelogEntry.set_trailerc                 C   s(   | j r|  j |7  _ n| s$|| _ d S r5   )r]   isspace)r   contentr   r   r   add_content   s    zChangelogEntry.add_contentc                 C   s   | j S r5   )r[   r%   r   r   r   r)      s    zChangelogEntry.versionc                 C   s   | j S r5   r   r%   r   r   r   numeric_urgency   s    zChangelogEntry.numeric_urgencyc                 C   s   | j S r5   )r^   r%   r   r   r   ra      s    zChangelogEntry.binnmuc                 C   s   | j S r5   )rZ   r%   r   r   r   r_      s    zChangelogEntry.headerc                 C   s   | j S r5   )r\   r%   r   r   r   rc      s    zChangelogEntry.trailerc                 C   s
   | j  S r5   )r]   rb   r%   r   r   r   rf      s    zChangelogEntry.contentc                 C   s2   | j d | j d | j }| j r*| jr*|S | S )NrC   )r_   rf   rc   rY   )r   resultr   r   r   __str__   s    zChangelogEntry.__str__N)F)r/   r0   r1   r$   rd   rg   propertyr)   ri   ra   r_   rc   rf   rk   __repr__r   r   r   r   rW      s"   






rW   c                   @   s`   e Zd Zdd Zedd Zedd Zedd Zed	d
 Zedd Z	dd Z
dd ZdS )Changesc                 C   s    || _ g | _g | _td| _d S )Nr   )_package_entries_binnmusr   )r   packager   r   r   r$      s    zChanges.__init__c                 C   s   | j S r5   )ro   r%   r   r   r   rr      s    zChanges.packagec                 C   s   | j S r5   rh   r%   r   r   r   ri      s    zChanges.numeric_urgencyc                 C   s   | j S r5   )rp   r%   r   r   r   entries   s    zChanges.entriesc                 C   s   | j S r5   )rq   r%   r   r   r   binnmus   s    zChanges.binnmusc                 C   s    | j rdtt| j d S dS )NrC   rX   )rp   joinmaprK   r%   r   r   r   changes   s    zChanges.changesc                 C   s4   |j r| j| n| j| t| j|j| _d S r5   )ra   rq   rQ   rp   minr   ri   r   entryr   r   r   
save_entry   s    zChanges.save_entryc                 C   s   | j   | j  d S r5   )rp   reverserq   r%   r   r   r   r|      s    
zChanges.reverseN)r/   r0   r1   r$   rl   rr   ri   rs   rt   rw   r{   r|   r   r   r   r   rn      s   




rn   c                   @   sT   e Zd ZedZedZedejZedZ	dZ
dd Zdd	 Zd
d ZdS )ChangelogParserz8^\S+ \((?P<version>.*)\) .*;.*urgency=(?P<urgency>\w+).*zV^(\S+ \(?\d.*\)|Old Changelog:|Changes|ChangeLog begins|Mon|Tue|Wed|Thu|Fri|Sat|Sun).*z(;;\s*)?Local\s+variables.*z^\s--\s.*<.*@.*>.*$zbinary-only=yesc                 C   s
   || _ d S r5   )_changes)r   rw   r   r   r   r$      s    zChangelogParser.__init__c           
      C   s  d}d}d}|rt |nd}| D ]R}|dd}|drBq$|dur|ds\|dkr|sx| j|rx|| n
|| q$|s| j|nd}|rd}|	d	}	|rt
|	|d
kr qz| | |dur|t| jjkrd} qzt||	|	d| j|v }q$| j|rF|s( qzd}| | t|ddd}q$| j|r\ qzq$|durr|| q$ qzq$| | |S )zParse changelog or news from the given file descriptor.
        If since_version is specified, only save entries later
        than the specified version.
        If latest is specified, only the latest N versions.FNr:   r;   #r   r   Tr)   r   r`   rX   r   )int	readlinesrR   r-   _changelog_trailerr+   rd   rg   _changelog_headerr,   apt_pkgZversion_compare_save_entrylenr~   rs   rW   _binnmu_marker_changelog_header_ancient_changelog_header_emacs)
r   fdsince_versionlatestZancientrz   Zis_debian_changelogr"   r+   r)   r   r   r   parse   sT    






zChangelogParser.parsec                 C   s   |d ur| j | d S r5   )r~   r{   ry   r   r   r   r   *  s    zChangelogParser._save_entryN)r/   r0   r1   r2   r3   r   r   
IGNORECASEr   r   r   r$   r   r   r   r   r   r   r}      s   


9r}   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
ChangelogsReaderc                 C   s"   || _ || _|| _|| _|| _d S r5   )_source_pkg_name_rootdir_since_version_latest_reverse)r   Zsource_pkg_nameZrootdirr   r   r|   r   r   r   r$   /  s
    zChangelogsReader.__init__c                    sR   t j  fdd}t||d}|r8t||dp6|}|s@d S jrN    S )Nc                    s   | p tjj| S r5   )_read_changelogospathru   r   )Zaccfnamerw   r   r   r   <lambda>9  s   z2ChangelogsReader.read_changelogs.<locals>.<lambda>F)rn   r   r   r   r|   )r   	filenamesZbinnmus_filenamesZ
find_firstrj   r   r   r   read_changelogs6  s    
z ChangelogsReader.read_changelogsc                 C   sP   |  |}|sdS |& t||| j| jW  d    S 1 sB0    Y  d S )NF)_open_changelog_filer}   r   r   r   )r   filenamerw   r   r   r   r   r   H  s
    
z ChangelogsReader._read_changelogc                 C   s   t  |}|D ]}zTtj|r4ttd|  n*|drNt	|W   S t
|dW   S W  qW q ty } z&|jtjkr|jtjkr W Y d }~qd }~0 0 qd S )Nz(Ignoring `%s' (seems to be a directory!)z.gzrb)globr   r   isdirALCLogerrorr   endswithgzipZGzipFilerG   IOErrorerrnoZENOENTZELOOP)r   r   r   er   r   r   r   P  s    


z%ChangelogsReader._open_changelog_fileN)r/   r0   r1   r$   r   r   r   r   r   r   r   r   .  s   r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )r   c                 C   sJ   || _ t }|| j  |jd }|j| _| | _| | _|j	| _
d S )Nr   )r   r4   rU   r6   r   binaryr&   r)   r   r   arch)r   r   parserZpkgdatar   r   r   r$   b  s    


zPackage.__init__c              
   C   s   |  d}|  d}|  d| j }|  d}g }	|dksB|dkrL|	| |dks\|dkrz|	| |	| |	| | |	}
z>t| j|
|||}||d}||| |}W t|
d	 nt|
d	 0 ||fS )
ai  Extract changelog and binnmu entries, news or both from the package.

        Unpacks changelog or news files from the binary package, and parses them.
        If since_version is specified, only return entries later than the specified version.
        If latest is specified, only the latest N versions.
        Returns a tuple of sequences of Changes objects.zNEWS.Debianzchangelog.Debianzchangelog.Debian.	changelogZbothnewsZ
changelogsNr   )	_changelog_variationsr   extend_extract_contentsr   r&   r   shutilrmtree)r   Zwhichr   r   r|   Znews_filenamesZchangelog_filenamesZchangelog_filenames_binnmuZchangelog_filenames_nativer   tempdirreaderr   r   r   r   r   extract_changesn  s(    








zPackage.extract_changesc           	      C   sz  t jdd}tj|| jd }t|d}z2zLdddd| j| jf g}t	t
d	d
t|i  tj||tjddd W n tjy } z>tt
d| j|jr|jddnt|d  W Y d}~n~d}~0  ty } z*tt
d| jt|d  W Y d}~n<d}~0 0 t| jd||||gdW |  t|d S W |  t|d n|  t|d 0 dS )a  Run apt-get changelog and parse the downloaded changelog.

        Retrieve changelog using the "apt-get changelog" command, and parse it.
        If since_version is specified, only return entries later than the specified version.
        If latest is specified, only the latest N versions.
        Returns a single sequence of Changes objects or None on downloading or parsing failure.apt-listchangesprefixz
.changelogwzapt-getz-qqr   z%s=%sz%Calling %(cmd)s to retrieve changelogcmdx   T)stdoutstderrZtimeoutZcheckz]Unable to retrieve changelog for package %(pkg)s; 'apt-get changelog' failed with: %(errmsg)sr:   r;   )pkgrF   Nz_Unable to retrieve changelog for package %(pkg)s; could not run 'apt-get changelog': %(errmsg)srX   r   )tempfilemkdtempr   r   ru   r   rG   r   r   debugr   rK   rP   runPIPEZCalledProcessErrorr   r   rR   rI   r   r&   r   closer   r   )	r   r   r   r|   r   Zchangelog_fileZchangelog_fdrS   rN   r   r   r   extract_changes_via_apt  s@    	


zPackage.extract_changes_via_aptc                 C   sp   t jdd}dt| jt|ddd |D f }t|}t|rlt	|t
jkrlt|d t|S )Nr   r   zFdpkg-deb --fsys-tarfile %s | tar xf - --wildcards -C %s %s 2>/dev/nullr   c                 S   s   g | ]}t |qS r   )shlexquoter>   r   r   r   rA     rB   z-Package._extract_contents.<locals>.<listcomp>r   )r   r   r   r   r   ru   r   systemWIFSIGNALEDWTERMSIGsignalSIGINTr   r   KeyboardInterrupt)r   r   r   Zextract_commandZstatusr   r   r   r     s    
zPackage._extract_contentsc                    s   ddg} fdd|D S )Nz./usr/share/doc/*/%s.gzz./usr/share/doc/*/%sc                    s   g | ]}|  qS r   r   r>   r   r   r   rA     rB   z1Package._changelog_variations.<locals>.<listcomp>r   )r   r   Zformatsr   r   r   r     s    zPackage._changelog_variationsN)r/   r0   r1   r$   r   r   r   r   r   r   r   r   r   a  s
   #*r   )r2   r   r   r   r   r   r   r   r   rP   r   r   ZALChacksr   	functoolsr   r   r   r4   rW   rn   r}   r   r   __all__r   r   r   r   <module>   s,   
0'1(G3s