diff options
Diffstat (limited to 'src/de/danoeh/antennapod/miroguide/conn')
3 files changed, 305 insertions, 0 deletions
diff --git a/src/de/danoeh/antennapod/miroguide/conn/MiroGuideConnector.java b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideConnector.java new file mode 100644 index 000000000..4637c7725 --- /dev/null +++ b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideConnector.java @@ -0,0 +1,128 @@ +package de.danoeh.antennapod.miroguide.conn; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.net.Uri; + +/** Executes HTTP requests and returns the results. */ +public class MiroGuideConnector { + private HttpClient httpClient; + + private static final String HOST_URL = "https://www.miroguide.com/api/"; + private static final String PATH_GET_CHANNELS = "get_channels"; + private static final String PATH_LIST_CATEGORIES = "list_categories"; + private static final String PATH_GET_CHANNEL = "get_channel"; + + public MiroGuideConnector() { + httpClient = new DefaultHttpClient(); + } + + public void shutdown() { + httpClient.getConnectionManager().shutdown(); + } + + private Uri.Builder getBaseURIBuilder(String path) { + Uri.Builder builder = Uri.parse(HOST_URL).buildUpon(); + builder.appendPath(path).appendQueryParameter("datatype", "json"); + return builder; + } + + public JSONArray getArrayResponse(Uri uri) throws MiroGuideException { + try { + JSONArray result = new JSONArray(executeRequest(uri)); + return result; + } catch (JSONException e) { + e.printStackTrace(); + throw new MiroGuideException(); + } + } + + public JSONObject getSingleObjectResponse(Uri uri) throws MiroGuideException { + try { + JSONObject result = new JSONObject(executeRequest(uri)); + return result; + } catch (JSONException e) { + e.printStackTrace(); + throw new MiroGuideException(); + } + } + + /** + * Executes a HTTP GET request with the given URI and returns the content of + * the return value. + * + * @throws MiroGuideException + */ + private String executeRequest(Uri uri) throws MiroGuideException { + HttpGet httpGet = new HttpGet(uri.toString()); + String result = null; + try { + HttpResponse response = httpClient.execute(httpGet); + if (response.getStatusLine().getStatusCode() == 200) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + InputStream in = entity.getContent(); + + BufferedReader reader = new BufferedReader( + new InputStreamReader(in)); + result = reader.readLine(); + in.close(); + } + } else { + throw new MiroGuideException(response.getStatusLine() + .getReasonPhrase()); + } + } catch (IOException e) { + e.printStackTrace(); + throw new MiroGuideException(e.getMessage()); + } + return result; + + } + + public Uri createGetChannelsUri(String filter, String filterValue, + String sort, String limit, String offset) throws MiroGuideException { + Uri.Builder resultBuilder = getBaseURIBuilder(PATH_GET_CHANNELS); + resultBuilder.appendQueryParameter("filter", filter) + .appendQueryParameter("filter_value", filterValue); + + if (sort != null) { + resultBuilder.appendQueryParameter("sort", sort); + } + if (limit != null) { + resultBuilder.appendQueryParameter("limit", limit); + } + if (offset != null) { + resultBuilder.appendQueryParameter("offset", offset); + } + Uri result = resultBuilder.build(); + return result; + } + + public Uri createListCategoriesURI() throws MiroGuideException { + Uri.Builder resultBuilder = getBaseURIBuilder(PATH_LIST_CATEGORIES); + Uri result = resultBuilder.build(); + + return result; + } + + public Uri createGetChannelUri(String id) throws MiroGuideException { + Uri.Builder resultBuilder = getBaseURIBuilder(PATH_GET_CHANNEL) + .appendQueryParameter("id", id); + Uri result = resultBuilder.build(); + return result; + } + +} diff --git a/src/de/danoeh/antennapod/miroguide/conn/MiroGuideException.java b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideException.java new file mode 100644 index 000000000..6097761d8 --- /dev/null +++ b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideException.java @@ -0,0 +1,23 @@ +package de.danoeh.antennapod.miroguide.conn; + +public class MiroGuideException extends Exception { + private static final long serialVersionUID = -8834656185748713194L; + + public MiroGuideException() { + super(); + } + + public MiroGuideException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public MiroGuideException(String arg0) { + super(arg0); + } + + public MiroGuideException(Throwable arg0) { + super(arg0); + } + + +} diff --git a/src/de/danoeh/antennapod/miroguide/conn/MiroGuideService.java b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideService.java new file mode 100644 index 000000000..5cb137574 --- /dev/null +++ b/src/de/danoeh/antennapod/miroguide/conn/MiroGuideService.java @@ -0,0 +1,154 @@ +package de.danoeh.antennapod.miroguide.conn; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import de.danoeh.antennapod.miroguide.model.MiroGuideChannel; +import de.danoeh.antennapod.miroguide.model.MiroGuideItem; + + +/** Provides methods to communicate with the Miroguide API on an abstract level. */ +public class MiroGuideService { + private static final String TAG = "MiroGuideService"; + + public static final int DEFAULT_CHANNEL_LIMIT = 20; + + public static final String FILTER_CATEGORY = "category"; + public static final String FILTER_NAME = "name"; + public static final String SORT_NAME = "name"; + public static final String SORT_POPULAR = "popular"; + public static final String SORT_RATING = "rating"; + + public static final String JSON_DATE_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ss"; + + private MiroGuideConnector connector; + + private static ThreadLocal<SimpleDateFormat> jSONDateFormat = new ThreadLocal<SimpleDateFormat>() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat(JSON_DATE_FORMAT_STRING, Locale.US); + } + + }; + + public MiroGuideService() { + connector = new MiroGuideConnector(); + } + + public void close() { + connector.shutdown(); + } + + public String[] getCategories() throws MiroGuideException { + JSONArray resultArray = connector.getArrayResponse(connector + .createListCategoriesURI()); + String[] result = new String[resultArray.length()]; + for (int i = 0; i < resultArray.length(); i++) { + try { + result[i] = resultArray.getJSONObject(i).getString("name"); + } catch (JSONException e) { + e.printStackTrace(); + throw new MiroGuideException(); + } + } + return result; + } + + /** Get a list of MiroGuideChannel objects without their items. */ + public List<MiroGuideChannel> getChannelList(String filter, String filterValue, + String sort, int limit, int offset) throws MiroGuideException { + JSONArray resultArray = connector.getArrayResponse(connector + .createGetChannelsUri(filter, filterValue, sort, + Integer.toString(limit), Integer.toString(offset))); + int resultLen = resultArray.length(); + List<MiroGuideChannel> channels = new ArrayList<MiroGuideChannel>(resultLen); + for (int i = 0; i < resultLen; i++) { + JSONObject content = null; + try { + content = resultArray.getJSONObject(i); + MiroGuideChannel channel = extractMiroChannel(content, false); + channels.add(channel); + } catch (JSONException e) { + e.printStackTrace(); + throw new MiroGuideException(); + } + } + + return channels; + } + + /** + * Get a single channel with its items. + * + * @throws MiroGuideException + */ + public MiroGuideChannel getChannel(long id) throws MiroGuideException { + JSONObject resultObject = connector.getSingleObjectResponse(connector + .createGetChannelUri(Long.toString(id))); + MiroGuideChannel result = null; + try { + result = extractMiroChannel(resultObject, true); + } catch (JSONException e) { + e.printStackTrace(); + throw new MiroGuideException(); + } + return result; + } + + /** + * Get a MiroGuideChannel object from it's JSON source. The itemlist of the + * channel can be included or excluded + * + * @throws JSONException + */ + private MiroGuideChannel extractMiroChannel(JSONObject content, boolean withItems) + throws JSONException { + long id = content.getLong("id"); + String name = content.getString("name"); + String description = content.getString("description"); + String thumbnailUrl = content.optString("thumbnail_url"); + String downloadUrl = content.getString("url"); + String websiteUrl = content.getString("website_url"); + if (!withItems) { + return new MiroGuideChannel(id, name, thumbnailUrl, downloadUrl, + websiteUrl, description); + } else { + JSONArray itemData = content.getJSONArray("item"); + int numItems = itemData.length(); + ArrayList<MiroGuideItem> items = new ArrayList<MiroGuideItem>(numItems); + for (int i = 0; i < numItems; i++) { + items.add(extractMiroItem(itemData.getJSONObject(i))); + } + + return new MiroGuideChannel(id, name, thumbnailUrl, downloadUrl, + websiteUrl, description, items); + } + } + + /** Get a MiroGuideItem from its JSON source. */ + private MiroGuideItem extractMiroItem(JSONObject content) throws JSONException { + Date date = parseMiroItemDate(content.getString("date")); + String description = content.getString("description"); + String name = content.getString("name"); + String url = content.getString("url"); + return new MiroGuideItem(name, description, date, url); + } + + private Date parseMiroItemDate(String s) { + try { + return jSONDateFormat.get().parse(s); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + +} |