Browse Source

Initial work on Twitter searching (with hashtags)

Change-Id: Ieb45d85e606bf0a883a5c2fb56e14841f9827ab5
Reviewed-on: http://gerrit.dmdirc.com/1310
Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com>
Reviewed-by: Shane Mc Cormack <shane@dmdirc.com>
tags/0.6.4
Chris Smith 14 years ago
parent
commit
d6e817728c

+ 26
- 0
src/com/dmdirc/addons/parser_twitter/Twitter.java View File

267
                             this.channels.put(channel, newChannel);
267
                             this.channels.put(channel, newChannel);
268
                         }
268
                         }
269
                     } catch (NumberFormatException nfe) { }
269
                     } catch (NumberFormatException nfe) { }
270
+                } else if (channel.startsWith("#")) {
271
+                    newChannel.setLocalTopic("Search results for " + channel);
272
+                    synchronized (this.channels) {
273
+                        this.channels.put(channel, newChannel);
274
+                    }
270
                 }
275
                 }
276
+                
271
                 doJoinChannel(newChannel);
277
                 doJoinChannel(newChannel);
272
             } else {
278
             } else {
273
                 sendNumericOutput(474, new String[]{":"+myServerName, "474", myself.getNickname(), channel, "Cannot join channel - name is not valid, or you are already there."});
279
                 sendNumericOutput(474, new String[]{":"+myServerName, "474", myself.getNickname(), channel, "Cannot join channel - name is not valid, or you are already there."});
1000
         long lastReplyId = -1;
1006
         long lastReplyId = -1;
1001
         long lastTimelineId = -1;
1007
         long lastTimelineId = -1;
1002
         long lastDirectMessageId = -1;
1008
         long lastDirectMessageId = -1;
1009
+        final Map<TwitterChannelInfo, Long> lastSearchIds = new HashMap<TwitterChannelInfo, Long>();
1003
 
1010
 
1004
         if (saveLastIDs) {
1011
         if (saveLastIDs) {
1005
             if (getConfigManager().hasOptionString(myPlugin.getDomain(), "lastReplyId-"+myServerName+"-"+myUsername)) {
1012
             if (getConfigManager().hasOptionString(myPlugin.getDomain(), "lastReplyId-"+myServerName+"-"+myUsername)) {
1094
                 }
1101
                 }
1095
             }
1102
             }
1096
 
1103
 
1104
+            for (TwitterChannelInfo searchChannel : channels.values()) {
1105
+                if (searchChannel.getName().startsWith("#")) {
1106
+                    long lastId = lastSearchIds.containsKey(searchChannel)
1107
+                            ? lastSearchIds.get(searchChannel) : -1;
1108
+                    final List<TwitterStatus> statuses
1109
+                            = api.getSearchResults(searchChannel.getName(), lastId);
1110
+
1111
+                    for (TwitterStatus status : statuses) {
1112
+                        final ChannelClientInfo cci = searchChannel
1113
+                                .getChannelClient(status.getUserName(), true);
1114
+                        sendChannelMessage(searchChannel, new Date(status.getTime()),
1115
+                                status.getText(), cci, status.getUserName());
1116
+                        lastId = Math.max(lastId, status.getID());
1117
+                    }
1118
+
1119
+                    lastSearchIds.put(searchChannel, lastId);
1120
+                }
1121
+            }
1122
+
1097
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastReplyId-"+myServerName+"-"+myUsername, Long.toString(lastReplyId));
1123
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastReplyId-"+myServerName+"-"+myUsername, Long.toString(lastReplyId));
1098
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastTimelineId-"+myServerName+"-"+myUsername, Long.toString(lastTimelineId));
1124
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastTimelineId-"+myServerName+"-"+myUsername, Long.toString(lastTimelineId));
1099
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastDirectMessageId-"+myServerName+"-"+myUsername, Long.toString(lastDirectMessageId));
1125
             IdentityManager.getConfigIdentity().setOption(myPlugin.getDomain(), "lastDirectMessageId-"+myServerName+"-"+myUsername, Long.toString(lastDirectMessageId));

+ 64
- 13
src/com/dmdirc/addons/parser_twitter/api/TwitterAPI.java View File

23
 package com.dmdirc.addons.parser_twitter.api;
23
 package com.dmdirc.addons.parser_twitter.api;
24
 
24
 
25
 import java.io.BufferedReader;
25
 import java.io.BufferedReader;
26
+import java.io.ByteArrayInputStream;
26
 import java.io.IOException;
27
 import java.io.IOException;
28
+import java.io.InputStreamReader;
29
+import java.io.UnsupportedEncodingException;
27
 import java.net.HttpURLConnection;
30
 import java.net.HttpURLConnection;
28
 import java.net.MalformedURLException;
31
 import java.net.MalformedURLException;
32
+import java.net.NoRouteToHostException;
29
 import java.net.ProtocolException;
33
 import java.net.ProtocolException;
30
 import java.net.URL;
34
 import java.net.URL;
35
+import java.net.URLEncoder;
36
+import java.text.ParseException;
37
+import java.text.SimpleDateFormat;
38
+import java.util.ArrayList;
31
 import java.util.HashMap;
39
 import java.util.HashMap;
40
+import java.util.LinkedList;
32
 import java.util.List;
41
 import java.util.List;
33
 import java.util.Map;
42
 import java.util.Map;
43
+
44
+import javax.xml.parsers.DocumentBuilder;
45
+import javax.xml.parsers.DocumentBuilderFactory;
34
 import javax.xml.parsers.ParserConfigurationException;
46
 import javax.xml.parsers.ParserConfigurationException;
47
+
35
 import oauth.signpost.OAuth;
48
 import oauth.signpost.OAuth;
36
 import oauth.signpost.OAuthConsumer;
49
 import oauth.signpost.OAuthConsumer;
37
 import oauth.signpost.OAuthProvider;
50
 import oauth.signpost.OAuthProvider;
43
 import oauth.signpost.exception.OAuthNotAuthorizedException;
56
 import oauth.signpost.exception.OAuthNotAuthorizedException;
44
 import oauth.signpost.signature.SignatureMethod;
57
 import oauth.signpost.signature.SignatureMethod;
45
 
58
 
46
-import java.io.ByteArrayInputStream;
47
-
48
-import java.io.InputStreamReader;
49
-import java.io.UnsupportedEncodingException;
50
-import java.net.NoRouteToHostException;
51
-import java.net.URLEncoder;
52
-import java.text.ParseException;
53
-import java.text.SimpleDateFormat;
54
-import java.util.ArrayList;
55
-import java.util.LinkedList;
56
-import javax.xml.parsers.DocumentBuilder;
57
-import javax.xml.parsers.DocumentBuilderFactory;
58
-
59
 import org.w3c.dom.Document;
59
 import org.w3c.dom.Document;
60
 import org.w3c.dom.Element;
60
 import org.w3c.dom.Element;
61
 import org.w3c.dom.NodeList;
61
 import org.w3c.dom.NodeList;
1123
         return result;
1123
         return result;
1124
     }
