summaryrefslogtreecommitdiff
path: root/src/Chapter2/restapi/RESTSearchExample.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/Chapter2/restapi/RESTSearchExample.java')
-rw-r--r--src/Chapter2/restapi/RESTSearchExample.java311
1 files changed, 311 insertions, 0 deletions
diff --git a/src/Chapter2/restapi/RESTSearchExample.java b/src/Chapter2/restapi/RESTSearchExample.java
new file mode 100644
index 0000000..510661c
--- /dev/null
+++ b/src/Chapter2/restapi/RESTSearchExample.java
@@ -0,0 +1,311 @@
+/* TweetTracker. Copyright (c) Arizona Board of Regents on behalf of Arizona State University
+ * @author shamanth
+ */
+package Chapter2.restapi;
+
+import Chapter2.support.OAuthTokenSecret;
+import Chapter2.openauthentication.OAuthExample;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import oauth.signpost.OAuthConsumer;
+import oauth.signpost.basic.DefaultOAuthConsumer;
+import oauth.signpost.exception.OAuthCommunicationException;
+import oauth.signpost.exception.OAuthExpectationFailedException;
+import oauth.signpost.exception.OAuthMessageSignerException;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+
+public class RESTSearchExample
+{
+ BufferedWriter OutFileWriter;
+ OAuthTokenSecret OAuthTokens;
+ OAuthConsumer Consumer;
+ String query = "#protest";
+ String DEF_FILENAME = "searchresults.json";
+
+ /**
+ * Creates a OAuthConsumer with the current consumer & user access tokens and secrets
+ * @return consumer
+ */
+ public OAuthConsumer GetConsumer()
+ {
+ OAuthConsumer consumer = new DefaultOAuthConsumer(utils.OAuthUtils.CONSUMER_KEY,utils.OAuthUtils.CONSUMER_SECRET);
+ consumer.setTokenWithSecret(OAuthTokens.getAccessToken(), OAuthTokens.getAccessSecret());
+ return consumer;
+ }
+
+ /**
+ * Load the User Access Token, and the User Access Secret
+ */
+ public void LoadTwitterToken()
+ {
+ //Un-comment before release
+// OAuthExample oae = new OAuthExample();
+// OAuthTokens = oae.GetUserAccessKeySecret();
+ //Remove before release
+ OAuthTokens = OAuthExample.DEBUGUserAccessSecret();
+ }
+
+ /**
+ * Fetches tweets matching a query
+ * @param query for which tweets need to be fetched
+ * @return an array of status objects
+ */
+ public JSONArray GetSearchResults(String query)
+ {
+ try{
+ //construct the request url
+ String URL_PARAM_SEPERATOR = "&";
+ StringBuilder url = new StringBuilder();
+ url.append("https://api.twitter.com/1.1/search/tweets.json?q=");
+ //query needs to be encoded
+ url.append(URLEncoder.encode(query, "UTF-8"));
+ url.append(URL_PARAM_SEPERATOR);
+ url.append("count=100");
+ URL navurl = new URL(url.toString());
+ HttpURLConnection huc = (HttpURLConnection) navurl.openConnection();
+ huc.setReadTimeout(5000);
+ Consumer.sign(huc);
+ huc.connect();
+ if(huc.getResponseCode()==400||huc.getResponseCode()==404||huc.getResponseCode()==429)
+ {
+ System.out.println(huc.getResponseMessage());
+ try {
+ huc.disconnect();
+ Thread.sleep(this.GetWaitTime("/friends/list"));
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ if(huc.getResponseCode()==500||huc.getResponseCode()==502||huc.getResponseCode()==503)
+ {
+ System.out.println(huc.getResponseMessage());
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ BufferedReader bRead = new BufferedReader(new InputStreamReader((InputStream) huc.getInputStream()));
+ String temp;
+ StringBuilder page = new StringBuilder();
+ while( (temp = bRead.readLine())!=null)
+ {
+ page.append(temp);
+ }
+ JSONTokener jsonTokener = new JSONTokener(page.toString());
+ try {
+ JSONObject json = new JSONObject(jsonTokener);
+ JSONArray results = json.getJSONArray("statuses");
+ return results;
+ } catch (JSONException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ } catch (OAuthCommunicationException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (OAuthMessageSignerException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (OAuthExpectationFailedException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ }catch(IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves the rate limit status of the application
+ * @return
+ */
+ public JSONObject GetRateLimitStatus()
+ {
+ try{
+ URL url = new URL("https://api.twitter.com/1.1/application/rate_limit_status.json");
+ HttpURLConnection huc = (HttpURLConnection) url.openConnection();
+ huc.setReadTimeout(5000);
+ OAuthConsumer consumer = new DefaultOAuthConsumer(utils.OAuthUtils.CONSUMER_KEY,utils.OAuthUtils.CONSUMER_SECRET);
+ consumer.setTokenWithSecret(OAuthTokens.getAccessToken(), OAuthTokens.getAccessSecret());
+ consumer.sign(huc);
+ huc.connect();
+ BufferedReader bRead = new BufferedReader(new InputStreamReader((InputStream) huc.getContent()));
+ StringBuffer page = new StringBuffer();
+ String temp= "";
+ while((temp = bRead.readLine())!=null)
+ {
+ page.append(temp);
+ }
+ bRead.close();
+ return (new JSONObject(page.toString()));
+ } catch (JSONException ex) {
+ Logger.getLogger(RESTApiExample.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (OAuthCommunicationException ex) {
+ Logger.getLogger(RESTApiExample.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (OAuthMessageSignerException ex) {
+ Logger.getLogger(RESTApiExample.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (OAuthExpectationFailedException ex) {
+ Logger.getLogger(RESTApiExample.class.getName()).log(Level.SEVERE, null, ex);
+ }catch(IOException ex)
+ {
+ Logger.getLogger(RESTApiExample.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return null;
+ }
+
+ /**
+ * Initialize the file writer
+ * @param path of the file
+ * @param outFilename name of the file
+ */
+ public void InitializeWriters(String outFilename) {
+ try {
+ File fl = new File(outFilename);
+ if(!fl.exists())
+ {
+ fl.createNewFile();
+ }
+ /**
+ * Use UTF-8 encoding when saving files to avoid
+ * losing Unicode characters in the data
+ */
+ OutFileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFilename,true),"UTF-8"));
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Close the opened filewriter to save the data
+ */
+ public void CleanupAfterFinish()
+ {
+ try {
+ OutFileWriter.close();
+ } catch (IOException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * Writes the retrieved data to the output file
+ * @param data containing the retrived information in JSON
+ * @param user name of the user currently being written
+ */
+ public void WriteToFile(JSONArray searchResults)
+ {
+ try
+ {
+ for(int i=0;i<searchResults.length();i++)
+ {
+ try {
+ OutFileWriter.write(searchResults.getJSONObject(i).toString());
+ OutFileWriter.newLine();
+ } catch (JSONException ex) {
+ Logger.getLogger(RESTSearchExample.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Retrieves the wait time if the API Rate Limit has been hit
+ * @param api the name of the API currently being used
+ * @return the number of milliseconds to wait before initiating a new request
+ */
+ public long GetWaitTime(String api)
+ {
+ JSONObject jobj = this.GetRateLimitStatus();
+ if(jobj!=null)
+ {
+ try {
+ if(!jobj.isNull("resources"))
+ {
+ JSONObject resourcesobj = jobj.getJSONObject("resources");
+ JSONObject statusobj = resourcesobj.getJSONObject("statuses");
+ JSONObject apilimit = statusobj.getJSONObject(api);
+ int numremhits = apilimit.getInt("remaining");
+ if(numremhits<=1)
+ {
+ long resettime = apilimit.getInt("reset");
+ resettime = resettime*1000; //convert to milliseconds
+ return resettime;
+ }
+ }
+ } catch (JSONException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Creates an OR search query from the supplied terms
+ * @param queryTerms
+ * @return a String formatted as term1 OR term2
+ */
+ public String CreateORQuery(ArrayList<String> queryTerms)
+ {
+ String OR_Operator = " OR ";
+ StringBuffer querystr = new StringBuffer();
+ int count = 1;
+ for(String term:queryTerms)
+ {
+ if(count==1)
+ {
+ querystr.append(term);
+ }
+ else
+ {
+ querystr.append(OR_Operator).append(term);
+ }
+ }
+ return querystr.toString();
+ }
+
+ public static void main(String[] args)
+ {
+ RESTSearchExample rse = new RESTSearchExample();
+ ArrayList<String> queryterms = new ArrayList<String>();
+ String outfilename = rse.DEF_FILENAME;
+ if(args!=null)
+ {
+ if(args.length>0)
+ {
+ for(int i=0;i<args.length;i++)
+ {
+ queryterms.add(args[i]);
+ }
+ }
+ else
+ {
+ queryterms.add(rse.query);
+ }
+ }
+ rse.LoadTwitterToken();
+ rse.Consumer = rse.GetConsumer();
+ System.out.println(rse.GetRateLimitStatus());
+ rse.InitializeWriters(outfilename);
+ JSONArray results = rse.GetSearchResults(rse.CreateORQuery(queryterms));
+ if(results!=null)
+ {
+ rse.WriteToFile(results);
+ }
+ rse.CleanupAfterFinish();
+ }
+}