@ -1,109 +1,134 @@
import re
import requests
import time
from modules . downloader import try_download
from modules . files_worker import *
count_wines = 25 # Количество элементов для записи в .tmp файл
repos = { # Список репозиториев для обработки и их короткие имена
" GloriousEggroll/proton-ge-custom " : " proton-ge-custom " ,
" Kron4ek/Wine-Builds " : " Kron4ek " ,
" GloriousEggroll/wine-ge-custom " : " wine-ge-custom " ,
" Kron4ek/Wine-Builds " : " Kron4ek " ,
" CachyOS/proton-cachyos " : " proton-cachyos " ,
" Castro-Fidel/wine_builds " : " LG "
}
def source_list_checker ( tmp_path ) : # Проверка наличия и обновления файлов с о списками исходников
mirrors = {
" https://cloud.linux-gaming.ru " : " LG_mirror "
}
def source_list_checker ( tmp_path ) :
for repo , short_name in repos . items ( ) :
output_file = os . path . join ( tmp_path , f " { short_name } .tmp " )
if not os . path . exists ( output_file ) :
log . info ( f " Файл { output_file } не существует. Получаем данные из репозитория. " )
source_list_downloader ( repo , tmp_path , short_name , output_file )
continue # Переходим к следующему репозиторию
if os . path . getsize ( output_file ) == 0 : # Проверяем, является ли файл пустым
log . info ( f " Файл { output_file } пуст. Обновляем данные. " )
source_list_downloader ( repo , tmp_path , short_name , output_file )
continue # Переходим к следующему репозиторию
last_modified_time = get_last_modified_time ( output_file ) # Получаем время последнего изменения файла
if last_modified_time is None : # Если время не удалось получить, пробуем обновить файл
log . info ( f " Н е удалось получить время последнего изменения для { output_file } . Попытаемся обновить. " )
source_list_downloader ( repo , tmp_path , short_name , output_file )
continue # Переходим к следующему репозиторию
current_time = time . time ( )
if current_time - last_modified_time > = 10800 : # 10800 секунд = 3 часа, проверяем, устарел ли файл
log . info ( f " Файл { output_file } устарел. Обновляем данные. " )
if not os . path . exists ( output_file ) or os . path . getsize ( output_file ) == 0 or \
( time . time ( ) - get_last_modified_time ( output_file , fallback = 0 ) ) > = 10800 :
source_list_downloader ( repo , tmp_path , short_name , output_file )
else :
log . info ( f " Файл { output_file } существует и был обновлён менее 3 часов назад. Используем кэшированные данные. " )
def source_list_downloader ( repo , tmp_path , short_name , output_file ) :
url = f " https://api.github.com/repos/ { repo } /releases?per_page= { count_wines } "
temp_file = os . path . join ( tmp_path , f " { short_name } .tmp.new " ) # Временный файл
for mirror_url , short_name in mirrors . items ( ) :
output_file = os . path . join ( tmp_path , f " { short_name } .tmp " )
if not os . path . exists ( output_file ) or os . path . getsize ( output_file ) == 0 or \
( time . time ( ) - get_last_modified_time ( output_file , fallback = 0 ) ) > = 10800 :
source_list_downloader ( mirror_url , tmp_path , short_name , output_file , use_github = False )
else :
log . info ( f " Файл { output_file } существует и был обновлён менее 3 часов назад. Используем кэшированные данные. " )
def source_list_downloader ( source , tmp_path , short_name , output_file , use_github = True ) :
if use_github :
url = f " https://api.github.com/repos/ { source } /releases?per_page= { count_wines } "
else :
url = f " { source } / "
temp_file = os . path . join ( tmp_path , f " { short_name } .tmp.new " )
try :
response = requests . get ( url )
response . raise_for_status ( ) # Возбудим исключение для ошибок HTTP
releases = response . json ( )
response . raise_for_status ( )
log . debug ( f " Ответ API: { releases } " )
tar_files = [ ] # Проверяем каждый релиз
for release in releases :
assets = release . get ( ' assets ' , [ ] )
for asset in assets :
asset_name = asset [ ' name ' ]
if (
( re . search ( r ' (wine|proton) ' , asset_name , re . IGNORECASE ) or
re . search ( r ' ^GE-Proton \ d+- \ d+ \ .tar \ .gz$ ' , asset_name ) or
re . search ( r ' ^GE-Proton \ d+(- \ d+)? \ .tar \ .xz$ ' , asset_name ) ) and
( asset_name . endswith ( ' .tar.gz ' ) or asset_name . endswith ( ' .tar.xz ' ) )
) :
tar_files . append ( asset_name ) # Собираем все подходящие файлы
log . debug ( f " Найденный файл: { asset_name } " )
tar_urls = [ ] # Список для хранения полных URL-адресов архивов
if not tar_files :
log . warning ( f " Нет подходящих файлов в репозитории { repo } . " )
return # Выходим из функции, если нет файлов
if use_github :
releases = response . json ( )
for release in releases :
assets = release . get ( ' assets ' , [ ] )
for asset in assets :
asset_name = asset [ ' name ' ]
asset_url = asset [ ' browser_download_url ' ]
if (
( re . search ( r ' (wine|proton) ' , asset_name , re . IGNORECASE ) or
re . search ( r ' ^GE-Proton \ d+- \ d+ \ .tar \ .gz$ ' , asset_name ) or
re . search ( r ' ^GE-Proton \ d+(- \ d+)? \ .tar \ .xz$ ' , asset_name ) ) and
( asset_name . endswith ( ' .tar.gz ' ) or asset_name . endswith ( ' .tar.xz ' ) )
) :
tar_urls . append ( asset_url ) # Добавляем полный URL в список
else : # Обработка страницы с зеркалом
content = response . text
log . debug ( f " Содержимое зеркала: { content } " ) # Записываем содержимое страницы для отладки
relative_urls = re . findall ( r ' href=[ \' " ]?(portproton/[^ \' " >]+ \ .tar \ .(gz|xz))[ \' " ]? ' , content )
with open ( temp_file , ' w ' ) as file : # Записываем найденные файлы во временный файл
file . write ( " \n " . join ( tar_files ) )
base_url = " https://cloud.linux-gaming.ru/ "
tar_urls = [ base_url + url [ 0 ] for url in relative_urls ] # Используем первый элемент кортежа для формирования полного URL
log . info ( f " Данные успешно записаны в временный файл { temp_file } . " )
if not tar_urls : # Проверка на наличие URL
log . warning ( f " Нет подходящих файлов в { ' GitHub ' if use_github else ' зеркале ' } { source } . " )
return
if os . path . exists ( temp_file ) : # Если запись прошла успешно, заменяем основной файл
os . replace ( temp_file , output_file )
log . info ( f " Файл { output_file } успешно обновлен. " )
with open ( temp_file , ' w ' ) as file : # Запись найденных URL в файл
file . write ( " \n " . join ( tar_urls ) )
os . replace ( temp_file , output_file )
log . info ( f " Файл { output_file } успешно обновлен. " )
except requests . exceptions . RequestException as e :
log . error ( f " Ошибка при получении данных из { repo } : { str ( e ) } " )
log . error ( f " Ошибка при получении данных из { sou rc e} : { str ( e ) } " )
def get_sources ( args , tmp_path , dist_path ) :
def get_sources ( args , tmp_path , dist_path , mirror ):
os . makedirs ( tmp_path , exist_ok = True )
source_list_checker ( tmp_path )
if args :
for arg in args :
for repo , short_name in repos . items ( ) : # определяем короткое имя репозитория
if not args :
log . critical ( " Аргументы не предоставлены. Завершение работы. " )
return
for arg in args :
target_dir_path = os . path . join ( dist_path , arg ) # Формируем название искомого каталога
if os . path . isdir ( target_dir_path ) : # Проверяем, существует ли запрашиваемый каталог
log . debug ( f " Запрашиваемый каталог ' { arg } ' найден в ' { dist_path } ' . " )
else :
log . debug ( f " Запрашиваемый каталог ' { arg } ' не найден в ' { dist_path } ' . " )
file_found = False
for repo , short_name in repos . items ( ) : # Определяем, какой источник использовать в зависимости от флага mirror
if mirror and short_name == " LG " :
short_name = " LG_mirror " # Меняем имя под зеркалом
tmp_file_path = os . path . join ( tmp_path , f " { short_name } .tmp " )
if os . path . exists ( tmp_file_path ) : # проверяем наличие файла
if os . path . exists ( tmp_file_path ) :
with open ( tmp_file_path , ' r ' ) as file :
all_tar_gz_files = file . read ( ) . splitlines ( )
all_urls = file . read ( ) . splitlines ( )
log . debug ( f " Получили ссылки { all_urls } " )
for file_to_download in all_tar_gz_files : # Ищем совпадение в файле
if arg in file_to_download :
log . info ( f " Найдено совпадение для ' { arg } ' : { file_to_download } в файле { tmp_file_path } " )
url = f " https://github.com/ { repo } /releases/latest/download/ { file_to_download } " # Получаем URL файла
tmp_file = os . path . join ( tmp_path , file_to_download )
for url in all_urls : # Проверяем, есть ли URL соответствующий имени каталога
log . debug ( f " Проверяем ссылку { url } " )
if f " { arg } .tar. " in os . path . basename ( url ) :
log . info ( f " Совпадение для ' { arg } ' найдено в файле { tmp_file_path } " )
tmp_file = os . path . join ( tmp_path , os . path . basename ( url ) )
log . debug ( f " Сформирован путь к файлу: { tmp_file } " )
if not os . path . exists ( tmp_file ) :
try :
try_download ( url , tmp_path )
try_download ( url , tmp_ file )
unpack ( tmp_file , dist_path )
try_remove_file ( tmp_file )
except Exception as e :
log . error ( f " Ошибка при загрузке или распаковке: { str ( e ) } " )
file_found = True # Устанавливаем флаг, что файл найден
break # Прерываем цикл, если файл найден
if not file_found :
log . critical ( f " { arg } не найден в файле { tmp_file_path } . Завершение! Проверьте корректность переданного имени wine/proton. " )