1124
     }
1125
 
1125
 
1126
+    /**
1127
+     * Retrieves the search results for the specified term.
1128
+     *
1129
+     * @param term The term to be searched for
1130
+     * @return A list of matching statuses
1131
+     */
1132
+    public List<TwitterStatus> getSearchResults(final String term) {
1133
+        return getSearchResults(term, -1);
1134
+    }
1135
+
1136
+    /**
1137
+     * Retrieves the search results for the specified term, requesting only
1138
+     * statuses newer than the specified lastStatusId.
1139
+     *
1140
+     * @param term The term to be searched for
1141
+     * @param lastStatusId Maximum status ID to not be returned
1142
+     * @return A list of matching statuses
1143
+     */
1144
+    public List<TwitterStatus> getSearchResults(final String term, final long lastStatusId) {
1145
+        final List<TwitterStatus> result = new ArrayList<TwitterStatus>();
1146
+
1147
+        try {
1148
+            final XMLResponse doc = getXML("http://search.twitter.com/search.atom?since_id="
1149
+                    +lastStatusId + "&rpp=100&q=" + URLEncoder.encode(term, "utf-8"));
1150
+
1151
+            if (doc.isGood()) {
1152
+                final NodeList nodes = doc.getElementsByTagName("entry");
1153
+                for (int i = 0; i < nodes.getLength(); i++) {
1154
+                    final Element element = (Element) nodes.item(i);
1155
+                    final String message = TwitterAPI.getElementContents(element, "title", "");
1156
+                    final long id = Long.parseLong(TwitterAPI.getElementContents(element, "id", "::-1").split(":")[2]);
1157
+                    final String user = TwitterAPI.getElementContents((Element) element.getElementsByTagName("author").item(0), "name", "").split(" ")[0];
1158
+
1159
+                    final long time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(TwitterAPI.getElementContents(element, "published", "")).getTime();
1160
+
1161
+                    result.add(0, new TwitterStatus(this, message, -1, id, user, time));
1162
+                }
1163
+            }
1164
+        } catch (UnsupportedEncodingException ex) {
1165
+            if (isDebug()) {
1166
+                handleError(ex, "* (1) getSearchResults: "+term+" | "+lastStatusId, apiInput, apiOutput);
1167
+            }
1168
+        } catch (ParseException ex) {
1169
+            if (isDebug()) {
1170
+                handleError(ex, "* (2) getSearchResults: "+term+" | "+lastStatusId, apiInput, apiOutput);
1171
+            }
1172
+        }
1173
+
1174
+        return result;
1175
+    }
1176
+
1126
     /**
1177
     /**
1127
      * Get a list of TwitterUsers who we are following.
1178
      * Get a list of TwitterUsers who we are following.
1128
      *
1179
      *

+ 2
- 1
src/com/dmdirc/addons/parser_twitter/api/TwitterMessage.java View File

66
      * @param api
66
      * @param api
67
      * @param message Message contents
67
      * @param message Message contents
68
      * @param id ID of message
68
      * @param id ID of message
69
-     * @param sender User who send this.
69
+     * @param sender User who send this
70
+     * @param target User this message was sent to
70
      * @param time Time this message was sent
71
      * @param time Time this message was sent
71
      */
