fetch them from rtl.nl.
cache = new ProgrammeCache(config);
}
- public List<Programme> getProgrammes(Channel channel, int day, boolean fetchDetails)
+ public List<Programme> getProgrammes(Channel channel, int day)
throws Exception {
ArrayList<Channel> list = new ArrayList<Channel>(2);
list.add(channel);
- return getProgrammes(list, day, fetchDetails);
+ return getProgrammes(list, day);
}
@Override
package org.vanbest.xmltv;\r
\r
import java.util.ArrayList;\r
-import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.List;\r
-import java.util.Map;\r
import java.util.Set;\r
\r
import javax.xml.stream.XMLStreamException;\r
protected boolean enabled = true;\r
int source;\r
\r
- public final static int CHANNEL_SOURCE_TVGIDS=1;\r
- public final static int CHANNEL_SOURCE_RTL=2;\r
- private final static String[] CHANNEL_SOURCE_NAMES={"tvgids.nl", "rtl.nl"};\r
- private static Map<String,Integer> channelSourceNameMap = new HashMap<String,Integer>();\r
-\r
- \r
protected Channel(int source, String id) {\r
this.id = id;\r
this.source = source;\r
}\r
\r
public String getXmltvChannelId() {\r
- switch (source) {\r
- case CHANNEL_SOURCE_TVGIDS:\r
- case CHANNEL_SOURCE_RTL:\r
- default:\r
- return id+"."+getSourceName();\r
- }\r
+ return id+"."+getSourceName();\r
}\r
\r
- public static String getChannelSourceName(int id) {\r
- return CHANNEL_SOURCE_NAMES[id-1];\r
- }\r
-\r
public String getSourceName() {\r
- return getChannelSourceName(source);\r
+ return EPGSourceFactory.getChannelSourceName(source);\r
}\r
\r
- public static int getChannelSourceId(String name) {\r
- if (channelSourceNameMap.isEmpty()) {\r
- int i=1;\r
- for (String s: CHANNEL_SOURCE_NAMES) {\r
- channelSourceNameMap.put(s, i);\r
- i++;\r
- }\r
- }\r
- return channelSourceNameMap.get(name);\r
- \r
- }\r
- \r
public void serialize(XMLStreamWriter writer) throws XMLStreamException {\r
writer.writeStartElement("channel");\r
writer.writeAttribute("id", getXmltvChannelId());\r
// command-line options
boolean quiet = false;
public int logLevel = LOG_DEFAULT;
+ boolean fetchDetails = true;
String project_version;
String build_time;
// System.out.println("Adding channel " + parts + " in file format " + fileformat);
switch(fileformat) {
case 0:
- c = Channel.getChannel(Channel.CHANNEL_SOURCE_TVGIDS, parts.get(1), parts.get(2));
+ c = Channel.getChannel(EPGSourceFactory.CHANNEL_SOURCE_TVGIDS, parts.get(1), parts.get(2));
if (parts.size()>3) {
c.addIcon(parts.get(3));
}
break;
case 1:
- c = Channel.getChannel(Channel.CHANNEL_SOURCE_TVGIDS, parts.get(1), parts.get(3));
+ c = Channel.getChannel(EPGSourceFactory.CHANNEL_SOURCE_TVGIDS, parts.get(1), parts.get(3));
if (parts.size()>4) {
c.addIcon(parts.get(4));
}
if (fileformat==2) {
source = Integer.parseInt(parts.get(1));
} else {
- source = Channel.getChannelSourceId(parts.get(1));
+ source = EPGSourceFactory.getChannelSourceId(parts.get(1));
}
c = Channel.getChannel(source, parts.get(2), parts.get(4));
if (parts.size()>5) {
import java.util.Set;
public interface EPGSource {
-
public class Stats {
int fetchErrors = 0;
int cacheHits = 0;
int cacheMisses = 0;
}
- public abstract void close() throws FileNotFoundException, IOException;
-
- public abstract List<Channel> getChannels();
+ public int getId();
+ public String getName();
+ public List<Channel> getChannels();
// Convenience method
- public abstract List<Programme> getProgrammes(Channel channel, int day,
- boolean fetchDetails) throws Exception;
-
- public abstract List<Programme> getProgrammes(List<Channel> channels,
- int day, boolean fetchDetails) throws Exception;
+ public List<Programme> getProgrammes(Channel channel, int day) throws Exception;
+ public List<Programme> getProgrammes(List<Channel> channels, int day) throws Exception;
- public abstract Stats getStats();
+ public Stats getStats();
public void clearCache();
-}
\ No newline at end of file
+ public void close() throws FileNotFoundException, IOException;
+}
--- /dev/null
+package org.vanbest.xmltv;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EPGSourceFactory {
+
+ public final static int CHANNEL_SOURCE_TVGIDS=1;
+ public final static int CHANNEL_SOURCE_RTL=2;
+
+ private final static int[] CHANNEL_IDS={CHANNEL_SOURCE_TVGIDS, CHANNEL_SOURCE_RTL};
+ private final static String[] CHANNEL_SOURCE_NAMES={"tvgids.nl", "rtl.nl"};
+ private static Map<String,Integer> channelSourceNameMap = new HashMap<String,Integer>();
+
+ private EPGSourceFactory() {
+ }
+
+ public static EPGSourceFactory newInstance() {
+ return new EPGSourceFactory();
+ }
+
+ public EPGSource createEPGSource(int source, Config config) {
+ switch(source) {
+ case EPGSourceFactory.CHANNEL_SOURCE_RTL:
+ return new RTL(config, false);
+ case EPGSourceFactory.CHANNEL_SOURCE_TVGIDS:
+ return new TvGids(config);
+ default:
+ return null;
+ }
+ }
+
+ public EPGSource createEPGSource(String source, Config config) {
+ int sourceId = EPGSourceFactory.getChannelSourceId(source);
+ return createEPGSource(sourceId, config);
+ }
+
+ public static String getChannelSourceName(int id) {
+ return CHANNEL_SOURCE_NAMES[id-1];
+ }
+
+ public static int getChannelSourceId(String name) {
+ if (channelSourceNameMap.isEmpty()) {
+ int i=1;
+ for (String s: EPGSourceFactory.CHANNEL_SOURCE_NAMES) {
+ EPGSourceFactory.channelSourceNameMap.put(s, i);
+ i++;
+ }
+ }
+ return EPGSourceFactory.channelSourceNameMap.get(name);
+ }
+
+ public int[] getAll() {
+ return CHANNEL_IDS;
+ }
+}
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
System.out.println("tv_grab_nl_java comes with ABSOLUTELY NO WARRANTY. It is free software, and you are welcome to redistribute it");
System.out.println("under certain conditions; `tv_grab_nl_java --license' for details.");
}
+
public void run() throws FactoryConfigurationError, Exception {
if (!config.quiet) {
showHeader();
- System.out.println("Fetching programme data for " + this.days + " starting from day " + this.offset);
+ System.out.println("Fetching programme data for " + this.days + " days starting from day " + this.offset);
int enabledCount = 0;
for(Channel c: config.channels) { if (c.enabled) enabledCount++; }
System.out.println("... from " + enabledCount + " channels");
System.out.println("... using cache at " + config.cacheDbHandle);
}
- EPGSource gids = new TvGids(config);
- if (clearCache) gids.clearCache();
+ Map<Integer,EPGSource> guides = new HashMap<Integer,EPGSource>();
+ EPGSourceFactory factory = EPGSourceFactory.newInstance();
+ //EPGSource gids = new TvGids(config);
+ //if (clearCache) gids.clearCache();
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputWriter);
writer.writeStartDocument();
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 "+config.project_version + ", built " + config.build_time);
+ writer.writeCharacters(System.getProperty("line.separator"));
for(Channel c: config.channels) if (c.enabled) c.serialize(writer);
for(Channel c: config.channels) {
if (!c.enabled) continue;
if (!config.quiet) System.out.print(".");
- List<Programme> programmes = gids.getProgrammes(c, day, true);
+ if(!guides.containsKey(c.source)) {
+ guides.put(c.source, factory.createEPGSource(c.source, config));
+ if (clearCache) guides.get(c.source).clearCache();
+ }
+ List<Programme> programmes = guides.get(c.source).getProgrammes(c, day);
for (Programme p: programmes) p.serialize(writer);
writer.flush();
}
writer.close();
try {
- gids.close();
+ for(int source: guides.keySet()) {
+ guides.get(source).close();
+ }
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!config.quiet) {
- EPGSource.Stats stats = gids.getStats();
+ EPGSource.Stats stats = new EPGSource.Stats();
+ for(int source: guides.keySet()) {
+ EPGSource.Stats part = guides.get(source).getStats();
+ stats.cacheHits += part.cacheHits;
+ stats.cacheMisses += part.cacheMisses;
+ stats.fetchErrors += part.fetchErrors;
+ }
System.out.println("Number of programmes from cache: " + stats.cacheHits);
System.out.println("Number of programmes fetched: " + stats.cacheMisses);
System.out.println("Number of fetch errors: " + stats.fetchErrors);
public void configure() throws IOException {
showHeader();
- EPGSource gids = new TvGids(config);
-
- Set<String> oldChannels = new HashSet<String>();
- for (Channel c: config.channels) {
- if (c.enabled) {
- oldChannels.add(c.source+"::"+c.id);
- }
- }
- List<Channel> channels = gids.getChannels();
-
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Delay between each request to the server (in milliseconds, default="+config.niceMilliseconds+"):");
// public String cacheDbHandle;
// public String cacheDbUser;
// public String cacheDbPassword;
+
+
+ EPGSourceFactory factory = EPGSourceFactory.newInstance();
+ int[] sources = factory.getAll();
+
+ System.out.println("Please select the TV programme information sources to use");
+ List<EPGSource> guides = new ArrayList<EPGSource>();
+ for(int source: sources) {
+ EPGSource guide = factory.createEPGSource(source, config);
+ System.out.print(" Use \"" + guide.getName() + "\" (Y/N):");
+ while(true) {
+ String s = reader.readLine().toLowerCase();
+ if ( s.startsWith("y")) {
+ guides.add(guide);
+ break;
+ } else if (s.startsWith("n")) {
+ break;
+ }
+ }
+ }
+
+ //EPGSource gids = new TvGids(config);
+
+ Set<String> oldChannels = new HashSet<String>();
+ for (Channel c: config.channels) {
+ if (c.enabled) {
+ oldChannels.add(c.source+"::"+c.id);
+ }
+ }
+
+ List<Channel> channels = new ArrayList<Channel>();
+ for(EPGSource guide: guides) {
+ channels.addAll(guide.getChannels());
+ }
boolean all = false;
boolean none = false;
try {
db = DriverManager.getConnection(config.cacheDbHandle, config.cacheDbUser, config.cacheDbPassword);
Statement stat = db.createStatement();
- stat.execute("CREATE TABLE IF NOT EXISTS cache (id VARCHAR(64) PRIMARY KEY, date DATE, programme OTHER)");
+ stat.execute("CREATE TABLE IF NOT EXISTS cache (source INTEGER, id VARCHAR(64), date DATE, programme OTHER, PRIMARY KEY (source,id))");
stat.close();
- getStatement = db.prepareStatement("SELECT programme FROM cache WHERE id=?");
- putStatement = db.prepareStatement("INSERT INTO cache VALUES (?,?,?)");
- removeStatement = db.prepareStatement("DELETE FROM cache WHERE id=?");
+ getStatement = db.prepareStatement("SELECT programme FROM cache WHERE source=? AND id=?");
+ putStatement = db.prepareStatement("INSERT INTO cache VALUES (?,?,?,?)");
+ removeStatement = db.prepareStatement("DELETE FROM cache WHERE source=? AND id=?");
clearStatement = db.prepareStatement("DELETE FROM cache");
} catch (SQLException e) {
db = null;
}
}
- public Programme get(String id) {
+ public Programme get(int source, String id) {
if (db==null) return null;
try {
- getStatement.setString(1, id);
+ getStatement.setInt(1, source);
+ getStatement.setString(2, id);
ResultSet r = getStatement.executeQuery();
if (!r.next()) return null; // not found
try {
Programme result = (Programme) r.getObject("programme");
return result;
} catch (java.sql.SQLDataException e) {
- removeCacheEntry(id);
+ removeCacheEntry(source, id);
return null;
}
} catch (SQLException e) {
}
}
- private void removeCacheEntry(String id) {
+ private void removeCacheEntry(int source, String id) {
try {
- removeStatement.setString(1, id);
+ removeStatement.setInt(1, source);
+ removeStatement.setString(2, id);
removeStatement.execute();
} catch (SQLException e) {
// TODO Auto-generated catch block
}
}
- public void put(String id, Programme prog) {
+ public void put(int source, String id, Programme prog) {
if (db == null) return;
try {
- putStatement.setString(1, id);
- putStatement.setDate(2, new java.sql.Date(prog.startTime.getTime()));
- putStatement.setObject(3, prog);
+ putStatement.setInt(1, source);
+ putStatement.setString(2, id);
+ putStatement.setDate(3, new java.sql.Date(prog.startTime.getTime()));
+ putStatement.setObject(4, prog);
+ //System.out.println(putStatement.toString());
int count = putStatement.executeUpdate();
if (count!=1 && !config.quiet) {
System.out.println("Weird, cache database update statement affected " + count + " rows");
import java.text.SimpleDateFormat;\r
import java.util.ArrayList;\r
import java.util.Calendar;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
import java.util.Date;\r
import java.util.HashMap;\r
import java.util.HashSet;\r
}\r
}\r
\r
+ public int getId() {\r
+ return EPGSourceFactory.CHANNEL_SOURCE_RTL;\r
+ }\r
+ \r
+ public String getName() {\r
+ return EPGSourceFactory.getChannelSourceName(getId());\r
+ }\r
+ \r
public List<Channel> getChannels() {\r
List<Channel> result = new ArrayList<Channel>(10);\r
\r
String name = (String) j.get(0);\r
String icon = icon_url+id+".gif";\r
\r
- Channel c = Channel.getChannel(Channel.CHANNEL_SOURCE_RTL, id, name, icon);\r
+ Channel c = Channel.getChannel(EPGSourceFactory.CHANNEL_SOURCE_RTL, id, name, icon);\r
result.add(c);\r
}\r
\r
+ Collections.sort(result, new Comparator<Channel>() {\r
+ public int compare(Channel o1, Channel o2) {\r
+ if (o1.source==o2.source) {\r
+ int c1=Integer.parseInt(o1.id);\r
+ int c2=Integer.parseInt(o2.id);\r
+ return (c1==c2 ? 0 : ((c1<c2)?-1:1) );\r
+ } else {\r
+ return o1.source<o2.source?-1:1;\r
+ }\r
+ }\r
+ });\r
return result;\r
}\r
\r
}\r
\r
@Override\r
- public List<Programme> getProgrammes(List<Channel> channels, int day,\r
- boolean fetchDetails) throws Exception {\r
+ public List<Programme> getProgrammes(List<Channel> channels, int day) throws Exception {\r
List<Programme> result = new LinkedList<Programme>();\r
Map<String,Channel> channelMap = new HashMap<String,Channel>();\r
for(Channel c: channels) {\r
- if (c.enabled && c.source==Channel.CHANNEL_SOURCE_RTL) channelMap.put(c.id, c);\r
+ if (c.enabled && c.source==EPGSourceFactory.CHANNEL_SOURCE_RTL) channelMap.put(c.id, c);\r
}\r
URL url = programmeUrl(day);\r
//String xmltext = fetchURL(url);\r
Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url.openStream());\r
Element root = xml.getDocumentElement();\r
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(root.getAttribute("date"));\r
- System.out.println("date: " + date);\r
+ //System.out.println("date: " + date);\r
String json = root.getTextContent();\r
- System.out.println("json: " + json);\r
+ //System.out.println("json: " + json);\r
JSONObject o = JSONObject.fromObject( json );\r
for( Object k: o.keySet()) {\r
String id = genericChannelId(k.toString());\r
if(!channelMap.containsKey(id)) {\r
- if (!config.quiet) System.out.println("Skipping programmes for channel " + id);\r
+ //if (!config.quiet) System.out.println("Skipping programmes for channel " + id);\r
continue;\r
}\r
JSONArray j = (JSONArray) o.get(k);\r
- System.out.println(k.toString()+": "+j.toString());\r
+ //System.out.println(k.toString()+": "+j.toString());\r
//System.out.println("Channel name:" + j.get(0));\r
for (int i=1; i<j.size() && i<MAX_PROGRAMMES_PER_DAY; i++) {\r
JSONArray p = (JSONArray) j.get(i);\r
String programme_id = p.getString(2);\r
String quark1 = p.getString(3);\r
String quark2 = p.getString(4);\r
- Programme prog = cache.get(programme_id);\r
+ Programme prog = cache.get(getId(), programme_id);\r
if (prog == null) {\r
stats.cacheMisses++;\r
prog = new Programme();\r
prog.addTitle(title);\r
prog.startTime = parseTime(date, starttime);\r
prog.channel = channelMap.get(id).getXmltvChannelId();\r
- if (fetchDetails) {\r
+ if (config.fetchDetails) {\r
fetchDetail(prog, date, programme_id);\r
}\r
- cache.put(programme_id, prog);\r
+ cache.put(getId(), programme_id, prog);\r
} else {\r
stats.cacheHits++;\r
}\r
writer.writeStartElement("tv");\r
for(Channel c: channels) {c.serialize(writer);}\r
writer.flush();\r
- List<Programme> programmes = rtl.getProgrammes(channels.subList(6, 9), 0, true);\r
+ List<Programme> programmes = rtl.getProgrammes(channels.subList(6, 9), 0);\r
//List<Programme> programmes = rtl.getProgrammes(channels, 0, true);\r
for(Programme p: programmes) {p.serialize(writer);}\r
writer.writeEndElement();\r
super(config);
}
+ public int getId() {
+ return EPGSourceFactory.CHANNEL_SOURCE_TVGIDS;
+ }
+
+ public String getName() {
+ return EPGSourceFactory.getChannelSourceName(getId());
+ }
+
public static URL programmeUrl(List<Channel> channels, int day) throws Exception {
StringBuilder s = new StringBuilder(programme_base_url);
if (channels.size() < 1) {
int id = zender.getInt("id");
String name = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(zender.getString("name"));
String icon = "http://tvgidsassets.nl/img/channels/53x27/" + id + ".png";
- Channel c = Channel.getChannel(Channel.CHANNEL_SOURCE_TVGIDS, Integer.toString(id), name, icon);
+ Channel c = Channel.getChannel(EPGSourceFactory.CHANNEL_SOURCE_TVGIDS, Integer.toString(id), name, icon);
result.add(c);
}
* @see org.vanbest.xmltv.EPGSource#getProgrammes(java.util.List, int, boolean)
*/
@Override
- public List<Programme> getProgrammes(List<Channel> channels, int day, boolean fetchDetails) throws Exception {
+ public List<Programme> getProgrammes(List<Channel> channels, int day) throws Exception {
List<Programme> result = new ArrayList<Programme>();
URL url = programmeUrl(channels, day);
JSONArray programs = (JSONArray) ps;
for( int i=0; i<programs.size() && i<MAX_PROGRAMMES_PER_DAY; i++ ) {
JSONObject programme = programs.getJSONObject(i);
- Programme p = programmeFromJSON(programme, fetchDetails);
+ Programme p = programmeFromJSON(programme, config.fetchDetails);
p.channel = c.getXmltvChannelId();
result.add(p);
}
for( Object o: programs.keySet() ) {
if (count>MAX_PROGRAMMES_PER_DAY) break;
JSONObject programme = programs.getJSONObject(o.toString());
- Programme p = programmeFromJSON(programme, fetchDetails);
+ Programme p = programmeFromJSON(programme, config.fetchDetails);
p.channel = c.getXmltvChannelId();
result.add(p);
count++;
*/
private Programme programmeFromJSON(JSONObject programme, boolean fetchDetails) throws Exception {
String id = programme.getString("db_id");
- Programme result = cache.get(id);
+ Programme result = cache.get(getId(), id);
boolean cached = (result != null);
if (result == null) {
stats.cacheMisses++;
}
if (!cached) {
// FIXME where to do this?
- cache.put(id, result);
+ cache.put(getId(), id, result);
}
if(config.logProgrammes()) {
System.out.println(result.toString());
List<Channel> my_channels = channels.subList(0,15);
for(Channel c: my_channels) {c.serialize(writer);}
writer.flush();
- List<Programme> programmes = gids.getProgrammes(my_channels, 2, true);
+ List<Programme> programmes = gids.getProgrammes(my_channels, 2);
for(Programme p: programmes) {p.serialize(writer);}
writer.writeEndElement();
writer.writeEndDocument();