Groovy > Youtube-felhasználó feltöltéseinek listázása

Azért ez a Groovy ijesztő tud lenni. Ijesztően egyszerű.

[code]
def u = 'HungarianDemocrat'
def f = new URL('http://gdata.youtube.com/feeds/api/users/'+u+'/uploads').getText('UTF-8')

def XmlParser_yt = new XmlParser().parseText(f)

XmlParser_yt.entry.each {

println it.title.text()
def arraylist = it.link.findAll {
it."@rel".contains('alternate')}

url = arraylist["@href"][0]

def command = 'python youtube-dl -t ' + url
def proc = command.execute()
proc.waitFor()

println "return code: ${ proc.exitValue()}"
println "stderr: ${proc.err.text}"
println "stdout: ${proc.in.text}"

}

[/code]

Szorgalmi feladatként a lapozást meg lehetne oldani, mert ez a megoldás csak az első 25 bejegyzést jeleníti meg. (Hint: link elem next attribútum rel értékkel)

Tehát jól nézne ki, ha a következőképp lehetne leszedni a videókat. Na persze, azóta már nem elérhetőek a videók. :D


for( page in yt_useruploads(user)){
     page.downloadAll()
}

Ahhoz, hogy ez működjön a yt_useruploads objektumpéldánynak implementálni kell az iterator() metódust, ami egy bejárót ad vissza. A bejárónak három metódust kell megvalósítani: a hasNext(), next() és remove() metódust. Egy ilyen bejárót az AbstractList egy belső privát osztályban valósít meg. Mivel Groovyban szkriptelünk, így ez a lehetőség nem elérhető.
Az iterator metódus objektumgyártóként funkcionál, így lehetne statikus is, de mivel az iterator metódusa paraméter nélküli, így nem tudjuk átadni neki a kezdő URL-t, kénytelenek vagyunk az osztályváltozóból kiolvasni, így bukva a statikusságot. Kurzorként az aktuális oldal URL-jét használjuk. Emellett eltároljuk osztályváltozóként azt az XmlReader példányt, amire a kurzor URL mutat, ez az actual.
A hasNext() első hívásánál az actual még nincs feltöltve, ezt kihasználva a kurzorban található URL-t lehívjuk, hogy van-e benne videó. Ha nincs, hamisat dobunk vissza. A lehívott URL mögötti XmlReader példányt eltároljuk későbbi használatra.
A next() metódus az actual-ból dolgozik. Kiszedi a következő lapra mutató linket, ezzel felülírja a kurzort majd visszaadja az actualt. Ha nincs következő link, a kurzor null-t kap és a hasNext() hamisat ad vissza.


class YTerator implements Iterator{
    
    def private actual    // XmlParser instance
    def private cursorURL // URL pointing to actual page
    
    def YTerator(startURL){
        this.cursorURL = startURL
    }
    def URLtoParser(url){
        new XmlParser().parseText(new URL(url).getText())
    }
    def boolean hasNext(){
        println '[+] hasNext'
        
        if (cursorURL == null) return false
        if (actual == null)     return true
        
        def arraylist = actual.link.findAll {
            it."@rel".contains('next')
        }	
        arraylist[0]==null?false:true
    }
    def next(){
        println '[+] next' 
        println ' +-- ' + cursorURL
        
        actual = URLtoParser(cursorURL)
        def arraylist = actual.link.findAll {
                    it."@rel".contains('next')
        }
        def newcursor =  arraylist["@href"][0]

        // stepping cursor
        cursorURL = newcursor
        actual
    }
    def void remove(){
    }
    def iterator(){
        new YTerator(cursorURL)
    }
}
/*** Usage ***/

def u = 'RamboZsolt'
def url = 'http://gdata.youtube.com/feeds/api/users/'+u+'/uploads'

println "[!] classic for Java operator"
for( XmlParser page :  new YTerator(url) ) {

    println "classic"
}
println "[!] groovy each"
new YTerator(url).each {

    println "each"
}
println "[!] groovy for..in operator"
for( page in new YTerator(url) ) {

    println "in"
}

Na, miután megvan a bejárónk, úgy találjuk, hogy nem az összes videót akarjuk letölteni, szeretnénk szűrni leírás alapján vagy cím alapján.



entry.grep { it.title.contains('hupikék törpikék') }

Ahol a kapcsos zárójel közötti rész egy klozúra(closure). Azt kell majd lenyomni szűrőként az iterator mélyére.

Infok:
[1] XML feldolgozás Groovyval, http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlParser
[2] Youtube feed protokoll a felhasználó feltöltéseinek lekérdezésére, http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html#…
[3] Youtube-video letöltő szkript Pythonban, https://github.com/rg3/youtube-dl/raw/2010.12.09/youtube-dl
[4] Külső program meghívása, http://groovy.codehaus.org/Executing+External+Processes+From+Groovy

Hozzászólások

durva, tenyleg, megtud egy kulso programot hivni, es xmlt parsolni. omg :)