OSDN Git Service

r64のリファクタリング.
[coroid/inqubus.git] / frontend / src / saccubus / net / NicoClient.java
1 package saccubus.net;
2
3 import java.io.File;
4 import java.net.URL;
5 import java.io.*;
6 import java.net.HttpURLConnection;
7 import java.net.InetSocketAddress;
8 import java.net.Proxy;
9 import java.net.URLEncoder;
10 import java.net.URLDecoder;
11 import javax.swing.JLabel;
12 import java.text.DateFormat;
13 import java.text.SimpleDateFormat;
14 import java.util.Date;
15 import java.text.*;
16 import javax.net.ssl.HttpsURLConnection;
17 import saccubus.ConvertStopFlag;
18 import saccubus.util.FileUtil;
19
20 /**
21  * <p>
22  * \83^\83C\83g\83\8b\82³\82«\82ã\82Î\82·
23  * </p>
24  * 
25  * <p>
26  * \90à\96¾: \83j\83R\83j\83R\93®\89æ\82Ì\93®\89æ\82ð\83R\83\81\83\93\83g\82Â\82«\82Å\95Û\91
27  * </p>
28  * 
29  * <p>
30  * \92\98\8dì\8c : Copyright (c) 2007 PSI
31  * </p>
32  * 
33  * <p>
34  * \89ï\8eÐ\96¼:
35  * </p>
36  * 
37  * @author \96¢\93ü\97Í
38  * @version 1.0
39  */
40 public class NicoClient {
41         private String Cookie = null;
42
43         private static final String TITLE_PARSE_STR_START = "<title>";
44         private final static DateFormat DateFmt = new SimpleDateFormat(
45                         "yyyy/MM/dd HH:mm:ss");
46         private final static DateFormat DateFmt2 = new SimpleDateFormat(
47                         "yyyy/MM/dd HH:mm");
48
49         private final String User;
50         private final String Pass;
51         private boolean Logged_in = false;
52         private final ConvertStopFlag StopFlag;
53         private final Proxy ConProxy;
54
55         private String VideoTitle = null;
56         private int VideoLength = -1;
57
58         private byte[] buf = new byte[1024 * 1024];
59
60         private String VideoUrl = null;
61         private String UserID = null;
62         private String ThreadID = null;
63         private String MsgUrl = null;
64
65         private String WayBackKey = "0";
66         private String WayBackTime = "0";
67         private final static String WAYBACKKEY_STR = "waybackkey=";
68
69         public NicoClient(final String user, final String pass,
70                         final ConvertStopFlag flag, final String proxy, final int proxy_port) {
71                 User = user;
72                 Pass = pass;
73                 if (proxy != null && proxy.length() > 0 && proxy_port >= 0
74                                 && proxy_port <= 65535) {
75                         ConProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxy,
76                                         proxy_port));
77                 } else {
78                         ConProxy = Proxy.NO_PROXY;
79                 }
80                 // \83\8d\83O\83C\83\93
81                 Logged_in = login();
82                 StopFlag = flag;
83         }
84
85         public String getBackCommentFromLength(String def) {
86                 if (VideoLength < 0) {
87                         return def;
88                 } else if (VideoLength >= 0 && VideoLength < 60) {
89                         return "100";
90                 } else if (VideoLength >= 60 && VideoLength < 300) {
91                         return "250";
92                 } else if (VideoLength >= 300 && VideoLength < 600) {
93                         return "500";
94                 } else {
95                         return "1000";
96                 }
97         }
98
99         public File getComment(final File file, final JLabel status,
100                         String back_comment) {
101                 System.out.print("Downloading comment size:" + back_comment + "...");
102                 try {
103                         if (file.canRead()) { // \83t\83@\83C\83\8b\82ª\82·\82Å\82É\91\8dÝ\82·\82é\82È\82ç\8dí\8f\9c\82·\82é\81B
104                                 file.delete();
105                         }
106                         OutputStream fos = new FileOutputStream(file);
107                         HttpURLConnection con = (HttpURLConnection) (new URL(MsgUrl))
108                                         .openConnection(ConProxy);
109                         con.setDoOutput(true);
110                         con.setDoInput(true);
111                         con.setRequestMethod("POST");
112                         con.addRequestProperty("Cookie", Cookie);
113                         con.addRequestProperty("Connection", "close");
114                         con.connect();
115                         OutputStream os = con.getOutputStream();
116                         String req = "<thread user_id=\"" + UserID + "\" when=\""
117                                         + WayBackTime + "\" waybackkey=\"" + WayBackKey
118                                         + "\" res_from=\"-" + back_comment
119                                         + "\" version=\"20061206\" thread=\"" + ThreadID + "\" />";
120                         os.write(req.getBytes());
121                         os.flush();
122                         os.close();
123                         if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
124                                 System.out.println("ng.\nCan't download comment:" + MsgUrl);
125                                 return null;
126                         }
127                         InputStream is = con.getInputStream();
128                         int read = 0;
129                         int max_size = 0;
130                         String content_length_str = con.getHeaderField("Content-length");
131                         if (content_length_str != null && !content_length_str.equals("")) {
132                                 max_size = Integer.parseInt(content_length_str);
133                         }
134                         int size = 0;
135                         while ((read = is.read(buf, 0, buf.length)) > 0) {
136                                 fos.write(buf, 0, read);
137                                 size += read;
138                                 if (max_size != 0) {
139                                         String per = Double.toString((((double) size) * 100)
140                                                         / max_size);
141                                         per = per.substring(0, Math.min(per.indexOf(".") + 3, per
142                                                         .length()));
143                                         status.setText("\83R\83\81\83\93\83g\83_\83E\83\93\83\8d\81[\83h\81F" + per + "\83p\81[\83Z\83\93\83g\8a®\97¹");
144                                 } else {
145                                         status.setText("\83R\83\81\83\93\83g\83_\83E\83\93\83\8d\81[\83h\92\86\81F"
146                                                         + Integer.toString(size >> 10) + "kbytes\83_\83E\83\93\83\8d\81[\83h");
147                                 }
148                                 if (StopFlag.needStop()) {
149                                         System.out.println("Stopped.");
150                                         is.close();
151                                         os.flush();
152                                         os.close();
153                                         con.disconnect();
154                                         file.delete();
155                                         return null;
156                                 }
157                         }
158                         System.out.println("ok.");
159                         is.close();
160                         fos.flush();
161                         fos.close();
162                         con.disconnect();
163                         return file;
164                 } catch (IOException ex) {
165                         ex.printStackTrace();
166                 }
167
168                 return null;
169         }
170
171         public File getVideo(final File file, final JLabel status) {
172                 if (VideoUrl == null) {
173                         System.out.println("Video url is not detected.");
174                         return null;
175                 }
176                 try {
177                         if (file.canRead()) { // \83t\83@\83C\83\8b\82ª\82·\82Å\82É\91\8dÝ\82·\82é\82È\82ç\8dí\8f\9c\82·\82é\81B
178                                 file.delete();
179                         }
180                         HttpURLConnection con = (HttpURLConnection) (new URL(VideoUrl))
181                                         .openConnection(ConProxy);
182                         /* \8fo\97Í\82Ì\82Ý */
183                         con.setDoInput(true);
184                         con.setRequestMethod("GET");
185                         con.addRequestProperty("Cookie", Cookie);
186                         con.connect();
187                         if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
188                                 System.out.println("Can't get video:" + VideoUrl);
189                                 return null;
190                         }
191                         InputStream is = con.getInputStream();
192                         OutputStream os = new FileOutputStream(file);
193                         String content_length_str = con.getHeaderField("Content-length");
194                         int max_size = 0;
195                         if (content_length_str != null && !content_length_str.equals("")) {
196                                 max_size = Integer.parseInt(content_length_str);
197                         }
198                         int size = 0;
199                         System.out.print("Downloading video...");
200                         int read = 0;
201                         while ((read = is.read(buf, 0, buf.length)) > 0) {
202                                 size += read;
203                                 os.write(buf, 0, read);
204                                 if (max_size != 0) {
205                                         String per = Double.toString((((double) size) * 100)
206                                                         / max_size);
207                                         per = per.substring(0, Math.min(per.indexOf(".") + 3, per
208                                                         .length()));
209                                         status.setText("\93®\89æ\83_\83E\83\93\83\8d\81[\83h\81F" + per + "\83p\81[\83Z\83\93\83g\8a®\97¹");
210                                 } else {
211                                         status.setText("\93®\89æ\83_\83E\83\93\83\8d\81[\83h\92\86\81F" + Integer.toString(size >> 10)
212                                                         + "kbytes\83_\83E\83\93\83\8d\81[\83h");
213                                 }
214                                 if (StopFlag.needStop()) {
215                                         System.out.println("Stopped.");
216                                         is.close();
217                                         os.flush();
218                                         os.close();
219                                         con.disconnect();
220                                         file.delete();
221                                         return null;
222                                 }
223                         }
224                         System.out.println("ok.");
225                         is.close();
226                         os.flush();
227                         os.close();
228                         con.disconnect();
229                         return file;
230                 } catch (FileNotFoundException ex) {
231                         ex.printStackTrace();
232                 } catch (IOException ex) {
233                         ex.printStackTrace();
234                 }
235                 return null;
236         }
237
238         public boolean getVideoHistoryAndTitle(String tag) {
239                 String url = "http://www.nicovideo.jp/watch/" + tag;
240                 System.out.print("Getting video history...");
241                 String new_cookie = null;
242                 try {
243                         HttpURLConnection con = (HttpURLConnection) (new URL(url))
244                                         .openConnection(ConProxy);
245                         /* \83\8a\83N\83G\83X\83g\82Ì\90Ý\92è */
246                         con.setRequestMethod("GET");
247                         con.addRequestProperty("Cookie", Cookie);
248                         con.addRequestProperty("Connection", "close");
249                         con.connect();
250                         if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
251                                 System.out.println("Can't getVideoHistory:" + url);
252                                 return false;
253                         }
254                         int i = 1;
255                         String key;
256                         String value;
257                         while ((key = con.getHeaderFieldKey(i)) != null) {
258                                 if (key.equalsIgnoreCase("Set-Cookie")) {
259                                         value = con.getHeaderField(i);
260                                         if (value != null) {
261                                                 new_cookie = value.substring(0, value.indexOf(";"));
262                                         }
263                                 }
264                                 i++;
265                         }
266                         BufferedReader br = new BufferedReader(new InputStreamReader(con
267                                         .getInputStream(), "UTF-8"));
268                         String ret;
269                         int index = -1;
270                         while ((ret = br.readLine()) != null && index < 0) {
271                                 if ((index = ret.indexOf(TITLE_PARSE_STR_START)) >= 0) {
272                                         VideoTitle = ret.substring(index+TITLE_PARSE_STR_START.length(), ret.indexOf("\81]", index));
273                                         VideoTitle = FileUtil.safeFileName(VideoTitle);
274                                 }
275                         }
276                         br.close();
277                         con.disconnect();
278                         if (new_cookie == null) {
279                                 System.out.println("Can't getVideoHistory: cannot get cookie.");
280                                 return false;
281                         }
282                         System.out.println("ok.");
283                         Cookie += "; ";
284                         Cookie += new_cookie;
285                 } catch (IOException ex) {
286                         ex.printStackTrace();
287                         return false;
288                 }
289
290                 return true;
291         }
292
293         public boolean getVideoInfo(String tag, String time) {
294                 if (!getVideoHistoryAndTitle(tag)) {
295                         return false;
296                 }
297                 try {
298                         String url = "http://www.nicovideo.jp/api/getflv?v=" + tag;
299                         System.out.print("Getting video informations...");
300                         HttpURLConnection con = (HttpURLConnection) (new URL(url))
301                                         .openConnection(ConProxy);
302                         /* \83\8a\83N\83G\83X\83g\82Ì\90Ý\92è */
303                         con.setRequestMethod("GET");
304                         con.addRequestProperty("Cookie", Cookie);
305                         con.addRequestProperty("Connection", "close");
306                         con.connect();
307                         if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
308                                 System.out.println("Can't getVideoInfo:" + url);
309                                 return false;
310                         }
311                         /* \96ß\82è\92l\82Ì\8eæ\93¾ */
312                         BufferedReader br = new BufferedReader(new InputStreamReader(con
313                                         .getInputStream()));
314                         String ret = br.readLine();
315                         br.close();
316                         con.disconnect();
317                         ret = URLDecoder.decode(ret, "Shift_JIS");
318                         String[] array = ret.split("&");
319                         int cnt = 0;
320                         for (int i = 0; i < array.length; i++) {
321                                 int idx = array[i].indexOf("=");
322                                 if (idx < 0) {
323                                         continue;
324                                 }
325                                 String key = array[i].substring(0, idx);
326                                 String value = array[i].substring(idx + 1);
327                                 if (ThreadID == null && key.equalsIgnoreCase("thread_id")) {
328                                         ThreadID = value;
329                                         cnt++;
330                                 } else if (VideoUrl == null && key.equalsIgnoreCase("url")) {
331                                         VideoUrl = value;
332                                         cnt++;
333                                 } else if (MsgUrl == null && key.equalsIgnoreCase("ms")) {
334                                         MsgUrl = value;
335                                         cnt++;
336                                 } else if (UserID == null && key.equalsIgnoreCase("user_id")) {
337                                         UserID = value;
338                                         cnt++;
339                                 } else if (VideoLength < 0 && key.equalsIgnoreCase("l")) {
340                                         try {
341                                                 VideoLength = Integer.parseInt(value);
342                                         } catch (NumberFormatException e) {
343                                                 VideoLength = -1;
344                                         }
345                                 }
346                         }
347                         if (cnt < 4) {
348                                 System.out
349                                                 .println("ng.\nCan't getVideoInfo: Can't get video informations.");
350                                 return false;
351                         }
352                         System.out.println("ok.");
353                 } catch (IOException ex) {
354                         ex.printStackTrace();
355                         return false;
356                 }
357                 if (!(time == null || time.equals("")) && !getWayBackKey(time)) { // WayBackKey
358                         return false;
359                 }
360                 return true;
361         }
362
363         public String getVideoTitle() {
364                 return VideoTitle;
365         }
366
367         private boolean getWayBackKey(String time) {
368                 System.out.print("Setting wayback time...");
369                 Date date = null;
370                 String waybacktime = "0";
371                 try {
372                         date = DateFmt.parse(time);
373                 } catch (ParseException ex2) {
374                         date = null;
375                 }
376                 if (date == null) {
377                         try {
378                                 date = DateFmt2.parse(time);
379                         } catch (ParseException ex3) {
380                                 date = null;
381                         }
382                 }
383                 if (date != null) {
384                         waybacktime = Long.toString(date.getTime() / 1000);
385                         System.out.println("ok.(" + date.toString() + "):" + waybacktime);
386                 } else {
387                         try {
388                                 long tmp_time = Long.parseLong(time);
389                                 waybacktime = Long.toString(tmp_time);
390                                 date = new Date(tmp_time * 1000);
391                                 System.out.println("ok.(" + date.toString() + "):"
392                                                 + waybacktime);
393                         } catch (NumberFormatException ex4) {
394                                 System.out.println("ng.");
395                                 System.out.println("Cannot parse wayback time.");
396                                 return false;
397                         }
398                 }
399                 System.out.print("Getting wayback key...");
400                 String url = "http://www.nicovideo.jp/api/getwaybackkey?thread="
401                                 + ThreadID;
402                 String ret = "";
403                 try {
404                         HttpURLConnection con = (HttpURLConnection) (new URL(url))
405                                         .openConnection(ConProxy);
406                         /* \83\8a\83N\83G\83X\83g\82Ì\90Ý\92è */
407                         con.setRequestMethod("GET");
408                         con.addRequestProperty("Cookie", Cookie);
409                         con.addRequestProperty("Connection", "close");
410                         con.setDoInput(true);
411                         con.connect();
412                         if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
413                                 System.out.println("Can't get WayBackKey:" + url);
414                                 return false;
415                         }
416                         /* \96ß\82è\92l\82Ì\8eæ\93¾ */
417                         BufferedReader br = new BufferedReader(new InputStreamReader(con
418                                         .getInputStream()));
419                         ret = br.readLine();
420                         br.close();
421                         con.disconnect();
422                 } catch (IOException ex1) {
423                         System.out.println("ng.");
424                         ex1.printStackTrace();
425                         return false;
426                 }
427                 int idx = 0;
428                 if ((idx = ret.indexOf(WAYBACKKEY_STR)) < 0) {
429                         System.out.println("ng.");
430                         System.out.println("Cannot find wayback key from response.");
431                         return false;
432                 }
433                 int end_idx = Math.max(ret.length(), ret.indexOf("&"));
434                 String waybackkey = ret.substring(idx + WAYBACKKEY_STR.length(),
435                                 end_idx);
436                 if (waybackkey == null || waybackkey.equals("")) {
437                         System.out.println("ng.");
438                         System.out.println("Cannot get wayback key.");
439                         return false;
440                 }
441                 System.out.println("ok. key:" + waybackkey);
442                 WayBackTime = waybacktime;
443                 WayBackKey = waybackkey;
444                 return true;
445         }
446
447         public boolean isLoggedIn() {
448                 return Logged_in;
449         }
450
451         private boolean login() {
452                 try {
453                         HttpURLConnection con = (HttpsURLConnection) (new URL(
454                                         "https://secure.nicovideo.jp/secure/login?site=niconico"))
455                                         .openConnection(ConProxy);
456                         /* \8fo\97Í\82Ì\82Ý */
457                         con.setDoOutput(true);
458                         HttpURLConnection.setFollowRedirects(false);
459                         con.setInstanceFollowRedirects(false);
460                         con.setRequestMethod("POST");
461                         con.addRequestProperty("Connection", "close");
462                         con.connect();
463                         StringBuffer sb = new StringBuffer(4096);
464                         sb.append("next_url=&");
465                         sb.append("mail=");
466                         sb.append(URLEncoder.encode(User, "Shift_JIS"));
467                         sb.append("&password=");
468                         sb.append(URLEncoder.encode(Pass, "Shift_JIS"));
469                         sb.append("&submit.x=103&submit.y=16");
470                         OutputStream os = con.getOutputStream();
471                         os.write(sb.substring(0).getBytes());
472                         os.flush();
473                         os.close();
474                         int code = con.getResponseCode();
475                         if (code < 200 || code >= 400) {
476                                 System.out.println("Can't login:" + con.getResponseMessage());
477                                 return false;
478                         }
479                         int i = 1;
480                         String key;
481                         String value;
482                         while ((key = con.getHeaderFieldKey(i)) != null) {
483                                 if (key.equalsIgnoreCase("Set-Cookie")) {
484                                         value = con.getHeaderField(i);
485                                         if (value != null) {
486                                                 Cookie = value.substring(0, value.indexOf(";"));
487                                         }
488                                 }
489                                 i++;
490                         }
491                         con.disconnect();
492                         if (Cookie == null) {
493                                 System.out.println("Can't login: cannot set cookie.");
494                                 return false;
495                         }
496                         System.out.println("Logged in.");
497                 } catch (IOException ex) {
498                         ex.printStackTrace();
499                         return false;
500                 }
501                 return true;
502         }
503 }