U
    &c\                     @   s   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 G dd de	Z
G dd deZG dd	 d	eZG d
d deZG dd deZdd Zdd ZG dd dZddddg fddZdS )    N)ElementTree)gettextc                   @   s   e Zd ZdS )NoDistroTemplateExceptionN)__name__
__module____qualname__ r   r   3/usr/lib/python3/dist-packages/aptsources/distro.pyr   %   s   r   c                   @   sl   e Zd Zg fddZdd ZdddZdd	 Zd
d ZdddZdd Z	dd Z
dd Zdd Zdd ZdS )Distributionc                 C   s.   || _ || _|| _|| _|| _d| _d| _dS )z2 Container for distribution specific informations Zdebzdeb-srcN)idcodenamedescriptionreleaseis_likebinary_typesource_type)selfr   r   r   r   r   r   r   r	   __init__+   s    zDistribution.__init__c                 C   s  || _ d| _g | _g | _g | _g | _g | _g | _g | _g | _	d| _
g | _d| _d| _d| _g | _| j jjD ]&}| |jrj|j| jkrj|| _ qqj| jdkrtd| j| jf g }g }g }g }| j jD ]}|js | |jr |jr |jjr | |jjr |jdr6|js6| j | |!|j" n|jdrZ|jrZ| j | n|j#| j$kr|js| j | |!|j" | |j nj|j#| j$kr|jr| j | nF|j#| j%kr|js| j | n"|j#| j%kr |jr | j | |js|j| jj&kr|js8|j#| j$kr8| j | q|js\|j#| j%kr\| j | q| j | qt'|| _t'|| _|!| |!| t'|| _t'|| _	| (  dS )zf
        Find the corresponding template, main and child sources
        for the distribution
        NF z7Error: could not find a distribution template for %s/%scdrom:))sourceslistsource_templatechild_sourcesmain_sourcesZdisabled_sourcesZcdrom_sourcesZdownload_compsenabled_compscdrom_comps
used_mediaget_source_codesource_code_sourcesdefault_servermain_servernearest_serverused_serversZmatcherZ	templatesis_codenamenameZdistributionr   r   r   listZinvaliddisttemplateZofficialuri
startswithZdisabledappendextendcompstyper   r   Zchildrensetget_mirrors)r   r   r'   Zmediar,   r   r   sourcer   r   r	   get_sources7   s    











zDistribution.get_sourcesNc              	   C   s  | j j| _| jD ]}|ds| j| qt| jdkrD| j| _	n| jd j
| _	i | _d}tj|rt|d}t|dddkr|j|_|d}|D ]v}z|jd }W n tk
r   |jd	 }Y nX z|jd
 }W n tk
r   |jd }Y nX td|| j| < qd| _d| _tjddd}	|	d}
|	d}|dkrRt|	}|	|
d |  }|rv|| | _|| jkr| j| | _|| _dS )zR
        Provide a set of mirrors where you can get the distribution from
        r   r   z%/usr/share/xml/iso-codes/iso_3166.xml)fileiterNZiso_3166_entryZcommon_namer$   Zalpha_2_codeZalpha_3_codeiso_3166ZLANGZen_UK)default_.   )r   base_urir    r   r)   r"   r*   lenr   r   r(   	countriesospathexistsr   getattrZgetiteratorr3   ZattribKeyErrorr   dgettextlowercountrycountry_codegetenvfindr!   )r   mirror_templateZmediumfnameZetitZelmZdescrcodeZlocaleazrE   r   r   r	   r/      sN    









zDistribution.get_mirrorsc                 C   sj   d}| d}| d}|dkr<|dkr<||td | }|| jkrXtd| j|  S d|d S dS )zu Try to get a human readable name for the main mirror of a country
            Customize for different distributions Nz://z.archive.ubuntu.comr8   Server for %s%s/ )rG   r;   r<   r6   rstripr   serverrD   iZlir   r   r	   _get_mirror_name   s    


zDistribution._get_mirror_namec                 C   s  dd }g }t | jdk s:t | jdkrt|| jd | jrt|td| jdg | jrp|| | j| jdg n8t | jdkr|| jd | js|td| jdg | jd }| jr||| js|| | j| jdg |r|| ||dg nt | jdkr|td| jdg | jrD|| | j| jdg |tdd	dg | jD ]L}| ||dg}||| js^||| jrq^n||kr^|| q^|S )
z- Return a list of used and suggested servers c                 S   s   t | d|dS )zl Helper function that handles comaprision of mirror urls
                that could contain trailing slashesrP   )rematchstriprQ   )Zmir1Zmir2r   r   r	   compare_mirrors   s    z5Distribution.get_server_list.<locals>.compare_mirrorsr9   r   zMain serverTFzCustom serversN)r;   r"   r    r*   r6   r!   rU   )r   rY   ZmirrorsrS   Zmirror_entryr   r   r	   get_server_list   sV     

  