72
      */
72
     protected TwitterMessage(final TwitterAPI api, final String message, final long id, final String sender, final String target, final Long time) {
73
     protected TwitterMessage(final TwitterAPI api, final String message, final long id, final String sender, final String target, final Long time) {

+ 10
- 0
src/com/dmdirc/addons/parser_twitter/api/TwitterStatus.java View File

23
 package com.dmdirc.addons.parser_twitter.api;
23
 package com.dmdirc.addons.parser_twitter.api;
24
 
24
 
25
 import com.dmdirc.addons.parser_twitter.api.commons.StringEscapeUtils;
25
 import com.dmdirc.addons.parser_twitter.api.commons.StringEscapeUtils;
26
+
26
 import org.w3c.dom.Element;
27
 import org.w3c.dom.Element;
27
 import org.w3c.dom.Node;
28
 import org.w3c.dom.Node;
28
 import org.w3c.dom.NodeList;
29
 import org.w3c.dom.NodeList;
174
         return (this.retweet) ? this.originalStatus.getUser() : myAPI.getUser(this.user);
175
         return (this.retweet) ? this.originalStatus.getUser() : myAPI.getUser(this.user);
175
     }
176
     }
176
 
177
 
178
+    /**
179
+     * Retrieves the username of the owner of this message.
180
+     *
181
+     * @return This message's owner.
182
+     */
183
+    public String getUserName() {
184
+        return retweet ? originalStatus.getUserName() : user;
185
+    }
186
+
177
     /**
187
     /**
178
      * Get the contents of this message
188
      * Get the contents of this message
179
      *
189
      *

+ 3
- 0
src/com/dmdirc/addons/parser_twitter/api/XMLResponse.java View File

24
 
24
 
25
 import java.io.IOException;
25
 import java.io.IOException;
26
 import java.net.HttpURLConnection;
26
 import java.net.HttpURLConnection;
27
+
27
 import org.w3c.dom.Document;
28
 import org.w3c.dom.Document;
28
 import org.w3c.dom.Element;
29
 import org.w3c.dom.Element;
29
 import org.w3c.dom.NodeList;
30
 import org.w3c.dom.NodeList;
30
 
31
 
31
 /**
32
 /**
33
+ * Describes an XML formatted response from a URL connection.
32
  *
34
  *
33
  * @author shane
35
  * @author shane
34
  */
36
  */
35
 public class XMLResponse {
37
 public class XMLResponse {
38
+
36
     /** The HttpURLConnection that was used. */
39
     /** The HttpURLConnection that was used. */
37
     private final HttpURLConnection request;
40
     private final HttpURLConnection request;
38
 
41
 

Loading…
Cancel
Save