]> www.vanbest.org Git - tv_grab_nl_java/commitdiff
More work on RTL
authorJan-Pascal van Best <janpascal@vanbest.org>
Tue, 27 Mar 2012 15:42:14 +0000 (17:42 +0200)
committerJan-Pascal van Best <janpascal@vanbest.org>
Tue, 27 Mar 2012 15:42:14 +0000 (17:42 +0200)
src/main/java/org/vanbest/xmltv/Config.java
src/main/java/org/vanbest/xmltv/Programme.java
src/main/java/org/vanbest/xmltv/RTL.java
src/main/java/org/vanbest/xmltv/TvGidsProgramme.java

index 5e7bd009ab0e57dd2fa06b8222be6021a5e5c6c5..818f1b84d0f3f0e8889f9cdfac1ccd42f43ebc27 100644 (file)
@@ -85,6 +85,13 @@ public class Config {
                return FileUtils.getFile(FileUtils.getUserDirectory(), ".xmltv", "tv_grab_nl_java.cache");
        }
 
+       public String translateCategory(String category) {
+               if(!cattrans.containsKey(category.toLowerCase())) {
+                       return category;
+               }
+               return cattrans.get(category.toLowerCase());
+       }
+
        static private Map<String,String> getDefaultCattrans() {
                Map<String,String> result = new HashMap<String,String>();
                result.put("amusement", "Animated");
index 94c1f21352b11a772c2fa3601e783df90c86bd89..ddbe0b36800d6a70900490932b699f1511a36c9f 100644 (file)
@@ -1,7 +1,15 @@
 package org.vanbest.xmltv;
 
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
 
 public class Programme {
        class Title {
@@ -24,13 +32,36 @@ public class Programme {
                List<String> commentators;
                List<String> guests;
        }
-       public Channel channel; // required
+       class Length {
+               TimeUnit unit; 
+               int count;
+       }
+       class Icon {
+               URL url;
+               int width;
+               int height;
+       }
+       class Episode {
+           String episode;
+           String system; // onscreen or xmltv_ns
+       }
+       class Video {
+               boolean present;
+               boolean colour;
+               String aspect; // eg. 16:9, 4:3
+               String quality; // eg. 'HDTV', '800x600'.
+       }
+       class Audio {
+               boolean present;
+               String stereo; // 'mono','stereo','dolby','dolby digital','bilingual' or 'surround'. 
+       }
        public Date startTime; // required
        public Date endTime;
     public Date pdcStart;
     public Date vpsStart;
     public String showview;
     public String videoplus;
+       public Channel channel; // required
     public String clumpidx;    
     
     public List<Title> titles; // at least one
@@ -41,6 +72,72 @@ public class Programme {
     public List<Title> categories;
     Title language;
     Title origLanguage;
+    Length length;
+    public List<Icon> icons;
+    public List<URL> urls;
+    public List<Title> countries;
+    public List<Episode> episodes;
+    public Video video;
+    public Audio audio;
+    /*
+    previously-shown?, premiere?, last-chance?, new?,
+    subtitles*, rating*, star-rating*, review* 
+    */
     
+    public void addTitle(String title) {
+       addTitle(title, null);
+    }
+    public void addTitle(String title, String lang) {
+       if(titles==null) titles = new ArrayList<Title>();
+       Title t = new Title();
+       t.title = title;
+       t.lang = lang;
+       titles.add(t);
+    }
+       public void addCategory(String category) {
+       addCategory(category, null);
+    }
+    public void addCategory(String category, String lang) {
+       if(categories==null) categories = new ArrayList<Title>();
+       Title t = new Title();
+       t.title = category;
+       t.lang = lang;
+       categories.add(t);
+    }
+
+    public void serialize(XMLStreamWriter writer) throws XMLStreamException {
+               DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss Z");
+
+               writer.writeStartElement("programme");
+               if(startTime != null) writer.writeAttribute("start", df.format(startTime));
+               if(channel != null) writer.writeAttribute("channel", ""+channel.id);
+               if(titles != null) {
+                       for(Title title: titles) {
+                               writer.writeStartElement("title");
+                               if (title.lang != null) writer.writeAttribute("lang", title.lang);
+                               if (title.title != null) writer.writeCharacters(title.title);
+                               writer.writeEndElement();
+                       }
+               }
+               if(categories != null) {
+                       for(Title category: categories) {
+                               writer.writeStartElement("category");
+                               if (category.lang != null) writer.writeAttribute("lang", category.lang);
+                               if (category.title != null) writer.writeCharacters(category.title);
+                               writer.writeEndElement();
+                       }
+               }
+/*             for(Icon i: icons) {
+                       i.serialize(writer);
+               }
+               for(String url: urls) {
+                       writer.writeStartElement("url");
+                       writer.writeCharacters(url);
+                       writer.writeEndElement();
+               }
+*/             
+               writer.writeEndElement();
+               writer.writeCharacters(System.getProperty("line.separator"));
+       }
     
 }
index e23e8c205dde97ac10d71aa3d3f99a0fd6a821bc..53f6491bb31b5b95168ea207d4dd7e3b0224ae06 100644 (file)
@@ -9,15 +9,25 @@ import java.net.URL;
 import java.text.ParseException;\r
 import java.text.SimpleDateFormat;\r
 import java.util.ArrayList;\r
+import java.util.Calendar;\r
 import java.util.Date;\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.parsers.DocumentBuilderFactory;\r
 import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.parsers.SAXParser;\r
+import javax.xml.parsers.SAXParserFactory;\r
 import javax.xml.stream.XMLEventFactory;\r
 import javax.xml.stream.XMLOutputFactory;\r
 import javax.xml.stream.XMLStreamWriter;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
 \r
 import net.sf.json.JSON;\r
 import net.sf.json.JSONArray;\r
@@ -26,16 +36,24 @@ import net.sf.json.JSONObject;
 import org.vanbest.xmltv.EPGSource.Stats;\r
 import org.w3c.dom.Document;\r
 import org.w3c.dom.Element;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
 import org.xml.sax.SAXException;\r
 \r
 public class RTL extends AbstractEPGSource implements EPGSource  {\r
 \r
-       static final String programme_url="http://www.rtl.nl/active/epg_data/dag_data/";\r
-       static final String detail_url="http://www.rtl.nl/active/epg_data/uitzending_data/";\r
-       static final String icon_url="http://www.rtl.nl/service/gids/components/vaste_componenten/";\r
+       private static final String programme_url="http://www.rtl.nl/active/epg_data/dag_data/";\r
+       private static final String detail_url="http://www.rtl.nl/active/epg_data/uitzending_data/";\r
+       private static final String icon_url="http://www.rtl.nl/service/gids/components/vaste_componenten/";\r
+       private static final String xmltv_channel_suffix = ".rtl.nl";\r
+       private static final int MAX_PROGRAMMES_PER_DAY = 5;\r
+       \r
+       class RTLException extends Exception {\r
+               public RTLException(String s) {\r
+                       super(s);\r
+               }\r
+       }\r
        \r
-       Stats stats = new Stats();\r
-\r
        public RTL(Config config) {\r
                super(config);\r
        }\r
@@ -62,7 +80,7 @@ public class RTL extends AbstractEPGSource implements EPGSource  {
                JSONObject o = JSONObject.fromObject( json );\r
                for( Object k: o.keySet()) {\r
                        JSONArray j = (JSONArray) o.get(k);\r
-                       String id = k.toString().replaceAll("^Z", ""); // remove initial Z\r
+                       String id = genericChannelId(k.toString());\r
                        String name = (String) j.get(0);\r
                        String icon = icon_url+id+".gif";\r
                        \r
@@ -73,34 +91,8 @@ public class RTL extends AbstractEPGSource implements EPGSource  {
                return result;\r
        }\r
        \r
-       protected void fetchDay(int day) throws Exception {\r
-               URL url = new URL(programme_url+day);\r
-               String xmltext = fetchURL(url);\r
-               System.out.println(xmltext);\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
-               String json = root.getTextContent();\r
-               System.out.println("json: " + json);\r
-               JSONObject o = JSONObject.fromObject( json );\r
-               for( Object k: o.keySet()) {\r
-                       JSONArray j = (JSONArray) o.get(k);\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<3; i++) {\r
-                               JSONArray p = (JSONArray) j.get(i);\r
-                               String starttime = p.getString(0);\r
-                               String title = p.getString(1);\r
-                               String id = p.getString(2);\r
-                               String quark1 = p.getString(3);\r
-                               String quark2 = p.getString(4);\r
-                               System.out.println("    starttime: " + starttime);\r
-                               System.out.println("        title: " + title);\r
-                               System.out.println("           id: " + id);\r
-                               fetchDetail(id);\r
-                       }\r
-               }\r
+       private String genericChannelId(String jsonid) {\r
+               return jsonid.replaceAll("^Z", "")+xmltv_channel_suffix; // remove initial Z\r
        }\r
        \r
        /*\r
@@ -128,35 +120,133 @@ public class RTL extends AbstractEPGSource implements EPGSource  {
         * </uitzending_data>\r
 \r
         */\r
-       private void fetchDetail(String id) throws Exception {\r
-               // TODO Auto-generated method stub\r
-               URL url = new URL(detail_url+id);\r
-               String xmltext = fetchURL(url);\r
-               System.out.println(xmltext);\r
+       private void fetchDetail(Programme prog, String id) throws Exception {\r
+               URL url = detailUrl(id);\r
                Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url.openStream());\r
                Element root = xml.getDocumentElement();\r
+               if (root.hasAttributes()) {\r
+                       System.out.println("Unknown attributes for RTL detail root node");\r
+               }\r
+               NodeList nodes = root.getChildNodes();\r
+               for( int i=0; i<nodes.getLength(); i++) {\r
+                       Node n = nodes.item(i);\r
+                       System.out.println(n.getNodeName());\r
+                       if (!n.getNodeName().equals("uitzending_data_item")) {\r
+                               System.out.println("Ignoring RTL detail, tag " + n.getNodeName() +", full xml:");\r
+                               Transformer t = TransformerFactory.newInstance().newTransformer();\r
+                               t.transform(new DOMSource(xml),new StreamResult(System.out));\r
+                               System.out.println();\r
+                               continue;\r
+                       }\r
+                       // we have a uitzending_data_item node\r
+                       NodeList subnodes = n.getChildNodes();\r
+                       for( int j=0; j<subnodes.getLength(); j++) {\r
+                               try {\r
+                                       handleNode(prog, subnodes.item(j));\r
+                               } catch (RTLException e) {\r
+                                       System.out.println(e.getMessage());\r
+                                       Transformer t = TransformerFactory.newInstance().newTransformer();\r
+                                       t.transform(new DOMSource(xml),new StreamResult(System.out));\r
+                                       System.out.println();\r
+                                       continue;\r
+                               }\r
+                       }\r
+               }\r
        }\r
 \r
-       @Override\r
-       public Set<TvGidsProgramme> getProgrammes(List<Channel> channels, int day,\r
+       \r
+       private void handleNode(Programme prog, Node n) throws RTLException {\r
+               if (n.getNodeType() != Node.ELEMENT_NODE) {\r
+                       throw new RTLException("Ignoring non-element node " + n.getNodeName());\r
+               }\r
+               Element e = (Element)n;\r
+               switch (e.getTagName()) {\r
+               case "genre":\r
+                       prog.addCategory(config.translateCategory(e.getTextContent()));\r
+                       break;\r
+               default:\r
+                       throw new RTLException("Ignoring unknown tag " + n.getNodeName() + ", content: \"" + e.getTextContent() + "\"");\r
+               }\r
+               //prog.endTime = parseTime(date, root.)\r
+       }\r
+\r
+       public Set<Programme> getProgrammes1(List<Channel> channels, int day,\r
                        boolean fetchDetails) throws Exception {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
+               Set<Programme> result = new HashSet<Programme>();\r
+               Map<String,Channel> channelMap = new HashMap<String,Channel>();\r
+               for(Channel c: channels) {\r
+                       if (c.enabled) channelMap.put(c.id, c);\r
+               }\r
+               URL url = programmeUrl(day);\r
+               //String xmltext = fetchURL(url);\r
+               //System.out.println(xmltext);\r
+               Thread.sleep(config.niceMilliseconds);\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
+               String json = root.getTextContent();\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
+                               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("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 starttime = p.getString(0);\r
+                               String title = p.getString(1);\r
+                               String programme_id = p.getString(2);\r
+                               String quark1 = p.getString(3);\r
+                               String quark2 = p.getString(4);\r
+                               Programme prog = new Programme();\r
+                               prog.addTitle(title);\r
+                               Date start = parseTime(date, starttime);\r
+                               prog.startTime = start;\r
+                               prog.channel = channelMap.get(id);\r
+                               fetchDetail(prog, programme_id);\r
+                               result.add(prog);\r
+                       }\r
+               }\r
+               return result;\r
        }\r
 \r
-       @Override\r
-       public Stats getStats() {\r
-               // TODO Auto-generated method stub\r
-               return stats;\r
+       private Date parseTime(Date date, String time) {\r
+               Calendar result = Calendar.getInstance();\r
+               result.setTime(date);\r
+               String[] parts = time.split(":");\r
+               if(parts.length != 2) {\r
+                       \r
+               }\r
+               int hour = Integer.parseInt(parts[0]);\r
+               if (hour<4) {\r
+                       result.add(Calendar.DAY_OF_MONTH, 1); // early tomorrow morning\r
+               }\r
+               result.set(Calendar.HOUR_OF_DAY, hour);\r
+               result.set(Calendar.MINUTE, Integer.parseInt(parts[1]));\r
+               return result.getTime();\r
+       }\r
+\r
+       private static URL programmeUrl(int day) throws MalformedURLException {\r
+               return new URL(programme_url+day);\r
+       }\r
+       \r
+       private static URL detailUrl(String id) throws Exception {\r
+               return new URL(detail_url+id);\r
        }\r
 \r
        /**\r
         * @param args\r
         */\r
        public static void main(String[] args) {\r
-               RTL rtl = new RTL();\r
+               Config config = Config.getDefaultConfig();\r
+               RTL rtl = new RTL(config);\r
                try {\r
-                       // rtl.fetchDay(1);\r
                        List<Channel> channels = rtl.getChannels();\r
                        System.out.println("Channels: " + channels);\r
                        XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);\r
@@ -167,14 +257,24 @@ public class RTL extends AbstractEPGSource implements EPGSource  {
                        writer.writeCharacters("\n");\r
                        writer.writeStartElement("tv");\r
                        for(Channel c: channels) {c.serialize(writer);}\r
+                       Set<Programme> programmes = rtl.getProgrammes1(channels.subList(0, 3), 0, true);\r
+                       for(Programme p: programmes) {p.serialize(writer);}\r
                        writer.writeEndElement();\r
                        writer.writeEndDocument();\r
                        writer.flush();\r
+                       rtl.close();\r
                } catch (Exception e) {\r
                        // TODO Auto-generated catch block\r
                        e.printStackTrace();\r
                }\r
        }\r
 \r
+       @Override\r
+       public Set<TvGidsProgramme> getProgrammes(List<Channel> channels, int day,\r
+                       boolean fetchDetails) throws Exception {\r
+               // TODO Refactor EPGSource to return Programme instead of TvGidsProgramme\r
+               return null;\r
+       }\r
+\r
 \r
 }\r
index c78fa82a98336bc8fd8057b50197057a57b3ef06..5ec1872b572492731f617c00a8e4f8a892fe8328 100644 (file)
@@ -126,9 +126,7 @@ public class TvGidsProgramme {
                 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());
-                }
+                genre = config.translateCategory(genre);
          }
 
          public String toString() {