zDistribution.get_server_listr   c              
   C   s   |dkr| j }|dkr| j}|dkr.t| j}|dkr<| j}| j|||||}| jr|| jkr| jj| j|||||j	| jj
|d d dS )z3
        Add distribution specific sources
        Nr9   )r2   pos)r   r   r%   r   r   r   addr   r   r2   index)r   r-   r(   r&   r,   ZcommentZ
new_sourcer   r   r	   
add_source  s&    
    zDistribution.add_sourcec                 C   sX   t |g}| jD ].}|jjD ] }|j|kr|jr||j qq|D ]}| | qDdS )z
        Enable a component in all main, child and source code sources
        (excluding cdrom based sources)

        comp:         the component that should be enabled
        N)r.   r   r'   Z
componentsr$   Zparent_componentr\   _enable_component)r   compr,   r0   cr   r   r	   enable_component%  s    

zDistribution.enable_componentc           	         sZ   fdd}g }| | j | | j i }i }|D ]B}|j| jkr4|j|krZt ||j< |jD ]}||j | q`q4| j	D ]B}|j| j
kr~|j|krt ||j< |jD ]}||j | qq~t| jdk r| jd  gd n*|D ]}||| q| j	D ]}||| q| jrVt| j	dk r>| j| j
d  gd n| j	D ]}||| qDd S )Nc                    s@   | j |krdS  || j  kr dS | j  || j    dS )z
            Check if we already added the component to the repository, since
            a repository could be splitted into different apt lines. If not
            add the component
            N)r&   r,   r*   r\   )r0   comps_per_distr`   r   r	   add_component_only_once7  s    
z?Distribution._enable_component.<locals>.add_component_only_oncer9   rO   )r,   )r-   r,   )r+   r   r   r-   r   r&   r.   r,   r\   r   r   r;   r^   r   )	r   r`   re   sourcesrc   Zcomps_per_sdistsra   r0   r   rd   r	   r_   5  s:    






zDistribution._enable_componentc                 C   s   g }| | j | | j | | j || jkrBg }| | j |D ]4}||jkrF|j| t|jdk rF| j| qFdS )zx
        Disable a component in all main, child and source code sources
        (excluding cdrom based sources)
        r9   N)	r+   r   r   r   r   r,   remover;   r   )r   r`   rf   r0   r   r   r	   disable_components  s    

zDistribution.disable_componentc                    s    fdd}g }g }| _  jD ]}|||| q  jD ]*}|jjdksV|jj|jkr8|||| q8 jD ]}|||| qjdS )zN Change the server of all distro specific sources to
            a given host c                    sd   || _ | jD ]8}| j | j|g|kr0| j| q|| j | j|g qt| jdk r` j|  d S )Nr9   )r(   r,   r&   rh   r*   r;   r   )r0   r(   seenr`   r   r   r	   change_server_of_source  s    
z;Distribution.change_server.<locals>.change_server_of_sourceN)r   r   r   r'   r:   r(   r   )r   r(   rl   Zseen_binaryZseen_sourcer0   r   rk   r	   change_server  s    


zDistribution.change_serverc                 C   s   || j krdS dS dS )z1 Compare a given name with the release codename. TFN)r   r   r$   r   r   r	   r#     s    
zDistribution.is_codename)N)NNNNr   )r   r   r   r   r1   r/   rU   rZ   r^   rb   r_   ri   rm   r#   r   r   r   r	   r
   )   s    ]
93        
>r
   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	DebianDistributionz+ Class to support specific Debian features c                 C   s    || j ks| jdkrdS dS dS )z Compare a given name with the release codename and check if
            if it can be used as a synonym for a development releases )ZtestingunstableTFN)r   r   rn   r   r   r	   r#     s    zDebianDistribution.is_codenamec                 C   sz   d}| d}| d}|dkr<|dkr<||td | }|| jkrhtdtd| j|    S d|d S dS )	z_ Try to get a human readable name for the main mirror of a country
            Debian specific Nz://ftp.z.debian.orgr8   rN   r4   rO   rP   )rG   r;   r<   r6   r   rB   rQ   rR   r   r   r	   rU     s    



 
