1   package com.webstersmalley.iplayer.feed;
2   
3   /**
4    *    Copyright 2009 Webster Smalley
5    *
6    *   Licensed under the Apache License, Version 2.0 (the "License");
7    *   you may not use this file except in compliance with the License.
8    *   You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing, software
13   *   distributed under the License is distributed on an "AS IS" BASIS,
14   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *   See the License for the specific language governing permissions and
16   *   limitations under the License.
17   *
18   */
19  
20  
21  import java.util.Random;
22  
23  import javax.xml.parsers.DocumentBuilder;
24  import javax.xml.parsers.DocumentBuilderFactory;
25  import javax.xml.xpath.XPath;
26  import javax.xml.xpath.XPathConstants;
27  import javax.xml.xpath.XPathExpression;
28  import javax.xml.xpath.XPathFactory;
29  
30  import org.apache.http.client.HttpClient;
31  import org.apache.http.client.ResponseHandler;
32  import org.apache.http.client.methods.HttpGet;
33  import org.apache.http.impl.client.BasicResponseHandler;
34  import org.apache.http.impl.client.DefaultHttpClient;
35  import org.apache.log4j.Logger;
36  import org.w3c.dom.Document;
37  import org.w3c.dom.Element;
38  
39  public class IPhoneProgramDownloader implements ProgramDownloader {
40  	private final Random random = new Random();
41  	private final XPath xpath = XPathFactory.newInstance().newXPath();
42  	private Logger logger = Logger.getLogger(getClass());
43  	
44  	private String decodeProgramGroupId(String programId) {
45  		String[] fields = programId.split(":");
46  		return fields[fields.length-1];
47  	}
48  	
49  	private String getRandomDigits(int length) {
50  		long mask = (new Double(Math.pow(10, length)).longValue() - 1);
51  		return new Long(random.nextLong()%mask).toString();
52  		
53  	}
54  	
55  	public void downloadProgram(Program program) {
56  		String programGroup = decodeProgramGroupId(program.getId());
57  		String playlistUrl = "http://www.bbc.co.uk/iplayer/playlist/" + programGroup;
58  		logger.debug("Got playlist Url: " + playlistUrl);
59  		
60  		try {
61  			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
62  			Document doc = builder.parse(playlistUrl);
63  
64  			XPathExpression expr = xpath.compile("//item");
65  			Element node = (Element)expr.evaluate(doc, XPathConstants.NODE);
66  			String programIdentifier = node.getAttribute("identifier");
67  			
68  			logger.debug("Got prog id: " + programIdentifier);
69  			
70  			String authUrl = "http://www.bbc.co.uk/mediaselector/3/auth/iplayer_streaming_http_mp3/" + programIdentifier + "?r=" + getRandomDigits(12);
71  			
72  			logger.debug("Auth URL is: " + authUrl);
73  			
74  			HttpClient client = new DefaultHttpClient();
75  			client.getParams().setParameter("http.useragent", "Apple iPhone v1.1.1 CoreMedia v1.0.0.3A110a");
76  			
77  			HttpGet get = new HttpGet(authUrl);
78  			
79  			ResponseHandler<String> handler = new BasicResponseHandler();
80  			
81  			
82  			String body = client.execute(get, handler);
83  		
84  			logger.info("Got: " + body);
85  			
86  		} catch (Exception e) {
87  			throw new RuntimeException("Error downloading program", e);
88  		}
89  	}
90  
91  }