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)
}
}