o
    헛dD                     @   s\   d Z ddlZddlmZmZ ddlZddlZddlZdZG dd de	Z
G dd deZdS )	z* Detection tool for nVidia graphics cards     N)PopenPIPEz)/usr/share/ubuntu-drivers-common/obsoletec                   @   s   e Zd ZdZdS )NoDatadirErrorz4Exception thrown when no modaliases dir can be foundN)__name__
__module____qualname____doc__ r	   r	   ?/usr/lib/python3/dist-packages/NvidiaDetector/nvidiadetector.pyr   "   s    r   c                   @   sx   e Zd ZdZddefddZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )NvidiaDetectiona  
    A simple class to:
      * Detect the available graphics cards
      * See what drivers support them (If they are
        NVIDIA cards). If more than one card is
        available, try to find the highest common
        driver version which supports them all.
        (READ the comments in the code for further
        details)
      * Return the recommended driver version
    Nc                 C   sb   ddi| _ || _|| _| || _|   |   |   |   |r)| 	  dS t
|   dS )a  
        printonly = if set to None will make an instance
                    of this class return the selected
                    driver.
                    If set to True it won't return
                    anything. It will simply and print
                    the choice.

        verbose   = if set to True will make the methods
                    print what is happening.
        currenti  N) _NvidiaDetection__driver_aliases	printonlyverbosegetObsoletePackagesoldPackages	detectiongetDatagetCardsremoveUnsupportedprintSelectionprintselectDriver)selfr   r   obsoleter	   r	   r
   __init__3   s   
zNvidiaDetection.__init__c                 C   s(   | j  D ]\}}||kr|  S qdS )z7Get the name of a driver from its corresponding integerN)r   items)r   valuekvr	   r	   r
   __get_name_from_valueQ   s
   z%NvidiaDetection.__get_name_from_valuec                 C   s:   | j |}|du r|drt|dd}t|}|S )z2Get the integer associated to the name of a driverNz-server )r   getendswithintreplace)r   namer   r	   r	   r
   __get_value_from_nameX   s   
z%NvidiaDetection.__get_value_from_namec                 C   sD   g }zdd t | D }dd |D }W |S  ty!   Y |S w )z.Read the list of obsolete packages from a filec                 S   s   g | ]}|  qS r	   )strip.0xr	   r	   r
   
<listcomp>e   s    z7NvidiaDetection.getObsoletePackages.<locals>.<listcomp>c                 S   s   g | ]}|d kr|qS )r!   r	   r)   r	   r	   r
   r,   f   s    )open	readlinesIOError)r   r   tempListr	   r	   r
   r   a   s   z#NvidiaDetection.getObsoletePackagesc                 C   s   g | _ tddgtdd}| d d}td}td}|D ]M}||}||}|rN|d		 
 }|d
	 
 }	|d |	 }
| j |
 q!|rn|d		 
 }|d
	 
 }	|d |	 }
| j |
 q!dS )z^
        Detect the models of the graphics cards
        and store them in self.cards
        lspciz-nTstdoutuniversal_newlinesr   
z6.*03(80|0[0-2]): *(?P<vendor>.+):(?P<device>.+) \(.+\)z/.*03(80|0[0-2]): *(?P<vendor>.+):(?P<device>.+)vendordevice:N)cardsr   r   communicatesplitrecompilematchgroupr(   lowerappend)r   p1pindentifier1indentifier2linem1m2id1id2idr	   r	   r
   r   k   s(   




zNvidiaDetection.detectionc              
   C   s  i | _ td}td}t D ]}|jdr(d|jv s(d|jv s(d|jv r)qz|jjd }W n t	t
fy<   Y qw ||j}|rK|d}n	td	|j  q| |}zK|r||d
d d dd}|dD ]2}|| }	|	std|j|f  qp|	d }
|	d }| j |g |
d |  qpW q ty   td|j|f  Y qw t| j  dkrtj  td dS dS )zi
        Get the data from the modaliases for each driver
        and store them in self.drivers
        zpci:v0000(.+)d0000(.+)svz5nvidia(?:\-driver|)\-([0-9]+)(:?\-server|)(:?\:i386|)nvidia-updatesexperimentalr   
