package com.scoopit.client; import java.io.IOException; import java.util.Map; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; import org.codehaus.jackson.annotate.JsonMethod; import org.codehaus.jackson.map.DeserializationConfig; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.scribe.builder.ServiceBuilder; import org.scribe.model.OAuthConstants; import org.scribe.model.OAuthRequest; import org.scribe.model.Response; import org.scribe.model.Verb; import org.scribe.oauth.OAuthService; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; import com.scoopit.model.Post; import com.scoopit.model.ResolverResult; import com.scoopit.model.Topic; import com.scoopit.model.User; /** * Very basic scoop client that executes queries anonymously authenticated via * OAuth * */ public class ScoopClient { private ObjectMapper mapper; private OAuthService client; public ScoopClient(String apiKey, String apiSecret) { client = new ServiceBuilder().provider(ScoopApi.class).apiKey(apiKey) .apiSecret(apiSecret).build(); mapper = new ObjectMapper(); mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY); mapper.configure( DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); } /* * OAuthRequest request = builOAuthRequest(Verb.GET, endpoint); * * for (Map.Entry<String, String> parameter : parameters.entries()) { * request.addBodyParameter(parameter.getKey(), parameter.getValue()); } * * signRequest(request); return sendRequest(request); } */ private JsonNode doGet(String endpoint, Multimap<String, String> parameters) throws ScoopApiExecutionException { OAuthRequest request = builOAuthRequest(Verb.GET, endpoint); for (Map.Entry<String, String> parameter : parameters.entries()) { request.addQuerystringParameter(parameter.getKey(), parameter.getValue()); } signRequest(request); return sendRequest(request); } private OAuthRequest builOAuthRequest(Verb verb, String endpoint) { // Build oauth request OAuthRequest request; request = new OAuthRequest(verb, "http://www.scoop.it" + endpoint); // Allow direct access to running nodes request.addHeader("X-SCOOP-HCK-X-DOMAINS", "true"); return request; } private void signRequest(OAuthRequest request) { client.signRequest(OAuthConstants.EMPTY_TOKEN, request); } private JsonNode sendRequest(OAuthRequest request) throws ScoopApiExecutionException { Response response = request.send(); if (!response.isSuccessful()) { throw new ScoopApiExecutionException(response, "Error executing query: " + response.getCode() + " - " + response.getBody(), null); } JsonNode ret; try { ret = mapper.readTree(response.getBody()); } catch (JsonProcessingException e) { throw new ScoopApiExecutionException( response, "Error parsing the json in the response: " + e.getMessage(), e); } catch (IOException e) { throw new ScoopApiExecutionException(response, "Errore reading the response: " + e.getMessage(), e); } return ret; } // profile private static final String PROFILE_ENDPOINT = "/api/1/profile"; public User getUser(Long id) throws ScoopApiExecutionException { return getUser(id, null, null, null, null, null, null, null, null); } public User getUser(Long id, Integer curated, Integer curable, Integer ncomments, Boolean getCuratedTopics, Boolean getFollowedTopics, Boolean getTags, Boolean getCreator, Boolean getStats) throws ScoopApiExecutionException { Multimap<String, String> params = LinkedListMultimap.create(); if (id != null) { params.put("id", id.toString()); } if (curated != null) { params.put("curated", curated.toString()); } else { params.put("curated", "30"); } if (curable != null) { params.put("curable", curable.toString()); } else { params.put("curable", "0"); } if (ncomments != null) { params.put("ncomments", ncomments.toString()); } else { params.put("ncomments", "0"); } if (getCuratedTopics != null) { params.put("getCuratedTopics", getCuratedTopics.toString()); } else { params.put("getCuratedTopics", "false"); } if (getFollowedTopics != null) { params.put("getFollowedTopics", getFollowedTopics.toString()); } else { params.put("getFollowedTopics", "false"); } if (getTags != null) { params.put("getTags", getTags.toString()); } else { params.put("getTags", "false"); } if (getCreator != null) { params.put("getCreator", getCreator.toString()); } if (getStats != null) { params.put("getStats", getStats.toString()); } else { params.put("getStats", "false"); } JsonNode root = doGet(PROFILE_ENDPOINT, params); if (root == null) { return null; } User model; try { model = mapper.readValue(root.get("user"), User.class); } catch (JsonParseException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } return model; } // topic private static final String TOPIC_ENDPOINT = "/api/1/topic"; public enum TopicOrder { tag, curationDate, user } public Topic getTopic(long id) throws ScoopApiExecutionException { return getTopic(id, null, null, null, null, null, null, null); } public Topic getTopic(long id, int nb, int page) throws ScoopApiExecutionException { return getTopic(id, nb, page, null, null, null, null, null); } public Topic getTopic(long id, Integer curated, Integer page, Integer curable, TopicOrder order, String tag, Long since, Integer ncomments) throws ScoopApiExecutionException { Multimap<String, String> params = LinkedListMultimap.create(); params.put("id", Long.toString(id)); if (curated != null) { params.put("curated", curated.toString()); } else { params.put("curated", "30"); } if (curable != null) { params.put("curable", curable.toString()); } else { params.put("curable", "0"); } if (ncomments != null) { params.put("ncomments", ncomments.toString()); } else { params.put("ncomments", "0"); } JsonNode root = doGet(TOPIC_ENDPOINT, params); if (root == null) { return null; } Topic model; try { model = mapper.readValue(root.get("topic"), Topic.class); } catch (JsonParseException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } return model; } // post private static final String POST_ENDPOINT = "/api/1/post"; public Post getPost(long id) throws ScoopApiExecutionException { return getPost(id, null); } public Post getPost(long id, Integer ncomments) throws ScoopApiExecutionException { Multimap<String, String> params = LinkedListMultimap.create(); params.put("id", Long.toString(id)); if (ncomments != null) { params.put("ncomments", ncomments.toString()); } else { params.put("ncomments", "0"); } JsonNode root = doGet(POST_ENDPOINT, params); if (root == null) { return null; } Post model; try { model = mapper.readValue(root.get("post"), Post.class); } catch (JsonParseException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } return model; } // Resolver private static String RESOLVER_ENDPOINT = "/api/1/resolver"; public Long resolveId(String shortName, ResolverResult.Type type) throws ScoopApiExecutionException { Multimap<String, String> params = LinkedListMultimap.create(); if (type != null) { params.put("type", type.toString()); } else { params.put("type", "Topic"); } params.put("shortName", shortName); JsonNode root = doGet(RESOLVER_ENDPOINT, params); if (root == null) { return null; } ResolverResult model; try { model = mapper.readValue(root, ResolverResult.class); } catch (JsonParseException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } return model.id; } }