Page 1 sur 1

Paquet WAPT Nvidia Driver

Posté : 22 août 2023 - 16:09
par SeiyaGame
Bonjour,

Je me permets de vous proposer un paquet que j'ai réalisé, destiné à l'installation des drivers Nvidia. Le paquet est une template, les utilisateurs ont la possibilité de choisir quel driver GPU il veule packager !

J'ai effectué l'installation, la désinstallation ainsi que la mise à jour du paquet.

Voici le code du fichier setup.py :

Code : Tout sélectionner

# -*- coding: utf-8 -*-
import re
from setuphelpers import *
from setupdevhelpers import *

"""
Usable WAPT package functions: install(), uninstall(), session_setup(), audit(), update_package()

"""

def sed(pattern, replace, source, count=0):
    """Reads a source file and writes the destination file.

    In each line, replaces pattern with replace.

    Args:
        pattern (str): pattern to match (can be re.pattern)
        replace (str): replacement str
        source  (str): input filename
        count (int): number of occurrences to replace   
    """

    fin = open(source, 'r')
    num_replaced = count

    dest_tmp = source + "_tmp"
    print(dest_tmp)
    fout = open(dest_tmp, 'w')

    for line in fin:
        out = re.sub(pattern, replace, line)
        fout.write(out)

        if out != line:
            num_replaced += 1
        if count and num_replaced > count:
            break
    try:
        fout.writelines(fin.readlines())
    except Exception as E:
        raise E

    fin.close()
    fout.close()

    shutil.move(dest_tmp, source) 

def install():
    # Declaring local variables
    bin_name = glob.glob("*.EXE")[0]
    driver_path = makepath(systemdrive, "NVIDIA")

    print("Extracting: " + bin_name)
    unzip_with_7zip(bin_name, driver_path)
    remove_file(bin_name)

    # Installing the software
    print("Installing: %s" % bin_name)

    install_exe_if_needed(
        makepath(driver_path, "setup.exe"),
        silentflags="-s -clean -noreboot -noeula",
        key="{B2FE1952-0186-46C3-BAEC-A80AA35AC5B8}_Display.Driver",
        min_version=control.get_software_version(),
        timeout=900,
    )

    print("Deletion of the driver folder")
    remove_tree(driver_path)

def uninstall():
    print(f'Uninstallation of {control.asrequirement()}')

    nvidia_display_nvx = "C:\\Program Files\\NVIDIA Corporation\\Installer2\\Display.Driver\\DisplayDriver.NVX"
    sed('uninstallReboot="true"', 'uninstallReboot="false"', nvidia_display_nvx, count=1)
    
    driversToUninstall = ["Display.Driver","HDAudio.Driver"]
    for driver in driversToUninstall:
        run(f"C:\\Windows\\SysWOW64\\RunDll32.EXE 'C:\\Program Files\\NVIDIA Corporation\\Installer2\\InstallerCore\\NVI2.DLL',UninstallPackage {driver} -silent")
Voici le code du fichier update_package.py :

Code : Tout sélectionner

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
from typing import Union
from urllib.parse import urlparse, parse_qs
from setupdevhelpers import *
from setuphelpers import *
import waptguihelper
import re

def get_lang():
    lang_dict = {
        "en-us": 1,
        "en-uk": 2,
        "en-in": 3,
        "de": 9,
        "es": 10,
        "fr": 12,
        "it": 13,
        "pl": 14,
        "pt": 15,
        "ru": 16,
    }
    lang_list = []
    for entry in lang_dict:
        lang_list.append({"Value": lang_dict[entry], "Short Name": entry})

    return waptguihelper.grid_dialog("Select a language (Please select only one)", lang_list, waptguihelper.GRT_SELECTED)[0]

def get_whql():
    whql_dict = {
        "Recommended/Certified": 1,
        "Beta": 0,
        "All": '',
    }
    whql_list = []
    for entry in whql_dict:
        whql_list.append({"Value": whql_dict[entry], "Type": entry})
        
    return waptguihelper.grid_dialog("Select a type of driver (Please select only one)", whql_list, waptguihelper.GRT_SELECTED)[0]['Value']

def xml_to_dict(xml_data: str):

    # Parse XML data
    root = ET.fromstring(xml_data)

    result = []
    for lookup_value in root.findall('.//LookupValue'):
        name = lookup_value.find('Name').text
        value = int(lookup_value.find('Value').text)
        result.append({'Value': value, 'Name': name})

    return result

def api_lookup_value_search(type_id: Union[str, int], parent_id: Union[str, int] = None):
    url = f"https://www.nvidia.fr/Download/API/lookupValueSearch.aspx?TypeID={type_id}"

    if parent_id is not None:
        url += f"&ParentID={parent_id}"

    headers = {
        'Content-Type': 'text/xml; charset=utf-8'
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.content
    except requests.HTTPError as e:
        print(f"An error occurred: {e}")
        return None

def get_product_type():
    return xml_to_dict(api_lookup_value_search(type_id=1))

def get_product_series(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=2, parent_id=id_product))

def get_product(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=3, parent_id=id_product))

def get_operating_system(id_product: Union[str, int]):
    return xml_to_dict(api_lookup_value_search(type_id=4, parent_id=id_product))

def make_download_url():
    
    product_type = waptguihelper.grid_dialog("Product Type (Please select only one)", get_product_type(), waptguihelper.GRT_SELECTED)[0]['Value']
    product_series = waptguihelper.grid_dialog("Product Series (Please select only one)", get_product_series(product_type), waptguihelper.GRT_SELECTED)[0]['Value']
    product = waptguihelper.grid_dialog("Product (Please select only one)", get_product(product_series), waptguihelper.GRT_SELECTED)[0]
    operating_sys = waptguihelper.grid_dialog("Operating System (Please select only one)", get_operating_system(product_series), waptguihelper.GRT_SELECTED)[0]
    lang = get_lang()
    whql = get_whql()

    # Hardcoded on nvidia website ...
    windows_list = ['Windows 10 64-bit', 'Windows Server 2022', 'Windows Server 2019', 'Windows Server 2016', 'Windows 11']
    product_type_list = [1, 3, 7, 11]

    dtcid = 1 if (operating_sys['Name'] in windows_list) and (product_type in product_type_list) else 0

    url_version = f"https://www.nvidia.fr/Download/processFind.aspx?psid={product_series}&pfid={product['Value']}&osid={operating_sys['Value']}" \
                  f"&lid={lang['Value']}&whql={whql}&lang={lang['Short Name']}&ctk=0&qnfslb=00&dtcid={dtcid}"
    
    return url_version

def update_package():
    # Declaring local variables
    result = False
    proxies = get_proxies()
    if not proxies:
        proxies = get_proxies_from_wapt_console()
    app_name = control.name

    if not control.sources:
        control.sources = make_download_url()
        control.save_control_to_wapt()

    url_version = control.sources

    # Getting latest version
    print("URL used is: %s" % url_version)
    for bs_search in bs_find_all(url_version, "tr", "id", "driverList", proxies=proxies, timeout=10):
        version_driver = bs_search.find_all('td')[2]
        version = re.search(r'(\d+(?:\.\d+)+)', version_driver.text).group(1)
        download_redirect = "https:" + bs_search.find('a').get('href')
        break
    
    button_href = bs_find(download_redirect, "btn_drvr_lnk_txt", proxies=proxies, timeout=10).find_parent('a').get('href')
    parsed_url = urlparse(button_href)
    query_params = parse_qs(parsed_url.query)
    path_download_url = query_params.get('url')[0]

    download_url = f"https://fr.download.nvidia.com{path_download_url}"
    latest_bin = download_url.split('/')[-1]

    print(f"Latest {app_name} version is: {version}")
    print(f"Download URL is: {download_url}")

    # Downloading latest binaries
    if not isfile(latest_bin):
        print(f"Downloading: {latest_bin}")
        wget(download_url, latest_bin, proxies=proxies)
    else:
        print(f"Binary is present: {latest_bin}")

    # Changing version of the package
    if Version(version) > Version(control.get_software_version()):
        print(f"Software version updated (from: {control.get_software_version()} to: {Version(version)})")
        result = True
    else:
        print("Software version up-to-date (%s)" % Version(version))
    
    control.set_software_version(version)
    control.save_control_to_wapt()

    # Deleting outdated binaries
    remove_outdated_binaries(version)

    # Validating or not update-package-sources
    return result

