29 KiB
29 KiB
🏗️ POSTER-BASH - MİMARİ TASARIM BELGESİ v1.0
Doküman Versiyonu
- Versiyon: 1.0
- Tarih: 2025-02-04
- Durum: Taslak (Onay Bekliyor)
1. SİSTEM GENEL BAKIŞ
1.1 Mimari Tarz
┌─────────────────────────────────────────────────────────────────┐
│ POSTER-BASH SYSTEM │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SCANNER │───▶│ IGDB │───▶│ DOWNLOADER │ │
│ │ Module │ │ Module │ │ Module │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ UI │ │ CONFIG │ │ LOG │ │
│ │ Module │ │ Module │ │ Module │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
1.2 Teknoloji Yığını
| Katman | Teknoloji | Açıklama |
|---|---|---|
| Script | Bash 4.0+ | POSIX uyumlu |
| HTTP Client | curl | API istekleri |
| JSON Parser | jq | JSON işleme |
| ASCII Art | figlet/toilet | 3D logo |
| Colors | ANSI Escape Codes | Renkli terminal |
| Config | bash variable export | Ayar yönetimi |
2. MODÜLER MİMARİ
2.1 Modül Hiyerarşisi
poster-bash (Main Entry Point)
│
├── lib/core.sh # Core utilities & shared functions
├── lib/config.sh # Config management
├── lib/logger.sh # Logging system
├── lib/ui.sh # Terminal UI & colors
├── lib/scanner.sh # Directory & ISO scanner
├── lib/igdb.sh # IGDB API integration
├── lib/downloader.sh # Poster download & retry logic
└── lib/auth.sh # OAuth token management
2.2 Modül Sorumlulukları
2.2.1 Main Entry Point (poster-bash)
Sorumluluklar:
- Başlangıç kontrolü (dependencies, config)
- 3D logo gösterimi
- Ana iş akışı koordinasyonu
- Hata yakalama ve graceful exit
Interface:
main() → init → scan → process → download → report → cleanup
2.2.2 Core Module (lib/core.sh)
Sorumluluklar:
- Global değişken tanımları
- Shared utility functions
- Error codes ve exit handling
- Network connectivity check
Public Functions:
- check_dependencies()
- check_internet()
- exit_with_code()
- sanitize_filename()
Exported Variables:
- SCRIPT_VERSION="1.0.0"
- RETRY_MAX=3
- TIMEOUT_SECONDS=30
2.2.3 Config Module (lib/config.sh)
Sorumluluklar:
- Config dosyası okuma/yazma
- Environment variable loading
- Validation ve defaults
Public Functions:
- config_load()
- config_save()
- config_get(key)
- config_set(key, value)
Config Structure:
~/.game-bash.conf:
IGDB_CLIENT_ID="..."
IGDB_CLIENT_SECRET="..."
IGDB_ACCESS_TOKEN="" # Auto-filled
IGDB_TOKEN_EXPIRES="" # Auto-filled
PROGRESS_MODE="both"
LOG_LEVEL="info"
RETRY_COUNT=3
2.2.4 Logger Module (lib/logger.sh)
Sorumluluklar:
- Log dosyasına yazma
- Terminal çıktısı formatlama
- Log level filtering
Public Functions:
- log_info(message)
- log_warn(message)
- log_error(message)
- log_success(message)
Log Format:
[YYYY-MM-DD HH:MM:SS] LEVEL Message
Output:
- Terminal: Colored output
- File: ~/.game-bash.log
2.2.5 UI Module (lib/ui.sh)
Sorumluluklar:
- ANSI renk yönetimi
- 3D ASCII logo gösterimi
- Progress bar çizimi
- Retro efektler
Public Functions:
- ui_show_logo()
- ui_print_header(text)
- ui_show_progress(current, total, text)
- ui_color_print(color, text)
Colors:
- RED: Errors
- GREEN: Success
- YELLOW: Warnings
- BLUE: Info
- MAGENTA: Headers
- CYAN: Progress
3D Logo:
- Font: "standard" (figlet) or "future" (toilet)
- Color: Cyan with bold
2.2.6 Scanner Module (lib/scanner.sh)
Sorumluluklar:
- Recursive directory scanning
- .iso dosyası tespiti
- Oyun adı çıkarımı
Public Functions:
- scanner_scan_directory(path)
- scanner_find_iso(directory)
- scanner_extract_game_name(iso_path)
Data Structure:
ISO Entry:
{
path: "/full/path/to/game.iso",
directory: "/full/path/to",
name: "Game Name",
has_poster: false
}
Return: Array of ISO entries (space-separated)
2.2.7 IGDB Module (lib/igdb.sh)
Sorumluluklar:
- OAuth token yönetimi
- Oyun arama
- Cover URL retrieval
Public Functions:
- igdb_authenticate() # Get/refresh token
- igdb_search_game(name) # Search by name
- igdb_search_with_vr(name) # Search with VR suffix
- igdb_get_cover_url(game_id) # Get cover image URL
API Endpoints:
POST https://id.twitch.tv/oauth2/token
Request: {"client_id":"...", "client_secret":"...", "grant_type":"client_credentials"}
Response: {"access_token":"...", "expires_in":5045603, "token_type":"bearer"}
POST https://api.igdb.com/v4/games
Headers: {"Authorization":"Bearer ${token}", "Client-ID":"${client_id}"}
Body: search "${name}"; fields name,cover;
Response: [{"id":123, "name":"Game", "cover":456}]
POST https://api.igdb.com/v4/covers
Headers: {"Authorization":"Bearer ${token}", "Client-ID":"${client_id}"}
Body: fields url,image_id; where id=${cover_id};
Response: [{"id":456, "image_id":"abc123", "url":"..."}]
Image URL: https://images.igdb.com/igdb/image/upload/t_cover_big/${image_id}.jpg
2.2.8 Downloader Module (lib/downloader.sh)
Sorumluluklar:
- Poster indirme
- Retry logic
- Dosya kaydetme
Public Functions:
- downloader_download_poster(url, output_path)
- downloader_retry_with_backoff(url, output_path, max_retries)
- downloader_check_if_exists(output_path)
Flow:
1. Check if poster.png exists → Skip if true
2. Download with curl
3. Validate file size (> 0)
4. On failure: Retry with exponential backoff (1s, 2s, 4s)
5. After max retries: Log and skip
2.2.9 Auth Module (lib/auth.sh)
Sorumluluklar:
- Token lifecycle management
- Token refresh logic
- Token validation
Public Functions:
- auth_get_token() # Returns valid token (refresh if needed)
- auth_is_expired() # Check if token expired
- auth_refresh() # Refresh from API
- auth_save_token() # Save to config
Token Flow:
1. Check config for cached token
2. Check expiration
3. If expired or missing → refresh
4. Save new token to config
3. VERİ AKIŞI
3.1 Ana Akış Diyagramı
┌─────────────────────────────────────────────────────────────────────┐
│ START │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ INITIALIZATION │
│ ├─ Check dependencies (curl, jq, figlet) │
│ ├─ Load config from ~/.game-bash.conf │
│ ├─ Check internet connectivity │
│ ├─ Initialize logger │
│ └─ Show 3D logo │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AUTHENTICATION │
│ ├─ Check cached token │
│ ├─ Validate expiration │
│ └─ Refresh if needed │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ SCANNING │
│ ├─ Scan current directory recursively │
│ ├─ Find all .iso files │
│ ├─ Extract game names │
│ └─ Build processing list │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ PROCESSING LOOP (for each ISO) │
│ ├─ Show progress: [1/15] Game Name │
│ ├─ Check if poster.png exists → Skip if yes │
│ ├─ Search IGDB for game │
│ ├─ Not found? → Retry with " VR" suffix │
│ ├─ Get cover URL from IGDB │
│ ├─ Download poster with retry (3x) │
│ └─ Log result (success/fail) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ REPORT │
│ ├─ Show summary │
│ │ ├─ Total games found │
│ │ ├─ Posters downloaded │
│ │ ├─ Skipped (already had poster) │
│ │ └─ Failed │
│ └─ Final message │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ END │
└─────────────────────────────────────────────────────────────────────┘
3.2 Detaylı Akış (Oyun İşleme)
For each ISO file:
┌──────────────────────────────────────────────────────────────────┐
│ scanner_find_iso() → Returns: /path/to/Game/Game.iso │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ scanner_extract_game_name() → Returns: "Game" │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ downloader_check_if_exists("/path/to/Game/poster.png") │
│ ├─ Exists? → Skip, log "Already has poster" │
│ └─ Not exists? → Continue │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ igdb_search_game("Game") │
│ ├─ Found? → Get cover_id │
│ └─ Not found? → igdb_search_game("Game VR") │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ igdb_get_cover_url(cover_id) │
│ ├─ Returns: https://images.igdb.com/.../image_id.jpg │
│ └─ Not found? → Log "No cover available", skip │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ downloader_retry_with_backoff(url, "/path/to/Game/poster.png", 3)│
│ ├─ Try 1: curl download │
│ ├─ Fail? → Wait 1s → Try 2 │
│ ├─ Fail? → Wait 2s → Try 3 │
│ ├─ Fail? → Wait 4s → Try 4 │
│ └─ All fail? → Log error, skip │
└──────────────────────────────────────────────────────────────────┘
4. API ENTEGRASYON DETAYLARI
4.1 IGDB API Spesifikasyonu
4.1.1 OAuth Token Request
# Endpoint
POST https://id.twitch.tv/oauth2/token
# Request Parameters (application/x-www-form-urlencoded)
client_id=buyzvv6qoyzj7rmauwkfom79h7fvpx
client_secret=tivj7d6b21vqybpb4fx1oe85nffibt
grant_type=client_credentials
# Expected Response (200 OK)
{
"access_token": "eyJhbGciOiIXVCJ9...",
"expires_in": 5045603,
"token_type": "bearer"
}
# Error Response (400 Bad Request)
{
"status": 400,
"message": "invalid client"
}
4.1.2 Games Search
# Endpoint
POST https://api.igdb.com/v4/games
# Headers
Authorization: Bearer ${ACCESS_TOKEN}
Client-ID: buyzvv6qoyzj7rmauwkfom79h7fvpx
Accept: application/json
# Request Body (APICalc query format)
search "Cyberpunk 2077";
fields name,cover;
limit 1;
# Expected Response (200 OK)
[
{
"id": 10904,
"name": "Cyberpunk 2077",
"cover": 12345
}
]
# Empty Response (no results)
[]
4.1.3 Covers Query
# Endpoint
POST https://api.igdb.com/v4/covers
# Headers (same as games)
Authorization: Bearer ${ACCESS_TOKEN}
Client-ID: buyzvv6qoyzj7rmauwkfom79h7fvpx
# Request Body
fields url,image_id;
where id = 12345;
# Expected Response
[
{
"id": 12345,
"image_id": "co1abc",
"url": "//images.igdb.com/igdb/image/upload/t_cover_big/co1abc.jpg"
}
]
# Final Image URL
https://images.igdb.com/igdb/image/upload/t_cover_big/co1abc.jpg
4.2 Image Size Options
| Size | URL Pattern | Dimensions | Use Case |
|---|---|---|---|
| cover_small | t_cover_small | 90x128 | Thumbnails |
| cover_big | t_cover_big | 264x374 | Default (our choice) |
| screenshot_med | t_screenshot_med | 569x320 | Not used |
| screenshot_big | t_screenshot_big | 889x500 | Not used |
4.3 Error Handling Strategy
HTTP Code | Action
----------|--------------------------------------------------
200 | Success, process response
400 | Invalid request, check token
401 | Unauthorized, refresh token
403 | Forbidden, check client credentials
404 | Not found (no games/covers), skip with warning
429 | Rate limit, wait and retry
500+ | Server error, retry with backoff
5. VERİ YAPILARI
5.1 ISO Entry Structure
# Bash array representation (space-separated)
ISO_ENTRY_FORMAT="{path}|{directory}|{name}|{has_poster}"
# Example
"/path/to/Game/Game.iso|/path/to/Game|Game|0"
# Access pattern
IFS='|' read -r path directory name has_poster <<< "$entry"
5.2 Config Structure
# Key-value pairs in bash source file
export IGDB_CLIENT_ID="buyzvv6qoyzj7rmauwkfom79h7fvpx"
export IGDB_CLIENT_SECRET="tivj7d6b21vqybpb4fx1oe85nffibt"
export IGDB_ACCESS_TOKEN=""
export IGDB_TOKEN_EXPIRES=""
export PROGRESS_MODE="both"
export LOG_LEVEL="info"
export RETRY_COUNT=3
5.3 Summary Statistics
# Runtime statistics (stored in variables)
TOTAL_GAMES=0
DOWNLOADED=0
SKIPPED=0
FAILED=0
6. KULLANICI ARAYÜZÜ TASARIMI
6.1 Terminal Düzeni
┌────────────────────────────────────────────────────────────────┐
│ ╔═══════════════════╗ │
│ ║ GAME POSTER ║ │
│ ╚═══════════════════╝ │
│ │
│ 📂 Scanning: /home/user/Games │
│ 🎮 Found: 15 ISO files │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ │
│ [1/15] Cyberpunk 2077 [██████░░░░] 40% │
│ ✓ Downloaded: poster.png │
│ │
│ [2/15] Elden Ring [████████░░] 53% │
│ ℹ Already has poster, skipping... │
│ │
│ [3/15] Unknown Game [███░░░░░░] 20% │
│ ⚠ Game not found, retrying with VR suffix... │
│ ⚠ Not found in IGDB │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ │
│ 📊 SUMMARY │
│ ✓ Downloaded: 12 │
│ ℹ Skipped: 2 │
│ ✗ Failed: 1 │
│ │
│ 📝 Log saved to: ~/.game-bash.log │
└────────────────────────────────────────────────────────────────┘
6.2 Renk Paleti
# ANSI Color Codes
COLOR_RESET='\033[0m'
COLOR_RED='\033[0;31m' # Errors
COLOR_GREEN='\033[0;32m' # Success
COLOR_YELLOW='\033[0;33m' # Warnings
COLOR_BLUE='\033[0;34m' # Info
COLOR_MAGENTA='\033[0;35m' # Headers
COLOR_CYAN='\033[0;36m' # Progress/Logo
COLOR_BOLD='\033[1m'
COLOR_DIM='\033[2m'
# Usage
echo -e "${COLOR_GREEN}✓ Success message${COLOR_RESET}"
echo -e "${COLOR_RED}✗ Error message${COLOR_RESET}"
6.3 Progress Bar Implementation
show_progress_bar() {
local current=$1
local total=$2
local width=40
local percentage=$((current * 100 / total))
local filled=$((width * current / total))
local empty=$((width - filled))
printf "["
printf "%${filled}s" | tr ' ' '█'
printf "%${empty}s" | tr ' ' '░'
printf "] %d%%\r" "$percentage"
}
7. HATA YÖNETİMİ
7.1 Exit Code Convention
EXIT_SUCCESS=0 # Normal exit
EXIT_ERROR_GENERAL=1 # General error
EXIT_ERROR_DEPS=2 # Missing dependencies
EXIT_ERROR_NETWORK=3 # Network error
EXIT_ERROR_AUTH=4 # Authentication failed
EXIT_ERROR_CONFIG=5 # Config error
EXIT_ERROR_API=6 # API error
7.2 Error Recovery Flow
Error Occurs
│
▼
Check Type
│
├─ Network Error → Check internet → Exit if offline
├─ Auth Error → Refresh token → Retry → Exit if fail
├─ API Error → Log warning → Skip current game → Continue
├─ Download Error → Retry (3x) → Log → Skip → Continue
└─ Config Error → Show message → Exit
7.3 Graceful Degradation
# Fallback behaviors
figlet not found → Use simple echo with colors
jq not found → Fatal error (required dependency)
curl not found → Fatal error (required dependency)
Token refresh fail → Exit with auth error
Internet down → Exit with network error
8. PERFORMANS VE SKALABİLİTE
8.1 Performance Targets
| Metric | Target | Notes |
|---|---|---|
| Startup time | < 2s | Logo + auth + scan |
| Per-game processing | 1-3s | API call + download |
| Memory usage | Minimal | Bash processes |
| Concurrent games | 1 | Sequential processing |
8.2 Optimization Strategies
1. Token Caching
- Store in config, reuse until expired
- Reduces auth overhead
2. Skip Existing Posters
- Check file existence before API call
- Saves bandwidth and time
3. Minimal Dependencies
- Only curl, jq, figlet required
- Fast startup, low overhead
4. Sequential Processing
- No parallel processing (bash limitation)
- Better error handling
9. GÜVENLİK
9.1 Security Considerations
1. Credential Protection
- Config file: ~/.game-bash.conf (chmod 600)
- .gitignore: Prevent git commit
- Never log tokens/secrets
2. Input Sanitization
- Escape game names before API call
- Validate paths before file operations
3. File Operations
- Check file exists before overwrite
- Use safe temp directories
4. Network Security
- HTTPS only for API calls
- Validate SSL certificates
9.2 File Permissions
# Config file
chmod 600 ~/.game-bash.conf
# Script
chmod 755 poster-bash
# Library files
chmod 644 lib/*.sh
10. TEST STRATEJİSİ
10.1 Unit Test Coverage
# Test categories
1. Config Tests
- Load valid config
- Handle missing config
- Save and reload
2. Scanner Tests
- Find ISO files
- Extract game names
- Handle empty directories
3. IGDB Tests
- Token refresh
- Game search
- Cover URL retrieval
4. Downloader Tests
- Download success
- Retry logic
- File existence check
5. Logger Tests
- All log levels
- File writing
- Terminal output
10.2 Integration Test Scenarios
1. End-to-End Flow
- Multiple games
- Mix of found/not found
- VR suffix retry
2. Error Scenarios
- No internet
- Invalid credentials
- API rate limit
3. Edge Cases
- Special characters in game names
- Very long directory names
- Permission denied
11. DEPLOYMENT
11.1 Installation
# Clone or download
git clone https://github.com/user/poster-bash.git
cd poster-bash
# Make executable
chmod +x poster-bash
# Copy to PATH (optional)
sudo cp poster-bash /usr/local/bin/
# First run (creates config)
./poster-bash
11.2 Directory Structure After Install
~/.game-bash.conf # User config
~/.game-bash.log # Log file
/usr/local/bin/poster-bash # Executable (if installed)
12. BAKIM VE EVRİM
12.1 Version Strategy
Semantic Versioning: MAJOR.MINOR.PATCH
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes
Current: v1.0.0
12.2 Future Enhancements
Planned Features:
- [ ] Parallel processing (background jobs)
- [ ] Custom poster size selection
- [ ] Multiple image sources fallback
- [ ] Interactive mode (select games manually)
- [ ] Database cache for faster lookups
- [ ] GUI mode (optional)
13. REFERANSLAR
13.1 External Documentation
13.2 Related Documents
REQUIREMENTS.md- Functional requirementsREADME.md- User documentation (to be created)CHANGELOG.md- Version history (to be created)
14. ONAY KONTROL LİSTESİ
- Modüler yapı tanımlandı
- API entegrasyonu tasarlandı
- Veri akışı diagramı oluşturuldu
- Hata yönetimi stratejisi belirlendi
- Güvenlik önlemleri tanımlandı
- UI/UX tasarımı tamamlandı
- Implementasyon onayı bekliyor
- Kodlama aşamasına hazır
v1.0 - 2025-02-04 | Tasarım Onayı Bekliyor