krkr
11/10/2011 - 7:13 AM

Canal+ VOD Groovy

Canal+ VOD Groovy

#!/usr/bin/groovy
/**
 * \o/ Canal+ VOD 4 Linux \o/
 *
 * @date 06/11/2011
 * @version 1.0
 * @author thb
 */

import static Constants.*

askSearch()

class Constants {
	static final downloadDir = "~/.zapcache"
	static final tempFile = "~/.zap.tmp"
	static final restSearchAPIUrl = "http://webservice.canal-plus.com/rest/bigplayer/search/"
	static final keyWords = [0:"Zapping", 1:"Guignols", 2:"Petit Journal", 3:"Grand Journal", 4:"Groland", 5:"SAV"]
	static final max = 10
}

def askSearch() {
	println "\n -- New Search -- "
	for ( k in keyWords ) {
	    println " * [" + k.key + "]" + " " + k.value
	}

	keyWord = eatLine(askSomething("> Enter a num or a word: "), keyWords)
	if (keyWord != null) {
		videos = getRemoteVideos(keyWord)
		if (videos.isEmpty()) {
			println "0 result :-("
			askSearch()
		}
		videos = videos.grep{ it.id < Math.min(max, videos.size()) }
		askWhatToPlay(videos)
	}
}

def askChooseLocalVideos(videos) {
	println "\n -- Videos already downloaded -- "

        for ( v in videos) { 
		v.displayInList()
        }
	video = eatLine(askSomething("> Enter a num: "), videos)
	if (video instanceof Video) {
		play(video	)
	} else {
		println "Invalid num"
		askChooseLocalVideos(videos)
	}
	return null
}

def askWhatToPlay(videos) {
	println "\n -- Videos found --"
	for ( v in videos) { 
		v.displayInList()
        }
	video = eatLine(askSomething("> Enter a num: "), videos)
	if (video instanceof Video) {
		play(video)
	} else {
		println "Invalid num"
		askWhatToPlay(videos)
	}
	return null
}

def eatLine (line, list) {
	if (line.equals("l")) {

		map = getLocalVideos()
		videos = []
		map.findAll{ true }.each{videos << it?.value}	
		askChooseLocalVideos(videos)
	} else if (line.equals("s")) {
		askSearch()
	} else if (line.equals("q")) {
		System.exit(1)
	} else if (line.isNumber() && line.toInteger() < list.size()) {
		return list[line.toInteger()]
	} else {
		return line
	}
}

def askSomething(question) {
	println "[s] search ? [l] list old videos [q] quit"
	return System.console().readLine(question)
}


def getRemoteVideos(keyWord) {
        new File(downloadDir).mkdir()

	file = new File(tempFile)
	try {
	    def url = new URL(restSearchAPIUrl + keyWord)
	    input = url.openStream()
	    output = new BufferedOutputStream(new FileOutputStream(tempFile))
	    output << input
	} finally {
		input?.close()
		output?.close()
	}

	localVideos = getLocalVideos()
	videos = new ArrayList()
	new XmlSlurper().parse(new File(tempFile)).VIDEO.each { v->
		title = v.INFOS.TITRAGE.TITRE.text()
		idCanal = v.ID.text()
		status = (localVideos.find{ it.value.idCanal == idCanal} != null) ? "already" : "new"
		date = v.INFOS.PUBLICATION.DATE.text()
		url = v.MEDIA.VIDEOS.HAUT_DEBIT.text()
		date = new Date().parse("dd/mm/yyyy", date).format("yyyy/mm/dd")
		videos.add(new Video(id: 0,idCanal: idCanal, title: title, date: date, status: status, url: url))
	}
	file.delete()
	i = 0	
	videos = videos.findAll{ it.title.contains(keyWord) }
	Collections.reverse(videos.sort{ it.date }) 
	for ( v in videos ) v.id = i++
	return videos
}

def getLocalVideos() {
        listExist = new HashMap()
	i = 0
	new File(downloadDir).eachFile() { filename ->
		url = filename
		// FIXME 
		idCanal = (filename =~ /.*\//).replaceAll("")
		idCanal = (idCanal =~ /&.*/).replaceAll("")
		title = (filename =~ /.*&/).replaceAll("")
		title = (title =~ /@.*/).replaceAll("")
		date = (filename =~ /.*@/).replaceAll("")
		date = (date =~ /.flv/).replaceAll("")
		date = date.replace('-', '/')
		listExist.put(i, new Video(id: i,idCanal: idCanal, title: title, date: date, status: "already", url: url))
		i++
        }
        return listExist
}

def play(video) {
	filename = downloadDir + "/" + video.getFilename() + ".flv"
	println video.status
	if (video.status.equals("new")) stream(video.url, filename)
	println "Play      ... " + filename
	("mplayer " + filename).execute().waitFor()
}

def stream(url, filename) {
	println "Download  ... " + filename
	println "From      ... " + url
	("flvstreamer -q -e -r " + url.replace(' ', '%20') + " -o " + filename).execute()
	"sleep 3".execute().waitFor()
}

class Video {
	int id
	String idCanal
	String title
	String date
	String status
	String url

	String getFilename() {
		def str = idCanal + "&" + title + "@" + date
		return str.replace(' ', '_').replace('/', '-')
	}

	String displayInList() {
		if (date == null)
			println " * [" + id + "] " + title
		else
			println " * [" + id + "] " +  date + " " + title + " " + "["+ status + "]"
	}

	boolean equals(video) {
		return idCanal.equals(video.idCanal)
	}
}