Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import requests
- import json
- from datetime import datetime
- import sys
- import time
- # Parametri di connessione
- RADARR_HOST = "http://10.0.0.100:7878"
- RADARR_API_KEY = "d3ddde8fcfe74bf99f81cba41d4f13f7"
- def format_bytes(size_bytes):
- """Formatta i byte in una rappresentazione leggibile (KB, MB, GB)"""
- if size_bytes == 0:
- return "0B"
- size_names = ("B", "KB", "MB", "GB", "TB", "PB")
- i = 0
- while size_bytes >= 1024 and i < len(size_names) - 1:
- size_bytes /= 1024.0
- i += 1
- return f"{size_bytes:.2f} {size_names[i]}"
- def format_datetime(date_string):
- """Formatta una data ISO in un formato più leggibile"""
- if not date_string:
- return "N/A"
- try:
- dt = datetime.fromisoformat(date_string.replace('Z', '+00:00'))
- return dt.strftime("%Y-%m-%d %H:%M:%S")
- except:
- return date_string
- def normalize_hash(hash_value, client=""):
- """
- Normalizza un hash per EMule/altri client per permettere i confronti
- Args:
- hash_value: Il valore dell'hash da normalizzare
- client: Il nome del client (per determinare il formato)
- Returns:
- Hash normalizzato
- """
- if not hash_value:
- return hash_value
- is_emule = client and ('emule' in client.lower() or 'emulerr' in client.lower())
- # Per client EMule, gestisci i formati a 32 e 40 caratteri
- if is_emule:
- if len(hash_value) == 32:
- return hash_value + '0' * 8 # Aggiungi 8 zeri per arrivare a 40 caratteri
- elif len(hash_value) == 40:
- return hash_value
- return hash_value
- def get_movie_history(movie_id):
- """
- Ottiene la cronologia specifica per un film
- Args:
- movie_id: L'ID del film in Radarr
- Returns:
- Lista di record della cronologia per quel film
- """
- url = f"{RADARR_HOST}/api/v3/history/movie"
- params = {
- "movieId": movie_id,
- "apikey": RADARR_API_KEY
- }
- try:
- response = requests.get(url, params=params)
- if response.status_code == 200:
- records = response.json()
- return records
- else:
- print(f"Errore nel recuperare la cronologia per il film {movie_id}: {response.status_code}")
- return []
- except Exception as e:
- print(f"Errore durante la connessione: {str(e)}")
- return []
- def get_history_for_file(filename, all_history=None):
- """
- Cerca nella cronologia globale per un nome file specifico
- """
- if not all_history:
- # Se non è stata fornita una cronologia, recuperala
- url = f"{RADARR_HOST}/api/v3/history"
- params = {
- "pageSize": 500,
- "page": 1,
- "sortKey": "date",
- "sortDirection": "descending",
- "apikey": RADARR_API_KEY
- }
- try:
- response = requests.get(url, params=params)
- if response.status_code == 200:
- data = response.json()
- all_history = data.get('records', [])
- else:
- return None
- except:
- return None
- # Normalizza il nome file per il confronto
- norm_filename = filename.lower()
- # Cerca nella cronologia per il nome file
- for record in all_history:
- source_title = record.get('sourceTitle', '').lower()
- if norm_filename == source_title or norm_filename in source_title or source_title in norm_filename:
- return record
- return None
- def get_movie_details(movie_id):
- """
- Recupera i dettagli di un film specifico
- Args:
- movie_id: L'ID del film in Radarr
- Returns:
- Dizionario con i dettagli del film
- """
- url = f"{RADARR_HOST}/api/v3/movie/{movie_id}"
- params = {
- "apikey": RADARR_API_KEY
- }
- try:
- response = requests.get(url, params=params)
- if response.status_code == 200:
- movie = response.json()
- return movie
- else:
- print(f"Errore nel recuperare i dettagli del film {movie_id}: {response.status_code}")
- return None
- except Exception as e:
- print(f"Errore durante la connessione: {str(e)}")
- return None
- def get_queue_items(page=1):
- """Recupera gli elementi della coda di download da Radarr"""
- # Costruzione dell'URL con tutti i parametri possibili
- url = (
- f"{RADARR_HOST}/api/v3/queue?"
- f"page={page}"
- f"&pageSize=10"
- f"&sortKey=timeleft"
- f"&sortDirection=ascending"
- f"&includeUnknownMovieItems=true"
- f"&includeMovie=true"
- )
- # Aggiunta dell'API key come parametro
- params = {
- "apikey": RADARR_API_KEY
- }
- try:
- # Ottieni prima la cronologia globale (ultimi 500 elementi)
- print("Recupero la cronologia globale...")
- history_url = f"{RADARR_HOST}/api/v3/history"
- history_params = {
- "pageSize": 500,
- "page": 1,
- "sortKey": "date",
- "sortDirection": "descending",
- "apikey": RADARR_API_KEY
- }
- history_response = requests.get(history_url, params=history_params)
- global_history = []
- if history_response.status_code == 200:
- history_data = history_response.json()
- global_history = history_data.get('records', [])
- print(f"Recuperati {len(global_history)} elementi dalla cronologia globale")
- else:
- print(f"Errore nel recupero della cronologia globale: {history_response.status_code}")
- # Ora recupera gli elementi della coda
- print(f"Recupero elementi della coda Radarr, pagina {page}...")
- response = requests.get(url, params=params)
- if response.status_code == 200:
- queue_data = response.json()
- # Stampare informazioni sulla coda
- print("\n" + "="*90)
- # Verifica la presenza dei campi di paginazione, altrimenti usa valori di default
- current_page = queue_data.get('page', 1)
- total_pages = queue_data.get('totalPages', 1)
- total_records = queue_data.get('totalRecords', 0)
- print(f"INFORMAZIONI SULLA CODA DI DOWNLOAD - PAGINA {current_page}/{total_pages}")
- print("="*90)
- print(f"Record totali: {total_records}")
- # Se 'records' non è presente, potrebbe essere una risposta diretta con gli elementi
- records = queue_data.get('records', [])
- if not records and isinstance(queue_data, list):
- records = queue_data
- print(f"Record in questa pagina: {len(records)}")
- # Cache per i risultati dei grab
- grab_results = {}
- # Analisi dettagliata degli elementi in coda
- for i, item in enumerate(records):
- print("\n" + "-"*90)
- print(f"ELEMENTO #{i+1}: {item.get('title', 'N/A')}")
- print("-"*90)
- # Informazioni di base
- print("\n[INFO DI BASE]")
- print(f"ID Coda: {item.get('id', 'N/A')}")
- # Determina il Movie ID
- movie_id = None
- if 'movieId' in item:
- movie_id = item['movieId']
- elif 'movie' in item and item['movie'] and 'id' in item['movie']:
- movie_id = item['movie']['id']
- if movie_id:
- print(f"Movie ID: {movie_id}")
- else:
- print("Movie ID: N/A")
- # Ottieni il client di download e il download ID
- download_client = item.get('downloadClient', '')
- download_id = item.get('downloadId', '')
- print(f"Stato: {item.get('status', 'N/A')}")
- print(f"Protocollo: {item.get('protocol', 'N/A')}")
- print(f"Download ID: {download_id}")
- print(f"Client di download: {download_client}")
- # Normalizza l'hash per EMuleRR
- normalized_download_id = normalize_hash(download_id, download_client)
- if normalized_download_id != download_id:
- print(f"Download ID (Normalizzato): {normalized_download_id}")
- print(f"Indice: {item.get('indexer', 'N/A')}")
- # Ottieni il titolo dell'item
- item_title = item.get('title', '')
- # PRIMA STRATEGIA: Cerca nella cronologia specifica del film se abbiamo un movie_id
- movie_history = []
- if movie_id:
- print(f"Cerco nella cronologia specifica del film (ID: {movie_id})...")
- movie_history = get_movie_history(movie_id)
- print(f"Trovati {len(movie_history)} record nella cronologia del film")
- # Cerca gli eventi "grabbed" nella cronologia del film
- grabbed_records = [r for r in movie_history if r.get('eventType') == 'grabbed']
- # FALLBACK STRATEGIA 1: Cerca nella cronologia globale per nome file
- if not grabbed_records:
- print(f"Nessun record 'grabbed' trovato nella cronologia del film. Cerco nella cronologia globale per nome file...")
- file_history = get_history_for_file(item_title, global_history)
- if file_history and file_history.get('eventType') == 'grabbed':
- grabbed_records = [file_history]
- print(f"Trovato 1 record 'grabbed' nella cronologia globale")
- # FALLBACK STRATEGIA 2: Cerca nella cronologia globale per hash
- if not grabbed_records and download_id:
- print(f"Cerco nella cronologia globale per hash...")
- # Entrambe le versioni dell'hash (con e senza zeri finali per EMule)
- hash_to_search = [download_id]
- if 'emule' in download_client.lower() or 'emulerr' in download_client.lower():
- if len(download_id) == 32:
- hash_to_search.append(download_id + '00000000')
- elif len(download_id) == 40 and download_id.endswith('00000000'):
- hash_to_search.append(download_id[:-8])
- # Cerca match diretti per qualsiasi versione dell'hash
- for h in hash_to_search:
- matching_records = [r for r in global_history if r.get('downloadId') == h]
- if matching_records:
- grabbed_records = [r for r in matching_records if r.get('eventType') == 'grabbed']
- if grabbed_records:
- print(f"Trovati {len(grabbed_records)} record 'grabbed' nella cronologia globale tramite hash")
- break
- # FALLBACK STRATEGIA 3: Cerca nella cronologia globale per movie_id
- if not grabbed_records and movie_id:
- print(f"Cerco nella cronologia globale per movie_id...")
- movie_records = [r for r in global_history if r.get('movieId') == movie_id]
- grabbed_records = [r for r in movie_records if r.get('eventType') == 'grabbed']
- if grabbed_records:
- print(f"Trovati {len(grabbed_records)} record 'grabbed' nella cronologia globale tramite movie_id")
- # Se abbiamo trovato eventi "grabbed", usa il più recente
- grab_record = None
- if grabbed_records:
- # Ordina per data (i più recenti prima)
- sorted_records = sorted(grabbed_records,
- key=lambda r: r.get('date', ''),
- reverse=True)
- grab_record = sorted_records[0]
- # NUOVO: Recupera il movie_id dal grab record se non era disponibile nell'item
- if not movie_id and grab_record and 'movieId' in grab_record:
- movie_id = grab_record['movieId']
- print(f"Movie ID recuperato dalla cronologia: {movie_id}")
- # Se abbiamo recuperato un movie_id, ottieni dettagli aggiuntivi
- movie_details = get_movie_details(movie_id)
- if movie_details:
- # Aggiungi i dettagli del film all'elemento in coda
- if 'movie' not in item:
- item['movie'] = movie_details
- print(f"Titolo film: {movie_details.get('title', 'N/A')}")
- print(f"Anno: {movie_details.get('year', 'N/A')}")
- # Se abbiamo trovato un record grabbed corrispondente
- if grab_record:
- grab_id = grab_record.get('downloadId', 'N/A')
- # Memorizza il risultato
- grab_results[i] = grab_record
- print(f"Grab ID (dalla cronologia): {grab_id}")
- # Normalizza l'hash per EMuleRR
- normalized_grab_id = normalize_hash(grab_id, download_client)
- if normalized_grab_id != grab_id:
- print(f"Grab ID (Normalizzato): {normalized_grab_id}")
- print(f"Titolo sorgente: {grab_record.get('sourceTitle', 'N/A')}")
- print(f"Data grab: {format_datetime(grab_record.get('date', ''))}")
- # Confronta se il grab_id corrisponde al download_id
- if normalized_grab_id == normalized_download_id or grab_id == download_id:
- print("CORRISPONDENZA: Il Grab ID è identico al Download ID")
- else:
- print("NOTA: Il Grab ID è diverso dal Download ID")
- else:
- grab_results[i] = None
- print("Grab ID: Non trovato nella cronologia")
- # Informazioni sul download
- print("\n[DETTAGLI DOWNLOAD]")
- print(f"Dimensione totale: {format_bytes(item.get('size', 0))}")
- if 'sizeleft' in item and item.get('size', 0) > 0:
- progress = 100 - (item['sizeleft'] / item['size'] * 100)
- print(f"Dimensione rimanente: {format_bytes(item.get('sizeleft', 0))}")
- print(f"Progresso: {progress:.2f}%")
- print(f"Tempo rimanente: {item.get('timeleft', 'N/A')}")
- print(f"Priorità di download: {item.get('downloadForced', False)}")
- if 'outputPath' in item:
- print(f"Percorso output: {item['outputPath']}")
- # Informazioni temporali
- print("\n[INFORMAZIONI TEMPORALI]")
- print(f"Aggiunto: {format_datetime(item.get('added', ''))}")
- print(f"Data pubblicazione: {format_datetime(item.get('publishDate', ''))}")
- # Errori e avvisi
- if item.get('errorMessage'):
- print("\n[ERRORI]")
- print(f"Messaggio di errore: {item['errorMessage']}")
- if item.get('statusMessages'):
- print("\n[MESSAGGI DI STATO]")
- for msg in item['statusMessages']:
- print(f"- Titolo: {msg.get('title', 'N/A')}")
- for message in msg.get('messages', []):
- print(f" • {message}")
- # Informazioni sul film
- if 'movie' in item and item['movie']:
- movie = item['movie']
- print("\n[INFORMAZIONI FILM]")
- print(f"Movie ID: {movie.get('id', 'N/A')}")
- print(f"Titolo: {movie.get('title', 'N/A')}")
- print(f"Titolo originale: {movie.get('originalTitle', 'N/A')}")
- print(f"Anno: {movie.get('year', 'N/A')}")
- print(f"TMDb ID: {movie.get('tmdbId', 'N/A')}")
- print(f"IMDb ID: {movie.get('imdbId', 'N/A') or 'N/A'}")
- # Dettagli qualità
- if 'quality' in item:
- print("\n[QUALITÀ]")
- quality = item['quality']
- if 'quality' in quality:
- q_details = quality['quality']
- print(f"Nome qualità: {q_details.get('name', 'N/A')}")
- print(f"Sorgente: {q_details.get('source', 'N/A')}")
- print(f"Risoluzione: {q_details.get('resolution', 'N/A')}")
- # Riepilogo dei Grab ID
- print("\n" + "="*110)
- print("RIEPILOGO GRAB ID DALLA CRONOLOGIA")
- print("="*110)
- print(f"{'#':<3} {'MOVIE ID':<8} {'CLIENT':<10} {'GRAB ID':<40} {'TITOLO'}")
- print("-"*110)
- for i, item in enumerate(records):
- # Determina il Movie ID (potenzialmente dal record del grab)
- movie_id = "N/A"
- if 'movieId' in item:
- movie_id = item['movieId']
- elif 'movie' in item and item['movie'] and 'id' in item['movie']:
- movie_id = item['movie']['id']
- elif grab_results.get(i) and 'movieId' in grab_results[i]:
- # Recupera il movie_id dal record del grab
- movie_id = grab_results[i]['movieId']
- client = item.get('downloadClient', 'N/A')
- grab_record = grab_results.get(i)
- grab_id = "N/A"
- if grab_record:
- grab_id = grab_record.get('downloadId', 'N/A')
- if 'emule' in client.lower() or 'emulerr' in client.lower():
- grab_id = normalize_hash(grab_id, client)
- title = item.get('title', 'N/A')
- if len(title) > 30:
- title = title[:27] + "..."
- print(f"{i+1:<3} {movie_id:<8} {client[:10]:<10} {grab_id:<40} {title}")
- return queue_data
- else:
- print(f"Errore nella richiesta: {response.status_code}")
- print(response.text)
- return None
- except Exception as e:
- print(f"Errore durante la connessione: {str(e)}")
- # Debug dell'errore
- import traceback
- print("\nTraceback completo dell'errore:")
- traceback.print_exc()
- return None
- # Esegue la funzione per la pagina specificata (default: 1)
- if __name__ == "__main__":
- page = 1
- if len(sys.argv) > 1:
- try:
- page = int(sys.argv[1])
- except:
- pass
- print(f"Recupero elementi della coda Radarr, pagina {page}...")
- result = get_queue_items(page=page)
- # Per salvare il risultato completo in un file JSON:
- if result:
- filename = f"radarr_queue_page{page}.json"
- with open(filename, "w") as f:
- json.dump(result, f, indent=2)
- print(f"\nRisultati salvati in {filename}")
- else:
- print("Nessun risultato da salvare.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement