package com.markupartist.iglaset.provider; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; import android.text.TextUtils; import android.util.Log; import com.markupartist.iglaset.util.HttpManager; import com.markupartist.iglaset.util.StringUtils; public class DrinksStore { private static String TAG = DrinksStore.class.getSimpleName(); private static String ARTICLES_BASE_URI = "http://www.iglaset.se/articles.xml"; private static String ARTICLE_DETAILS_URI = "http://www.iglaset.se/articles/%d.xml"; private static String RATE_URI = "http://www.iglaset.se/articles/%d/rate.xml?rating=%d&user_credentials=%s"; /** * Base URI for adding an article comment. */ private static String COMMENT_URI = "http://www.iglaset.se/comments.xml?user_credentials=%s"; private static String USER_RECOMMENDATIONS_URI = "http://www.iglaset.se/articles.xml?order_by=recommendation&recommendations=1"; private static String USER_RATINGS_URI = "http://www.iglaset.se/users/%d.xml?show=ratings"; private DrinksStore() { } private static class SingletonHolder { public static final DrinksStore instance = new DrinksStore(); } public static DrinksStore getInstance() { return SingletonHolder.instance; } public ArrayList<Drink> searchDrinks(SearchCriteria searchCriteria) throws IOException { final HttpGet get = new HttpGet(buildSearchUri(searchCriteria)); HttpEntity entity = null; final HttpResponse response = HttpManager.execute(get); entity = response.getEntity(); DrinksParser drinksParser = new DrinksParser(); return drinksParser.parse(entity.getContent()); } /** * Fins recommendations for the user. * @param searchCriteria the search criteria * @return list of recommendations * @throws IOException on connection problem */ public ArrayList<Drink> findRecommendations( RecommendationSearchCriteria searchCriteria) throws IOException { StringBuilder builder = new StringBuilder(String.format(USER_RECOMMENDATIONS_URI, searchCriteria.getUserId())); builder.append("&user_credentials=").append(searchCriteria.getAuthentication().v2.token); builder.append("&page=").append(searchCriteria.getPage()); builder.append(getSortModeParameter(searchCriteria.getSortMode())); final HttpGet get = new HttpGet(builder.toString()); HttpEntity entity = null; final HttpResponse response = HttpManager.execute(get); entity = response.getEntity(); DrinksParser drinksParser = new DrinksParser(); return drinksParser.parse(entity.getContent()); } /** * Find all drinks that the user has rated. * @param searchCriteria the search criteria * @return list of rated drinks * @throws IOException on connection problem */ public ArrayList<Drink> findRatedDrinks(RatingSearchCriteria searchCriteria) throws IOException { StringBuilder builder = new StringBuilder(String.format(USER_RATINGS_URI, searchCriteria.getUserId())); builder.append("&user_credentials=").append(searchCriteria.getAuthentication().v2.token); builder.append("&page=").append(searchCriteria.getPage()); builder.append(getSortModeParameter(searchCriteria.getSortMode())); Log.d(TAG, builder.toString()); final HttpGet get = new HttpGet(builder.toString()); HttpEntity entity = null; final HttpResponse response = HttpManager.execute(get); entity = response.getEntity(); DrinksParser drinksParser = new DrinksParser(); return drinksParser.parse(entity.getContent()); } public Drink getDrink(int id) { return getDrink(id, null); } public Drink getDrink(int id, AuthStore.Authentication authentication) { String searchUri = String.format(ARTICLE_DETAILS_URI, id); if (authentication != null && !TextUtils.isEmpty(authentication.v2.token)) { searchUri += "?user_credentials=" + authentication.v2.token; } final HttpGet get = new HttpGet(searchUri); ArrayList<Drink> drinks = new ArrayList<Drink>(); try { final HttpResponse response = HttpManager.execute(get); HttpEntity entity = response.getEntity(); DrinksParser drinksParser = new DrinksParser(); drinks = drinksParser.parse(entity.getContent()); } catch (IOException e) { Log.e(TAG, "Failed to read data: " + e.getMessage()); } Drink drink = null; if (drinks.size() == 1) { drink = drinks.get(0); } return drink; } public void rateDrink(Drink drink, float grade, AuthStore.Authentication authentication) { final HttpGet get = new HttpGet( String.format(RATE_URI, drink.getId(), (int) grade, authentication.v2.token)); HttpEntity entity = null; try { final HttpResponse response = HttpManager.execute(get); entity = response.getEntity(); entity.getContent(); } catch (IOException e) { Log.e(TAG, "Failed to read data: " + e.getMessage()); } } /** * Add a new comment to a drink. This will, unlike Android Market, add * an additional comment. It will not overwrite the user's previous one. * @param drink Drink to comment. * @param comment Comment to add. * @param authentication Authentication data. * @return Returns true if successful, false otherwise. * @throws IOException on connection problem. */ public Boolean commentDrink(Drink drink, String comment, AuthStore.Authentication authentication) throws IOException { final HttpPost post = new HttpPost(String.format(COMMENT_URI, authentication.v2.token)); ArrayList<NameValuePair> payload = new ArrayList<NameValuePair>(1); payload.add(new BasicNameValuePair("comment[article_id]", String.valueOf(drink.getId()))); payload.add(new BasicNameValuePair("comment[text]", comment)); try { post.setEntity(new UrlEncodedFormEntity(payload, "utf-8")); final HttpResponse response = HttpManager.execute(post); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return true; } else { Log.w(TAG, "Request failed, http status code was not OK."); return false; } } catch (UnsupportedEncodingException e) { // TODO What to do? :( e.printStackTrace(); return false; } } /** * Builds a the uri for search from a SearchCriteria * @param searchCriteria the search criteria * @return the search uri */ private String buildSearchUri(SearchCriteria searchCriteria) { Log.d(TAG, "building search uri from " + searchCriteria); StringBuilder builder = new StringBuilder(); builder.append(ARTICLES_BASE_URI).append("?"); builder.append("page=").append(searchCriteria.getPage()); if (!TextUtils.isEmpty(searchCriteria.getQuery())) builder.append("&str=").append(URLEncoder.encode(searchCriteria.getQuery())); if (searchCriteria.getCategory() > 0) builder.append("&category=").append(searchCriteria.getCategory()); if (searchCriteria.getAuthentication() != null && !TextUtils.isEmpty(searchCriteria.getAuthentication().v2.token)) builder.append("&user_credentials=").append(searchCriteria.getAuthentication().v2.token); builder.append(getSortModeParameter(searchCriteria.getSortMode())); ArrayList<Integer> tags = searchCriteria.getTags(); if (null != tags && tags.size() > 0) { builder.append("&tag_filter=or&tags[]="); builder.append(StringUtils.join(tags.toArray(), "&tags[]=")); } return builder.toString(); } private String getSortModeParameter(int mode) { String name = null; // Append sorting switch(mode) { case SearchCriteria.SORT_MODE_NAME: name = "name"; break; case SearchCriteria.SORT_MODE_RATING: name = "rating"; break; case SearchCriteria.SORT_MODE_PRODUCER: name = "producer"; break; case SearchCriteria.SORT_MODE_DATE: name = "time"; break; case SearchCriteria.SORT_MODE_NONE: default: name = null; break; } return (name != null ? "&order_by=" + name : ""); } }