From: Jan-Pascal van Best Date: Wed, 21 Mar 2012 08:21:46 +0000 (+0100) Subject: Moved whole project up one level X-Git-Tag: 0.5~4 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=2c1662e812ab31c916e21394fe98ead2d7fe6981;p=tv_grab_nl_java Moved whole project up one level --- diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..6c7804f --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1293e4d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/test.xml +/target diff --git a/.project b/.project new file mode 100644 index 0000000..2851774 --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + tv_grab_nl_java + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f4217b0 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..9d3a7c9 --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,5 @@ +#Fri Mar 09 20:00:15 CET 2012 +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..869a2c3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + org.vanbest.xmltv.tv_grab_nl_java + tv_grab_nl_java + 0.0.1-SNAPSHOT + + + net.sf.json-lib + json-lib + 2.4 + jdk15 + + + commons-cli + commons-cli + 1.2 + + + commons-io + commons-io + 2.1 + + + commons-lang + commons-lang + 2.6 + + + \ No newline at end of file diff --git a/src/org/vanbest/xmltv/Channel.java b/src/org/vanbest/xmltv/Channel.java new file mode 100644 index 0000000..5182d10 --- /dev/null +++ b/src/org/vanbest/xmltv/Channel.java @@ -0,0 +1,30 @@ +package org.vanbest.xmltv; + +public class Channel { + int id; + String name; + String shortName; + String iconUrl; + boolean selected; + + public Channel(int id, String name, String shortName) { + this.id = id; + this.name = name; + this.shortName = shortName; + } + public String toString() { + return "id: " + id + "; name: " + name + "; shortName: " + shortName; + } + + public String getChannelId() { + return id+".tvgids.nl"; + } + + public void fixup() { + this.name = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(name); + this.shortName = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(shortName); + } + public void setIconUrl(String url) { + this.iconUrl = url; + } +} diff --git a/src/org/vanbest/xmltv/Config.java b/src/org/vanbest/xmltv/Config.java new file mode 100644 index 0000000..f112293 --- /dev/null +++ b/src/org/vanbest/xmltv/Config.java @@ -0,0 +1,190 @@ +package org.vanbest.xmltv; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.io.FileUtils; + +public class Config { + public int niceMilliseconds; + public List channels; + public Map cattrans; + protected File cacheFile; + boolean quiet = false; + public int logLevel = LOG_DEFAULT; + + public static final int LOG_INFO = 0x0001; + public static final int LOG_JSON = 0x0100; + private static final int LOG_PROGRAMME_INFO = 0x0200; + + public static int LOG_DEFAULT = LOG_INFO; + + private Config() { + } + + public static Config getDefaultConfig() { + Config result = new Config(); + result.channels = new ArrayList(); + result.cattrans = getDefaultCattrans(); + result.cacheFile = defaultCacheFile(); + result.niceMilliseconds = 500; + return result; + } + + public Map getCategories() { + return cattrans; + } + + public void setChannels(List channels) { + this.channels = channels; + } + + public static File defaultCacheFile() { + return FileUtils.getFile(FileUtils.getUserDirectory(), ".xmltv", "tv_grab_nl_java.cache"); + } + + static private Map getDefaultCattrans() { + Map result = new HashMap(); + result.put("amusement", "Animated"); + result.put("comedy", "Comedy"); + result.put("documentaire", "Documentary"); + result.put("educatief", "Educational"); + result.put("erotiek", "Adult"); + result.put("film", "Film"); + result.put("muziek", "Art/Music"); + result.put("informatief", "Educational"); + result.put("jeugd", "Children"); + result.put("kunst/cultuur", "Arts/Culture"); + result.put("misdaad", "Crime/Mystery"); + result.put("muziek", "Music"); + result.put("natuur", "Science/Nature"); + result.put("nieuws/actualiteiten", "News"); + result.put("overige", "Unknown"); + result.put("religieus", "Religion"); + result.put("serie/soap", "Drama"); + result.put("sport", "Sports"); + result.put("theater", "Arts/Culture"); + result.put("wetenschap", "Science/Nature"); + return result; + } + + public void writeConfig(File configFile) throws IOException { + FileUtils.forceMkdir(configFile.getParentFile()); + PrintWriter out = new PrintWriter(new OutputStreamWriter( new FileOutputStream( configFile ))); + out.println("cache-file: " + escape(cacheFile.getPath())); + out.println("nice-time-milliseconds: " + niceMilliseconds); + for(Channel c: channels) { + if (!c.selected) { + out.print("#"); + } + out.print("channel: " + c.id + ": " + escape(c.name)); + if (c.iconUrl != null) { + out.print(" : " + escape(c.iconUrl)); + } + out.println(); + } + for(Map.Entry entry: cattrans.entrySet()) { + out.println("category: " + escape(entry.getKey()) + ": " + escape(entry.getValue())); + } + out.close(); + } + + public static String escape(String s) { + return "\"" + s.replace("\\", "\\\\").replaceAll("\\\"", "\\\\\"") + "\""; + } + + public static List splitLine(String s) { + List parts = new ArrayList(5); + int pos=0; + while (true) { + // Find first colon outside quotes + boolean quoted=false; + int quoteStart=-1; + StringBuffer buf = new StringBuffer(); + for (; pos=s.length()) { + break; + } + pos++; + } + return parts; + } + + public static Config readConfig(File file) { + Config result = getDefaultConfig(); + result.cattrans = new HashMap(); + try { + BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( file))); + + while(true) { + String s = reader.readLine(); + if(s==null) break; + if (!s.contains(":")) continue; + if (s.startsWith("#")) continue; + List parts = splitLine(s); + if (parts.get(0).toLowerCase().equals("channel")) { + Channel c = new Channel(Integer.parseInt(parts.get(1)), parts.get(2), ""); + if (parts.size()>3) { + c.setIconUrl(parts.get(3)); + } + result.channels.add(c); + } + switch (parts.get(0).toLowerCase()) { + case "category" : + result.cattrans.put(parts.get(1), parts.get(2)); + break; + case "cache-file": + result.cacheFile = new File(parts.get(1)); + break; + case "nice-time-milliseconds": + result.niceMilliseconds = Integer.parseInt(parts.get(1)); + } + } + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Error reading configuration file, continuing with empty configuration"); + return getDefaultConfig(); + } + return result; + } + + public boolean logJSON() { + return (logLevel & LOG_JSON) != 0; + } + + public boolean logProgrammes() { + return (logLevel & LOG_PROGRAMME_INFO) != 0; + } + +} + diff --git a/src/org/vanbest/xmltv/Main.java b/src/org/vanbest/xmltv/Main.java new file mode 100644 index 0000000..9aaf65d --- /dev/null +++ b/src/org/vanbest/xmltv/Main.java @@ -0,0 +1,247 @@ +package org.vanbest.xmltv; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLStreamException; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.GnuParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.Parser; +import org.apache.commons.io.FileUtils; + +public class Main { + private File configFile; + private Config config; + private PrintStream outputWriter; + private int days = 5; + private int offset = 0; + /** + * @param args + */ + + public Main() { + this.configFile = defaultConfigFile(); + this.outputWriter = System.out; + } + + public void run() throws FactoryConfigurationError, Exception { + if (!config.quiet) { + System.out.println("Fetching programme data for days " + this.offset + "-" + (this.offset+this.days-1)); + System.out.println("... from " + config.channels.size() + " channels"); + System.out.println("... using cache file " + config.cacheFile.getCanonicalPath()); + } + + XmlTvWriter writer = new XmlTvWriter(outputWriter, config); + writer.writeChannels(config.channels); + + TvGids gids = new TvGids(config); + + for (int day=offset; day programmes = new HashSet(); + for( Channel c: config.channels ) { + if (!config.quiet) System.out.print("."); + ArrayList cs = new ArrayList(2); + cs.add(c); + Set p = gids.getProgrammes(cs, day, true); + writer.writePrograms(p); + writer.flush(); + } + if (!config.quiet) System.out.println(); + } + + try { + gids.close(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + writer.close(); + if (!config.quiet) { + System.out.println("Number of programmes from cache: " + gids.cacheHits); + System.out.println("Number of programmes fetched: " + gids.cacheMisses); + System.out.println("Number of fetch errors: " + gids.fetchErrors); + } + } + + public void configure() throws IOException { + TvGids gids = new TvGids(config); + + Set oldChannels = new HashSet(); + for (Channel c: config.channels) { + oldChannels.add(c.id); + } + List channels = gids.getChannels(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + boolean all = false; + boolean none = false; + boolean keep = false; + for (Channel c: channels) { + boolean selected = oldChannels.contains(c.id); + System.out.print("add channel " + c.id + " (" + c.name + ") [[y]es,[n]o,[a]ll,[none],[k]eep selection (default=" + (selected?"yes":"no") + ")] "); + if (keep) { + c.selected = selected; + System.out.println(selected?"Y":"N"); + continue; + } + if (all) { + c.selected = true; + System.out.println("Y"); + continue; + } + if (none) { + c.selected = false; + System.out.println("N"); + continue; + } + while(true) { + String s = reader.readLine().toLowerCase(); + if (s.isEmpty()) { + c.selected = selected; + break; + } else if ( s.startsWith("k")) { + c.selected = selected; + keep = true; + break; + } else if ( s.startsWith("y")) { + c.selected = true; + break; + } else if ( s.startsWith("a")) { + c.selected = true; + all = true; + break; + } else if ( s.startsWith("none")) { + c.selected = false; + none = true; + break; + } else if ( s.startsWith("n")) { + c.selected = false; + break; + } + } + } + + config.setChannels(channels); + try { + config.writeConfig(configFile); + System.out.println("Configuration file written to " + configFile.getPath()); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void processOptions(String[] args) throws FileNotFoundException { + Options options = new Options(); + options.addOption("d", "description", false, "Display a description to identify this grabber"); + options.addOption("c", "capabilities", false, "Show grabber capabilities"); + options.addOption("q", "quiet", false, "Be quiet"); + options.addOption("o", "output", true, "Set xlmtv output filename"); + options.addOption("y", "days", true, "Number of days to grab"); + options.addOption("s", "offset", true, "Start day for grabbing (0=today)"); + options.addOption("n", "configure", false, "Interactive configuration"); + options.addOption("f", "config-file", true, "Configuration file location"); + options.addOption("h", "cache", true, "Cache file location"); + options.addOption("e", "help", false, "Show this help"); + options.addOption("l", "log-level", true, "Set log level (0x0100=JSON)"); + //options.addOption("p", "preferredmethod", false, "Show preferred method"); + + CommandLine line = null; + try { + line = new GnuParser().parse(options, args); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (line.hasOption("d")) { + System.out.println("tv_grab_nl_java is a parser for Dutch TV listings using the tvgids.nl JSON interface"); + System.exit(0); + } + if (line.hasOption("e")) { + // automatically generate the help statement + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp( "tv_grab_nl_java", options ); + System.exit(0); + } + if(line.hasOption("f")) { + configFile = new File(line.getOptionValue("f")); + } + config = Config.readConfig(configFile); + if (line.hasOption("q")) { + config.quiet = true; + } + + if (line.hasOption("o")) { + this.outputWriter = new PrintStream( new FileOutputStream(line.getOptionValue("o"))); + } + if (line.hasOption("l")) { + config.logLevel = Integer.parseInt(line.getOptionValue("l")); + } + if (line.hasOption("h")) { + config.cacheFile = new File(line.getOptionValue("h")); + } + if (line.hasOption("y")) { + this.days = Integer.parseInt(line.getOptionValue("y")); + } + if (line.hasOption("s")) { + this.offset = Integer.parseInt(line.getOptionValue("s")); + } + if (line.hasOption("c")) { + System.out.println("baseline"); + System.out.println("manualconfig"); + System.out.println("cache"); + // System.out.println("preferredmethod"); + System.exit(0); + } + if (line.hasOption("n")) { + try { + configure(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + System.exit(0); + } + + } + + public static File defaultConfigFile() { + return FileUtils.getFile(FileUtils.getUserDirectory(), ".xmltv", "tv_grab_nl_java.conf"); + } + + public static void main(String[] args) { + Main main = new Main(); + try { + main.processOptions(args); + main.run(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/src/org/vanbest/xmltv/Programme.java b/src/org/vanbest/xmltv/Programme.java new file mode 100644 index 0000000..e5ae3e1 --- /dev/null +++ b/src/org/vanbest/xmltv/Programme.java @@ -0,0 +1,133 @@ +package org.vanbest.xmltv; + +import java.util.Date; + +public class Programme { + public String getDb_id() { + return db_id; + } + + public void setDb_id(String db_id) { + this.db_id = db_id; + } + + public String getTitel() { + return titel; + } + + public void setTitel(String titel) { + this.titel = titel; + } + + public String getGenre() { + return genre; + } + + public void setGenre(String genre) { + this.genre = genre; + } + + public String getSoort() { + return soort; + } + + public void setSoort(String soort) { + this.soort = soort; + } + + public String getKijkwijzer() { + return kijkwijzer; + } + + public void setKijkwijzer(String kijkwijzer) { + this.kijkwijzer = kijkwijzer; + } + + public String getArtikel_id() { + return artikel_id; + } + + public void setArtikel_id(String artikel_id) { + this.artikel_id = artikel_id; + } + + public Date getDatum_start() { + return datum_start; + } + + public void setDatum_start(Date datum_start) { + this.datum_start = datum_start; + } + + public Date getDatum_end() { + return datum_end; + } + + public void setDatum_end(Date datum_end) { + this.datum_end = datum_end; + } + + public boolean isIs_highlight() { + return is_highlight; + } + + public void setIs_highlight(boolean is_highlight) { + this.is_highlight = is_highlight; + } + + public String getHighlight_afbeelding() { + return highlight_afbeelding; + } + + public void setHighlight_afbeelding(String highlight_afbeelding) { + this.highlight_afbeelding = highlight_afbeelding; + } + + public String getHighlight_content() { + return highlight_content; + } + + public void setHighlight_content(String highlight_content) { + this.highlight_content = highlight_content; + } + + String db_id; + String titel; + String genre; + String soort; + String kijkwijzer; + String artikel_id; + Date datum_start; + Date datum_end; + boolean is_highlight; + String highlight_afbeelding; + String highlight_content; + ProgrammeDetails details = null; + Channel channel = null; + + public void fixup(Config config) { + this.titel = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(titel); + this.genre = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(genre); + this.soort = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(soort); + this.highlight_content = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(highlight_content); + if(config.getCategories().containsKey(genre.toLowerCase())) { + genre = config.getCategories().get(genre.toLowerCase()); + } + } + + public String toString() { + StringBuffer s = new StringBuffer(); + s.append("id: " + db_id + ";"); + s.append("titel: " + titel + ";"); + s.append("genre: " + genre + ";"); + s.append("soort: " + soort + ";"); + s.append("kijkwijzer: " + kijkwijzer+ ";"); + s.append("artikel_id: " + artikel_id + ";"); + s.append("datum_start: " + datum_start + ";"); + s.append("datum_end: " + datum_end + ";"); + if (details != null) s.append("details:" + details.toString() ); + s.append("\n"); + + return s.toString(); + } +} diff --git a/src/org/vanbest/xmltv/ProgrammeCache.java b/src/org/vanbest/xmltv/ProgrammeCache.java new file mode 100644 index 0000000..c9a9858 --- /dev/null +++ b/src/org/vanbest/xmltv/ProgrammeCache.java @@ -0,0 +1,60 @@ +package org.vanbest.xmltv; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.FileUtils; + +public class ProgrammeCache { + private File cacheFile; + private Map cache; + + public ProgrammeCache(File cacheFile) { + this.cacheFile = cacheFile; + if (cacheFile.canRead()) { + try { + cache = (Map) new ObjectInputStream( new FileInputStream( cacheFile ) ).readObject(); + } catch (InvalidClassException e) { + // TODO Auto-generated catch block + + cache = new HashMap(); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + cache = new HashMap(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + cache = new HashMap(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + cache = new HashMap(); + } + } else { + cache = new HashMap(); + } + // FileUtils.forceMkdir(root); + } + + public ProgrammeDetails getDetails(String id) { + return cache.get(id); + } + + public void add(String id, ProgrammeDetails d) { + cache.put(id, d); + } + + public void close() throws FileNotFoundException, IOException { + new ObjectOutputStream( new FileOutputStream(cacheFile)).writeObject(cache); + } +} diff --git a/src/org/vanbest/xmltv/ProgrammeDetails.java b/src/org/vanbest/xmltv/ProgrammeDetails.java new file mode 100644 index 0000000..32550d3 --- /dev/null +++ b/src/org/vanbest/xmltv/ProgrammeDetails.java @@ -0,0 +1,135 @@ +package org.vanbest.xmltv; + +import java.io.Serializable; + +public class ProgrammeDetails implements Serializable { + String db_id; + String titel; + String datum; + String btijd; + String etijd; + String synop; + String kijkwijzer; + String genre; + String presentatie; + String acteursnamen_rolverdeling; + String regisseur; + String zender_id; + public boolean subtitle_teletekst = false; + public boolean stereo = false; + public boolean blacknwhite = false; + public boolean breedbeeld = false; + public String quality = null; + public boolean herhaling = false; + + public void fixup(Programme p, boolean quiet) { + this.titel = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(titel); + this.genre = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(genre); + this.synop = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(synop); + this.synop = this.synop.replaceAll("
", " "). + replaceAll("
", " "). + replaceAll("