z#DebianDistribution._get_mirror_namec                 C   s   t j| dd d S )Nz http://ftp.%s.debian.org/debian/rH   r
   r/   rk   r   r   r	   r/     s     zDebianDistribution.get_mirrorsN)r   r   r   __doc__r#   rU   r/   r   r   r   r	   ro     s   ro   c                   @   s   e Zd ZdZdd ZdS )UbuntuDistributionz+ Class to support specific Ubuntu features c                 C   s   t j| dd d S )Nz$http://%s.archive.ubuntu.com/ubuntu/rq   rr   rk   r   r   r	   r/     s     zUbuntuDistribution.get_mirrorsNr   r   r   rs   r/   r   r   r   r	   rt     s   rt   c                   @   s   e Zd ZdZdd ZdS )UbuntuRTMDistributionz/ Class to support specific Ubuntu RTM features c                 C   s   | j j| _d S )N)r   r:   r    rk   r   r   r	   r/     s    z!UbuntuRTMDistribution.get_mirrorsNru   r   r   r   r	   rv     s   rv   c               
   C   s   ddl m} m} ddl}ddddd}z@| d	d
g|d d }|d}|dd |dD  W n< tk
r } z|j|j	krt
d|  W 5 d}~X Y nX |S )z-Call lsb_release --idrc and return a mapping.r   PopenPIPENZsidDebianzDebian GNU/Linux unstable (sid)rp   )CodenameDistributor IDDescriptionReleaseZlsb_releasez-idrc)stdoutzutf-8c                 s   s    | ]}d |kr| d V  qdS )z:	N)split).0lr   r   r	   	<genexpr>  s      z_lsb_release.<locals>.<genexpr>
z#lsb_release failed, using defaults:)
subprocessrx   ry   errnocommunicatedecodeupdater   OSErrorENOENTloggingwarning)rx   ry   r   resultoutexcr   r   r	   _lsb_release  s    
 r   c               
   C   s   ddl m} m} ddl}zddl m} W n$ tk
rL   ttjtj	}Y nX zN| ddg||dd
 d }| D ]$}|d	rt|d
dd   W S qtW n< tk
r } z|j|jkrtd|  W 5 d}~X Y nX dS )z=Get the current channel from system-image-cli -i if possible.r   rw   N)DEVNULLzsystem-image-cliz-iT)r   stderrZuniversal_newlinesz	channel: z: r9   z+system-image-cli failed, using defaults: %s)r   rx   ry   r   r   ImportErrorr=   opendevnullO_RDWRr   
splitlinesr)   r   r   r   r   r   )rx   ry   r   r   r   r   r   r   r   r	   _system_image_channel  s0      
r   c                   @   s>   e Zd ZdZdZdddZdd Zdd Zd	d
 Zdd Z	dS )
_OSReleasez/etc/os-releaseTc                 C   sD   i | _ d| _tj| _tj| js&d S |   d| _|r@| 	  d S )NFT)
r   validr   OS_RELEASE_FILEr2   r=   r>   isfileparseinject_lsb_compat)r   Z
lsb_compatr   r   r	   r     s    z_OSRelease.__init__c                 C   sd   | j d | j d< | j d | j d< | j d| j d< | j d sN| j d| j d< | j d| j d	< d S )
NZIDr|   ZPRETTY_NAMEr}   ZVERSION_CODENAMEr{   ZUBUNTU_CODENAMEZ
VERSION_IDr~   )r   getrk   r   r   r	   r     s    
z_OSRelease.inject_lsb_compatc                 C   sB   t | jd}|D ]$}| }|s"q| j|dd  q|  d S )Nr=r9   )r   r2   rX   parse_entryr   close)r   fliner   r   r	   r     s    z_OSRelease.parsec                 C   s4   |  |}|dkr&t|tr&|d}|| j|< d S )NID_LIKE )parse_value
isinstancestrr   r   )r   keyvaluer   r   r	   r   &  s    

z_OSRelease.parse_entryc                 C   s"   t |}t|dkr|d S |S )Nr9   r   )shlexr   r;   )r   r   valuesr   r   r	   r   .  s    
z_OSRelease.parse_valueN)T)
r   r   r   ZDEFAULT_OS_RELEASE_FILEr   r   r   r   r   r   r   r   r   r	   r      s   

	r   c           	      C   s   | r|r|r|st  }g }t }|jr,|j}t }|d } |d }|d }|d }|dg }| dkrt }|dk	rd|krd	} |d
dd ddd }|}|}| dkrt| ||||S | d	krt	| ||||S | dkrt
| ||||S t| ||||S dS )z
    Check the currently used distribution and return the corresponding
    distriubtion class that supports distro specific features.

    If no paramter are given the distro will be auto detected via
    a call to lsb-release
    r|   r{   r}   r~   r   ZUbuntuNzubuntu-rtm/z
Ubuntu-RTM/r9   -r   rz   )r   r   r   r   r   r   rsplitr   rt   rv   ro   r
   )	r   r   r   r   r   Z
os_releaseZ	os_resultZ
lsb_resultZchannelr   r   r	   
get_distro5  s@    

    r   )r   r   rV   r   r=   Zxml.etree.ElementTreer   apt_pkgr6   	Exceptionr   objectr
   ro   rt   rv   r   r   r   r   r   r   r   r	   <module>   s(      5