Modaliases   z/%s package has unexpected name scheme. Skipping(N)r!   ,z&Package %s has unexpected modalias: %s   r8   z*Package %s has invalid modalias header: %sr   none)driversr<   r=   aptCacher&   
startswith	candidaterecordKeyErrorAttributeErrorr>   r?   loggingerror%_NvidiaDetection__get_value_from_namefindr%   r;   lstripr@   
setdefaultrA   
ValueErrorlenkeyssysr3   flushr   )r   vendor_product_re
package_repackagempackage_matchstripped_package_namedriver_versionaliasvpr6   productr	   r	   r
   r      s^   







zNvidiaDetection.getDatac                 C   s   i | _ g | _	 | jD ]}|d|d dkr(| jr"td| d  | j| q
t| jdd| _		 | jD ]4}d}| j	D ] }|| j| v r\d}| jrRtd	||f  | j 
|g | q<|si| j 
|g d
 q5d
S )z
        See if the detected graphics cards are NVIDIA cards.
        If they are NVIDIA cards, append them to self.nvidiaCards
        r   r8   10dezNVIDIA card found (rR   TreverseFzCard %s supported by driver %sN)driversForCardsnvidiaCardsr9   ra   r   r   rA   sortedrV   orderedListrc   )r   card	supporteddriverr	   r	   r
   r      s0   

	
zNvidiaDetection.getCardsc                 C   s\   g }| j D ]}d| j | v r|| q|D ]}| jr!td|  | j| | j |= qdS )zf
        Remove unsupported cards from self.nvidiaCards and from
        self.driversForCards
        NzRemoving unsupported card )rv   rA   r   r   rw   remove)r   unsupportedCardsrz   unsupportedr	   r	   r
   r      s   


z!NvidiaDetection.removeUnsupportedc           
      C   s  t | j}|dkr|dkru	 i }| jD ]}| j| D ]}||d ||  d7  < qqt|dd}	 g }|D ]}|| |krD|| q7t |dkrc	 |jdd |d }| jrb| jsbt	d|  n-	 |d }| jrt| jstt	d|  n	 | jt
| j d  d }| jr| jst	d|  	 | |}	|	dur|dkrd	pd
t|	 }|S |dkrd	pd
t| }|S 	 | jrt	d d}|S )zZ
        If more than one card is available, try to get the highest common driver
        r   rP   Trt   zRecommended NVIDIA driver: zRecommended NVIDIA driver: %dNi  znvidia-driver-rL   zNo NVIDIA package to install)re   rw   rv   rc   rx   rA   sortr   r   r   listrf   %_NvidiaDetection__get_name_from_valuestr)
r   cardsNumber
occurrencerz   drvoccurrences
candidatesr|   choicedriver_namer	   r	   r
   r     sZ   
	


	zNvidiaDetection.selectDriverc           	   	   C   s   	 g }g }t ddgtdd}| d }|d}|D ]}|ddkr.||d	d  qt|trPz||r>	 W |S W |S  t	yO   || Y |S w |D ]}z||r[	 W qR t	yj   || Y qRw |S )
z
        USAGE:
            * pkglist is the list of packages  you want to check
            * use lists for one or more packages
            * use a string if it is only one package
            * lists will work well in both cases
        dpkgz--get-selectionsTr2   r   r5   z	install	)
r   r   r:   r;   ra   rA   
isinstancer   indexrd   )	r   pkglistlinesnotinstalledrB   rC   crF   pkgr	   r	   r
   checkpkgd  s<   


	
zNvidiaDetection.checkpkgc                 C   s   |  | j}t|t| jkS )z
        oldPackages = a list of the names of the obsolete drivers
        notInstalled = a list of the obsolete drivers which are not
                       installed
        )r   r   re   )r   notInstalledr	   r	   r
   
getDrivers  s   
zNvidiaDetection.getDriversc                 C   sV   |   }|  r |rtj  t| dS tj  td dS tj  t| dS )z6
        Part for the kernel postinst.d/ hook
        rU   N)r   r   rg   r3   rh   r   )r   r|   r	   r	   r
   r     s   


zNvidiaDetection.printSelection)r   r   r   r   obsoletePackagesPathr   r   r`   r   r   r   r   r   r   r   r   r   r	   r	   r	   r
   r   &   s    	
!<.^$r   )r   r<   
subprocessr   r   rg   r^   rW   r   	Exceptionr   objectr   r	   r	   r	   r
   <module>   s   