import saccubus.ConvertStopFlag;
import saccubus.converter.profile.Proxy;
import saccubus.net.NicoClient;
+import saccubus.net.NicoClientImpl;
import saccubus.net.VideoInfo;
/**
host = null;
port = -1;
}
- client = new NicoClient(li.getMail(), li.getPass(), stopFlag, host, port);
+ // TODO Implを直接newしている
+ client = new NicoClientImpl(li.getMail(), li.getPass(), stopFlag, host, port) {};
if (!client.isLoggedIn()) {
throw new IOException("ログインに失敗");
package saccubus.net;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.HttpURLConnection;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.URLEncoder;
-import java.net.URLDecoder;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.HttpsURLConnection;
-import saccubus.ConvertStopFlag;
-import saccubus.util.FileUtil;
-import yukihane.Util;
-import static saccubus.net.VideoInfo.OfficialOption;
/**
- * <p>
- * タイトル: さきゅばす
- * </p>
- *
- * <p>
- * 説明: ニコニコ動画の動画をコメントつきで保存
- * </p>
- *
- * <p>
- * 著作権: Copyright (c) 2007 PSI
- * </p>
- *
- * <p>
- * 会社名:
- * </p>
- *
- * @author 未入力
- * @version 1.0
+ *
+ * @author yuki
*/
-public class NicoClient {
- private String Cookie = null;
+public interface NicoClient {
- private static final String TITLE_PARSE_STR_START = "<title>";
- private final static DateFormat DateFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
- private final static DateFormat DateFmt2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
+ String getBackCommentFromLength(VideoInfo videoInfo, String com);
- private final String User;
- private final String Pass;
- private boolean Logged_in = false;
- private final ConvertStopFlag StopFlag;
- private final Proxy ConProxy;
+ File getComment(VideoInfo videoInfo, File file, TextProgressListener listener, String com);
- private String WayBackKey = "0";
- private String WayBackTime = "0";
- private final static String WAYBACKKEY_STR = "waybackkey=";
+ File getTcomment(VideoInfo videoInfo, File file, TextProgressListener listener);
- public NicoClient(final String user, final String pass,
- final ConvertStopFlag flag, final String proxy, final int proxy_port) {
- User = user;
- Pass = pass;
- if (proxy != null && proxy.length() > 0 && proxy_port >= 0
- && proxy_port <= 65535) {
- ConProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxy,
- proxy_port));
- } else {
- ConProxy = Proxy.NO_PROXY;
- }
- // ログイン
- Logged_in = login();
- StopFlag = flag;
- }
+ File getVideo(VideoInfo videoInfo, File file, TextProgressListener listener);
- public String getBackCommentFromLength(VideoInfo vi, String def) {
- final int videoLength = vi.getVideoLength();
- if (videoLength < 0) {
- return def;
- } else if (videoLength >= 0 && videoLength < 60) {
- return "100";
- } else if (videoLength >= 60 && videoLength < 300) {
- return "250";
- } else if (videoLength >= 300 && videoLength < 600) {
- return "500";
- } else {
- return "1000";
- }
- }
+ boolean isLoggedIn();
- public File getComment(VideoInfo vi, final File file, final TextProgressListener status, String back_comment) {
- return downloadComment(back_comment, file, vi, status, false);
- }
+ VideoInfo getVideoInfo(String tag, String time) throws IOException;
- /**
- * 投稿者コメントをダウンロードする.
- * @param vi ビデオ情報.
- * @param file ダウンロード先ファイル.
- * @param status 進捗通知リスナ.
- * @return ダウンロードされたファイル. ダウンロードできなければnull.
- */
- public File getTcomment(VideoInfo vi, final File file, final TextProgressListener status) {
- return downloadComment("500", file, vi, status, true);
- }
-
- private File downloadComment(String back_comment, final File file, VideoInfo vi, final TextProgressListener status,
- boolean isTcomm) throws NumberFormatException {
- System.out.print("Downloading comment size:" + back_comment + "...");
- try {
- if (file.canRead()) { // ファイルがすでに存在するなら削除する。
- file.delete();
- }
- OutputStream fos = new FileOutputStream(file);
- HttpURLConnection con = (HttpURLConnection) (new URL(vi.getMsgUrl()))
- .openConnection(ConProxy);
- con.setDoOutput(true);
- con.setDoInput(true);
- con.setRequestMethod("POST");
- con.addRequestProperty("Cookie", Cookie);
- con.addRequestProperty("Connection", "close");
- con.connect();
- OutputStream os = con.getOutputStream();
- String tcommStr = (isTcomm) ? "fork=\"1\" " : "";
- String official = "";
- OfficialOption oo = vi.getOfficialOption();
- if (oo != null) {
- official = "force_184=\"" + oo.getForce184() + "\" threadkey=\"" + oo.getThreadKey() + "\" ";
- }
- String req = "<thread user_id=\"" + vi.getUserId() + "\" when=\"" + WayBackTime + "\" waybackkey=\""
- + WayBackKey + "\" res_from=\"-" + back_comment + "\" version=\"20061206\" thread=\"" + vi.
- getThreadId() + "\" " + tcommStr + official + "/>";
- os.write(req.getBytes());
- os.flush();
- os.close();
- if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- System.out.println("ng.\nCan't download comment:" + vi.getMsgUrl());
- return null;
- }
- InputStream is = con.getInputStream();
- int read = 0;
- int max_size = 0;
- String content_length_str = con.getHeaderField("Content-length");
- if (content_length_str != null && !content_length_str.equals("")) {
- max_size = Integer.parseInt(content_length_str);
- }
- int size = 0;
- final byte[] buf = new byte[1024 * 1024];
- while ((read = is.read(buf, 0, buf.length)) > 0) {
- fos.write(buf, 0, read);
- size += read;
- if (max_size != 0) {
- String per = Double.toString((((double) size) * 100) / max_size);
- per = per.substring(0, Math.min(per.indexOf(".") + 3, per.length()));
- status.setText("コメントダウンロード:" + per + "パーセント完了");
- } else {
- status.setText("コメントダウンロード中:" + Integer.toString(size >> 10) + "kbytesダウンロード");
- }
- if (StopFlag.needStop()) {
- System.out.println("Stopped.");
- is.close();
- os.flush();
- os.close();
- con.disconnect();
- file.delete();
- return null;
- }
- }
- System.out.println("ok.");
- is.close();
- fos.flush();
- fos.close();
- con.disconnect();
- return file;
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- public File getVideo(VideoInfo vi, final File file, final TextProgressListener status) {
- if (vi.getVideoUrl() == null) {
- System.out.println("Video url is not detected.");
- return null;
- }
- try {
-// if (file.canRead()) { // ファイルがすでに存在するなら削除する。
-// file.delete();
-// }
- HttpURLConnection con = (HttpURLConnection) (new URL(vi.getVideoUrl()))
- .openConnection(ConProxy);
- /* 出力のみ */
- con.setDoInput(true);
- con.setRequestMethod("GET");
- con.addRequestProperty("Cookie", Cookie);
- con.connect();
- if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- System.out.println("Can't get video:" + vi.getVideoUrl());
- return null;
- }
- final String extension = Util.getExtention(con.getContentType());
- File outFile = appendExtension(file, extension);
- InputStream is = con.getInputStream();
- OutputStream os = new FileOutputStream(outFile);
- String content_length_str = con.getHeaderField("Content-length");
- int max_size = 0;
- if (content_length_str != null && !content_length_str.equals("")) {
- max_size = Integer.parseInt(content_length_str);
- }
- int size = 0;
- System.out.print("Downloading video...");
- int read = 0;
- final byte[] buf = new byte[1024 * 1024];
- while ((read = is.read(buf, 0, buf.length)) > 0) {
- size += read;
- os.write(buf, 0, read);
- if (max_size != 0) {
- String per = Double.toString((((double) size) * 100)
- / max_size);
- per = per.substring(0, Math.min(per.indexOf(".") + 3, per
- .length()));
- status.setText("動画ダウンロード:" + per + "パーセント完了");
- } else {
- status.setText("動画ダウンロード中:" + Integer.toString(size >> 10)
- + "kbytesダウンロード");
- }
- if (StopFlag.needStop()) {
- System.out.println("Stopped.");
- is.close();
- os.flush();
- os.close();
- con.disconnect();
- outFile.delete();
- return null;
- }
- }
- System.out.println("ok.");
- is.close();
- os.flush();
- os.close();
- con.disconnect();
- return outFile;
- } catch (FileNotFoundException ex) {
- ex.printStackTrace();
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- /** @return ビデオ名 */
- public String getVideoHistoryAndTitle(String tag) throws IOException {
- String url = "http://www.nicovideo.jp/watch/" + tag;
- System.out.print("Getting video history...");
- String new_cookie = null;
- String videoTitle = null;
-
- HttpURLConnection con = (HttpURLConnection) (new URL(url)).openConnection(ConProxy);
- /* リクエストの設定 */
- con.setRequestMethod("GET");
- con.addRequestProperty("Cookie", Cookie);
- con.addRequestProperty("Connection", "close");
- con.connect();
- if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- throw new IOException("Can't getVideoHistory:" + url);
- }
- int i = 1;
- String key;
- String value;
- while ((key = con.getHeaderFieldKey(i)) != null) {
- if (key.equalsIgnoreCase("Set-Cookie")) {
- value = con.getHeaderField(i);
- if (value != null) {
- new_cookie = value.substring(0, value.indexOf(";"));
- }
- }
- i++;
- }
- BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
- String ret;
- int index = -1;
- while ((ret = br.readLine()) != null && index < 0) {
- if ((index = ret.indexOf(TITLE_PARSE_STR_START)) >= 0) {
- videoTitle = ret.substring(index + TITLE_PARSE_STR_START.length(), ret.indexOf("‐", index));
- videoTitle = FileUtil.safeFileName(videoTitle);
- }
- }
- br.close();
- con.disconnect();
- if (new_cookie == null) {
- System.out.println("Can't getVideoHistory: cannot get cookie.");
- return null;
- }
- System.out.println("ok.");
- Cookie += "; ";
- Cookie += new_cookie;
-
- return videoTitle;
- }
-
- public VideoInfo getVideoInfo(String tag, String time) throws IOException {
- final String videoTitle = getVideoHistoryAndTitle(tag);
-
- String url = "http://flapi.nicovideo.jp/api/getflv/" + tag;
- if (tag.startsWith("nm")) {
- url += "?as3=1";
- }
- System.out.print("Getting video informations...");
- Map<String,String> res = new NicoApiRequest(url).get();
- String threadId = res.get("thread_id");
- String videoUrl = res.get("url");
- String msgUrl = res.get("ms");
- String userId = res.get("user_id");
- int videoLength = -1;
- String videoLengthStr = res.get("l");
- try{
- videoLength = Integer.parseInt(videoLengthStr);
- }catch(NumberFormatException ex){}
-
- OfficialOption oo = null;
- if ("1".equals(res.get("needs_key"))) {
- oo = getOfficialOption(threadId);
- }
-
- VideoInfo vi = new VideoInfo(videoTitle, threadId, videoUrl, msgUrl, userId, videoLength, oo);
- System.out.println("ok.");
-
- if (!(time == null || time.equals("")) && !getWayBackKey(vi, time)) { // WayBackKey
- throw new IOException();
- }
- return vi;
- }
-
- private OfficialOption getOfficialOption(String threadId) throws IOException {
- String url = "http://flapi.nicovideo.jp/api/getthreadkey?thread="+threadId;
- Map<String,String> map = new NicoApiRequest(url).get();
- return new OfficialOption(map.get("threadkey"), map.get("force_184"));
- }
-
- private boolean getWayBackKey(VideoInfo vi, String time) {
- System.out.print("Setting wayback time...");
- Date date = null;
- String waybacktime = "0";
- try {
- date = DateFmt.parse(time);
- } catch (ParseException ex2) {
- date = null;
- }
- if (date == null) {
- try {
- date = DateFmt2.parse(time);
- } catch (ParseException ex3) {
- date = null;
- }
- }
- if (date != null) {
- waybacktime = Long.toString(date.getTime() / 1000);
- System.out.println("ok.(" + date.toString() + "):" + waybacktime);
- } else {
- try {
- long tmp_time = Long.parseLong(time);
- waybacktime = Long.toString(tmp_time);
- date = new Date(tmp_time * 1000);
- System.out.println("ok.(" + date.toString() + "):"
- + waybacktime);
- } catch (NumberFormatException ex4) {
- System.out.println("ng.");
- System.out.println("Cannot parse wayback time.");
- return false;
- }
- }
- System.out.print("Getting wayback key...");
- String url = "http://flapi.nicovideo.jp/api/getwaybackkey?thread="
- + vi.getThreadId();
- String ret = "";
- try {
- HttpURLConnection con = (HttpURLConnection) (new URL(url))
- .openConnection(ConProxy);
- /* リクエストの設定 */
- con.setRequestMethod("GET");
- con.addRequestProperty("Cookie", Cookie);
- con.addRequestProperty("Connection", "close");
- con.setDoInput(true);
- con.connect();
- if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- System.out.println("Can't get WayBackKey:" + url);
- return false;
- }
- /* 戻り値の取得 */
- BufferedReader br = new BufferedReader(new InputStreamReader(con
- .getInputStream()));
- ret = br.readLine();
- br.close();
- con.disconnect();
- } catch (IOException ex1) {
- System.out.println("ng.");
- ex1.printStackTrace();
- return false;
- }
- int idx = 0;
- if ((idx = ret.indexOf(WAYBACKKEY_STR)) < 0) {
- System.out.println("ng.");
- System.out.println("Cannot find wayback key from response.");
- return false;
- }
- int end_idx = Math.max(ret.length(), ret.indexOf("&"));
- String waybackkey = ret.substring(idx + WAYBACKKEY_STR.length(),
- end_idx);
- if (waybackkey == null || waybackkey.equals("")) {
- System.out.println("ng.");
- System.out.println("Cannot get wayback key.");
- return false;
- }
- System.out.println("ok. key:" + waybackkey);
- WayBackTime = waybacktime;
- WayBackKey = waybackkey;
- return true;
- }
-
- public boolean isLoggedIn() {
- return Logged_in;
- }
-
- private boolean login() {
- try {
- HttpURLConnection con = (HttpsURLConnection) (new URL(
- "https://secure.nicovideo.jp/secure/login?site=niconico"))
- .openConnection(ConProxy);
- /* 出力のみ */
- con.setDoOutput(true);
- HttpURLConnection.setFollowRedirects(false);
- con.setInstanceFollowRedirects(false);
- con.setRequestMethod("POST");
- con.addRequestProperty("Connection", "close");
- con.connect();
- StringBuffer sb = new StringBuffer(4096);
- sb.append("next_url=&");
- sb.append("mail=");
- sb.append(URLEncoder.encode(User, "Shift_JIS"));
- sb.append("&password=");
- sb.append(URLEncoder.encode(Pass, "Shift_JIS"));
- sb.append("&submit.x=103&submit.y=16");
- OutputStream os = con.getOutputStream();
- os.write(sb.substring(0).getBytes());
- os.flush();
- os.close();
- int code = con.getResponseCode();
- if (code < 200 || code >= 400) {
- System.out.println("Can't login:" + con.getResponseMessage());
- return false;
- }
- int i = 1;
- String key;
- String value;
- while ((key = con.getHeaderFieldKey(i)) != null) {
- if (key.equalsIgnoreCase("Set-Cookie")) {
- value = con.getHeaderField(i);
- if (value != null) {
- Cookie = value.substring(0, value.indexOf(";"));
- }
- }
- i++;
- }
- con.disconnect();
- if (Cookie == null) {
- System.out.println("Can't login: cannot set cookie.");
- return false;
- }
- System.out.println("Logged in.");
- } catch (IOException ex) {
- ex.printStackTrace();
- return false;
- }
- return true;
- }
-
- private File appendExtension(File file, String extension) {
- final String e = "." + extension;
- final String defExt = ".flv";
- String path = file.getPath();
- if (path.endsWith(e)) {
- return file;
- } else if (path.endsWith(defExt)) {
- path = path.substring(0, path.length() - defExt.length());
- }
- return new File(path + e);
- }
-
- private class NicoApiRequest {
-
- private final String url;
-
- private NicoApiRequest(String url) {
- this.url = url;
- }
-
- private Map<String,String> get() throws IOException {
- Map<String, String> map = new HashMap<String, String>();
- System.out.print("Getting video informations...");
- HttpURLConnection con = (HttpURLConnection) (new URL(url)).openConnection(ConProxy);
- /* リクエストの設定 */
- con.setRequestMethod("GET");
- con.addRequestProperty("Cookie", Cookie);
- con.addRequestProperty("Connection", "close");
- con.connect();
- if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- throw new IOException("Can't getVideoInfo:" + url);
- }
- /* 戻り値の取得 */
- BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
- String ret = br.readLine();
- br.close();
- con.disconnect();
- ret = URLDecoder.decode(ret, "Shift_JIS");
- String[] array = ret.split("&");
- int cnt = 0;
- for (int i = 0; i < array.length; i++) {
- int idx = array[i].indexOf("=");
- if (idx < 0) {
- continue;
- }
- String key = array[i].substring(0, idx);
- String value = array[i].substring(idx + 1);
- map.put(key, value);
- }
- return map;
- }
- }
}
--- /dev/null
+package saccubus.net;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.URLEncoder;
+import java.net.URLDecoder;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javax.net.ssl.HttpsURLConnection;
+import saccubus.ConvertStopFlag;
+import saccubus.util.FileUtil;
+import yukihane.Util;
+import static saccubus.net.VideoInfo.OfficialOption;
+
+/**
+ * <p>
+ * タイトル: さきゅばす
+ * </p>
+ *
+ * <p>
+ * 説明: ニコニコ動画の動画をコメントつきで保存
+ * </p>
+ *
+ * <p>
+ * 著作権: Copyright (c) 2007 PSI
+ * </p>
+ *
+ * <p>
+ * 会社名:
+ * </p>
+ *
+ * @author 未入力
+ * @version 1.0
+ */
+public class NicoClientImpl implements NicoClient {
+ private String Cookie = null;
+
+ private static final String TITLE_PARSE_STR_START = "<title>";
+ private final static DateFormat DateFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+ private final static DateFormat DateFmt2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
+
+ private final String User;
+ private final String Pass;
+ private boolean Logged_in = false;
+ private final ConvertStopFlag StopFlag;
+ private final Proxy ConProxy;
+
+ private String WayBackKey = "0";
+ private String WayBackTime = "0";
+ private final static String WAYBACKKEY_STR = "waybackkey=";
+
+ public NicoClientImpl(final String user, final String pass,
+ final ConvertStopFlag flag, final String proxy, final int proxy_port) {
+ User = user;
+ Pass = pass;
+ if (proxy != null && proxy.length() > 0 && proxy_port >= 0
+ && proxy_port <= 65535) {
+ ConProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxy,
+ proxy_port));
+ } else {
+ ConProxy = Proxy.NO_PROXY;
+ }
+ // ログイン
+ Logged_in = login();
+ StopFlag = flag;
+ }
+
+ @Override
+ public String getBackCommentFromLength(VideoInfo vi, String def) {
+ final int videoLength = vi.getVideoLength();
+ if (videoLength < 0) {
+ return def;
+ } else if (videoLength >= 0 && videoLength < 60) {
+ return "100";
+ } else if (videoLength >= 60 && videoLength < 300) {
+ return "250";
+ } else if (videoLength >= 300 && videoLength < 600) {
+ return "500";
+ } else {
+ return "1000";
+ }
+ }
+
+ @Override
+ public File getComment(VideoInfo vi, final File file, final TextProgressListener status, String back_comment) {
+ return downloadComment(back_comment, file, vi, status, false);
+ }
+
+ /**
+ * 投稿者コメントをダウンロードする.
+ * @param vi ビデオ情報.
+ * @param file ダウンロード先ファイル.
+ * @param status 進捗通知リスナ.
+ * @return ダウンロードされたファイル. ダウンロードできなければnull.
+ */
+ @Override
+ public File getTcomment(VideoInfo vi, final File file, final TextProgressListener status) {
+ return downloadComment("500", file, vi, status, true);
+ }
+
+ private File downloadComment(String back_comment, final File file, VideoInfo vi, final TextProgressListener status,
+ boolean isTcomm) throws NumberFormatException {
+ System.out.print("Downloading comment size:" + back_comment + "...");
+ try {
+ if (file.canRead()) { // ファイルがすでに存在するなら削除する。
+ file.delete();
+ }
+ OutputStream fos = new FileOutputStream(file);
+ HttpURLConnection con = (HttpURLConnection) (new URL(vi.getMsgUrl()))
+ .openConnection(ConProxy);
+ con.setDoOutput(true);
+ con.setDoInput(true);
+ con.setRequestMethod("POST");
+ con.addRequestProperty("Cookie", Cookie);
+ con.addRequestProperty("Connection", "close");
+ con.connect();
+ OutputStream os = con.getOutputStream();
+ String tcommStr = (isTcomm) ? "fork=\"1\" " : "";
+ String official = "";
+ OfficialOption oo = vi.getOfficialOption();
+ if (oo != null) {
+ official = "force_184=\"" + oo.getForce184() + "\" threadkey=\"" + oo.getThreadKey() + "\" ";
+ }
+ String req = "<thread user_id=\"" + vi.getUserId() + "\" when=\"" + WayBackTime + "\" waybackkey=\""
+ + WayBackKey + "\" res_from=\"-" + back_comment + "\" version=\"20061206\" thread=\"" + vi.
+ getThreadId() + "\" " + tcommStr + official + "/>";
+ os.write(req.getBytes());
+ os.flush();
+ os.close();
+ if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ System.out.println("ng.\nCan't download comment:" + vi.getMsgUrl());
+ return null;
+ }
+ InputStream is = con.getInputStream();
+ int read = 0;
+ int max_size = 0;
+ String content_length_str = con.getHeaderField("Content-length");
+ if (content_length_str != null && !content_length_str.equals("")) {
+ max_size = Integer.parseInt(content_length_str);
+ }
+ int size = 0;
+ final byte[] buf = new byte[1024 * 1024];
+ while ((read = is.read(buf, 0, buf.length)) > 0) {
+ fos.write(buf, 0, read);
+ size += read;
+ if (max_size != 0) {
+ String per = Double.toString((((double) size) * 100) / max_size);
+ per = per.substring(0, Math.min(per.indexOf(".") + 3, per.length()));
+ status.setText("コメントダウンロード:" + per + "パーセント完了");
+ } else {
+ status.setText("コメントダウンロード中:" + Integer.toString(size >> 10) + "kbytesダウンロード");
+ }
+ if (StopFlag.needStop()) {
+ System.out.println("Stopped.");
+ is.close();
+ os.flush();
+ os.close();
+ con.disconnect();
+ file.delete();
+ return null;
+ }
+ }
+ System.out.println("ok.");
+ is.close();
+ fos.flush();
+ fos.close();
+ con.disconnect();
+ return file;
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public File getVideo(VideoInfo vi, final File file, final TextProgressListener status) {
+ if (vi.getVideoUrl() == null) {
+ System.out.println("Video url is not detected.");
+ return null;
+ }
+ try {
+// if (file.canRead()) { // ファイルがすでに存在するなら削除する。
+// file.delete();
+// }
+ HttpURLConnection con = (HttpURLConnection) (new URL(vi.getVideoUrl()))
+ .openConnection(ConProxy);
+ /* 出力のみ */
+ con.setDoInput(true);
+ con.setRequestMethod("GET");
+ con.addRequestProperty("Cookie", Cookie);
+ con.connect();
+ if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ System.out.println("Can't get video:" + vi.getVideoUrl());
+ return null;
+ }
+ final String extension = Util.getExtention(con.getContentType());
+ File outFile = appendExtension(file, extension);
+ InputStream is = con.getInputStream();
+ OutputStream os = new FileOutputStream(outFile);
+ String content_length_str = con.getHeaderField("Content-length");
+ int max_size = 0;
+ if (content_length_str != null && !content_length_str.equals("")) {
+ max_size = Integer.parseInt(content_length_str);
+ }
+ int size = 0;
+ System.out.print("Downloading video...");
+ int read = 0;
+ final byte[] buf = new byte[1024 * 1024];
+ while ((read = is.read(buf, 0, buf.length)) > 0) {
+ size += read;
+ os.write(buf, 0, read);
+ if (max_size != 0) {
+ String per = Double.toString((((double) size) * 100)
+ / max_size);
+ per = per.substring(0, Math.min(per.indexOf(".") + 3, per
+ .length()));
+ status.setText("動画ダウンロード:" + per + "パーセント完了");
+ } else {
+ status.setText("動画ダウンロード中:" + Integer.toString(size >> 10)
+ + "kbytesダウンロード");
+ }
+ if (StopFlag.needStop()) {
+ System.out.println("Stopped.");
+ is.close();
+ os.flush();
+ os.close();
+ con.disconnect();
+ outFile.delete();
+ return null;
+ }
+ }
+ System.out.println("ok.");
+ is.close();
+ os.flush();
+ os.close();
+ con.disconnect();
+ return outFile;
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ /** @return ビデオ名 */
+ public String getVideoHistoryAndTitle(String tag) throws IOException {
+ String url = "http://www.nicovideo.jp/watch/" + tag;
+ System.out.print("Getting video history...");
+ String new_cookie = null;
+ String videoTitle = null;
+
+ HttpURLConnection con = (HttpURLConnection) (new URL(url)).openConnection(ConProxy);
+ /* リクエストの設定 */
+ con.setRequestMethod("GET");
+ con.addRequestProperty("Cookie", Cookie);
+ con.addRequestProperty("Connection", "close");
+ con.connect();
+ if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new IOException("Can't getVideoHistory:" + url);
+ }
+ int i = 1;
+ String key;
+ String value;
+ while ((key = con.getHeaderFieldKey(i)) != null) {
+ if (key.equalsIgnoreCase("Set-Cookie")) {
+ value = con.getHeaderField(i);
+ if (value != null) {
+ new_cookie = value.substring(0, value.indexOf(";"));
+ }
+ }
+ i++;
+ }
+ BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
+ String ret;
+ int index = -1;
+ while ((ret = br.readLine()) != null && index < 0) {
+ if ((index = ret.indexOf(TITLE_PARSE_STR_START)) >= 0) {
+ videoTitle = ret.substring(index + TITLE_PARSE_STR_START.length(), ret.indexOf("‐", index));
+ videoTitle = FileUtil.safeFileName(videoTitle);
+ }
+ }
+ br.close();
+ con.disconnect();
+ if (new_cookie == null) {
+ System.out.println("Can't getVideoHistory: cannot get cookie.");
+ return null;
+ }
+ System.out.println("ok.");
+ Cookie += "; ";
+ Cookie += new_cookie;
+
+ return videoTitle;
+ }
+
+ @Override
+ public VideoInfo getVideoInfo(String tag, String time) throws IOException {
+ final String videoTitle = getVideoHistoryAndTitle(tag);
+
+ String url = "http://flapi.nicovideo.jp/api/getflv/" + tag;
+ if (tag.startsWith("nm")) {
+ url += "?as3=1";
+ }
+ System.out.print("Getting video informations...");
+ Map<String,String> res = new NicoApiRequest(url).get();
+ String threadId = res.get("thread_id");
+ String videoUrl = res.get("url");
+ String msgUrl = res.get("ms");
+ String userId = res.get("user_id");
+ int videoLength = -1;
+ String videoLengthStr = res.get("l");
+ try{
+ videoLength = Integer.parseInt(videoLengthStr);
+ }catch(NumberFormatException ex){}
+
+ OfficialOption oo = null;
+ if ("1".equals(res.get("needs_key"))) {
+ oo = getOfficialOption(threadId);
+ }
+
+ VideoInfo vi = new VideoInfo(videoTitle, threadId, videoUrl, msgUrl, userId, videoLength, oo);
+ System.out.println("ok.");
+
+ if (!(time == null || time.equals("")) && !getWayBackKey(vi, time)) { // WayBackKey
+ throw new IOException();
+ }
+ return vi;
+ }
+
+ private OfficialOption getOfficialOption(String threadId) throws IOException {
+ String url = "http://flapi.nicovideo.jp/api/getthreadkey?thread="+threadId;
+ Map<String,String> map = new NicoApiRequest(url).get();
+ return new OfficialOption(map.get("threadkey"), map.get("force_184"));
+ }
+
+ private boolean getWayBackKey(VideoInfo vi, String time) {
+ System.out.print("Setting wayback time...");
+ Date date = null;
+ String waybacktime = "0";
+ try {
+ date = DateFmt.parse(time);
+ } catch (ParseException ex2) {
+ date = null;
+ }
+ if (date == null) {
+ try {
+ date = DateFmt2.parse(time);
+ } catch (ParseException ex3) {
+ date = null;
+ }
+ }
+ if (date != null) {
+ waybacktime = Long.toString(date.getTime() / 1000);
+ System.out.println("ok.(" + date.toString() + "):" + waybacktime);
+ } else {
+ try {
+ long tmp_time = Long.parseLong(time);
+ waybacktime = Long.toString(tmp_time);
+ date = new Date(tmp_time * 1000);
+ System.out.println("ok.(" + date.toString() + "):"
+ + waybacktime);
+ } catch (NumberFormatException ex4) {
+ System.out.println("ng.");
+ System.out.println("Cannot parse wayback time.");
+ return false;
+ }
+ }
+ System.out.print("Getting wayback key...");
+ String url = "http://flapi.nicovideo.jp/api/getwaybackkey?thread="
+ + vi.getThreadId();
+ String ret = "";
+ try {
+ HttpURLConnection con = (HttpURLConnection) (new URL(url))
+ .openConnection(ConProxy);
+ /* リクエストの設定 */
+ con.setRequestMethod("GET");
+ con.addRequestProperty("Cookie", Cookie);
+ con.addRequestProperty("Connection", "close");
+ con.setDoInput(true);
+ con.connect();
+ if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ System.out.println("Can't get WayBackKey:" + url);
+ return false;
+ }
+ /* 戻り値の取得 */
+ BufferedReader br = new BufferedReader(new InputStreamReader(con
+ .getInputStream()));
+ ret = br.readLine();
+ br.close();
+ con.disconnect();
+ } catch (IOException ex1) {
+ System.out.println("ng.");
+ ex1.printStackTrace();
+ return false;
+ }
+ int idx = 0;
+ if ((idx = ret.indexOf(WAYBACKKEY_STR)) < 0) {
+ System.out.println("ng.");
+ System.out.println("Cannot find wayback key from response.");
+ return false;
+ }
+ int end_idx = Math.max(ret.length(), ret.indexOf("&"));
+ String waybackkey = ret.substring(idx + WAYBACKKEY_STR.length(),
+ end_idx);
+ if (waybackkey == null || waybackkey.equals("")) {
+ System.out.println("ng.");
+ System.out.println("Cannot get wayback key.");
+ return false;
+ }
+ System.out.println("ok. key:" + waybackkey);
+ WayBackTime = waybacktime;
+ WayBackKey = waybackkey;
+ return true;
+ }
+
+ @Override
+ public boolean isLoggedIn() {
+ return Logged_in;
+ }
+
+ private boolean login() {
+ try {
+ HttpURLConnection con = (HttpsURLConnection) (new URL(
+ "https://secure.nicovideo.jp/secure/login?site=niconico"))
+ .openConnection(ConProxy);
+ /* 出力のみ */
+ con.setDoOutput(true);
+ HttpURLConnection.setFollowRedirects(false);
+ con.setInstanceFollowRedirects(false);
+ con.setRequestMethod("POST");
+ con.addRequestProperty("Connection", "close");
+ con.connect();
+ StringBuffer sb = new StringBuffer(4096);
+ sb.append("next_url=&");
+ sb.append("mail=");
+ sb.append(URLEncoder.encode(User, "Shift_JIS"));
+ sb.append("&password=");
+ sb.append(URLEncoder.encode(Pass, "Shift_JIS"));
+ sb.append("&submit.x=103&submit.y=16");
+ OutputStream os = con.getOutputStream();
+ os.write(sb.substring(0).getBytes());
+ os.flush();
+ os.close();
+ int code = con.getResponseCode();
+ if (code < 200 || code >= 400) {
+ System.out.println("Can't login:" + con.getResponseMessage());
+ return false;
+ }
+ int i = 1;
+ String key;
+ String value;
+ while ((key = con.getHeaderFieldKey(i)) != null) {
+ if (key.equalsIgnoreCase("Set-Cookie")) {
+ value = con.getHeaderField(i);
+ if (value != null) {
+ Cookie = value.substring(0, value.indexOf(";"));
+ }
+ }
+ i++;
+ }
+ con.disconnect();
+ if (Cookie == null) {
+ System.out.println("Can't login: cannot set cookie.");
+ return false;
+ }
+ System.out.println("Logged in.");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ private File appendExtension(File file, String extension) {
+ final String e = "." + extension;
+ final String defExt = ".flv";
+ String path = file.getPath();
+ if (path.endsWith(e)) {
+ return file;
+ } else if (path.endsWith(defExt)) {
+ path = path.substring(0, path.length() - defExt.length());
+ }
+ return new File(path + e);
+ }
+
+ private class NicoApiRequest {
+
+ private final String url;
+
+ private NicoApiRequest(String url) {
+ this.url = url;
+ }
+
+ private Map<String,String> get() throws IOException {
+ Map<String, String> map = new HashMap<String, String>();
+ System.out.print("Getting video informations...");
+ HttpURLConnection con = (HttpURLConnection) (new URL(url)).openConnection(ConProxy);
+ /* リクエストの設定 */
+ con.setRequestMethod("GET");
+ con.addRequestProperty("Cookie", Cookie);
+ con.addRequestProperty("Connection", "close");
+ con.connect();
+ if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new IOException("Can't getVideoInfo:" + url);
+ }
+ /* 戻り値の取得 */
+ BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ String ret = br.readLine();
+ br.close();
+ con.disconnect();
+ ret = URLDecoder.decode(ret, "Shift_JIS");
+ String[] array = ret.split("&");
+ int cnt = 0;
+ for (int i = 0; i < array.length; i++) {
+ int idx = array[i].indexOf("=");
+ if (idx < 0) {
+ continue;
+ }
+ String key = array[i].substring(0, idx);
+ String value = array[i].substring(idx + 1);
+ map.put(key, value);
+ }
+ return map;
+ }
+ }
+}