diff --git a/winehelper b/winehelper index 970c776..a0b192c 100755 --- a/winehelper +++ b/winehelper @@ -1465,6 +1465,130 @@ remove_prefix() { fi } +generate_wine_metadata () { + WINE_METADATA_FILE="$WH_TMP_DIR/wine_metadata.json" + + if [[ -f "$WINE_METADATA_FILE" ]]; then + if find "$WINE_METADATA_FILE" -mmin -1440 | grep -q . ; then + print_info "Файл метаданных $WINE_METADATA_FILE обновлялся менее 24 часов назад. Пропускаем генерацию." + return 0 + fi + print_info "Файл метаданных $WINE_METADATA_FILE устарел." + print_info "Начинаем обновление..." + else + print_info "Генерации метаданных..." + fi + + TMP_WINE_META="$WH_TMP_DIR/wine_metadata" + local FETCH_ERROR_FLAG="$TMP_WINE_META/fetch.error" + rm -f "$FETCH_ERROR_FLAG" + + mkdir -p "$TMP_WINE_META" + + cleanup() { + rm -rf "$TMP_WINE_META" + } + trap cleanup EXIT + + fetch_github_releases() { + local repo="$1" + local wine_metadata_file="$2" + + local url="https://api.github.com/repos/$repo/releases" + + if ! curl -s --fail -H "Accept: application/vnd.github.v3+json" "$url" > "$wine_metadata_file"; then + touch "$FETCH_ERROR_FLAG" + return 1 + fi + + if ! jq -e 'type == "array"' "$wine_metadata_file" >/dev/null 2>&1; then + try_remove_file "$wine_metadata_file" + touch "$FETCH_ERROR_FLAG" + return 1 + fi + + print_info "Получение данных для $repo" + } + + create_wine_entries() { + local input_file="$1" + local file_extension="$2" + local exclude_patterns="$3" + + jq -r --arg ext "$file_extension" ' + .[] | + .assets[] | + select(.browser_download_url | test($ext)) | + { + name: (.name | gsub($ext; "")), + url: .browser_download_url + } + ' "$input_file" | \ + if [[ -n "$exclude_patterns" ]]; then + jq -c --arg patterns "$exclude_patterns" ' + select(.name | test($patterns) | not) + ' + else + jq -c '.' + fi + } + + # Формат: "ключ_json;репозиторий;расширение_файла;шаблон_исключения" + local sources=( + "proton_ge;GloriousEggroll/proton-ge-custom;\\.tar\\.gz$;github-action" + "wine_kron4ek;Kron4ek/Wine-Builds;\\.tar\\.xz$;-x86" + "proton_lg;Castro-Fidel/wine_builds;\\.tar\\.xz$;plugins" + "proton_cachyos;CachyOS/proton-cachyos;\\.tar\\.xz$;znver" + "proton_sarek;pythonlover02/Proton-Sarek;\\.tar\\.gz$;" + "proton_em;Etaash-mathamsetty/Proton;\\.tar\\.xz$;" + ) + + for source_data in "${sources[@]}"; do + ( + IFS=';' read -r key repo extension exclude_pattern <<< "$source_data" + + local releases_file="$TMP_WINE_META/${key}_releases.json" + local entries_file="$TMP_WINE_META/${key}.json" + + fetch_github_releases "$repo" "$releases_file" || exit 1 + create_wine_entries "$releases_file" "$extension" "$exclude_pattern" > "$entries_file" + ) & + done + + wait + + if [[ -f "$FETCH_ERROR_FLAG" ]]; then + fatal "Ошибка при получении релизов. Возможно, превышен лимит запросов к API GitHub или проблема с сетью." + fi + + print_ok "Все данные получены." + + print_info "Создание итогового JSON файла..." + + jq -n \ + --slurpfile proton_ge "$TMP_WINE_META/proton_ge.json" \ + --slurpfile wine_kron4ek "$TMP_WINE_META/wine_kron4ek.json" \ + --slurpfile proton_lg "$TMP_WINE_META/proton_lg.json" \ + --slurpfile proton_cachyos "$TMP_WINE_META/proton_cachyos.json" \ + --slurpfile proton_sarek "$TMP_WINE_META/proton_sarek.json" \ + --slurpfile proton_em "$TMP_WINE_META/proton_em.json" \ + '{ + proton_ge: $proton_ge, + wine_kron4ek: $wine_kron4ek, + proton_lg: $proton_lg, + proton_cachyos: $proton_cachyos, + proton_sarek: $proton_sarek, + proton_em: $proton_em + }' > "$WINE_METADATA_FILE" + + if jq empty "$WINE_METADATA_FILE" 2>/dev/null; then + print_ok "JSON файл создан успешно: $WINE_METADATA_FILE" + else + print_error "Ошибка создания JSON файла" + exit 1 + fi +} + create_prefix() { print_info "Существующие префиксы:" local prefixes=() @@ -1870,6 +1994,7 @@ case "$arg1" in create-prefix) create_prefix "$@" ;; remove-prefix) remove_prefix "$@" ;; create-base-pfx) create_base_pfx "$@" ;; + generate-db) generate_wine_metadata "$@" ;; *) if [[ -f "$arg1" ]] ; then WIN_FILE_EXEC="$(readlink -f "$arg1")"