/* SageTV Plugin Repository Mirror Last Modified: 12 Jul 2011 Author: Derek Battams Use this script to mirror all plugins hosted on SageTV's HTTP server. The script will also generate a new 'repo.xml' file in the root directory of the mirror (i.e. in the root of localOutput defined below). This script only copies and mirrors files hosted by SageTV. It also only downloads files which do not exist locally or whose MD5 checksums have changed. Therefore, it is safe to run this script periodically and automatically, perhaps via the SJQv4 crontab. */ import org.apache.commons.codec.digest.DigestUtils import groovy.xml.XmlUtil def TEST_MODE = false // The master plugins XML file // def url = 'http://127.0.0.1:8000/SageTVPlugins.xml' def url = 'http://download.sage.tv/SageTVPlugins.xml' // Root directory where we're going to mirror the plugins //def localOutput = new File('S:\\SageTV\\SageTV\\Plugins\\Repository') def localOutput = new File('S:\\SageTV\\Repository\\Plugins') // Links matching this regex will be mirrored // def regex = /^http:\/\/download.sage/ def regex = /.*/ // Replace the mirrored links with this prefix // Mongoose Webserver located in S:\SageTV def targetUrl = 'http://127.0.0.1:8000/Repository/Plugins' def xml = new URL(url).getText('UTF-8') def plugins = new XmlSlurper().parseText(xml) def count = 0 plugins.SageTVPlugin.findAll { it.Package.findAll { it.Location.text() =~ regex }.size() > 0 }.each { plugin -> println "ID: $plugin.Identifier" plugin.Package.findAll { it.Location.text() =~ regex }.each { println "\tLocation: $it.Location" def localFile = new File(new File(localOutput, plugin.Identifier.text()), it.Location.text().substring(it.Location.text().lastIndexOf('/'))) if(!localFile.getName().toLowerCase().endsWith('.zip')) { println '\tWARNING: File name appears to be a redirect link!' localFile = new File(new File(localOutput, plugin.Identifier.text()), "${DigestUtils.md5Hex(localFile.getName())}.zip") } println "\tDownload: $localFile" def localStream = null println "\tMD5: $it.MD5" if(!TEST_MODE && (!localFile.exists() || DigestUtils.md5Hex((localStream = new FileInputStream(localFile))).toLowerCase() != it.MD5.text().toLowerCase())) { print '\tDownloading... ' localFile.getParentFile().mkdirs() def start = System.currentTimeMillis() def target = new FileOutputStream(localFile) try { def src = new URL(it.Location.text()).openStream() target << src src.close() println "DONE [${System.currentTimeMillis() - start}ms]" it.Location = "$targetUrl/${plugin.Identifier.text()}/${localFile.getName()}" ++count } catch(IOException e) { println 'FAILED (IOException)' } target.close() } else println '\tLatest version already downloaded!' it.Location = "$targetUrl/${plugin.Identifier.text()}/${localFile.getName()}" if(localStream) localStream.close() } } println "$count file(s) downloaded" new File(localOutput, 'REPO_SageTVPlugins.xml').write(XmlUtil.serialize(plugins))