", " "). + replaceAll("

", " "). + replaceAll("", " "). + replaceAll("", " "). + replaceAll("", " "). + replaceAll("", " "). + trim(); + if ((synop == null || synop.isEmpty()) && ( genre == null || (!genre.toLowerCase().equals("movies") && !genre.toLowerCase().equals("film")))) { + String[] parts = p.titel.split("[[:space:]]*:[[:space:]]*", 2); + if (parts.length >= 2 ) { + if (!quiet) { + System.out.println("Splitting title from \"" + p.titel + "\" to: \"" + parts[0].trim() + "\"; synop: \"" + parts[1].trim() + "\""); + } + titel = parts[0].trim(); + p.titel = titel; + synop = parts[1].trim(); + } + } + this.presentatie = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(presentatie); + this.acteursnamen_rolverdeling = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(acteursnamen_rolverdeling); + this.regisseur = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(regisseur); + } + + public String getDb_id() { + return db_id; + } + public void setDb_id(String db_id) { + this.db_id = db_id; + } + public String getTitel() { + return titel; + } + public void setTitel(String titel) { + this.titel = titel; + } + public String getDatum() { + return datum; + } + public void setDatum(String datum) { + this.datum = datum; + } + public String getBtijd() { + return btijd; + } + public void setBtijd(String btijd) { + this.btijd = btijd; + } + public String getEtijd() { + return etijd; + } + public void setEtijd(String etijd) { + this.etijd = etijd; + } + public String getSynop() { + return synop; + } + public void setSynop(String synop) { + this.synop = synop; + } + public String getKijkwijzer() { + return kijkwijzer; + } + public void setKijkwijzer(String kijkwijzer) { + this.kijkwijzer = kijkwijzer; + } + public String getGenre() { + return genre; + } + public void setGenre(String genre) { + this.genre = genre; + } + public String getPresentatie() { + return presentatie; + } + public void setPresentatie(String presentatie) { + this.presentatie = presentatie; + } + public String getActeursnamen_rolverdeling() { + return acteursnamen_rolverdeling; + } + public void setActeursnamen_rolverdeling(String acteursnamen_rolverdeling) { + this.acteursnamen_rolverdeling = acteursnamen_rolverdeling; + } + public String getRegisseur() { + return regisseur; + } + public void setRegisseur(String regisseur) { + this.regisseur = regisseur; + } + public String getZender_id() { + return zender_id; + } + public void setZender_id(String zender_id) { + this.zender_id = zender_id; + } + @Override + public String toString() { + return "ProgrammeDetails [db_id=" + db_id + ", titel=" + titel + + ", datum=" + datum + ", btijd=" + btijd + ", etijd=" + etijd + + ", synop=" + synop + ", kijkwijzer=" + kijkwijzer + + ", genre=" + genre + ", presentatie=" + presentatie + + ", acteursnamen_rolverdeling=" + acteursnamen_rolverdeling + + ", regisseur=" + regisseur + ", zender_id=" + zender_id + "]"; + } +} diff --git a/src/org/vanbest/xmltv/TvGids.java b/src/org/vanbest/xmltv/TvGids.java new file mode 100644 index 0000000..4df5ddb --- /dev/null +++ b/src/org/vanbest/xmltv/TvGids.java @@ -0,0 +1,286 @@ +package org.vanbest.xmltv; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sf.ezmorph.MorpherRegistry; +import net.sf.ezmorph.ObjectMorpher; +import net.sf.ezmorph.object.DateMorpher; +import net.sf.json.JSON; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import net.sf.json.util.JSONUtils; + +public class TvGids { + + static String channels_url="http://www.tvgids.nl/json/lists/channels.php"; + static String programme_base_url="http://www.tvgids.nl/json/lists/programs.php"; + static String detail_base_url = "http://www.tvgids.nl/json/lists/program.php"; + static String html_detail_base_url = "http://www.tvgids.nl/programma/"; + + Config config; + ProgrammeCache cache; + static boolean initialised = false; + int fetchErrors = 0; + int cacheHits = 0; + int cacheMisses = 0; + + public TvGids(Config config) { + this.config = config; + cache = new ProgrammeCache(config.cacheFile); + if ( ! initialised ) { + init(); + initialised = true; + } + } + + public static void init() { + String[] formats = {"yyyy-MM-dd HH:mm:ss"}; + MorpherRegistry registry = JSONUtils.getMorpherRegistry(); + registry.registerMorpher( new DateMorpher(formats, new Locale("nl"))); + registry.registerMorpher( new ObjectMorpher() { + public Object morph(Object value) { + String s = (String) value; + return org.apache.commons.lang.StringEscapeUtils.unescapeHtml(s); + } + public Class morphsTo() { + return String.class; + } + public boolean supports(Class clazz) { + return clazz == String.class; + } + }, true); + } + + public void close() throws FileNotFoundException, IOException { + cache.close(); + } + + public List getChannels() { + List result = new ArrayList(10); + URL url = null; + try { + url = new URL(channels_url); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + StringBuffer json = new StringBuffer(); + try { + + BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream())); + + String s; + while ((s = reader.readLine()) != null) json.append(s); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (config.logJSON()) System.out.println(json.toString()); + JSONArray jsonArray = JSONArray.fromObject( json.toString() ); + // System.out.println( jsonArray ); + + for( int i=0; i channels, int day) throws Exception { + StringBuilder s = new StringBuilder(programme_base_url); + if (channels.size() < 1) { + throw new Exception("should have at least one channel"); + } + s.append("?channels="); + boolean first = true; + for(Channel i: channels) { + if (first) { + s.append(i.id); + first = false; + } else { + s.append(","+i.id); + } + } + s.append("&day="); + s.append(day); + + return new URL(s.toString()); + } + + public static URL JSONDetailUrl(String id) throws Exception { + StringBuilder s = new StringBuilder(detail_base_url); + s.append("?id="); + s.append(id); + return new URL(s.toString()); + } + + public static URL HTMLDetailUrl(String id) throws Exception { + StringBuilder s = new StringBuilder(html_detail_base_url); + s.append(id); + s.append("/"); + return new URL(s.toString()); + } + + public Set getProgrammes(List channels, int day, boolean fetchDetails) throws Exception { + Set result = new HashSet(); + URL url = programmeUrl(channels, day); + + JSONObject jsonObject = fetchJSON(url); + //System.out.println( jsonObject ); + + for( Channel c: channels) { + JSON ps = (JSON) jsonObject.get(""+c.id); + if ( ps.isArray() ) { + JSONArray programs = (JSONArray) ps; + for( int i=0; i(.*?):(.*?)"); + Pattern HDPattern = Pattern.compile("HD \\d+[ip]?"); + Pattern kijkwijzerPattern = Pattern.compile("\"(.*?)\""); + + p.details = cache.getDetails(p.db_id); + if ( p.details == null ) { + cacheMisses++; + + URL url = JSONDetailUrl(p.db_id); + JSONObject json = fetchJSON(url); + p.details = (ProgrammeDetails) JSONObject.toBean(json, ProgrammeDetails.class); + + url = HTMLDetailUrl(p.db_id); + String clob=fetchURL(url); + //System.out.println("clob:"); + //System.out.println(clob); + Matcher m = progInfoPattern.matcher(clob); + if (m.find()) { + String progInfo = m.group(); + //System.out.println("progInfo"); + //System.out.println(progInfo); + Matcher m2 = infoLinePattern.matcher(progInfo); + while (m2.find()) { + //System.out.println(" infoLine: " + m2.group()); + //System.out.println(" key: " + m2.group(1)); + //System.out.println(" value: " + m2.group(2)); + String key = m2.group(1); + String value = m2.group(2); + switch(key.toLowerCase()) { + case "bijzonderheden": + String[] list = value.split(","); + for( String item: list) { + if (item.toLowerCase().contains("teletekst")) { + p.details.subtitle_teletekst = true; + } else if (item.toLowerCase().contains("breedbeeld")) { + p.details.breedbeeld = true; + } else if (value.toLowerCase().contains("zwart")) { + p.details.blacknwhite = true; + } else if (value.toLowerCase().contains("stereo")) { + p.details.stereo = true; + } else if (value.toLowerCase().contains("herhaling")) { + p.details.herhaling = true; + } else { + Matcher m3 = HDPattern.matcher(value); + if (m3.find()) { + p.details.quality = m3.group(); + } else { + if (!config.quiet) System.out.println(" Unknown value in 'bijzonderheden': " + item); + } + } + } + break; + } + Matcher m3 = kijkwijzerPattern.matcher(progInfo); + List kijkwijzer = new ArrayList(); + while (m3.find()) { + kijkwijzer.add(m3.group(1)); + } + if (!kijkwijzer.isEmpty()) { + // log.debug() + // System.out.println(" (kijkwijzer): " + p.details.kijkwijzer); + // System.out.println(" kijkwijzer: " + kijkwijzer); + } + } + } + + p.details.fixup(p, config.quiet); + cache.add(p.db_id, p.details); + } else { + cacheHits++; + } + } +} diff --git a/src/org/vanbest/xmltv/XmlTvWriter.java b/src/org/vanbest/xmltv/XmlTvWriter.java new file mode 100644 index 0000000..483b3c4 --- /dev/null +++ b/src/org/vanbest/xmltv/XmlTvWriter.java @@ -0,0 +1,232 @@ +package org.vanbest.xmltv; + +import java.io.OutputStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.List; + +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLStreamException; + +public class XmlTvWriter { + + private XMLStreamWriter writer; + private XMLEventFactory eventFactory; + private Config config; + + public XmlTvWriter(OutputStream os, Config config) throws XMLStreamException, FactoryConfigurationError { + this.config = config; + this.writer = XMLOutputFactory.newInstance().createXMLStreamWriter(os); + this.eventFactory = XMLEventFactory.newInstance(); + + writer.writeStartDocument(); + writer.writeCharacters("\n"); + writer.writeDTD(""); + writer.writeCharacters("\n"); + writer.writeStartElement("tv"); + writer.writeAttribute("generator-info-url","http://www.vanbest.org/"); + writer.writeAttribute("source-info-url", "http://tvgids.nl/"); + writer.writeAttribute("source-info-name", "TvGids.nl"); + writer.writeAttribute("generator-info-name", "tv_grab_nl_java release 0.4"); + writeln(); + } + + public void writeln() throws XMLStreamException { + writer.writeCharacters(System.getProperty("line.separator")); + } + + public void writeChannels(List channels) throws XMLStreamException { + for(Channel c: channels) { + writer.writeStartElement("channel"); + writer.writeAttribute("id", c.getChannelId()); + writer.writeStartElement("display-name"); + writer.writeAttribute("lang", "nl"); + writer.writeCharacters(c.name); + writer.writeEndElement(); + + if (c.iconUrl != null) { + writer.writeStartElement("icon"); + writer.writeAttribute("src", c.iconUrl); + writer.writeEndElement(); + } + + writer.writeEndElement(); + writeln(); } + } + + /* TODO: + * boolean is_highlight; + * String highlight_afbeelding; + * String highlight_content; + * soort + * artikel_id ??? + * + */ + public void writePrograms(Collection programs) throws XMLStreamException { + DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss Z"); + for(Programme p: programs) { + writer.writeStartElement("programme"); + writer.writeAttribute("start", df.format(p.datum_start)); + writer.writeAttribute("stop", df.format(p.datum_end)); + writer.writeAttribute("channel", ""+p.channel.getChannelId()); + writeln(); + + writer.writeStartElement("title"); + writer.writeAttribute("lang", "nl"); + writer.writeCharacters(p.titel); + writer.writeEndElement(); + writeln(); + + if(p.details.synop != null && ! p.details.synop.isEmpty()) { + writer.writeStartElement("desc"); + writer.writeAttribute("lang", "nl"); + writer.writeCharacters(p.details.synop); + writer.writeEndElement(); + writeln(); + } + + if (p.details != null) { + if ( p.is_highlight) { + //System.out.println("Highlight"); + //System.out.println(" " + p.highlight_afbeelding); + //System.out.println(" " + p.highlight_content); + } else { + if (p.highlight_afbeelding!= null && !p.highlight_afbeelding.isEmpty()) { + //System.out.println("highlight_afbeelding: " + p.highlight_afbeelding); + } + if (p.highlight_content!= null && !p.highlight_content.isEmpty()) { + //System.out.println("highlight_content: " + p.highlight_content); + } + } + if ( (p.details.presentatie != null && !p.details.presentatie.isEmpty()) || + (p.details.regisseur != null && !p.details.regisseur.isEmpty()) || + (p.details.acteursnamen_rolverdeling != null && !p.details.acteursnamen_rolverdeling.isEmpty()) + ) { + writer.writeStartElement("credits"); + if (p.details.regisseur != null && !p.details.regisseur.isEmpty()) { + String[] parts = p.details.regisseur.split(","); + for (String s: parts) { + writer.writeStartElement("director"); + writer.writeCharacters(s.trim()); + writer.writeEndElement(); + } + } + if (p.details.acteursnamen_rolverdeling != null && !p.details.acteursnamen_rolverdeling.isEmpty()) { + String[] parts = p.details.acteursnamen_rolverdeling.split(","); + for (String s: parts) { + writer.writeStartElement("actor"); + writer.writeCharacters(s.trim()); + writer.writeEndElement(); + } + } + if (p.details.presentatie != null && !p.details.presentatie.isEmpty()) { + String[] parts = p.details.presentatie.split(","); + for (String s: parts) { + writer.writeStartElement("presenter"); + writer.writeCharacters(s.trim()); + writer.writeEndElement(); + } + } + writer.writeEndElement(); + writeln(); + } + writer.writeStartElement("category"); + writer.writeAttribute("lang", "en"); + writer.writeCharacters(p.genre); + writer.writeEndElement(); + writeln(); + + if (p.details.blacknwhite || p.details.breedbeeld) { + writer.writeStartElement("video"); + if (p.details.blacknwhite) { + writer.writeStartElement("colour"); + writer.writeCharacters("no"); + writer.writeEndElement(); + } + if (p.details.breedbeeld) { + writer.writeStartElement("aspect"); + writer.writeCharacters("16x9"); + writer.writeEndElement(); + } + if (p.details.quality != null) { + writer.writeStartElement("quality"); + writer.writeCharacters(p.details.quality); + writer.writeEndElement(); + } + writer.writeEndElement(); + writeln(); + } + + if (p.details.stereo) { + writer.writeStartElement("audio"); + writer.writeStartElement("stereo"); + writer.writeCharacters("stereo"); + writer.writeEndElement(); + writer.writeEndElement(); + writeln(); + } + + if (p.details.herhaling) { + writer.writeEmptyElement("previously-shown"); + } + + if (p.details.subtitle_teletekst) { + writer.writeStartElement("subtitles"); + writer.writeAttribute("type", "teletext"); + writer.writeEndElement(); + writeln(); + } + + /* TODO: Icon attribuut gebruiken? + */ + if (p.details.kijkwijzer != null && !p.details.kijkwijzer.isEmpty()) { + writer.writeStartElement("rating"); + writer.writeAttribute("system", "kijkwijzer"); + writer.writeStartElement("value"); + for (int i=0; i - - - - - - diff --git a/tv_grab_nl_java/.gitignore b/tv_grab_nl_java/.gitignore deleted file mode 100644 index 1293e4d..0000000 --- a/tv_grab_nl_java/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/test.xml -/target diff --git a/tv_grab_nl_java/.project b/tv_grab_nl_java/.project deleted file mode 100644 index 2851774..0000000 --- a/tv_grab_nl_java/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - tv_grab_nl_java - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.m2e.core.maven2Nature - org.eclipse.jdt.core.javanature - - diff --git a/tv_grab_nl_java/.settings/org.eclipse.jdt.core.prefs b/tv_grab_nl_java/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index f4217b0..0000000 --- a/tv_grab_nl_java/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,12 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.7 diff --git a/tv_grab_nl_java/.settings/org.eclipse.m2e.core.prefs b/tv_grab_nl_java/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index 9d3a7c9..0000000 --- a/tv_grab_nl_java/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -#Fri Mar 09 20:00:15 CET 2012 -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/tv_grab_nl_java/pom.xml b/tv_grab_nl_java/pom.xml deleted file mode 100644 index 869a2c3..0000000 --- a/tv_grab_nl_java/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - 4.0.0 - org.vanbest.xmltv.tv_grab_nl_java - tv_grab_nl_java - 0.0.1-SNAPSHOT - - - net.sf.json-lib - json-lib - 2.4 - jdk15 - - - commons-cli - commons-cli - 1.2 - - - commons-io - commons-io - 2.1 - - - commons-lang - commons-lang - 2.6 - - - \ No newline at end of file diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/Channel.java b/tv_grab_nl_java/src/org/vanbest/xmltv/Channel.java deleted file mode 100644 index 5182d10..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/Channel.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.vanbest.xmltv; - -public class Channel { - int id; - String name; - String shortName; - String iconUrl; - boolean selected; - - public Channel(int id, String name, String shortName) { - this.id = id; - this.name = name; - this.shortName = shortName; - } - public String toString() { - return "id: " + id + "; name: " + name + "; shortName: " + shortName; - } - - public String getChannelId() { - return id+".tvgids.nl"; - } - - public void fixup() { - this.name = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(name); - this.shortName = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(shortName); - } - public void setIconUrl(String url) { - this.iconUrl = url; - } -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/Config.java b/tv_grab_nl_java/src/org/vanbest/xmltv/Config.java deleted file mode 100644 index f112293..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/Config.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.io.FileUtils; - -public class Config { - public int niceMilliseconds; - public List channels; - public Map cattrans; - protected File cacheFile; - boolean quiet = false; - public int logLevel = LOG_DEFAULT; - - public static final int LOG_INFO = 0x0001; - public static final int LOG_JSON = 0x0100; - private static final int LOG_PROGRAMME_INFO = 0x0200; - - public static int LOG_DEFAULT = LOG_INFO; - - private Config() { - } - - public static Config getDefaultConfig() { - Config result = new Config(); - result.channels = new ArrayList(); - result.cattrans = getDefaultCattrans(); - result.cacheFile = defaultCacheFile(); - result.niceMilliseconds = 500; - return result; - } - - public Map getCategories() { - return cattrans; - } - - public void setChannels(List channels) { - this.channels = channels; - } - - public static File defaultCacheFile() { - return FileUtils.getFile(FileUtils.getUserDirectory(), ".xmltv", "tv_grab_nl_java.cache"); - } - - static private Map getDefaultCattrans() { - Map result = new HashMap(); - result.put("amusement", "Animated"); - result.put("comedy", "Comedy"); - result.put("documentaire", "Documentary"); - result.put("educatief", "Educational"); - result.put("erotiek", "Adult"); - result.put("film", "Film"); - result.put("muziek", "Art/Music"); - result.put("informatief", "Educational"); - result.put("jeugd", "Children"); - result.put("kunst/cultuur", "Arts/Culture"); - result.put("misdaad", "Crime/Mystery"); - result.put("muziek", "Music"); - result.put("natuur", "Science/Nature"); - result.put("nieuws/actualiteiten", "News"); - result.put("overige", "Unknown"); - result.put("religieus", "Religion"); - result.put("serie/soap", "Drama"); - result.put("sport", "Sports"); - result.put("theater", "Arts/Culture"); - result.put("wetenschap", "Science/Nature"); - return result; - } - - public void writeConfig(File configFile) throws IOException { - FileUtils.forceMkdir(configFile.getParentFile()); - PrintWriter out = new PrintWriter(new OutputStreamWriter( new FileOutputStream( configFile ))); - out.println("cache-file: " + escape(cacheFile.getPath())); - out.println("nice-time-milliseconds: " + niceMilliseconds); - for(Channel c: channels) { - if (!c.selected) { - out.print("#"); - } - out.print("channel: " + c.id + ": " + escape(c.name)); - if (c.iconUrl != null) { - out.print(" : " + escape(c.iconUrl)); - } - out.println(); - } - for(Map.Entry entry: cattrans.entrySet()) { - out.println("category: " + escape(entry.getKey()) + ": " + escape(entry.getValue())); - } - out.close(); - } - - public static String escape(String s) { - return "\"" + s.replace("\\", "\\\\").replaceAll("\\\"", "\\\\\"") + "\""; - } - - public static List splitLine(String s) { - List parts = new ArrayList(5); - int pos=0; - while (true) { - // Find first colon outside quotes - boolean quoted=false; - int quoteStart=-1; - StringBuffer buf = new StringBuffer(); - for (; pos=s.length()) { - break; - } - pos++; - } - return parts; - } - - public static Config readConfig(File file) { - Config result = getDefaultConfig(); - result.cattrans = new HashMap(); - try { - BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( file))); - - while(true) { - String s = reader.readLine(); - if(s==null) break; - if (!s.contains(":")) continue; - if (s.startsWith("#")) continue; - List parts = splitLine(s); - if (parts.get(0).toLowerCase().equals("channel")) { - Channel c = new Channel(Integer.parseInt(parts.get(1)), parts.get(2), ""); - if (parts.size()>3) { - c.setIconUrl(parts.get(3)); - } - result.channels.add(c); - } - switch (parts.get(0).toLowerCase()) { - case "category" : - result.cattrans.put(parts.get(1), parts.get(2)); - break; - case "cache-file": - result.cacheFile = new File(parts.get(1)); - break; - case "nice-time-milliseconds": - result.niceMilliseconds = Integer.parseInt(parts.get(1)); - } - } - } catch (IOException e) { - e.printStackTrace(); - System.out.println("Error reading configuration file, continuing with empty configuration"); - return getDefaultConfig(); - } - return result; - } - - public boolean logJSON() { - return (logLevel & LOG_JSON) != 0; - } - - public boolean logProgrammes() { - return (logLevel & LOG_PROGRAMME_INFO) != 0; - } - -} - diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/Main.java b/tv_grab_nl_java/src/org/vanbest/xmltv/Main.java deleted file mode 100644 index 9aaf65d..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/Main.java +++ /dev/null @@ -1,247 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLStreamException; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.GnuParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.cli.Parser; -import org.apache.commons.io.FileUtils; - -public class Main { - private File configFile; - private Config config; - private PrintStream outputWriter; - private int days = 5; - private int offset = 0; - /** - * @param args - */ - - public Main() { - this.configFile = defaultConfigFile(); - this.outputWriter = System.out; - } - - public void run() throws FactoryConfigurationError, Exception { - if (!config.quiet) { - System.out.println("Fetching programme data for days " + this.offset + "-" + (this.offset+this.days-1)); - System.out.println("... from " + config.channels.size() + " channels"); - System.out.println("... using cache file " + config.cacheFile.getCanonicalPath()); - } - - XmlTvWriter writer = new XmlTvWriter(outputWriter, config); - writer.writeChannels(config.channels); - - TvGids gids = new TvGids(config); - - for (int day=offset; day programmes = new HashSet(); - for( Channel c: config.channels ) { - if (!config.quiet) System.out.print("."); - ArrayList cs = new ArrayList(2); - cs.add(c); - Set p = gids.getProgrammes(cs, day, true); - writer.writePrograms(p); - writer.flush(); - } - if (!config.quiet) System.out.println(); - } - - try { - gids.close(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - writer.close(); - if (!config.quiet) { - System.out.println("Number of programmes from cache: " + gids.cacheHits); - System.out.println("Number of programmes fetched: " + gids.cacheMisses); - System.out.println("Number of fetch errors: " + gids.fetchErrors); - } - } - - public void configure() throws IOException { - TvGids gids = new TvGids(config); - - Set oldChannels = new HashSet(); - for (Channel c: config.channels) { - oldChannels.add(c.id); - } - List channels = gids.getChannels(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - boolean all = false; - boolean none = false; - boolean keep = false; - for (Channel c: channels) { - boolean selected = oldChannels.contains(c.id); - System.out.print("add channel " + c.id + " (" + c.name + ") [[y]es,[n]o,[a]ll,[none],[k]eep selection (default=" + (selected?"yes":"no") + ")] "); - if (keep) { - c.selected = selected; - System.out.println(selected?"Y":"N"); - continue; - } - if (all) { - c.selected = true; - System.out.println("Y"); - continue; - } - if (none) { - c.selected = false; - System.out.println("N"); - continue; - } - while(true) { - String s = reader.readLine().toLowerCase(); - if (s.isEmpty()) { - c.selected = selected; - break; - } else if ( s.startsWith("k")) { - c.selected = selected; - keep = true; - break; - } else if ( s.startsWith("y")) { - c.selected = true; - break; - } else if ( s.startsWith("a")) { - c.selected = true; - all = true; - break; - } else if ( s.startsWith("none")) { - c.selected = false; - none = true; - break; - } else if ( s.startsWith("n")) { - c.selected = false; - break; - } - } - } - - config.setChannels(channels); - try { - config.writeConfig(configFile); - System.out.println("Configuration file written to " + configFile.getPath()); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void processOptions(String[] args) throws FileNotFoundException { - Options options = new Options(); - options.addOption("d", "description", false, "Display a description to identify this grabber"); - options.addOption("c", "capabilities", false, "Show grabber capabilities"); - options.addOption("q", "quiet", false, "Be quiet"); - options.addOption("o", "output", true, "Set xlmtv output filename"); - options.addOption("y", "days", true, "Number of days to grab"); - options.addOption("s", "offset", true, "Start day for grabbing (0=today)"); - options.addOption("n", "configure", false, "Interactive configuration"); - options.addOption("f", "config-file", true, "Configuration file location"); - options.addOption("h", "cache", true, "Cache file location"); - options.addOption("e", "help", false, "Show this help"); - options.addOption("l", "log-level", true, "Set log level (0x0100=JSON)"); - //options.addOption("p", "preferredmethod", false, "Show preferred method"); - - CommandLine line = null; - try { - line = new GnuParser().parse(options, args); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - if (line.hasOption("d")) { - System.out.println("tv_grab_nl_java is a parser for Dutch TV listings using the tvgids.nl JSON interface"); - System.exit(0); - } - if (line.hasOption("e")) { - // automatically generate the help statement - HelpFormatter formatter = new HelpFormatter(); - formatter.printHelp( "tv_grab_nl_java", options ); - System.exit(0); - } - if(line.hasOption("f")) { - configFile = new File(line.getOptionValue("f")); - } - config = Config.readConfig(configFile); - if (line.hasOption("q")) { - config.quiet = true; - } - - if (line.hasOption("o")) { - this.outputWriter = new PrintStream( new FileOutputStream(line.getOptionValue("o"))); - } - if (line.hasOption("l")) { - config.logLevel = Integer.parseInt(line.getOptionValue("l")); - } - if (line.hasOption("h")) { - config.cacheFile = new File(line.getOptionValue("h")); - } - if (line.hasOption("y")) { - this.days = Integer.parseInt(line.getOptionValue("y")); - } - if (line.hasOption("s")) { - this.offset = Integer.parseInt(line.getOptionValue("s")); - } - if (line.hasOption("c")) { - System.out.println("baseline"); - System.out.println("manualconfig"); - System.out.println("cache"); - // System.out.println("preferredmethod"); - System.exit(0); - } - if (line.hasOption("n")) { - try { - configure(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - System.exit(0); - } - - } - - public static File defaultConfigFile() { - return FileUtils.getFile(FileUtils.getUserDirectory(), ".xmltv", "tv_grab_nl_java.conf"); - } - - public static void main(String[] args) { - Main main = new Main(); - try { - main.processOptions(args); - main.run(); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/Programme.java b/tv_grab_nl_java/src/org/vanbest/xmltv/Programme.java deleted file mode 100644 index e5ae3e1..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/Programme.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.vanbest.xmltv; - -import java.util.Date; - -public class Programme { - public String getDb_id() { - return db_id; - } - - public void setDb_id(String db_id) { - this.db_id = db_id; - } - - public String getTitel() { - return titel; - } - - public void setTitel(String titel) { - this.titel = titel; - } - - public String getGenre() { - return genre; - } - - public void setGenre(String genre) { - this.genre = genre; - } - - public String getSoort() { - return soort; - } - - public void setSoort(String soort) { - this.soort = soort; - } - - public String getKijkwijzer() { - return kijkwijzer; - } - - public void setKijkwijzer(String kijkwijzer) { - this.kijkwijzer = kijkwijzer; - } - - public String getArtikel_id() { - return artikel_id; - } - - public void setArtikel_id(String artikel_id) { - this.artikel_id = artikel_id; - } - - public Date getDatum_start() { - return datum_start; - } - - public void setDatum_start(Date datum_start) { - this.datum_start = datum_start; - } - - public Date getDatum_end() { - return datum_end; - } - - public void setDatum_end(Date datum_end) { - this.datum_end = datum_end; - } - - public boolean isIs_highlight() { - return is_highlight; - } - - public void setIs_highlight(boolean is_highlight) { - this.is_highlight = is_highlight; - } - - public String getHighlight_afbeelding() { - return highlight_afbeelding; - } - - public void setHighlight_afbeelding(String highlight_afbeelding) { - this.highlight_afbeelding = highlight_afbeelding; - } - - public String getHighlight_content() { - return highlight_content; - } - - public void setHighlight_content(String highlight_content) { - this.highlight_content = highlight_content; - } - - String db_id; - String titel; - String genre; - String soort; - String kijkwijzer; - String artikel_id; - Date datum_start; - Date datum_end; - boolean is_highlight; - String highlight_afbeelding; - String highlight_content; - ProgrammeDetails details = null; - Channel channel = null; - - public void fixup(Config config) { - this.titel = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(titel); - this.genre = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(genre); - this.soort = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(soort); - this.highlight_content = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(highlight_content); - if(config.getCategories().containsKey(genre.toLowerCase())) { - genre = config.getCategories().get(genre.toLowerCase()); - } - } - - public String toString() { - StringBuffer s = new StringBuffer(); - s.append("id: " + db_id + ";"); - s.append("titel: " + titel + ";"); - s.append("genre: " + genre + ";"); - s.append("soort: " + soort + ";"); - s.append("kijkwijzer: " + kijkwijzer+ ";"); - s.append("artikel_id: " + artikel_id + ";"); - s.append("datum_start: " + datum_start + ";"); - s.append("datum_end: " + datum_end + ";"); - if (details != null) s.append("details:" + details.toString() ); - s.append("\n"); - - return s.toString(); - } -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeCache.java b/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeCache.java deleted file mode 100644 index c9a9858..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeCache.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InvalidClassException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.io.FileUtils; - -public class ProgrammeCache { - private File cacheFile; - private Map cache; - - public ProgrammeCache(File cacheFile) { - this.cacheFile = cacheFile; - if (cacheFile.canRead()) { - try { - cache = (Map) new ObjectInputStream( new FileInputStream( cacheFile ) ).readObject(); - } catch (InvalidClassException e) { - // TODO Auto-generated catch block - - cache = new HashMap(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - cache = new HashMap(); - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - cache = new HashMap(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - cache = new HashMap(); - } - } else { - cache = new HashMap(); - } - // FileUtils.forceMkdir(root); - } - - public ProgrammeDetails getDetails(String id) { - return cache.get(id); - } - - public void add(String id, ProgrammeDetails d) { - cache.put(id, d); - } - - public void close() throws FileNotFoundException, IOException { - new ObjectOutputStream( new FileOutputStream(cacheFile)).writeObject(cache); - } -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeDetails.java b/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeDetails.java deleted file mode 100644 index 32550d3..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/ProgrammeDetails.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.Serializable; - -public class ProgrammeDetails implements Serializable { - String db_id; - String titel; - String datum; - String btijd; - String etijd; - String synop; - String kijkwijzer; - String genre; - String presentatie; - String acteursnamen_rolverdeling; - String regisseur; - String zender_id; - public boolean subtitle_teletekst = false; - public boolean stereo = false; - public boolean blacknwhite = false; - public boolean breedbeeld = false; - public String quality = null; - public boolean herhaling = false; - - public void fixup(Programme p, boolean quiet) { - this.titel = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(titel); - this.genre = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(genre); - this.synop = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(synop); - this.synop = this.synop.replaceAll("
", " "). - replaceAll("
", " "). - replaceAll("

", " "). - replaceAll("

", " "). - replaceAll("", " "). - replaceAll("", " "). - replaceAll("", " "). - replaceAll("", " "). - trim(); - if ((synop == null || synop.isEmpty()) && ( genre == null || (!genre.toLowerCase().equals("movies") && !genre.toLowerCase().equals("film")))) { - String[] parts = p.titel.split("[[:space:]]*:[[:space:]]*", 2); - if (parts.length >= 2 ) { - if (!quiet) { - System.out.println("Splitting title from \"" + p.titel + "\" to: \"" + parts[0].trim() + "\"; synop: \"" + parts[1].trim() + "\""); - } - titel = parts[0].trim(); - p.titel = titel; - synop = parts[1].trim(); - } - } - this.presentatie = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(presentatie); - this.acteursnamen_rolverdeling = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(acteursnamen_rolverdeling); - this.regisseur = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(regisseur); - } - - public String getDb_id() { - return db_id; - } - public void setDb_id(String db_id) { - this.db_id = db_id; - } - public String getTitel() { - return titel; - } - public void setTitel(String titel) { - this.titel = titel; - } - public String getDatum() { - return datum; - } - public void setDatum(String datum) { - this.datum = datum; - } - public String getBtijd() { - return btijd; - } - public void setBtijd(String btijd) { - this.btijd = btijd; - } - public String getEtijd() { - return etijd; - } - public void setEtijd(String etijd) { - this.etijd = etijd; - } - public String getSynop() { - return synop; - } - public void setSynop(String synop) { - this.synop = synop; - } - public String getKijkwijzer() { - return kijkwijzer; - } - public void setKijkwijzer(String kijkwijzer) { - this.kijkwijzer = kijkwijzer; - } - public String getGenre() { - return genre; - } - public void setGenre(String genre) { - this.genre = genre; - } - public String getPresentatie() { - return presentatie; - } - public void setPresentatie(String presentatie) { - this.presentatie = presentatie; - } - public String getActeursnamen_rolverdeling() { - return acteursnamen_rolverdeling; - } - public void setActeursnamen_rolverdeling(String acteursnamen_rolverdeling) { - this.acteursnamen_rolverdeling = acteursnamen_rolverdeling; - } - public String getRegisseur() { - return regisseur; - } - public void setRegisseur(String regisseur) { - this.regisseur = regisseur; - } - public String getZender_id() { - return zender_id; - } - public void setZender_id(String zender_id) { - this.zender_id = zender_id; - } - @Override - public String toString() { - return "ProgrammeDetails [db_id=" + db_id + ", titel=" + titel - + ", datum=" + datum + ", btijd=" + btijd + ", etijd=" + etijd - + ", synop=" + synop + ", kijkwijzer=" + kijkwijzer - + ", genre=" + genre + ", presentatie=" + presentatie - + ", acteursnamen_rolverdeling=" + acteursnamen_rolverdeling - + ", regisseur=" + regisseur + ", zender_id=" + zender_id + "]"; - } -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/TvGids.java b/tv_grab_nl_java/src/org/vanbest/xmltv/TvGids.java deleted file mode 100644 index 4df5ddb..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/TvGids.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.sf.ezmorph.MorpherRegistry; -import net.sf.ezmorph.ObjectMorpher; -import net.sf.ezmorph.object.DateMorpher; -import net.sf.json.JSON; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import net.sf.json.util.JSONUtils; - -public class TvGids { - - static String channels_url="http://www.tvgids.nl/json/lists/channels.php"; - static String programme_base_url="http://www.tvgids.nl/json/lists/programs.php"; - static String detail_base_url = "http://www.tvgids.nl/json/lists/program.php"; - static String html_detail_base_url = "http://www.tvgids.nl/programma/"; - - Config config; - ProgrammeCache cache; - static boolean initialised = false; - int fetchErrors = 0; - int cacheHits = 0; - int cacheMisses = 0; - - public TvGids(Config config) { - this.config = config; - cache = new ProgrammeCache(config.cacheFile); - if ( ! initialised ) { - init(); - initialised = true; - } - } - - public static void init() { - String[] formats = {"yyyy-MM-dd HH:mm:ss"}; - MorpherRegistry registry = JSONUtils.getMorpherRegistry(); - registry.registerMorpher( new DateMorpher(formats, new Locale("nl"))); - registry.registerMorpher( new ObjectMorpher() { - public Object morph(Object value) { - String s = (String) value; - return org.apache.commons.lang.StringEscapeUtils.unescapeHtml(s); - } - public Class morphsTo() { - return String.class; - } - public boolean supports(Class clazz) { - return clazz == String.class; - } - }, true); - } - - public void close() throws FileNotFoundException, IOException { - cache.close(); - } - - public List getChannels() { - List result = new ArrayList(10); - URL url = null; - try { - url = new URL(channels_url); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - StringBuffer json = new StringBuffer(); - try { - - BufferedReader reader = new BufferedReader( new InputStreamReader( url.openStream())); - - String s; - while ((s = reader.readLine()) != null) json.append(s); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - if (config.logJSON()) System.out.println(json.toString()); - JSONArray jsonArray = JSONArray.fromObject( json.toString() ); - // System.out.println( jsonArray ); - - for( int i=0; i channels, int day) throws Exception { - StringBuilder s = new StringBuilder(programme_base_url); - if (channels.size() < 1) { - throw new Exception("should have at least one channel"); - } - s.append("?channels="); - boolean first = true; - for(Channel i: channels) { - if (first) { - s.append(i.id); - first = false; - } else { - s.append(","+i.id); - } - } - s.append("&day="); - s.append(day); - - return new URL(s.toString()); - } - - public static URL JSONDetailUrl(String id) throws Exception { - StringBuilder s = new StringBuilder(detail_base_url); - s.append("?id="); - s.append(id); - return new URL(s.toString()); - } - - public static URL HTMLDetailUrl(String id) throws Exception { - StringBuilder s = new StringBuilder(html_detail_base_url); - s.append(id); - s.append("/"); - return new URL(s.toString()); - } - - public Set getProgrammes(List channels, int day, boolean fetchDetails) throws Exception { - Set result = new HashSet(); - URL url = programmeUrl(channels, day); - - JSONObject jsonObject = fetchJSON(url); - //System.out.println( jsonObject ); - - for( Channel c: channels) { - JSON ps = (JSON) jsonObject.get(""+c.id); - if ( ps.isArray() ) { - JSONArray programs = (JSONArray) ps; - for( int i=0; i(.*?):(.*?)"); - Pattern HDPattern = Pattern.compile("HD \\d+[ip]?"); - Pattern kijkwijzerPattern = Pattern.compile("\"(.*?)\""); - - p.details = cache.getDetails(p.db_id); - if ( p.details == null ) { - cacheMisses++; - - URL url = JSONDetailUrl(p.db_id); - JSONObject json = fetchJSON(url); - p.details = (ProgrammeDetails) JSONObject.toBean(json, ProgrammeDetails.class); - - url = HTMLDetailUrl(p.db_id); - String clob=fetchURL(url); - //System.out.println("clob:"); - //System.out.println(clob); - Matcher m = progInfoPattern.matcher(clob); - if (m.find()) { - String progInfo = m.group(); - //System.out.println("progInfo"); - //System.out.println(progInfo); - Matcher m2 = infoLinePattern.matcher(progInfo); - while (m2.find()) { - //System.out.println(" infoLine: " + m2.group()); - //System.out.println(" key: " + m2.group(1)); - //System.out.println(" value: " + m2.group(2)); - String key = m2.group(1); - String value = m2.group(2); - switch(key.toLowerCase()) { - case "bijzonderheden": - String[] list = value.split(","); - for( String item: list) { - if (item.toLowerCase().contains("teletekst")) { - p.details.subtitle_teletekst = true; - } else if (item.toLowerCase().contains("breedbeeld")) { - p.details.breedbeeld = true; - } else if (value.toLowerCase().contains("zwart")) { - p.details.blacknwhite = true; - } else if (value.toLowerCase().contains("stereo")) { - p.details.stereo = true; - } else if (value.toLowerCase().contains("herhaling")) { - p.details.herhaling = true; - } else { - Matcher m3 = HDPattern.matcher(value); - if (m3.find()) { - p.details.quality = m3.group(); - } else { - if (!config.quiet) System.out.println(" Unknown value in 'bijzonderheden': " + item); - } - } - } - break; - } - Matcher m3 = kijkwijzerPattern.matcher(progInfo); - List kijkwijzer = new ArrayList(); - while (m3.find()) { - kijkwijzer.add(m3.group(1)); - } - if (!kijkwijzer.isEmpty()) { - // log.debug() - // System.out.println(" (kijkwijzer): " + p.details.kijkwijzer); - // System.out.println(" kijkwijzer: " + kijkwijzer); - } - } - } - - p.details.fixup(p, config.quiet); - cache.add(p.db_id, p.details); - } else { - cacheHits++; - } - } -} diff --git a/tv_grab_nl_java/src/org/vanbest/xmltv/XmlTvWriter.java b/tv_grab_nl_java/src/org/vanbest/xmltv/XmlTvWriter.java deleted file mode 100644 index 483b3c4..0000000 --- a/tv_grab_nl_java/src/org/vanbest/xmltv/XmlTvWriter.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.vanbest.xmltv; - -import java.io.OutputStream; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.List; - -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLStreamWriter; -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLEventFactory; -import javax.xml.stream.XMLStreamException; - -public class XmlTvWriter { - - private XMLStreamWriter writer; - private XMLEventFactory eventFactory; - private Config config; - - public XmlTvWriter(OutputStream os, Config config) throws XMLStreamException, FactoryConfigurationError { - this.config = config; - this.writer = XMLOutputFactory.newInstance().createXMLStreamWriter(os); - this.eventFactory = XMLEventFactory.newInstance(); - - writer.writeStartDocument(); - writer.writeCharacters("\n"); - writer.writeDTD(""); - writer.writeCharacters("\n"); - writer.writeStartElement("tv"); - writer.writeAttribute("generator-info-url","http://www.vanbest.org/"); - writer.writeAttribute("source-info-url", "http://tvgids.nl/"); - writer.writeAttribute("source-info-name", "TvGids.nl"); - writer.writeAttribute("generator-info-name", "tv_grab_nl_java release 0.4"); - writeln(); - } - - public void writeln() throws XMLStreamException { - writer.writeCharacters(System.getProperty("line.separator")); - } - - public void writeChannels(List channels) throws XMLStreamException { - for(Channel c: channels) { - writer.writeStartElement("channel"); - writer.writeAttribute("id", c.getChannelId()); - writer.writeStartElement("display-name"); - writer.writeAttribute("lang", "nl"); - writer.writeCharacters(c.name); - writer.writeEndElement(); - - if (c.iconUrl != null) { - writer.writeStartElement("icon"); - writer.writeAttribute("src", c.iconUrl); - writer.writeEndElement(); - } - - writer.writeEndElement(); - writeln(); } - } - - /* TODO: - * boolean is_highlight; - * String highlight_afbeelding; - * String highlight_content; - * soort - * artikel_id ??? - * - */ - public void writePrograms(Collection programs) throws XMLStreamException { - DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss Z"); - for(Programme p: programs) { - writer.writeStartElement("programme"); - writer.writeAttribute("start", df.format(p.datum_start)); - writer.writeAttribute("stop", df.format(p.datum_end)); - writer.writeAttribute("channel", ""+p.channel.getChannelId()); - writeln(); - - writer.writeStartElement("title"); - writer.writeAttribute("lang", "nl"); - writer.writeCharacters(p.titel); - writer.writeEndElement(); - writeln(); - - if(p.details.synop != null && ! p.details.synop.isEmpty()) { - writer.writeStartElement("desc"); - writer.writeAttribute("lang", "nl"); - writer.writeCharacters(p.details.synop); - writer.writeEndElement(); - writeln(); - } - - if (p.details != null) { - if ( p.is_highlight) { - //System.out.println("Highlight"); - //System.out.println(" " + p.highlight_afbeelding); - //System.out.println(" " + p.highlight_content); - } else { - if (p.highlight_afbeelding!= null && !p.highlight_afbeelding.isEmpty()) { - //System.out.println("highlight_afbeelding: " + p.highlight_afbeelding); - } - if (p.highlight_content!= null && !p.highlight_content.isEmpty()) { - //System.out.println("highlight_content: " + p.highlight_content); - } - } - if ( (p.details.presentatie != null && !p.details.presentatie.isEmpty()) || - (p.details.regisseur != null && !p.details.regisseur.isEmpty()) || - (p.details.acteursnamen_rolverdeling != null && !p.details.acteursnamen_rolverdeling.isEmpty()) - ) { - writer.writeStartElement("credits"); - if (p.details.regisseur != null && !p.details.regisseur.isEmpty()) { - String[] parts = p.details.regisseur.split(","); - for (String s: parts) { - writer.writeStartElement("director"); - writer.writeCharacters(s.trim()); - writer.writeEndElement(); - } - } - if (p.details.acteursnamen_rolverdeling != null && !p.details.acteursnamen_rolverdeling.isEmpty()) { - String[] parts = p.details.acteursnamen_rolverdeling.split(","); - for (String s: parts) { - writer.writeStartElement("actor"); - writer.writeCharacters(s.trim()); - writer.writeEndElement(); - } - } - if (p.details.presentatie != null && !p.details.presentatie.isEmpty()) { - String[] parts = p.details.presentatie.split(","); - for (String s: parts) { - writer.writeStartElement("presenter"); - writer.writeCharacters(s.trim()); - writer.writeEndElement(); - } - } - writer.writeEndElement(); - writeln(); - } - writer.writeStartElement("category"); - writer.writeAttribute("lang", "en"); - writer.writeCharacters(p.genre); - writer.writeEndElement(); - writeln(); - - if (p.details.blacknwhite || p.details.breedbeeld) { - writer.writeStartElement("video"); - if (p.details.blacknwhite) { - writer.writeStartElement("colour"); - writer.writeCharacters("no"); - writer.writeEndElement(); - } - if (p.details.breedbeeld) { - writer.writeStartElement("aspect"); - writer.writeCharacters("16x9"); - writer.writeEndElement(); - } - if (p.details.quality != null) { - writer.writeStartElement("quality"); - writer.writeCharacters(p.details.quality); - writer.writeEndElement(); - } - writer.writeEndElement(); - writeln(); - } - - if (p.details.stereo) { - writer.writeStartElement("audio"); - writer.writeStartElement("stereo"); - writer.writeCharacters("stereo"); - writer.writeEndElement(); - writer.writeEndElement(); - writeln(); - } - - if (p.details.herhaling) { - writer.writeEmptyElement("previously-shown"); - } - - if (p.details.subtitle_teletekst) { - writer.writeStartElement("subtitles"); - writer.writeAttribute("type", "teletext"); - writer.writeEndElement(); - writeln(); - } - - /* TODO: Icon attribuut gebruiken? - */ - if (p.details.kijkwijzer != null && !p.details.kijkwijzer.isEmpty()) { - writer.writeStartElement("rating"); - writer.writeAttribute("system", "kijkwijzer"); - writer.writeStartElement("value"); - for (int i=0; i