|
@@ -0,0 +1,271 @@
|
|
1
|
+/*
|
|
2
|
+ * To change this template, choose Tools | Templates
|
|
3
|
+ * and open the template in the editor.
|
|
4
|
+ */
|
|
5
|
+
|
|
6
|
+package com.md87.charliebravo.commands;
|
|
7
|
+
|
|
8
|
+import com.dmdirc.util.Downloader;
|
|
9
|
+import com.dmdirc.util.MapList;
|
|
10
|
+import com.md87.charliebravo.Command;
|
|
11
|
+import com.md87.charliebravo.Followup;
|
|
12
|
+import com.md87.charliebravo.InputHandler;
|
|
13
|
+import com.md87.charliebravo.Response;
|
|
14
|
+import java.io.StringReader;
|
|
15
|
+import java.net.URLEncoder;
|
|
16
|
+import java.nio.charset.Charset;
|
|
17
|
+import java.util.ArrayList;
|
|
18
|
+import java.util.HashMap;
|
|
19
|
+import java.util.LinkedList;
|
|
20
|
+import java.util.List;
|
|
21
|
+import java.util.Map;
|
|
22
|
+import org.jdom.Document;
|
|
23
|
+import org.jdom.Element;
|
|
24
|
+import org.jdom.Namespace;
|
|
25
|
+import org.jdom.input.SAXBuilder;
|
|
26
|
+
|
|
27
|
+/**
|
|
28
|
+ *
|
|
29
|
+ * @author chris
|
|
30
|
+ */
|
|
31
|
+public class NewzbinCommand implements Command {
|
|
32
|
+
|
|
33
|
+ protected static final String URL = "/search/query/?q=%s" +
|
|
34
|
+ "&area=-1&fpn=p&searchaction=Go&areadone=-1&sort=date&order=desc" +
|
|
35
|
+ "&feed=rss";
|
|
36
|
+
|
|
37
|
+ protected static final String LOGIN_URL = "https://www.newzbin.com/account/login";
|
|
38
|
+
|
|
39
|
+ @SuppressWarnings("unchecked")
|
|
40
|
+ public void execute(InputHandler handler, Response response, String line) throws Exception {
|
|
41
|
+ if (line.isEmpty()) {
|
|
42
|
+ response.sendMessage("You need to specify a search query", true);
|
|
43
|
+ } else {
|
|
44
|
+ final Map<String, String> args = new HashMap<String, String>();
|
|
45
|
+ args.put("ret_url", String.format(URL,
|
|
46
|
+ URLEncoder.encode(line, Charset.defaultCharset().name())));
|
|
47
|
+ args.put("username", "dataforce");
|
|
48
|
+ args.put("password", "dfrox");
|
|
49
|
+ final List<String> result = Downloader.getPage(LOGIN_URL, args);
|
|
50
|
+ final StringBuilder data = new StringBuilder();
|
|
51
|
+
|
|
52
|
+ for (String resultline : result) {
|
|
53
|
+ data.append(resultline);
|
|
54
|
+ data.append('\n');
|
|
55
|
+ }
|
|
56
|
+
|
|
57
|
+ System.out.println(data);
|
|
58
|
+
|
|
59
|
+ final Document document = new SAXBuilder().build(new StringReader(data.toString()));
|
|
60
|
+ final List<Result> results = new LinkedList<Result>();
|
|
61
|
+
|
|
62
|
+ for (Element item : (List<Element>) document.getRootElement()
|
|
63
|
+ .getChild("channel").getChildren("item")) {
|
|
64
|
+ results.add(new Result(item));
|
|
65
|
+ }
|
|
66
|
+
|
|
67
|
+ response.sendMessage("there " + (results.size() == 1 ? "was" : "were")
|
|
68
|
+ + " " + results.size() + " result" + (results.size() == 1 ? "s" : "")
|
|
69
|
+ + " returned." + (results.size() == 1 ? "It is: " : "The first one is: ")
|
|
70
|
+ + results.get(0).getSummary());
|
|
71
|
+ response.addFollowup(new AttributesFollowup(results.get(0)));
|
|
72
|
+ response.addFollowup(new NextFollowup(results, 1));
|
|
73
|
+ }
|
|
74
|
+
|
|
75
|
+ }
|
|
76
|
+
|
|
77
|
+ protected static class NextFollowup implements Followup {
|
|
78
|
+
|
|
79
|
+ private final List<Result> results;
|
|
80
|
+ private final int next;
|
|
81
|
+
|
|
82
|
+ public NextFollowup(List<Result> results, int next) {
|
|
83
|
+ this.results = results;
|
|
84
|
+ this.next = next;
|
|
85
|
+ }
|
|
86
|
+
|
|
87
|
+ public boolean matches(String line) {
|
|
88
|
+ return next < results.size() && line.equalsIgnoreCase("next");
|
|
89
|
+ }
|
|
90
|
+
|
|
91
|
+ public void execute(InputHandler handler, Response response, String line) throws Exception {
|
|
92
|
+ response.sendMessage("result " + next + "/" + results.size() + "is: "
|
|
93
|
+ + results.get(next).getSummary());
|
|
94
|
+ response.addFollowup(new AttributesFollowup(results.get(next)));
|
|
95
|
+ response.addFollowup(new NextFollowup(results, next + 1));
|
|
96
|
+ response.addFollowup(new PreviousFollowup(results, next - 1));
|
|
97
|
+ }
|
|
98
|
+
|
|
99
|
+ }
|
|
100
|
+
|
|
101
|
+ protected static class PreviousFollowup implements Followup {
|
|
102
|
+
|
|
103
|
+ private final List<Result> results;
|
|
104
|
+ private final int prev;
|
|
105
|
+
|
|
106
|
+ public PreviousFollowup(List<Result> results, int next) {
|
|
107
|
+ this.results = results;
|
|
108
|
+ this.prev = next;
|
|
109
|
+ }
|
|
110
|
+
|
|
111
|
+ public boolean matches(String line) {
|
|
112
|
+ return prev > 0 && line.equalsIgnoreCase("previous");
|
|
113
|
+ }
|
|
114
|
+
|
|
115
|
+ public void execute(InputHandler handler, Response response, String line) throws Exception {
|
|
116
|
+ response.sendMessage("result " + prev + "/" + results.size() + "is: "
|
|
117
|
+ + results.get(prev).getSummary());
|
|
118
|
+ response.addFollowup(new AttributesFollowup(results.get(prev)));
|
|
119
|
+ response.addFollowup(new NextFollowup(results, prev + 1));
|
|
120
|
+ response.addFollowup(new PreviousFollowup(results, prev - 1));
|
|
121
|
+ }
|
|
122
|
+
|
|
123
|
+ }
|
|
124
|
+
|
|
125
|
+ protected static class AttributesFollowup implements Followup {
|
|
126
|
+
|
|
127
|
+ private final Result result;
|
|
128
|
+
|
|
129
|
+ public AttributesFollowup(Result result) {
|
|
130
|
+ this.result = result;
|
|
131
|
+ }
|
|
132
|
+
|
|
133
|
+ public boolean matches(String line) {
|
|
134
|
+ return line.equalsIgnoreCase("attributes");
|
|
135
|
+ }
|
|
136
|
+
|
|
137
|
+ public void execute(InputHandler handler, Response response, String line) throws Exception {
|
|
138
|
+ final StringBuilder builder = new StringBuilder();
|
|
139
|
+
|
|
140
|
+ for (Map.Entry<String, List<String>> entry : result.getAttributes().entrySet()) {
|
|
141
|
+ if (builder.length() > 0) {
|
|
142
|
+ builder.append("; ");
|
|
143
|
+ }
|
|
144
|
+
|
|
145
|
+ builder.append(entry.getKey() + ": ");
|
|
146
|
+
|
|
147
|
+ boolean first = true;
|
|
148
|
+ for (String value : entry.getValue()) {
|
|
149
|
+ if (first) {
|
|
150
|
+ first = false;
|
|
151
|
+ } else {
|
|
152
|
+ builder.append(", ");
|
|
153
|
+ }
|
|
154
|
+
|
|
155
|
+ builder.append(value);
|
|
156
|
+ }
|
|
157
|
+ }
|
|
158
|
+
|
|
159
|
+ response.setInheritFollows(true);
|
|
160
|
+ response.sendMessage("that result has the following attributes: " + builder.toString());
|
|
161
|
+ }
|
|
162
|
+
|
|
163
|
+ }
|
|
164
|
+
|
|
165
|
+ protected static class Result {
|
|
166
|
+
|
|
167
|
+ protected static final String REPORT_NS = "http://www.newzbin.com/DTD/2007/feeds/report/";
|
|
168
|
+ protected static final String NZB_URL = "http://www.newzbin.com/browse/post/%s/nzb/";
|
|
169
|
+
|
|
170
|
+ private final String title, category, moreinfo, nfolink, poster, date;
|
|
171
|
+ private final MapList<String, String> attributes = new MapList<String, String>();
|
|
172
|
+ private final List<String> groups = new ArrayList<String>();
|
|
173
|
+ private final int id, nfoid, views, comments;
|
|
174
|
+ private final long size;
|
|
175
|
+
|
|
176
|
+ public Result(final Element element) {
|
|
177
|
+ final Namespace namespace = Namespace.getNamespace(REPORT_NS);
|
|
178
|
+
|
|
179
|
+ title = element.getChildTextTrim("title");
|
|
180
|
+ id = Integer.parseInt(element.getChildTextTrim("id", namespace));
|
|
181
|
+ category = element.getChildTextTrim("category", namespace);
|
|
182
|
+
|
|
183
|
+ for (Object attribute : element.getChildren("attributes", namespace)) {
|
|
184
|
+ final String type = ((Element) attribute).getAttributeValue("type");
|
|
185
|
+ final String value = ((Element) attribute).getTextTrim();
|
|
186
|
+ attributes.add(type, value);
|
|
187
|
+ }
|
|
188
|
+
|
|
189
|
+ for (Object group : element.getChildren("groups", namespace)) {
|
|
190
|
+ groups.add(((Element) group).getTextTrim());
|
|
191
|
+ }
|
|
192
|
+
|
|
193
|
+ moreinfo = element.getChildTextTrim("moreinfo", namespace);
|
|
194
|
+
|
|
195
|
+ nfoid = Integer.parseInt(element.getChild("nfo", namespace)
|
|
196
|
+ .getChildText("fileid", namespace));
|
|
197
|
+ nfolink = element.getChild("nfo", namespace)
|
|
198
|
+ .getChildText("link", namespace);
|
|
199
|
+ poster = element.getChildText("poster", namespace);
|
|
200
|
+ size = Long.parseLong(element.getChildTextTrim("size", namespace));
|
|
201
|
+ date = element.getChildText("postdate", namespace);
|
|
202
|
+ views = Integer.parseInt(element.getChild("stats", namespace)
|
|
203
|
+ .getChildText("views", namespace));
|
|
204
|
+ comments = Integer.parseInt(element.getChild("stats", namespace)
|
|
205
|
+ .getChildText("comments", namespace));
|
|
206
|
+ }
|
|
207
|
+
|
|
208
|
+ public String getSummary() {
|
|
209
|
+ return "'" + title + "' (" + getSizeMB() + "MiB), nzb link: "
|
|
210
|
+ + String.format(NZB_URL, id);
|
|
211
|
+ }
|
|
212
|
+
|
|
213
|
+ public String getSizeMB() {
|
|
214
|
+ return String.format("%,.2f", size / (1024 * 1024));
|
|
215
|
+ }
|
|
216
|
+
|
|
217
|
+ public MapList<String, String> getAttributes() {
|
|
218
|
+ return attributes;
|
|
219
|
+ }
|
|
220
|
+
|
|
221
|
+ public String getCategory() {
|
|
222
|
+ return category;
|
|
223
|
+ }
|
|
224
|
+
|
|
225
|
+ public int getComments() {
|
|
226
|
+ return comments;
|
|
227
|
+ }
|
|
228
|
+
|
|
229
|
+ public String getDate() {
|
|
230
|
+ return date;
|
|
231
|
+ }
|
|
232
|
+
|
|
233
|
+ public List<String> getGroups() {
|
|
234
|
+ return groups;
|
|
235
|
+ }
|
|
236
|
+
|
|
237
|
+ public int getId() {
|
|
238
|
+ return id;
|
|
239
|
+ }
|
|
240
|
+
|
|
241
|
+ public String getMoreinfo() {
|
|
242
|
+ return moreinfo;
|
|
243
|
+ }
|
|
244
|
+
|
|
245
|
+ public int getNfoid() {
|
|
246
|
+ return nfoid;
|
|
247
|
+ }
|
|
248
|
+
|
|
249
|
+ public String getNfolink() {
|
|
250
|
+ return nfolink;
|
|
251
|
+ }
|
|
252
|
+
|
|
253
|
+ public String getPoster() {
|
|
254
|
+ return poster;
|
|
255
|
+ }
|
|
256
|
+
|
|
257
|
+ public long getSize() {
|
|
258
|
+ return size;
|
|
259
|
+ }
|
|
260
|
+
|
|
261
|
+ public String getTitle() {
|
|
262
|
+ return title;
|
|
263
|
+ }
|
|
264
|
+
|
|
265
|
+ public int getViews() {
|
|
266
|
+ return views;
|
|
267
|
+ }
|
|
268
|
+
|
|
269
|
+ }
|
|
270
|
+
|
|
271
|
+}
|