if __name__ == "__main__":
    pass
Et pour finir le fichier control :

Code : Tout sélectionner

package           : loq-nvidia-driver-template
version           : 1.0-5
architecture      : x64
section           : base
priority          : optional
name              : Template Nvidia Driver
categories        : Drivers
maintainer        : Flavien Schelfaut (Loquidy)
description       : Template for Nvidia graphics card drivers
depends           : loq-7zip
conflicts         : 
maturity          : PROD
locale            : all
target_os         : windows
min_wapt_version  : 2.0
sources           :
installed_size    : 
impacted_process  : 
description_fr    : 
description_pl    : 
description_de    : 
description_es    : 
description_pt    : 
description_it    : 
description_nl    : 
description_ru    : 
audit_schedule    : 
editor            : Nvidia
keywords          : 
licence           : 
homepage          : https://www.nvidia.fr/Download/Find.aspx?lang=fr
package_uuid      : f6c6c352-ed8f-4dc1-86c2-540a58e5dbcb
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 10.0
max_os_version    : 
icon_sha256sum    : 
signer            : loqwapt
signer_fingerprint: b4bf538731a5e9de85fe3a5014052844fe130cb54afab01cd1aaf90f284bd72e
signature         : r/yg/Fz/pEqmbjiPupR+7HoafCLqfjv+ycGHTz+r7dRsMptL9w589y3O6rSg+qKSe9wKPWaI9g1X5WFh3Gh5CZBMOYCs02tIx4n9+B7/JHlitTm7qY2FMRh6T5mVZO9XecgV/Ex75deDvXVLw3GyUtJKnHhOn5JfPl/ldPYzQmtn6ap8ujGCqRGjIfBaa/bVhK19pgqka/6c0c52X0S83X3jj2avvAKXnyCYGipciIypgbNm6+TCKWUCjwIEQN6sXdekBlDZcQQAiJ8d8v0scqSVX2ljS+SbGnfobAbH8Vp5RWtvIqSXcGHOP2zRUeMcrLS2yYYyoLNgPJgFDWK+OA==
signature_date    : 2023-08-22T08:53:43.914722
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
Informations générales :

Serveur WAPT : Debian 11, version 2.4.0.14143, Édition Entreprise
Machine d'administration : Windows 11, version WAPT 2.4.0.14143

Re: Paquet WAPT Nvidia Driver

Posté : 23 août 2023 - 17:00
par dcardon
Merci beaucoup pour ton partage Flavien :-) ! Je vais voir avec Jimmy pour l'intégrer au store si c'est ok pour toi.

Denis

Re: Paquet WAPT Nvidia Driver

Posté : 23 août 2023 - 20:36
par SeiyaGame
Je serais ravi de le mettre à disposition de tous :D !
Il se pourrait que la partie concernant le proxy nécessite une révision ou une amélioration, car je n'ai pas la possibilité de le tester.

De plus, j'ai dans mes cartons 2-3 autres paquets ( Template AMD Driver, logiciel Jabra et la suite de logiciel Charlemagne ...)
J'hésite à poster le paquet charlemagne parce qu'il est un peu compliqué à maintenir ( Il y as au moins 13 logiciels avec chacun des dépendances et 2 ont pas encore un numéro de version correct )