[Python] Traduttore automatico di sottotitoli

La mia smodata passione per le serie tv made in USA mi ha iniziato al binge watching molto prima che ne venisse coniato il termine per diventare una moda. Ricordo ancora il week end di una decina di anni fa, passato a ‘recuperare’ su internet gli episodi delle prime tre stagioni di «Battlestar Galactica» poco prima della trasmissione in America della quarta stagione. Di lì ho scoperto che non mi piaceva attendere qualche anno prima di poter guardare una serie tv che mi interessava e che internet da questo punto di vista era una notevole risorsa se si era disposti ad abituare l’occhio a non perdersi nessuna scena sbirciando contemporaneamente i sottotitoli sullo schermo (ancora tante grazie Italiansubs!).


Ora che i sottotitoli in italiano si fa più fatica a trovarli, un po’ per gioco e un po’ per utilità, ho pensato di creare uno script in Python che traduce un file di sottotitoli in inglese nel corrispettivo in italiano utilizzando la libreria googletrans (link) che sfrutta l’API di Google Translate. Il risultato non sarà dei più corretti ma IMHO abbastanza accettabile per godersi un episodio della propria serie tv preferita.


Ingredienti:

    • python 3
    • libreria googletrans (per la traduzione)
    • librerie sys, os (per la gestione dei file)
    • libreria timeit (per computare le prestazioni)

Per installare la libreria avendo a disposizione l’utility PIP è sufficiente digitare il seguente comando:

pip install googletrans

Analizziamo le parti principali del sorgente:

Innanzitutto importiamo le librerie che ci necessitano:

import sys, os
from googletrans import Translator
from timeit import default_timer as timer

Memorizziamo in una variabile il tempo iniziale che ci servirà per calcolare successivamente le prestazioni dello script:

start = timer()

E inizializziamo il traduttore sull’API pubblica di Google Translate:

translator = Translator(service_urls=[
      'translate.google.com',
      'translate.google.it',
    ])

Il progetto prevede di dare in pasto al traduttore le frasi contenute in un file in formato .srt contenente i sottotitoli in inglese, strutturalmente fatto in questo modo:

Per quanto riguarda il nome del file da tradurre lo passeremo come argomento nell’istruzione di esecuzione del programma. Il nome del file prodotto con i sottotitoli tradotti in italiano sarà generato conseguentemente aggiungendo il suffisso “_tradotto”. Viene anche controllata l’esistenza di un eventuale precedente file di traduzione avente lo stesso nome di quello in produzione e nel caso verrà cancellato.

try:
sourcefile = sys.argv[1]
resultfile = sys.argv[1].replace('.srt', '')+'_tradotto.srt'
except:
sourcefile = "sottotitolo.srt"
resultfile = sourcefile.replace('.srt', '')+'_tradotto.srt'

if os.path.isfile(resultfile) == True:
os.remove(resultfile)

Nessun problema ad aprire il file in questione e scomporre le righe di testo in elementi di una lista. Inoltre già che ci siamo cancelliamo gli eventuali inutili spazi vuoti in testa e in coda a ciascuna riga con il metodo strip():

with open(sourcefile) as f:
    content = f.readlines()
content = [x.strip() for x in content]

Ovviamente al nostro traduttore dovremo passare ‘solo’ i testi e non gli altri elementi utili alla renderizzazione a video dei sottotitoli. Inoltre al traduttore dobbiamo passare delle frasi intere, anche se nel file dovessero risultare ‘spezzate’ su più righe.

