diff --git a/poster-bash b/poster-bash old mode 100644 new mode 100755 index aae4cc1..d7ce2d8 --- a/poster-bash +++ b/poster-bash @@ -1,14 +1,15 @@ #!/bin/bash # poster-bash - Oyun posteri indirici (Standalone) -# Version: 1.0.0 +# Version: 1.0.0 - Config-Free Version # https://github.com/wisecolt/poster-bash # # Tüm modülleri içeren tek dosya halinde script +# Sadece .env dosyası kullanır - config dosyası yok set -e ############################################################################### -# CORE MODULE - lib/core.sh +# CORE MODULE ############################################################################### # Version info @@ -27,7 +28,6 @@ export EXIT_ERROR_API=6 # Constants export RETRY_MAX=3 export TIMEOUT_SECONDS=30 -export CONFIG_FILE="${HOME}/.game-bash.conf" export LOG_FILE="${HOME}/.game-bash.log" # IGDB API endpoints @@ -160,7 +160,7 @@ format_bytes() { } ############################################################################### -# CONFIG MODULE - lib/config.sh +# CONFIG MODULE (.env only) ############################################################################### # Find .env file (search in script directory and parent directories) @@ -174,7 +174,7 @@ config_find_env() { return 0 fi - # Check parent directory (for poster_bash folder case) + # Check parent directory local parent_dir parent_dir="$(dirname "$current_dir")" if [ -f "${parent_dir}/.env" ]; then @@ -223,77 +223,7 @@ config_load_env() { return 0 } -# Load configuration from file -config_load() { - if [ ! -f "$CONFIG_FILE" ]; then - return 1 - fi - - # Source the config file - # shellcheck source=/dev/null - source "$CONFIG_FILE" - return 0 -} - -# Save configuration to file -config_save() { - cat > "$CONFIG_FILE" << EOF -# ~/.game-bash.conf -# Game Poster Bash - Configuration File -# Auto-generated on $(get_timestamp) - -# IGDB API Credentials (from .env or defaults) -IGDB_CLIENT_ID="${IGDB_CLIENT_ID}" -IGDB_CLIENT_SECRET="${IGDB_CLIENT_SECRET}" -IGDB_REDIRECT_URI="${IGDB_REDIRECT_URI:-http://localhost}" - -# OAuth Token Cache (auto-filled by script) -IGDB_ACCESS_TOKEN="${IGDB_ACCESS_TOKEN:-}" -IGDB_TOKEN_EXPIRES="${IGDB_TOKEN_EXPIRES:-}" - -# Application Settings -PROGRESS_MODE="${PROGRESS_MODE:-both}" -LOG_LEVEL="${LOG_LEVEL:-info}" -RETRY_COUNT="${RETRY_COUNT:-3}" - -# Poster Settings -POSTER_FILENAME="${POSTER_FILENAME:-poster.png}" -POSTER_FORMAT="${POSTER_FORMAT:-png}" - -# UI Settings -SHOW_3D_LOGO="${SHOW_3D_LOGO:-true}" -RETRO_MODE="${RETRO_MODE:-true}" - -# Scan Directories (from .env) -SCAN_DIR="${SCAN_DIR:-}" -TEST_DIR="${TEST_DIR:-}" -EOF - - chmod 600 "$CONFIG_FILE" -} - -# Get config value -config_get() { - local key="$1" - local default="${2:-}" - - # Expand variable name and get value - if [ -n "${!key}" ]; then - echo "${!key}" - else - echo "$default" - fi -} - -# Set config value -config_set() { - local key="$1" - local value="$2" - - export "$key=$value" -} - -# Initialize config with defaults +# Initialize config with defaults from .env config_init() { # First, try to load .env file config_load_env @@ -302,8 +232,6 @@ config_init() { export IGDB_CLIENT_ID="${IGDB_CLIENT_ID:-buyzvv6qoyzj7rmauwkfom79h7fvpx}" export IGDB_CLIENT_SECRET="${IGDB_CLIENT_SECRET:-tivj7d6b21vqybpb4fx1oe85nffibt}" export IGDB_REDIRECT_URI="${IGDB_REDIRECT_URI:-http://localhost}" - export IGDB_ACCESS_TOKEN="${IGDB_ACCESS_TOKEN:-}" - export IGDB_TOKEN_EXPIRES="${IGDB_TOKEN_EXPIRES:-}" export PROGRESS_MODE="${PROGRESS_MODE:-both}" export LOG_LEVEL="${LOG_LEVEL:-info}" export RETRY_COUNT="${RETRY_COUNT:-3}" @@ -311,10 +239,9 @@ config_init() { export POSTER_FORMAT="${POSTER_FORMAT:-png}" export SHOW_3D_LOGO="${SHOW_3D_LOGO:-true}" export RETRO_MODE="${RETRO_MODE:-true}" - - # Directory settings (from .env or empty) export SCAN_DIR="${SCAN_DIR:-}" export TEST_DIR="${TEST_DIR:-}" + export TEST_MODE="false" } # Validate required config @@ -322,21 +249,18 @@ config_validate() { local errors=0 if [ -z "$IGDB_CLIENT_ID" ]; then - echo "Hata: IGDB_CLIENT_ID yapılandırılmamış." >&2 + echo "Hata: IGDB_CLIENT_ID yapılandırılmamış (.env dosyasına bakın)" >&2 errors=$((errors + 1)) fi if [ -z "$IGDB_CLIENT_SECRET" ]; then - echo "Hata: IGDB_CLIENT_SECRET yapılandırılmamış." >&2 + echo "Hata: IGDB_CLIENT_SECRET yapılandırılmamış (.env dosyasına bakın)" >&2 errors=$((errors + 1)) fi - # In test mode, validate TEST_DIR - if [ "$TEST_MODE" = "true" ]; then - if [ -z "$TEST_DIR" ]; then - echo "Hata: TEST modunda TEST_DIR yapılandırılmamış." >&2 - errors=$((errors + 1)) - fi + if [ -z "$SCAN_DIR" ] && [ -z "$TEST_DIR" ]; then + echo "Hata: SCAN_DIR veya TEST_DIR tanımlanmalı (.env dosyasına bakın)" >&2 + errors=$((errors + 1)) fi return $errors @@ -358,7 +282,7 @@ config_get_scan_dir() { } ############################################################################### -# LOGGER MODULE - lib/logger.sh +# LOGGER MODULE ############################################################################### # ANSI color codes @@ -438,7 +362,7 @@ log_debug() { _log_write "DEBUG" $LOG_LEVEL_DEBUG "$1" "$COLOR_DIM" } -# Initialize logger (create log file, set permissions) +# Initialize logger logger_init() { # Create log file if it doesn't exist if [ ! -f "$LOG_FILE" ]; then @@ -483,7 +407,7 @@ logger_tail() { } ############################################################################### -# UI MODULE - lib/ui.sh +# UI MODULE ############################################################################### # Show 3D ASCII logo @@ -496,7 +420,6 @@ ui_show_logo() { # Try toilet first (has 3D fonts), then figlet, then simple echo if [ $HAS_TOILET -eq 1 ]; then - # Try to use a 3D font if available if toilet -f future "GAME POSTER" 2>/dev/null; then echo "" return 0 @@ -527,9 +450,9 @@ ui_print_header() { local width=50 echo "" - echo -e "${COLOR_BOLD}${COLOR_CYAN}$(printf '%*s' "$width" '' | tr ' ' '━')${COLOR_RESET}" + echo -e "${COLOR_BOLD}${COLOR_CYAN}$(printf '%*s' "$width" '' | tr ' ' '─')${COLOR_RESET}" echo -e "${COLOR_BOLD}${COLOR_CYAN} $text${COLOR_RESET}" - echo -e "${COLOR_BOLD}${COLOR_CYAN}$(printf '%*s' "$width" '' | tr ' ' '━')${COLOR_RESET}" + echo -e "${COLOR_BOLD}${COLOR_CYAN}$(printf '%*s' "$width" '' | tr ' ' '─')${COLOR_RESET}" echo "" } @@ -632,7 +555,7 @@ ui_print_divider() { } ############################################################################### -# SCANNER MODULE - lib/scanner.sh +# SCANNER MODULE ############################################################################### # Store found ISO entries (format: path|directory|name) @@ -689,6 +612,33 @@ scanner_get_poster_path() { echo "$directory/$POSTER_FILENAME" } +# Clear all posters in TEST_DIR (test mode only) +scanner_clear_test_posters() { + local test_dir="$TEST_DIR" + + if [ -z "$test_dir" ] || [ ! -d "$test_dir" ]; then + log_debug "TEST_DIR bulunamadı, poster silme atlanıyor" + return 0 + fi + + log_info "TEST posterları temizleniyor: $test_dir" + + local count=0 + while IFS= read -r -d '' poster_file; do + rm -f "$poster_file" + count=$((count + 1)) + done < <(find "$test_dir" -type f -name "$POSTER_FILENAME" -print0 2>/dev/null) + + if [ $count -gt 0 ]; then + log_info "$count adet poster silindi" + echo -e " ${COLOR_YELLOW}⚠ $count adet eski poster temizlendi${COLOR_RESET}" + else + log_debug "Silinecek poster bulunamadı" + fi + + return 0 +} + # Scan from config (uses SCAN_DIR or TEST_DIR based on mode) scanner_scan_from_config() { local scan_dir @@ -742,7 +692,7 @@ scanner_scan_from_config() { } ############################################################################### -# AUTH MODULE - lib/auth.sh +# AUTH MODULE ############################################################################### # Calculate Unix timestamp for expiration @@ -750,26 +700,17 @@ get_timestamp_unix() { date +%s } -# Check if token is expired -auth_is_expired() { - local expires="$1" - - if [ -z "$expires" ]; then - return 0 # No expiration = expired +# Authenticate and get access token (cached in RAM for session) +# Token bir kez alınıp tüm oturum boyunca kullanılır +auth_authenticate() { + # Check if we already have a valid token in memory + if [ -n "$IGDB_ACCESS_TOKEN" ]; then + log_debug "Mevcut token kullanılıyor" + return 0 fi - local now - now=$(get_timestamp_unix) - - # Add 60 second buffer - local expires_with_buffer=$((expires - 60)) - - [ $now -ge $expires_with_buffer ] -} - -# Authenticate and get access token -auth_authenticate() { - log_info "IGDB API'ye bağlanılıyor..." + # Show notification on screen + echo -ne "${COLOR_DIM} 🔄 Access_token alınıyor...${COLOR_RESET}\r" local response local http_code @@ -790,6 +731,7 @@ auth_authenticate() { response=$(echo "$response" | head -n -1) if [ "$http_code" != "200" ]; then + echo -e "${COLOR_RED} ✗ Token alınamadı (HTTP $http_code)${COLOR_RESET}" log_error "OAuth başarısız: HTTP $http_code" log_error "Response: $response" return 1 @@ -803,57 +745,35 @@ auth_authenticate() { expires_in=$(echo "$response" | jq -r '.expires_in // empty') if [ -z "$access_token" ]; then + echo -e "${COLOR_RED} ✗ Token alınamadı${COLOR_RESET}" log_error "Token alınamadı" return 1 fi - # Calculate expiration timestamp - local now - local expires_timestamp - now=$(get_timestamp_unix) - expires_timestamp=$((now + expires_in)) - - # Save to environment + # Save to environment (RAM cache - session only) export IGDB_ACCESS_TOKEN="$access_token" - export IGDB_TOKEN_EXPIRES="$expires_timestamp" - # Save to config - config_save + # Show success on screen (clear the line) + echo -e "${COLOR_GREEN} ✓ Token alındı${COLOR_RESET} ${COLOR_DIM}(${expires_in}s geçerli)${COLOR_RESET}" - log_success "OAuth başarılı, token alındı" + log_success "OAuth başarılı" return 0 } -# Get valid access token (refresh if needed) +# Get valid access token (from RAM cache or authenticate) auth_get_token() { - # Check if we have a token - if [ -z "$IGDB_ACCESS_TOKEN" ]; then - log_debug "Token bulunamadı, yeni token alınıyor..." - auth_authenticate - return $? + # If token exists in memory, use it + if [ -n "$IGDB_ACCESS_TOKEN" ]; then + return 0 fi - # Check if token is expired - if auth_is_expired "$IGDB_TOKEN_EXPIRES"; then - log_debug "Token süresi doldu, yenileniyor..." - auth_authenticate - return $? - fi - - # Token is valid - log_debug "Mevcut token geçerli" - return 0 -} - -# Clear token from memory and config -auth_clear_token() { - export IGDB_ACCESS_TOKEN="" - export IGDB_TOKEN_EXPIRES="" - config_save + # Otherwise, authenticate to get a new token + auth_authenticate + return $? } ############################################################################### -# IGDB MODULE - lib/igdb.sh +# IGDB MODULE ############################################################################### # Search for a game by name @@ -918,7 +838,6 @@ igdb_search_game() { ;; 401) log_error "Yetkilendirme hatası, token yenileniyor..." - auth_clear_token auth_get_token # Retry once igdb_search_game "$game_name" @@ -1037,42 +956,9 @@ igdb_search_with_vr_fallback() { } ############################################################################### -# DOWNLOADER MODULE - lib/downloader.sh +# DOWNLOADER MODULE ############################################################################### -# Clean all posters from test directory before test run -downloader_clean_test_posters() { - local test_dir="$1" - - if [ ! -d "$test_dir" ]; then - log_warn "Test dizini bulunamadı: $test_dir" - return 1 - fi - - log_info "Test posterleri temizleniyor: $test_dir" - - local count=0 - local posters - posters=$(find "$test_dir" -type f -name "$POSTER_FILENAME" 2>/dev/null) - - if [ -z "$posters" ]; then - log_info "Temizlenecek poster bulunamadı" - return 0 - fi - - # Remove each poster - while IFS= read -r poster; do - if [ -f "$poster" ]; then - rm -f "$poster" - count=$((count + 1)) - log_debug "Silindi: $poster" - fi - done <<< "$posters" - - log_info "Temizlenen poster sayısı: $count" - return 0 -} - # Check if poster already exists downloader_check_if_exists() { local poster_path="$1" @@ -1266,19 +1152,16 @@ ${COLOR_BOLD}Kullanım:${COLOR_RESET} ${COLOR_BOLD}Seçenekler:${COLOR_RESET} -h, --help Bu yardım mesajını gösterir -v, --version Versiyon bilgisini gösterir - -c, --config Yapılandırma dosyasının konumunu gösterir -l, --log Log dosyasını gösterir --clear-log Log dosyasını temizler - --init Yapılandırma dosyasını yeniden oluşturur - --test-run Test modunda çalışır (TEST_DIR kullanır) + --test-run Test modunda çalışır (önce eski posterleri temizler) -${COLOR_BOLD}Örnekler:${COLOR_RESET} - poster-bash # Config'deki SCAN_DIR'yi tarar - poster-bash --test-run # Test modunda TEST_DIR'yi tarar - poster-bash --log # Son logları göster +${COLOR_BOLD}Kullanım:${COLOR_RESET} + poster-bash # .env'deki SCAN_DIR'yi tarar + poster-bash --test-run # .env'deki TEST_DIR'yi tarar ${COLOR_BOLD}.env Dosyası:${COLOR_RESET} - Script ile aynı dizinde .env dosyası oluşturun: + Script ile aynı dizinde .env oluşturun: IGDB_CLIENT_ID=your_client_id IGDB_CLIENT_SECRET=your_client_secret @@ -1294,6 +1177,10 @@ EOF show_version() { echo "${COLOR_BOLD}${SCRIPT_NAME}${COLOR_RESET} v${SCRIPT_VERSION}" echo "Bash oyun posteri indirici" + echo "" + echo "Sürüm 1.0.0 - Config-Free Version" + echo "- .env dosyası ile yapılandırma" + echo "- Her çalıştırmada yeni IGDB token'ı alınır" } # Initialize the application @@ -1307,19 +1194,19 @@ app_init() { # Initialize config (loads .env if present) config_init - # Load config file if exists - if config_load; then - log_debug "Config dosyası yüklendi" - else - log_debug "Config dosyası yok, varsayılanlar kullanılıyor" - config_save - fi - # Validate config if ! config_validate; then echo "" echo "Hata: Gerekli yapılandırma eksik." >&2 - echo "Lütfen .env dosyasını kontrol edin veya config dosyasını düzenleyin: $CONFIG_FILE" >&2 + echo "Lütfen .env dosyasını kontrol edin:" >&2 + echo "" >&2 + echo " cd /path/to/your/games" >&2 + echo " cat > .env << EOF" >&2 + echo " IGDB_CLIENT_ID=your_client_id" >&2 + echo " IGDB_CLIENT_SECRET=your_client_secret" >&2 + echo " SCAN_DIR=/path/to/your/games" >&2 + echo " TEST_DIR=/test-games" >&2 + echo " EOF" >&2 exit $EXIT_ERROR_CONFIG fi @@ -1347,16 +1234,6 @@ main() { show_version exit $EXIT_SUCCESS ;; - -c|--config) - echo "Config: ${CONFIG_FILE}" - if [ -f "$CONFIG_FILE" ]; then - echo "" - cat "$CONFIG_FILE" - else - echo "Config dosyası bulunamadı" - fi - exit $EXIT_SUCCESS - ;; -l|--log) echo "Log: ${LOG_FILE}" if [ -f "$LOG_FILE" ]; then @@ -1372,12 +1249,6 @@ main() { echo "Log dosyası temizlendi" exit $EXIT_SUCCESS ;; - --init) - config_init - config_save - echo "Config dosyası oluşturuldu: ${CONFIG_FILE}" - exit $EXIT_SUCCESS - ;; --test-run) test_mode=true ;; @@ -1387,10 +1258,21 @@ main() { app_init # Enable test mode if requested - if [ "$test_mode" = true ]; then + if [ "$test_mode" = "true" ]; then config_enable_test_mode + # Clear existing posters in TEST_DIR first + scanner_clear_test_posters fi + # Authenticate with IGDB (before scanning) + ui_print_header "🔐 IGDB Bağlantısı" + if ! auth_get_token; then + ui_status_error "IGDB bağlantısı başarısız" + exit $EXIT_ERROR_AUTH + fi + ui_status_success "IGDB bağlantısı başarılı" + echo "" + # Get scan directory from config local scan_dir scan_dir="$(config_get_scan_dir)" @@ -1410,13 +1292,6 @@ main() { echo -e " ${COLOR_DIM}Dizin:${COLOR_RESET} $scan_dir" echo "" - # Clean old posters in test mode before starting - if [ "$TEST_MODE" = "true" ]; then - log_info "Test modu: Eski posterler temizleniyor..." - downloader_clean_test_posters "$scan_dir" - echo "" - fi - # Scan from config if ! scanner_scan_from_config; then ui_status_error "Dizin tarama başarısız" @@ -1435,15 +1310,6 @@ main() { echo -e " ${COLOR_GREEN}✓${COLOR_RESET} Bulunan oyun: ${COLOR_BOLD}$game_count${COLOR_RESET}" echo "" - # Authenticate with IGDB - ui_print_header "🔐 IGDB Bağlantısı" - if ! auth_get_token; then - ui_status_error "IGDB bağlantısı başarısız" - exit $EXIT_ERROR_AUTH - fi - ui_status_success "IGDB bağlantısı başarılı" - echo "" - # Process all games ui_print_header "🎮 Poster İndirme" downloader_process_all