3
	`\                 @   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 | _x2| j jjD ]$}| j|jrl|j| jkrl|| _P qlW | jdkrtd| j| jf g }g }g }g }x| j jD ]}|j r| j|jr|jr|jjr| j|jjr|jjdr@|j r@| jj | |j!|j" n|jjdrd|jrd| jj | n|j#| j$kr|j r| jj | |j!|j" |j |j nl|j#| j$kr|jr| jj | nH|j#| j%kr|j r| jj | n"|j#| j%kr|jr| jj | |j r|j| jj&kr|j rJ|j#| j$krJ| jj | q|j rp|j#| j%krp| jj | q| jj | qW t'|| _t'|| _|j!| |j!| t'|| _t'|| _	| j(  dS )zf
        Find the corresponding template, main and child sources
        for the distribution
        NF z7Error: could not find a distribution template for %s/%sz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| _x$| jD ]}|jds| jj| qW t| jdkrH| j| _	n| jd j
| _	i | _d}tjj|rt|d}t|dddkr|j|_|jd}x|D ]x}y|jd }W n tk
r   |jd	 }Y nX y|jd
 }W n  tk
r    |jd }Y nX tjd|| j|j < qW d| _d| _tjddd}	|	jd}
|	jd}|dkr\t|	}|	|
d | j }|r|| | _|| jkr| j| | _|| _dS )zR
        Provide a set of mirrors where you can get the distribution from
        zcdrom: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getiteratorr2   ZattribKeyErrorr   dgettextlowercountrycountry_codegetenvfindr    )r   mirror_templateZmediumfnameZetitZelmZdescrcodeZlocaleazrD   r   r   r	   r.      sL    









zDistribution.get_mirrorsc             C   sj   d}|j d}|j d}|dkr<|d	kr<||td | }|| jkrXtd| j|  S d|j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.comr7   zServer for %sz%sz/ r8   r8   )rF   r:   r;   r5   rstrip)r   serverrC   i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|jtd| jdg | jrp|j| j| j| jdg nBt | jdko|| jd | j r|jtd| jdg | jd }| jr||| js|j| j| j| jdg |r|j| j||dg nt | jdkr|jtd| jdg | jrJ|j| j| j| jdg |jtdd	dg xV| jD ]L}| j||dg}||| jsf||| jrqfn||krf|j| qfW |S )
z- Return a list of used and suggested servers c             S   s   t j| jd|jdS )zl Helper function that handles comaprision of mirror urls
                that could contain trailing slashesz/ )rematchstriprM   )Zmir1Zmir2r   r   r	   compare_mirrors   s    z5Distribution.get_server_list.<locals>.compare_mirrorsr7   r   zMain serverTFzCustom serversN)r:   r!   r   r)   r5   r    rQ   )r   rU   ZmirrorsrN   Zmirror_entryr   r   r	   get_server_list   sB    

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|||||}| jr|| jkr| jj| j|||||j	| jjj
|d d dS )z3
        Add distribution specific sources
        Nr7   )r1   pos)r   r   r$   r   r   r   addr   r   r1   index)r   r,   r'   r%   r+   ZcommentZ
new_sourcer   r   r	   
add_source  s    
zDistribution.add_sourcec             C   sd   t |g}x<| jD ]2}x,|jjD ] }|j|kr |jr |j|j q W qW x|D ]}| j| qNW d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_componentrX   _enable_component)r   compr+   r/   cr   r   r	   enable_component%  s    

zDistribution.enable_componentc       	         sx   fdd}g }|j | j |j | j i }i }xN|D ]F}|j| jkr6|j|kr\t ||j< x|jD ]}||j j| qdW q6W xP| j	D ]F}|j| j
kr|j|krt ||j< x|jD ]}||j j| qW qW t| jdk r| jd  gd n4x|D ]}||| qW x| j	D ]}||| qW | jrtt| j	dk rX| j| j
d  gd nx| j	D ]}||| q`W d S )Nc                s@   | j |krdS  || j  kr dS | jj  || 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)   rX   )r/   comps_per_dist)r\   r   r	   add_component_only_once7  s    
z?Distribution._enable_component.<locals>.add_component_only_oncer7   z%s)r+   )r,   r+   )r*   r   r   r,   r   r%   r-   r+   rX   r   r   r:   rZ   r   )	r   r\   r`   sourcesr_   Zcomps_per_sdistsr]   r/   r   )r\   r	   r[   5  s:    



zDistribution._enable_componentc             C   s   g }|j | j |j | j |j | j || jkrBg }|j | j x<|D ]4}||jkrH|jj| t|jdk rH| jj| qHW dS )zx
        Disable a component in all main, child and source code sources
        (excluding cdrom based sources)
        r7   N)	r*   r   r   r   r   r+   remover:   r   )r   r\   ra   r/   r   r   r	   disable_components  s    


zDistribution.disable_componentc                s    fdd}g }g }| _ x jD ]}|||| q"W x4 jD ]*}|jjdks\|jj|jkr>|||| q>W x jD ]}|||| qtW dS )zN Change the server of all distro specific sources to
            a given host c                sh   || _ xB| jD ]8}| j | j|g|kr2| jj| q|j| j | j|g qW t| jdk rd jj|  d S )Nr7   )r'   r+   r%   rc   r)   r:   r   )r/   r'   seenr\   )r   r   r	   change_server_of_source  s    z;Distribution.change_server.<locals>.change_server_of_sourceN)r   r   r   r&   r9   r'   r   )r   r'   rf   Zseen_binaryZseen_sourcer/   r   )r   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   r0   r.   rQ   rV   rZ   r^   r[   rd   rg   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 testingunstableTFN)ri   rj   )r   r   )r   r#   r   r   r	   r"     s    zDebianDistribution.is_codenamec             C   sz   d}|j d}|j d}|d	kr<|d
kr<||td | }|| jkrhtdtjd| j| j j  S d|j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.orgr7   zServer for %sr3   z%sz/ r8   r8   )rF   r:   r;   r5   r   rA   rM   )r   rN   rC   rO   rP   r   r   r	   rQ     s    



z#DebianDistribution._get_mirror_namec             C   s   t j| dd d S )Nz http://ftp.%s.debian.org/debian/)rG   )r
   r.   )r   r   r   r	   r.     s    zDebianDistribution.get_mirrorsN)r   r   r   __doc__r"   rQ   r.   r   r   r   r	   rh     s   rh   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/)rG   )r
   r.   )r   r   r   r	   r.     s    zUbuntuDistribution.get_mirrorsN)r   r   r   rk   r.   r   r   r   r	   rl     s   rl   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   r9   r   )r   r   r   r	   r.     s    z!UbuntuRTMDistribution.get_mirrorsN)r   r   r   rk   r.   r   r   r   r	   rm     s   rm   c              C   s   ddl m} m} ddl}ddddd}y@| d	d
g|dj d }|jd}|jdd |jdD  W n< tk
r } z |j|j	krt
jd|  W Y dd}~X nX |S )z-Call lsb_release --idrc and return a mapping.r   )PopenPIPENZsidDebianzDebian GNU/Linux unstable (sid)rj   )CodenamezDistributor IDDescriptionReleaseZlsb_releasez-idrc)stdoutzutf-8c             s   s    | ]}d |kr|j 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:)
subprocessrn   ro   errnocommunicatedecodeupdateru   OSErrorENOENTloggingwarning)rn   ro   r{   resultoutexcr   r   r	   _lsb_release  s    
 r   c              C   s   ddl m} m} ddl}yddl m} W n$ tk
rL   tjtjtj	}Y nX yL| ddg||ddj
 d }x*|j D ]}|jd	rv|jd
dd S qvW W n< tk
r } z |j|jkrtjd|  W Y dd}~X nX dS )z=Get the current channel from system-image-cli -i if possible.r   )rn   ro   N)DEVNULLzsystem-image-cliz-iT)rt   stderrZuniversal_newlinesz	channel: z: r7   z+system-image-cli failed, using defaults: %s)rz   rn   ro   r{   r   ImportErrorr<   opendevnullO_RDWRr|   
splitlinesr(   ru   r   r   r   r   )rn   ro   r{   r   r   rw   r   r   r   r	   _system_image_channel  s$    

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| js&d S | j  d| _|r@| j	  d S )NFT)
r   validr   OS_RELEASE_FILEr1   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 jd| j d< | j d sN| j jd| j d< | j jd| j d	< d S )
NZIDzDistributor IDZPRETTY_NAMErr   ZVERSION_CODENAMErq   ZUBUNTU_CODENAMEZ
VERSION_IDrs   )r   get)r   r   r   r	   r     s    
z_OSRelease.inject_lsb_compatc             C   sF   t | jd}x,|D ]$}|j }|s$q| j|jdd  qW |j  d S )Nr=r7   )r   r1   rT   parse_entryru   close)r   fliner   r   r	   r     s    
z_OSRelease.parsec             C   s4   | j |}|dkr&t|tr&|jd}|| j|< d S )NID_LIKE )parse_value
isinstancestrru   r   )r   keyvaluer   r   r	   r   &  s    

z_OSRelease.parse_entryc             C   s"   t j|}t|dkr|d S |S )Nr7   r   )shlexru   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   | o|o|o|st  }g }t }|jr,|j}t }|d } |d }|d }|d }|jdg }| dkrt }|dk	rd|krd	} |jd
dd j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
    zDistributor IDrq   rr   rs   r   ZUbuntuNzubuntu-rtm/z
Ubuntu-RTM/r7   -r   rp   )r   r   r   r   r   r   rsplitru   rl   rm   rh   r
   )	r   r   r   r   r   Z
os_releaseZ	os_resultZ
lsb_resultZchannelr   r   r	   
get_distro5  s6    

r   )r   r   rR   r   r<   Zxml.etree.ElementTreer   apt_pkgr5   	Exceptionr   objectr
   rh   rl   rm   r   r   r   r   r   r   r   r	   <module>   s&      5