o
    4f\                     @   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   4/usr/lib/python3/dist-packages/DistUpgrade/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 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_sourcesdisabled_sourcescdrom_sourcesdownload_compsenabled_compscdrom_comps
used_mediaget_source_codesource_code_sourcesdefault_servermain_servernearest_serverused_serversmatcher	templatesis_codenamenamedistributionr   r   r   listinvaliddisttemplateofficialuri
startswithdisabledappendextendcompstyper   r   childrensetget_mirrors)r   r   r/   mediar6   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iterNiso_3166_entrycommon_namer*   alpha_2_codealpha_3_codeiso_3166LANGen_UK)default_.   )r   base_urir$   r    r2   r&   r4   lenr   r#   r1   	countriesospathexistsr   getattrgetiteratorr?   attribKeyErrorr   dgettextlowercountrycountry_codegetenvfindr%   )r   mirror_templatemediumfnameetitelmdescrcodelocaleazrY   r   r   r	   r:      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.comrJ   Server for %s%s/ )r[   rM   rN   rH   rstripr   serverrX   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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 slashesri   )rematchstriprj   )mir1mir2r   r   r	   compare_mirrors   s   z5Distribution.get_server_list.<locals>.compare_mirrorsrK   r   zMain serverTFzCustom serversN)rM   r&   r$   r4   rH   r%   ro   )r   ru   mirrorsrl   mirror_entryr   r   r	   get_server_list   sT   !



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
        NrK   )r>   pos)r#   r   r,   r   r   r   addr!   r   r>   index)r   r7   r1   r.   r6   comment
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)r9   r   r/   
componentsr*   parent_componentrz   _enable_component)r   compr6   r<   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.   r6   r4   rz   )r<   comps_per_distr   r   r	   add_component_only_once7  s   
z?Distribution._enable_component.<locals>.add_component_only_oncerK   rh   )r6   )r7   r6   )r5   r   r   r7   r   r.   r9   r6   rz   r"   r   rM   r~   r!   )	r   r   r   sourcesr   comps_per_sdistsr   r<   r   r   r	   r   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)
        rK   N)	r5   r   r   r"   r   r6   removerM   r   )r   r   r   r<   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 )NrK   )r1   r6   r.   r   r4   rM   r   )r<   r1   seenr   r   r   r	   change_server_of_source  s   
z;Distribution.change_server.<locals>.change_server_of_sourceN)r#   r   r   r/   rL   r1   r"   )r   r1   r   seen_binaryseen_sourcer<   r   r   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   r=   r:   ro   rx   r~   r   r   r   r   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 )testingunstableTF)r   r   r   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.orgrJ   rg   rD   rh   ri   )r[   rM   rN   rH   r   rV   rj   rk   r   r   r	   ro     s   



z#DebianDistribution._get_mirror_namec                 C      t j| dd d S )Nz http://ftp.%s.debian.org/debian/r\   r
   r:   r   r   r   r	   r:        
zDebianDistribution.get_mirrorsN)r   r   r   __doc__r)   ro   r:   r   r   r   r	   r     s
    r   c                   @      e Zd ZdZdd ZdS )UbuntuDistributionz+ Class to support specific Ubuntu features c                 C   r   )Nz$http://%s.archive.ubuntu.com/ubuntu/r   r   r   r   r   r	   r:     r   zUbuntuDistribution.get_mirrorsNr   r   r   r   r:   r   r   r   r	   r         r   c                   @   r   )UbuntuRTMDistributionz/ Class to support specific Ubuntu RTM features c                 C   s   | j j| _d S r   )r   rL   r$   r   r   r   r	   r:     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PIPENsidDebianzDebian GNU/Linux unstable (sid)r   )CodenameDistributor IDDescriptionRelease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   stderruniversal_newlinesz	channel: z: rK   z+system-image-cli failed, using defaults: %s)r   r   r   r   r   ImportErrorrO   opendevnullO_RDWRr   
splitlinesr2   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_FILEr>   rO   rP   isfileparseinject_lsb_compat)r   
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 )
NIDr   PRETTY_NAMEr   VERSION_CODENAMEr   UBUNTU_CODENAME
VERSION_IDr   )r   getr   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=rK   )r   r>   rr   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 )NrK   r   )shlexr   rM   )r   r   valuesr   r   r	   r   /  s   
z_OSRelease.parse_valueN)T)
r   r   r   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   UbuntuNzubuntu-rtm/z
Ubuntu-RTM/rK   -r   r   )r   r   r   r   r   r   rsplitr   r   r   r   r
   )	r   r   r   r   r   
os_release	os_result
lsb_resultchannelr   r   r	   
get_distro6  s8   


r   )r   r   rp   r   rO   xml.etree.ElementTreer   apt_pkgrH   	Exceptionr   objectr
   r   r   r   r   r   r   r   r   r   r   r	   <module>   s*      5