o
    ra\                     @   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                   @   sp   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rH|j| jkrH|| _ nq5| jdu rXt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r|js| j | |!|j" n[|jdr|jr| j | nK|j#| j$kr|js| j | |!|j" | |j n/|j#| j$kr|jr| j | n|j#| j%kr|js| j | n|j#| j%kr|jr| j | |js$|j| jj&v r$|js|j#| j$kr| j | qd|js|j#| j%kr| j | qd| j | qdt'|| _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   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r"| j| _	n| jd j
| _	i | _d}tj|rt|d}t|dddu rE|j|_|d}|D ]9}z|jd }W n tyc   |jd	 }Y nw z|jd
 }W n tyy   |jd }Y nw td|| j| < qLd| _d| _tjddd}	|	d}
|	d}|dkrt|	}|	|
d |  }|r|| | _|| jv r| j| | _|| _dS 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_3166LANGZen_UK)default_.   )r   base_urir    r   r)   r"   r*   lenr   r   r(   	countriesospathexistsr   getattrZgetiteratorr4   ZattribKeyErrorr   dgettextlowercountrycountry_codegetenvfindr!   )r   mirror_templateZmediumfnameetitZelmZdescrcodelocaleazrG   r   r   r	   r0      sV   










zDistribution.get_mirrorsc                 C   sf   d}| d}| d}|dkr|dkr||td | }|| jv r,td| j|  S d|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.comr:   Server for %s%s/ )rI   r=   r>   r8   rstripr   serverrF   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r:|| jd | jr:|td| jdg | jr8|| | j| jdg |S t | jdkr|| jd | js|td| jdg | jd }| jrp||| jsp|| | j| jdg |r}|| ||dg |S t | jdkr|td| jdg | jr|| | j| jdg |tdd	dg | jD ] }| ||dg}||| js||| jrq||v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 slashesrT   )rematchstriprU   )Zmir1Zmir2r   r   r	   compare_mirrors   s   z5Distribution.get_server_list.<locals>.compare_mirrorsr;   r   zMain serverTFzCustom serversN)r=   r"   r    r*   r8   r!   rY   )r   r]   ZmirrorsrW   Zmirror_entryr   r   r	   get_server_list   sV   !



zDistribution.get_server_listr   c              
   C   s   |du r| j }|du r| j}|du rt| j}|du r| j}| j|||||}| jrH|| jkrJ| jj| j|||||j	| jj
|d d dS dS dS )z3
        Add distribution specific sources
        Nr;   )r3   pos)r   r   r%   r   r   r   addr   r   r3   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 ]}| | q"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_componentr`   _enable_component)r   compr,   r1   cr   r   r	   enable_component%  s   

zDistribution.enable_componentc           	         sZ   fdd}g }| | j | | j i }i }|D ]!}|j| jkr;|j|vr-t ||j< |jD ]
}||j | q0q| j	D ]!}|j| j
kr`|j|vrRt ||j< |jD ]
}||j | qUq?t| jdk rr| jd  gd n|D ]}||| qt| j	D ]}||| q| jrt| j	dk r| j| j
d  gd d S | j	D ]	}||| qd S d S )Nc                    s@   | j |vrdS  || j  v 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`   )r1   comps_per_distrd   r   r	   add_component_only_once7  s   
z?Distribution._enable_component.<locals>.add_component_only_oncer;   rS   )r,   )r-   r,   )r+   r   r   r-   r   r&   r/   r,   r`   r   r   r=   rb   r   )	r   rd   ri   sourcesrg   Zcomps_per_sdistsre   r1   r   rh   r	   rc   5  sB   






zDistribution._enable_componentc                 C   s   g }| | j | | j | | j || jv r!g }| | j |D ]}||jv r=|j| t|jdk r=| j| q#dS )zx
        Disable a component in all main, child and source code sources
        (excluding cdrom based sources)
        r;   N)	r+   r   r   r   r   r,   remover=   r   )r   rd   rj   r1   r   r   r	   disable_components  s   

zDistribution.disable_componentc                    s    fdd}g }g }| _  jD ]}|||| q jD ]}|jjdu s+|jj|jkr1|||| q jD ]}|||| q5dS )zN Change the server of all distro specific sources to
            a given host c                    sh   || _ | jD ]}| j | j|g|v r| j| q|| j | j|g qt| jdk r2 j|  d S d S )Nr;   )r(   r,   r&   rl   r*   r=   r   )r1   r(   seenrd   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(   rp   Zseen_binaryZseen_sourcer1   r   ro   r	   change_server  s   


zDistribution.change_serverc                 C   s   || j krdS dS )z1 Compare a given name with the release codename. TF)r   r   r$   r   r   r	   r#     s   
zDistribution.is_codenameN)NNNNr   )r   r   r   r   r2   r0   rY   r^   rb   rf   rc   rm   rq   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v r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unstableTF)r   r   rr   r   r   r	   r#     s   zDebianDistribution.is_codenamec                 C   sv   d}| d}| d}|dkr|dkr||td | }|| jv r4tdtd| j|    S d|d S )	z_ Try to get a human readable name for the main mirror of a country
            Debian specific Nz://ftp.z.debian.orgr:   rR   r5   rS   rT   )rI   r=   r>   r8   r   rD   rU   rV   r   r   r	   rY     s   



z#DebianDistribution._get_mirror_namec                 C      t j| dd d S )Nz http://ftp.%s.debian.org/debian/rJ   r
   r0   ro   r   r   r	   r0        
zDebianDistribution.get_mirrorsN)r   r   r   __doc__r#   rY   r0   r   r   r   r	   rt     s
    rt   c                   @      e Zd ZdZdd ZdS )UbuntuDistributionz+ Class to support specific Ubuntu features c                 C   rv   )Nz$http://%s.archive.ubuntu.com/ubuntu/rw   rx   ro   r   r   r	   r0     ry   zUbuntuDistribution.get_mirrorsNr   r   r   rz   r0   r   r   r   r	   r|         r|   c                   @   r{   )UbuntuRTMDistributionz/ Class to support specific Ubuntu RTM features c                 C   s   | j j| _d S rs   )r   r<   r    ro   r   r   r	   r0     s   z!UbuntuRTMDistribution.get_mirrorsNr}   r   r   r   r	   r     r~   r   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 |S  ty[ } z|j|j	krPt
d|  W Y d}~|S W Y d}~|S d}~ww )z-Call lsb_release --idrc and return a mapping.r   PopenPIPENZsidDebianzDebian GNU/Linux unstable (sid)ru   )CodenameDistributor IDDescriptionReleaseZlsb_releasez-idrc)stdoutzutf-8c                 s   s"    | ]}d |v r| d V  qdS )z:	N)split).0liner   r   r	   	<genexpr>  s    z_lsb_release.<locals>.<genexpr>
z#lsb_release failed, using defaults:)
subprocessr   r   errnocommunicatedecodeupdater   OSErrorENOENTloggingwarning)r   r   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y%   ttjtj	}Y nw z(| ddg||dd
 d }| D ]}|d	rK|d
dd   W S q9W dS  tyu } z|j|jkrjtd|  W Y d}~dS W Y d}~dS d}~ww )z=Get the current channel from system-image-cli -i if possible.r   r   N)DEVNULLzsystem-image-cliz-iT)r   stderrZuniversal_newlinesz	channel: z: r;   z+system-image-cli failed, using defaults: %s)r   r   r   r   r   ImportErrorr?   opendevnullO_RDWRr   
splitlinesr)   r   r   r   r   r   )r   r   r   r   r   r   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   sH   i | _ d| _tj| _tj| jsd S |   d| _|r"| 	  d S d S )NFT)
r   validr   OS_RELEASE_FILEr3   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 s'| j d| j d< | j d| j d	< d S )
NZIDr   ZPRETTY_NAMEr   ZVERSION_CODENAMEr   ZUBUNTU_CODENAMEZ
VERSION_IDr   )r   getro   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=r;   )r   r3   r\   parse_entryr   close)r   fr   r   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 )Nr;   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|sRt  }g }t }|jr|j}t }|d } |d }|d }|d }|dg }| dkrRt }|durRd|v rRd	} |d
dd ddd }|}|}| dkr^t| ||||S | d	krjt	| ||||S | dkrvt
| ||||S t| ||||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/r;   -r   r   )r   r   r   r   r   r   rsplitr   r|   r   rt   r
   )	r   r   r   r   r   Z
os_releaseZ	os_resultZ
lsb_resultZchannelr   r   r	   
get_distro6  s8   


r   )r   r   rZ   r   r?   Zxml.etree.ElementTreer   apt_pkgr8   	Exceptionr   objectr
   rt   r|   r   r   r   r   r   r   r   r   r	   <module>   s*      5