Processiamo ciascuna riga della lista creata e scartiamo quelle righe (senza eliminarle perché ci occorreranno poi per scrivere correttamente il file .srt dei sottotitoli tradotti) contenenti un numero intero (cioè il numero del sottotitolo) piuttosto che la durata del sottotitolo (che Python vede comunque come una stringa di testo da qui la trovata di pulire la riga dal segno di separazione (“:”) e di considerarne solo i primi 5 caratteri, in modo che ad esempio la riga “00:00:03,886 –> 00:00:07,961” venga computata come “00000” che Python riconosce giustamente come numero e quindi ce la fa scartare:

for item in content:
    count += 1
    if item.isdigit() == False:
        try:
            control = item.replace(":","")
            part = control[0:4].isdigit()
        except:
            part = False

Per risolvere il problema delle frasi spezzate su più righe come abbiamo ad esempio in questo caso:

Dove per ottenere una traduzione corretta occorre passare al traduttore una corretta frase interaBut you won’t fix the real problem” e non due righe separate come si presentano nel file. Si andrà quindi a tradurre quanto memorizzato in una lista ‘volatile’ solo dopo aver incontrato un salto di riga vuoto come questo:

Di seguito la mia soluzione che memorizza il testo da tradurre nella stringa “datradurre” che viene passata al traduttore istanziando l’oggetto translations da cui ricaviamo il testo tradotto quando la variabile trigger ‘accio’ processa una riga vuota. Ovviamente occorre tenere conto che sebbene al traduttore la frase di due righe verrà fornita in una riga sola, al momento della ricostruzione del sottotitolo tradotto la frase dovrà essere nuovamente divisa se troppo lunga per non perdere in leggibilità del sottotitolo: la frase sarà ‘spezzata in due righe dovesse essere composta da più di 5 parole e comunque da più di 40 caratteri (esclusi i segni ‘speciali di renderizzazione). Dopo aver passato la stringa al traduttore questa viene azzerata, pronta per le righe successive. Il tutto viene memorizzato in una lista denominata ‘traduzione’ a cui si aggiungeranno man mano tutte le righe processate, comprendenti il numero del sottotitolo, i tempi di inizio e fine visualizzazione e la traduzione ottenuta (o il testo originale se il programma non è riuscito a tradurre).

       if part != True:
            datradurre = datradurre +' '+item
            datrad_non.append(datradurre)
            accio = ("_______"+str(item)+"________________>")
            if accio == "_______________________>":
                try:
                    translations = translator.translate(datradurre, src='en', dest='it')
                    trad = translations.text
                    parole = 0
                    a = trad.split(" ")
                    for i in a:
                        if (i!=" " and i!="<i>" and i!="</" and i!="i>" and i!="-" and i!="..."):
                            parole=parole+1
                    if parole >5 and len(trad) >40:
                        frase = range(6,parole)
                        primariga = str(a[0])+' '+str(a[1])+' '+str(a[2])+' '+str(a[3])+' '+str(a[4])+' '+str(a[5])
                        secondariga = ''
                        for x in frase:
                            secondariga = secondariga+' '+str(a[x])
                        traduzione.append(primariga)
                        traduzione.append(secondariga[1:])
                        traduzione.append(item)
                        TRcount += 1
                    else:
                        traduzione.append(trad)
                        traduzione.append(item)
                        TRcount += 1
                except:
                    for x in datrad_non:
                        traduzione.append(x)
                    traduzione.append(item)
                    NOcount += 1
                datradurre = ""
                datrad_non.clear()
        else:
            traduzione.append(item)

Dopo aver processato tutte le righe si può procedere a generare scrivendo riga per riga il file .srt con i sottotitoli tradotti:

with open(resultfile, 'a') as f:
    for item in traduzione:
        f.write(item+'\n')

Possiamo calcolare a questo punto il tempo di esecuzione in secondi del programma:

end = timer()
tempo = "{0:.2f}".format((end - start))

E infine visualizzare le statistiche raccolte con i vari contatori alimentati durante il processo di traduzione:

print('\n')
print ('Totale righe _________ '+str(count))
print ('Totale traduzioni ____ '+str(TRcount))
print ('Problemi traduzioni __ '+str(NOcount))
print ('Totale tempo _________ '+tempo+'s')
print('\n')

Non sarà lo script meglio scritto, ma in un tempo ragionevole (circa 300 secondi per processare un episodio di tre quarti d’ora) riesce a sfornare dei sottotitoli in italiano discretamente accettabili.

Codice sorgente completo disponibile su GITHUB (link).

[RISOLTO] Il mistero di Windows 10 in bianco e nero

L’altro giorno  mi è stato riferito che un utente dell’ufficio da qualche ora si trovava a lavorare davanti ad una schermata grigia. I due monitor collegati al computer davano lo stesso problema che non erano riusciti a risolvere né muovendo i cavi né agendo sulle impostazioni della scheda video.

Mi sono allora ricordato che Windows 10 ha tutta una serie di ‘filtri colore‘ creati appositamente per migliorare l’esperienza di utilizzo alle persone affette da patologie visive come il daltonismo. Tali impostazioni seguono una sensibilità degli sviluppatori software degli ultimi anni: in alcuni giochi soprattutto FPS attraverso filtri per le diverse patologie di visione si cerca di ampliare la platea di giocatori.

Su Windows 10 il relativo pannello si trova in Impostazioni > Colore e contrasto elevato e ho scoperto che il filtro in scala di grigi si può attivare anche premendo la combinazione di tasti WIN+CTRL+C. Esistono diversi filtri, dalla semplice scala di grigi, anche invertita, inversione dei colori, fino alle diverse combinazioni di colore in grado di favorire la visione per le persone affette dai diversi tipi di daltonismo (deuteronopia, protanopia, tritanopia).

L’utente in questione, molto probabilmente accidentalmente, ha premuto la suddetta combinazione di tasti e voilà svelato il mistero di Windows 10 in bianco e nero.

Riassunto istruzioni: Continua a leggere

[Tutorial – Linux] Alla scoperta di Conky (Configurazione delle opzioni generali)

Nello scorso post vi ho presentato Conky, spiegato come installarlo, inoltre vi ho fornito copia del mio file .conkyrc e spiegato come iniziare con questo meraviglioso creatore di widget, utile strumento per monitorare le risorse del proprio sistema direttamente sul desktop.istantanea_2017-01-26_17-07-03

Adesso è il momento di fare sul serio.

Nei prossimi post cercherò di spiegarvi in dettaglio i segreti del file di configurazione in modo che possiate sfruttare appieno le potenzialità di Conky che, come ho già precisato, fa della personalizzazione il suo principale punto di forza che lo contraddistingue dalla concorrenza.

Superate le prime difficoltà per comprendere le logiche che stanno dietro al file di configurazione è possibile ‘costruirsi‘ il proprio widget, secondo le proprie esigenze tecniche e artistiche.

Per iniziare la nostra piccola guida do per scontato che abbiate seguito le istruzioni di installazione e avvio del precedente post e che siate quindi pronti per configurare il vostro file .conkyrc
Prenderemo spunto dalla mia configurazione solo per semplificare la spiegazione e non perdere il filo.

Se avete già dato una scorsa oppure no al file completo (che potete scaricare da qui) vi sarete accorti che è possibile suddividerlo in tre blocchi logici:

  1. intestazione ed eventuale licenza (commentato con il carattere # e quindi non interpretato come istruzione);
  2. impostazioni e controlli per la visualizzazione del widget;
  3. istruzioni per la visualizzazione delle informazioni.
I primi due punti sono separati dal terzo dalla riga:
TEXT
In questo post analizzeremo in dettaglio i primi due punti.

Di seguito vi rimetto la parte di configurazione da me realizzata con la spiegazione dei singoli valori utilizzati:

###################################################
#  BY ZIRCONET - 2017                             #
#  Questa configurazione richiede l'installazione #
#  dei font ROBOTO e ANONYMOUS                    #
###################################################

#Conky parte di default in background?
background yes

# Intervallo di aggiornamento (in secondi)
update_interval 1

# Abilitazione double buffering per evitare lo sfarfallio
double_buffer yes

# ------ fonts ------
use_xft yes                  # usa Xft (anti-aliased font)?
xftfont roboto:size=9        # set di font da utilizzare
xftalpha 1                   # controllo trasparenza

# ------ proprietà finestra ------ 
own_window yes               # crea una propria finestra
own_window_type desktop      # tipo della finestra 
own_window_transparent yes   # controllo trasparenza
own_window_argb_visual yes   # trasparenza reale
own_window_argb_value 0      # controllo opacità [0-255]
alignment top_right          # Allineamento widget

#controlli migliorativi della finestra 
own_window_hints undecorated,below,sticky      
own_window_hints skip_taskbar,skip_pager

# ------ dimensioni ------
maximum_width 300            # larghezza massima
minimum_size 5 5             # misura minima della finestra

# ------ colori ------ 
default_color white
default_shade_color white
default_outline_color white 
 
# ------ bordi ------ 
draw_borders 0          # Disegna bordi?
border_margin 0         # margini dei bordi
border_width 0          # larghezza bordi
draw_shades no          # Disegna ombre?
draw_outline no         # Disegna bordi attorno al testo?
draw_graph_borders yes  # Disegna bordi attorno a grafici?

# Distanza tra i bordi e il testo 
gap_x 10                # distanza asse x
gap_y 10                # distanza asse y
  
# ------ altri controlli ------ 
no_buffers yes          # controllo per calcolo uso ram
show_graph_scale yes    # mostra valori nei grafici
show_graph_range no     # mostra i minuti nei grafici
cpu_avg_samples 3       # numero dei samples per calcolo media
net_avg_samples 3       # numero dei samples per calcolo media
max_text_width 0        # controllo linea a capo
out_to_console no       # controllo output in console

I controlli che ho utilizzato sono ovviamente quelli che mi occorrevano per utilizzare il mio progetto: il mio consiglio è quello di smanettare il più possibile per trovare infine ciò che più fa al caso vostro.

Alcuni controlli si spiegano da sé, per tutti ho cercato di mettergli accanto un breve commento esplicativo.

Per chi volesse una spiegazione più specifica oppure vuole una panoramica più esaustiva può fare riferimento alla pagina ufficiale che trovate qui.

[Tutorial – Linux] Alla scoperta di Conky

Conky è un programma utile per monitorare le risorse del proprio sistema direttamente sul desktop. Si tratta di un progetto free software, fork di Torsmo che a differenza del suo progenitore sembra ben mantenuto dai suoi creatori. Tutte le informazioni possibili e immaginabili sono disponibili sulla relativa pagina di Github.conkylogosmall

Sebbene non richieda molte risorse è comunque un potente strumento con il quale creare widget per tenere sotto controllo diversi parametri (carico della CPU, utilizzo della ram e della memoria swap, uso dello spazio su disco, monitor temperature, monitor processi in esecuzione, controllo flusso upload/download, controllo messaggi di sistema, ecc…) e molto altro ancora anche attraverso l’utilizzo di script esterni al programma. I creatori di Conky affermano che sono disponibili almeno 300 oggetti nativi con i quali sbizzarrirsi nonché la piena compatibilità con Lua e altri programmi di script.

L’unica difficoltà è compilare secondo le proprie esigenze il file di configurazione, ma va detto pure che è proprio l’alta configurabilità il suo principale pregio. Per i meno smaliziati e pigri sono comunque facilmente reperibili in rete una miriade di configurazioni pre-à-porter che richiedono magari solo piccoli aggiustamenti per girare correttamente sul proprio sistema.

Dopo una lunga sessione di smanettamenti vari ecco come si presenta ora il mio desktop:istantanea_2017-01-25_22-55-27

istantanea_2017-01-25_23-11-34

Sebbene il limite all’aspetto grafico e limitato solo dall’immaginazione, personalmente ho voluto mantenere per il mio widget un profilo piuttosto classico.

Adesso direttamente sul mio desktop posso avere una visione di insieme in real-time di tutto quello che sta facendo il mio computer e in dettaglio:

– la versione del sistema e l’uptime;
– il carico della CPU con relativi grafici;
– l’utilizzo della RAM con relativi grafici;
– l’utilizzo della memoria SWAP;
– i carichi di sistema;
– i processi caricati e in esecuzione;
– il monitor temperature sistema;
– il controllo della connettività Wireless;
– il controllo del download/upload rete;
– il monitor del File system;
– il monitor utilizzo disco con grafici;
– l’elenco dei principali processi in esecuzione;
– l’elenco dei file presenti nel device di storage.

Avrei potuto continuare, ma alla fine mi sono accontentato… (qui il link per scaricare la mia configurazione).


Installazione & Configurazione base

  • Innanzitutto installiamo Conky:
    Per sistemi Ubuntu/Debian procediamo con il seguente comando:

    $ sudo apt-get install conky-all 
  • Creiamo il file di configurazione nella cartella home/utente con il seguente comando:
    $ nano ~/.conkyrc 
  • Adesso è il momento di editare il file di configurazione:
    • prendendo spunto dagli esempi reperibili sul sito homeproject-screenshot;
    • oppure utilizzando come base la configurazione di default presente in /etc/conky/conky.conf dando il seguente comando:
      $ cp /etc/conky/conky.conf ~/.conkyrc

    Avvio automatico di Conky

  • Creiamo lo script per l’avvio allo startup:
    • digitiamo il seguente comando:
      $ sudo gedit /opt/conky-start 
    • lo script sarà composto dalle seguenti tre righe, quindi salviamo:
      #!/bin/sh
      sleep 20 && conky -c ~/.conky/conkyrc
      exit 
  • Rendiamo eseguibile lo script appena creato con il seguente comando:
    $ sudo chmod +x /opt/conky-start
  • istantanea_2017-01-26_00-41-14Per dire al nostro sistema di avviare l’eseguibile all’avvio per farlo basta andare in Sistema ->Preferenze ->Applicazioni d’Avvio ->Aggiungi e qui inseriamo:
    • su Nome:
                conky-start
    • su Commento:
               avvio di conky
    • su Comando:
              /opt/conky-start

    Infine clicchiamo su OK e al riavvio avremo (dopo 20 secondi circa) il nostro Conky avviato.



Magari nel prossimo post analizzeremo in dettaglio come procedere con la customizzazione della configurazione di Conky.

[Guida] Come eliminare le inutili app preinstallate in Windows 10

Avete installato con successo la vostra copia di Windows 10 e vi siete accorti che la Microsoft ha pensato bene di regalarvi tutta una serie di app inutili che non utilizzerete mai e occupano solo spazio che giustamente vorrete utilizzare per installare le app che vi fanno più comodo.

Rispetto a tutte le altre app queste richiedono una procedura diversa per essere disinstallate.

Windows_10_-_screenshot

Ecco le istruzioni per sbarazzarvi delle inutili app preinstallate in Windows 10.

Quello che dovrete fare è:

  • Ricercate nella casella di ricerca il programma Windows PowerShell;
  • Cliccare con il tasto destro sulla voce così individuata quindi scegliere “Esegui come amministratore“;
  • Copiare ed incollare le stringhe di comando (cmdlets) sottostanti nel PowerShell (*), a seconda dell’app che volete disinstallare;
  • Per confermare il comando di disinstallazione premete Invio.

Xbox:

Get-AppxPackage *xbox* | Remove-AppxPackage

Registratore:

Get-AppxPackage *soundrec* | Remove-AppxPackage

Solitaire Collection:

Get-AppxPackage *solit* | Remove-AppxPackage

Foto:

Get-AppxPackage *photo* | Remove-AppxPackage

Connessione guidata telefono:

Get-AppxPackage *phone* | Remove-AppxPackage

Groove Music, Film e programmi TV:

Get-AppxPackage *zune* | Remove-AppxPackage

Contatti:

Get-AppxPackage *people* | Remove-AppxPackage

Meteo, Sport e Money:

Get-AppxPackage *bing* | Remove-AppxPackage

Posta e Calendario:

Get-AppxPackage *communi* | Remove-AppxPackage

3D Builder:

Get-AppxPackage *3d* | Remove-AppxPackage

Fotocamera:

Get-AppxPackage *camera* | Remove-AppxPackage

OneNote:

Get-AppxPackage *OneNote* | Remove-AppxPackage

Come reinstallare le app Windows 10 eliminate

Allo stesso modo, sempre servendosi dell’interfaccia Powershell, è in qualunque momento possibile reinstallare in blocco  tutte le app predefinite di Windows 10 eliminate in precedenza.

Utilizzando la combinazione di tasti Windows+X quindi selezionando Prompt dei comandi (amministratore), si dovrà digitare powershell ed infine il comando seguente:

Get-AppxPackage -AllUsers, Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}

[Risolto] Opensuse – “Btrfs Error: No space is left on device”

OpenSUSElogo

Uno dei pochi problemi che ho riscontrato utilizzando la distro di Opensuse è quella di vedere lo spazio del sistema aumentare enormemente fino a quando saturare il device, rendendolo praticamente inutilizzabile, fino ad arrivare all’errore “Btrfs Error: No space is left on device”.

Guardando in giro sono venuto a conoscenza che gran parte del problema è dovuto a Snapper, il software (inclusa dalla versione 12.1 in avanti) che si occupa di gestire le istantanee di sistema (snapshot) del file system btrfs. Uno strumento molto comodo che funziona po’ come per i punti di ripristino di Windows.

snapper_03

Prima e dopo l’esecuzione di un modulo di YaST o zypper, viene creato uno snapshot. Snapper permette di confrontare le due istantanee e fornisce i mezzi per annullare le differenze tra le due istantanee. Esiste inoltre la possibilità di effettuare backup di sistema con la creazione di snapshots orari dei sottovolumi di sistema.

Il lato negativo è che questi snapshot occupano un sacco di spazio. Quindi per recuperare spazio occorre fare ogni tanto una pulizia.

Un problema da considerare è che Continua a leggere

[Risolto] EXCEL: Come calcolare il numero di mesi tra due date

Problema: in un foglio di lavoro contenente due date occorre ottenere il valore dell’intervallo espresso in mesi.

– nel caso l’intervallo tra le date sia inferiore all’anno è sufficiente procedere con la semplice differenza del contenuto delle due celle formattandole con la funzione MESI();

– purtroppo a differenza del calcolo in giorni, il programma Excel non è in grado di computare correttamente i mesi quando le date appartengono ad anni diversi e quindi occorre utilizzare qualche “trucchetto“. Occorre quindi procedere con una formula in cui faremo fare dapprima la differenza degli anni usando la funzione ANNO(), quindi moltiplicando il risultato per 12 per il computo in mesi e infine aggiungendo questo risultato alla differenza dei mesi usando la funzione MESE().

excel

%d blogger hanno fatto clic su Mi Piace per questo: