dimecres, 10 d’agost del 2011

Retardador de subtítols SubRip (again bis). Groovy version.

El darrer post va ser la versió BeanShell del retardador [1] [2]. No he pogut resistir-me a fer  la versió amb Groovy.


import java.text.DateFormat
import java.text.SimpleDateFormat

// els arguments estan a la variable args

// verifica que té 3 arguments
if (args.length != 3 ) {
    sUsage = "Usage:\tdelayer filein.srt fileout.srt delay" +
             "\n\texample 1: delayer filein.srt fileout.srt 10000 --> delays 10 seconds" +
             "\n\texample 2: delayer filein.srt fileout.srt -10000 --> advances 10 seconds"

    print "incorrect number of arguments"
    print(sUsage)
    System.exit(1)
}

// l'anterior també es podria fer amb CliBuilder

// calcula el delta
lDelta = Long.parseLong(args[2])

// prepara el SimpleDateFormat
sdf = new SimpleDateFormat("HH:mm:ss,SSS")

// obre els fitxers
fFileIn = new File(args[0])
fFileOut = new File(args[1])

// buffer
sFileOut = ""

fFileIn.eachLine { sLine -> 
                sTokens = sLine.split("-->")
                if (sTokens.length == 2) {
                    // si té dos elements, és la línia de temps
                              
                    // els "pela"
                    sTempsInici = sTokens[0].trim()
                    sTempsFi = sTokens[1].trim()

                    // els converteix a Date
                    dTempsInici = sdf.parse(sTempsInici)
                    dTempsFi = sdf.parse(sTempsFi)
                              
                    // Els suma el retard
                    dTempsIniciDelayed = new Date(dTempsInici.getTime() + lDelta)
                    dTempsFiDelayed = new Date(dTempsFi.getTime() + lDelta)

                    // converteix els Date a String amb el mateix SimpleDateFormat
                    sTempsIniciDelayed = sdf.format(dTempsIniciDelayed)
                    sTempsFiDelayed = sdf.format(dTempsFiDelayed)

                    // Munta la línia
                    sLine = "${sTempsIniciDelayed} --> ${sTempsFiDelayed}"
    }
               
    sFileOut += "${sLine}\r\n"
}
// escriu el buffer
fFileOut.write(sFileOut)

// no hi ha close . L'objecte File no en té. ni li cal.

// acaba aquí


La versió en Groovy té un aspecte sensiblement diferent de la versió BeanShell. Ara bé, cal dir que per a escriure el codi Groovy he parti del codi BeanShell, que, excepte per la presa d'arguments l'intèrpret Groovy l'ha agafat sense cap més queixa. Diguem que amb el BeanShell ja tenia el 99% del Groovy fet. Per la seva banda, el BeanShell era, pràcticament, Java.

Però, és clar, el codi resultant no tenia l'aspecte d'un script Groovy.  Així que vaig començar a modificar-lo per a seguir un estil de codificació més Groovy.

Primer de tot, el tractament dels arguments és més senzill que amb BeanShell, doncs args ésdisponible directament. Com amb la vesió Python, hauria pogut utilitzar un mòdul per a tractar els arguments de la línia de comandes, el CliBuilder, però ho deixo per a una altre ocasió.

Observar que no he fet servir ";" .

Importació de llibreries Java i ús de SimpleDateFormat per a fer el parseig de ñes cadenes i el formateig dels dates, com amb BeanShell.

Simplificació de la lectura i escriptura dels fitxers amb l'objecte Groovy File. Aquest objecte NO és l'objecte Java File. File de Groovy simplifica el tractament dels fitxers. Fixem-nos com n'hi ha prou amb obrir el fitxer per nom i després, fent us d'una closure,  llegeix línia per línia el fitxer. M'he estalviat els BufferedReader.

Per a cada línia fa el mateix tractament  que amb l'script BeanShell però, en comptes d'escriure línia a línia, el que fa és construir una cadena sFile, un buffer, amb tota la informació del fitxer. En comptes de fer servir l'operador '+' per a concatenar, opta per una solució més Groovyana:

sLine = "${sTempsIniciDelayed} --> ${sTempsFiDelayed}"

Un cop processades totes les línies, escriu el buffer de cop, amb el mètode write de l'objecte File.

És evident la simplificació comparant amb BeanShell, o que l'equivalent amb Java. M'atreviria a dir que, fins i tot, és més simplificat que amb Python.

Però tampoc aniré més enllà. Es tracta d'un script molt senzill i no seria correcte treure'n conclusions sobre la potència dels tres llenguatges. Segur que en totes tres versions, Python, BeanShell, Groovy es podrien buscar simplificacions addicionals. I en tot cas, a l'hora de triar una solució o altre, hi han factors que poden ser molt més determinants que la potència del llenguatge: disponibilitat d'entorns de desenvolupament, coneixements i experiència dels programadors...

Prenguem, doncs, aquest script d'avui només com un petit tast d'un altre aroma del cafè: Groovy, un altre llenguatge per a la JVM.

Cap comentari:

Publica un comentari a l'entrada