j. TdZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z ej ddddlmZedZdZd Zd Zd ed ed edeeeffdZdededeefdZdeeded edefdZdZedkr edSdS)u MediaTrack - OMDB Batch Enrichment =================================== Scarica dati OMDB (locandina, sinossi, cast, rating...) per i prodotti che hanno codice_imdb ma non hanno ancora dati in OmdbData. Fase 1 — Nuovi record: prodotti senza OmdbData o stub piu' vecchi di 30 giorni. Fase 2 — Retry poster: record con dati OK ma poster mancante/N/A da piu' di 45 giorni. Re-scarica dati + poster da OMDB. Aggiorna scaricato_il cosi' il retry successivo avviene dopo altri 45 giorni. Chiamato da Frank come job schedulato (job_type: 'batch' via bat wrapper). Opera direttamente sul DB server — indipendente dal config locale. Usage: python omdb_batch_enrich.py [--db-path PATH] [--posters-dir PATH] [--batch-size 500] [--delay 5.0] [--dry-run] Frank job config (via bat wrapper): executable_path : C:\Users\Mauro Gagliardi\Dropbox\adrian\PYTHON\omdb_enrich\omdb_batch_enrich.bat job_type : batch schedule : es. ogni notte alle 02:00 (cron: 0 2 * * *) N)Path)datetime timedeltatimezonez:C:\Users\Mauro Gagliardi\Dropbox\adrian\PYTHON\MyICR_Suite)database_logicz@I:\SOFTWARE\PYTHON_SRV\PYTHON_LOCAL\MyICR_Suite\local_db\postersz,I:\SOFTWARE\PYTHON_SRV\sync_db\mediatrack.db- codice_imdb url_poster posters_dirreturncr|r|dkrdS||dz }|rdS|ddtdtdzD][} t j|d }|jd krd S||jd d dkrdS| |jdt|jdfcS#tj j $rd|dtd}Yntj j $r}d|dtd|}Yd }~nid }~wtj j$r}dt|fcYd }~cSd }~wt $r}dd|fcYd }~cSd }~wt"$r}d|}Yd }~nd }~wwxYw|tkrt%jd]d|fS)uc Scarica il JPG della locandina e lo salva in posters_dir/{codice_imdb}.jpg. Restituisce (stato, dettaglio): 'ok' — scaricato con successo 'skip' — file gia' presente su disco 'no_url'— url_poster assente o N/A '404' — URL non trovato (Amazon CDN scaduto) 'error' — errore di rete/IO transitorio zN/Ano_urlz.jpg)skiprT)parentsexist_oktimeouti)404rNs)errorz&downloaded content is not a valid JPEGokz bytesztimeout (attempt /)zconnection error (attempt ): rz write error: z unexpected: r)existsmkdirrangePOSTER_RETRIESrequestsget status_coderaise_for_statuscontent write_byteslen exceptionsTimeoutConnectionError HTTPErrorstrOSError Exceptiontimesleep)r r r destattemptrdetailes OC:\Users\Mauro Gagliardi\Dropbox\adrian\PYTHON\omdb_enrich\omdb_batch_enrich.pydownload_posterr:3sg u,,| K--- -D {{}}zdT222NQ.// ( Z444A}## yy   y!}//HHH   QY ' ' 'C NN2222 2 2 2"* E E EDDD>DDDFFF"2 S S SR'RRNRRqRRFFFFFF", # # #CFF? " " " " " " " " 0 0 0/A/// / / / / / / / / ( ( ('A''FFFFFF ( ^ # # JqMMM F?sZ!C'C*2C"FFD++FEF F'E5-F5 FF  Fdb_pathlimitctj|d}tj|_|}t jtjttz d}| d||fd| D}||S)u Fase 2 — Restituisce i record con dati OMDB presenti ma poster mancante o N/A da piu' di POSTER_RETRY_DAYS giorni. Query diretta su SQLite, indipendente da database_logic, cosi' non serve modificare MyICR Suite. r)days%Y-%m-%d %H:%M:%Sav SELECT A.id_media, A.titolo_ufficiale, A.codice_imdb FROM AnagraficaMedia A JOIN OmdbData O ON A.id_media = O.id_media_fk WHERE O.titolo_omdb IS NOT NULL AND (O.url_poster IS NULL OR O.url_poster NOT LIKE 'http%') AND (O.scaricato_il IS NULL OR O.scaricato_il < ?) ORDER BY O.scaricato_il ASC LIMIT ? c,g|]}t|S)dict).0r6s r9 z5get_prodotti_poster_da_refreshare..vs , , ,DGG , , ,)sqlite3connectRow row_factorycursorrnowrutcrPOSTER_RETRY_DAYSstrftimeexecutefetchallclose)r;r<concurcutoffrowss r9!get_prodotti_poster_da_refresharerWbs /'2 . . .CkCO **,,Cl8<((9:K+L+L+LL V VWj k kFKK  %    - ,S\\^^ , , ,DIIKKK KrFprodottidelaycdx}x}x}x}x}}g} t|} d} t|dD]\} } | d}| d}| d}tj||\}|r|dz }tj|}|rt |||nd\}}|dvr|dz }d }n9|d kr|dz }d }n+|d krd }n"|dz }d}| d|d|td| dd| d|d|dddd|d ntfd| DrAtj |||dz }td| dd| d|dddd|d nJ|dz }| |d|dtd| dd| d|dddd|d | | krtj |||||||| d S)!zOEsegue il loop di enrichment su una lista di prodotti. Restituisce i contatori.r)zerror getting datazmovie not foundzseries not foundzincorrect imdb idz not found!rid_mediar titolo_ufficialer)rrz[P]rz[!]rz z[X]zPOSTER z: z [z>4rz] OK  N2z<50 (rc3DK|]}|vVdS)N)lower)rDphrasemsgs r9 z_run_phase..s0IIV6SYY[[(IIIIIIrFz] N/F rz] ERR z) -> doneerrors not_found poster_ok poster_404 poster_err error_log) r* enumeraterimporta_e_salva_da_omdbget_poster_urlr:appendprintanymark_omdb_not_foundr2r3)rXrYr rfrgrhrirjrkrltotalnot_found_phrasesipr[r titolosuccessr stato dettaglio poster_tagrcs @r9 _run_phaser}{sFGGDG6GIG GJI MME<(A&&%%1 m & *+%=h TT   \ AID'6x@@JXbv{J TTThv E9&&Q " %a " (""" a "   !E;!E!E)!E!EFFF YYYYuYY:YYss YYY;YYY Z Z Z ZIIII7HIIIII \28[IIIQ QAQQQ5QQss QQQ;QQQRRRR!   F!C!Ck!C!Cc!C!CDDDZAZZZ5ZZss ZZZ;ZZUXZZ[[[ u99 Ju   Yj   rFc J tjd}|dtt|dtd|dt dd |d t d d |d td|dd|jt_ j rtj nt}tj}t!d|dt!djt!d|t!djdjdjdgfd}t+j|d}||dd#t!dt3jdds,t!djd t3jdjrt!d!jtj}t!d"|ddddddgd#}|dkrjr@tjjj}t!d$t=|d%netjjj}t!d&t=|d't?|j|}nt!d(tAjj}t!d)tBd*t=|ddddddgd#} |rLjr!t!d+t=|d%n$t!t?|j|} tj} tj|z "} t!d,t!d-d.d/d0d1d/t!d2|d3d/d0| d3d/t!d4|d5d/d0| d5d/t!d6|d7d/d0| d7d/t!d8|d9d/d0| d9d/t!d:|d;d/d0| d;d/t!d<|d=d/d0| d=d/t!d>| t!d?| d@dA|dB| dBz} | r&t!dC| D]} t!dD| |d3|d=z|d;z| d3z| d=z| d;z}|d=| d=z}|dEkr<||z dFkr3t!dG|dH|dI||z dJdKt3jdLdS|dkr+|d3| d3zdkrt3jdLdSdSdS)MNz$OMDB Batch Enrichment per MediaTrack) descriptionz --db-path)typedefaultz --posters-dirz --batch-sizeiz(Prodotti per fase per run (default: 500))rrhelpz--delayg@z)Secondi tra richieste OMDB (default: 5.0)z --distributorz --dry-run store_true)actionz[OMDB Batch] Avvio : r@z[OMDB Batch] DB : z[OMDB Batch] Poster : z![OMDB Batch] Param : batch_size=z, delay=z s, dry_run=cZtjd<dS)Nr)rr;r )argsresultsr9_checkzmain.._checks%d4<007799&)))rFT)targetdaemon rru:[OMDB Batch] Rete non raggiungibile (timeout 10s) — skipz[OMDB Batch] DB non trovato: u — skipz"[OMDB Batch] Filtro distributore: u/ [OMDB Batch] FASE 1 — Nuovi record in coda: rez[OMDB Batch] DRY-RUN Fase 1: z prodotti da processare.z[OMDB Batch] Batch caricato: z prodotti z![OMDB Batch] Nessun nuovo record.u0 [OMDB Batch] FASE 2 — Poster da refreshare (>zgg): z[OMDB Batch] DRY-RUN Fase 2: z [OMDB Batch] === RIEPILOGO ===zMDB Batch] zFASE 1z>8z zFASE 2zMDB Batch] Completati : rfzMDB Batch] Poster OK : rizMDB Batch] Poster 404 : rjzMDB Batch] Poster ERR : rkzMDB Batch] Non su OMDB : rhzMDB Batch] Errori OMDB : rgzMDB Batch] Rimasti F1 : zMDB Batch] Durata : z.0fsrlz [OMDB Batch] Dettaglio errori:z - g?u.[OMDB Batch] ⚠️ Tasso di errore elevato: rr_z.0%u?) — possibile problema sistemico (API key, rate limit, altro)r)#argparseArgumentParser add_argumentr/DEFAULT_DB_PATHintfloat parse_argsr;r NOME_DATABASEr rDEFAULT_POSTERS_DIRrrLrqrO batch_sizerYdry_run threadingThreadstartjoinsysexit distributorcount_prodotti_da_arricchireget_prodotti_da_arricchirer*r}rWrN total_seconds)parserr start_timert total_in_codar1rX prodotti_f2r2rimastielapsed all_errorsr8total_attempts total_errorsrrs @@r9mainrs  $1W X X XF  c?KKK c4@@@ c3GIII  eSHJJJ c4@@@  ===     D#'>BB 2333 4DL$/RRK h>O h hVYZeVfVf h hiiiqq M MBB < B \#k2B2B\\\ ] ] ] ] GGGK[AAB 9;;G|~~ *99;;G -... D D D Dx D D DEEE H6 H H HF H H HIII R; R R Rbo R R RSSS T<(8 T T Tr,?O T T TUUU T<(8 T T Tr,?O T T TUUU R; R R Rbo R R RSSS L8 L L L2h< L L LMMM 1 1 1222 6 6 6 6 6777K2k?2J 1222  A ***    Z"X,.K@2f:MPRS[P\\_abm_nnNh<"X,.L ~ = D D s|ssnss~-rsss t t t    r&zBvJ61<<    <rs. 2222222222PQQQ999999d^__B,,#,D,USVX[S[_,,,,^s34:24d4E444444nhhhV zDFFFFFrF