OSDN Git Service

Cookie関係情報をコンフィグから取得しプロファイルを作成する処理の実装
[coroid/inqubus.git] / frontend / src / saccubus / worker / impl / download / Download.java
index 51810e1..898b7db 100644 (file)
@@ -4,15 +4,17 @@ import static saccubus.worker.impl.download.DownloadStatus.*;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.logging.Logger;
+import java.util.Date;
+import java.util.EnumSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import nicobrowser.DownloadCommentType;
 import nicobrowser.GetFlvResult;
 import nicobrowser.NamePattern;
 import nicobrowser.NicoHttpClient;
 import nicobrowser.ProgressListener;
 import nicobrowser.WayBackInfo;
 import nicobrowser.entity.NicoContent.Status;
-import org.apache.http.HttpException;
 import saccubus.worker.Worker;
 import saccubus.worker.WorkerListener;
 import saccubus.worker.profile.CommentProfile;
@@ -34,12 +36,15 @@ import saccubus.worker.profile.ProxyProfile;
  */
 public class Download extends Worker<DownloadResult, DownloadProgress> {
 
-    private static final Logger logger = Logger.getLogger(Download.class.getName());
+    private static final Logger logger = LoggerFactory.getLogger(Download.class);
+    private static final Object timeLockObj = new Object();
+    private static volatile long lastStartTime = 0L;
     private final DownloadProfile profile;
     private final String videoId;
+    private final int waitDownload;
 
     public Download(DownloadProfile profile, String videoId) {
-        this(profile, videoId, null);
+        this(profile, videoId, null, 30);
     }
 
     /**
@@ -50,37 +55,19 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
      * @param listener
      * @param flag
      */
-    public Download(DownloadProfile profile, String videoId, WorkerListener<DownloadResult, DownloadProgress> listener) {
-        // TODO listener登録
+    public Download(DownloadProfile profile, String videoId, WorkerListener<DownloadResult, DownloadProgress> listener,
+            int wait) {
         super(listener);
         this.videoId = videoId;
         this.profile = profile;
+        this.waitDownload = wait;
     }
 
-//    @Override
-//    public Boolean call() throws Exception {
-//        try {
-//            final DownloadResult result = doInBackground();
-//            return Boolean.valueOf(result.getResultValue());
-//        } finally {
-//            // TODO 何か処理が必要?
-////            getStopFlag().finished();
-//        }
-//    }
-//    // TODO Runnableを実装しなくなったので削除する
-//    public void run() {
-//        try {
-//            call();
-//        } catch (Exception ex) {
-//            String text = (ex.getMessage() != null) ? ex.getMessage() : "予期しないエラー発生のため中断しました。";
-//            sendText(text);
-//            logger.log(Level.SEVERE, null, ex);
-//        }
-//    }
     @Override
     public DownloadResult work() throws Exception {
+        waitAndGo();
 
-        publish(new DownloadProgress(PROCESS, "ログイン中"));
+        publish(new DownloadProgress(PROCESS, 0.0, "ログイン中"));
 
         NicoHttpClient client = null;
         nicobrowser.VideoInfo vi = null;
@@ -114,9 +101,14 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
             final String name = pattern.createFileName(videoId, true);
             final File file = new File(profile.getCommentProfile().getDir(), name);
 
-            commentFile = client.getCommentFile(vi, file.getPath(), wbi, profile.getCommentProfile().
-                    getLengthRelatedCommentSize(),
-                    profile.getCommentProfile().isDisablePerMinComment());
+            final EnumSet<DownloadCommentType> commentSet = EnumSet.of(DownloadCommentType.OWNER);
+            if (profile.getCommentProfile().isDisablePerMinComment()) {
+                commentSet.add(DownloadCommentType.COMMENT_OLD);
+            } else {
+                commentSet.add(DownloadCommentType.COMMENT);
+            }
+            commentFile = client.getCommentFile(vi, file.getPath(), commentSet, wbi, profile.getCommentProfile().
+                    getLengthRelatedCommentSize());
         } else {
             commentFile = profile.getCommentProfile().getLocalFile();
         }
@@ -132,7 +124,7 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
                 @Override
                 public void progress(long fileSize, long downloadSize) {
                     final double vol = (double) downloadSize / (double) fileSize * 100.0;
-                    publish(new DownloadProgress(PROCESS, String.format("ダウンロード%.2f%%", vol)));
+                    publish(new DownloadProgress(PROCESS, vol, String.format("ダウンロード%.2f%%", vol)));
                 }
             });
 
@@ -140,35 +132,8 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
         } else {
             videoFile = profile.getVideoProfile().getLocalFile();
         }
-        return new DownloadResult(true, videoFile, commentFile);
 
-
-        // TODO FFMPEG 実行開始は別タスクとして実装する.
-//        if (!profile.getOutputFileSetting().isConvert()) {
-//            publish(new DownloadProgress("動画・コメントを保存し、変換は行いませんでした。"));
-//            return new DownloadResult(true);
-//        }
-//
-//        if (!videoFile.isFile()) {
-//            throw new IOException("入力動画ファイルが存在しません:" + videoFile.getPath());
-//        }
-//
-//        if (profile.getOutputFileSetting().isAddComment()) {
-//            if (!commentFile.isFile()) {
-//                throw new IOException("入力コメントファイルが存在しません:" + commentFile.getPath());
-//            }
-//        } else {
-//            commentFile = null;
-//        }
-//
-//        /*ビデオ名の確定*/
-//        final boolean isNotLow = (vf == null) ? true : (vf.getStatus() != Status.GET_LOW);
-//        File convertedVideoFile = getOutputFileName(vi.getTitleInWatchPage(), isNotLow);
-//
-
-//        boolean res = new FfmpegCommand(getListener(), getStopFlag(), commentFile, videoFile,
-//                convertedVideoFile, profile.getFfmpeg(), profile.getGeneralSetting()).execute();
-//        return res;
+        return new DownloadResult(true, videoFile, commentFile);
     }
 
     /** @return 何かダウンロードするものがあればtrue. */
@@ -176,48 +141,25 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
         return (profile.getVideoProfile().isDownload() || profile.getCommentProfile().isDownload());
     }
 
-    // TODO どこかに処理を移す必要がある.
-    /**
-     * (ネットワーク設定以外の)設定を検証する.
-     * @throws IllegalArgumentException 設定に不備がある場合.
-     */
-//    private void validSetting() {
-//        if (profile.getOutputFileSetting().isConvert()) {
-//            File a = profile.getFfmpeg().getFfmpeg();
-//            if (!a.canRead()) {
-//                throw new IllegalArgumentException("FFmpegが見つかりません。");
-//            }
-//            if (profile.getFfmpeg().getVhook().getPath().indexOf(' ') >= 0) {
-//                throw new IllegalArgumentException("すいません。現在vhookライブラリには半角空白は使えません。");
-//            }
-//            a = profile.getFfmpeg().getVhook();
-//            if (!a.canRead()) {
-//                throw new IllegalArgumentException("Vhookライブラリが見つかりません。");
-//            }
-//            a = profile.getFfmpeg().getFont();
-//            if (!a.canRead()) {
-//                throw new IllegalArgumentException("フォントが見つかりません。");
-//            }
-//        }
-//    }
     /**
      * HttpClientを生成し, ニコニコ動画サーバへログインします.
      * @return 生成したHttpClientインスタンス.
      * @throws IOException ログイン失敗.
      * @throws InterruptedException ログイン失敗.
      */
-    // TODO HttpException を投げるのをやめたい. コンパイル時にHttpComponentが必要になるので.
-    private NicoHttpClient createClientAndLogin() throws IOException, InterruptedException, HttpException {
+    private NicoHttpClient createClientAndLogin() throws IOException, InterruptedException {
         final NicoHttpClient client = createClient(profile.getProxyProfile());
-        final boolean hasLogin;
-        try {
-            hasLogin = client.login(profile.getLoginInfo().getMail(), profile.getLoginInfo().getPassword());
+        if (profile.getLoginProfile().needsLogin()) {
+
+            final boolean hasLogin = client.login(profile.getLoginProfile().getMail(), profile.getLoginProfile().
+                    getPassword());
             if (!hasLogin) {
                 throw new IOException("login fail");
             }
-        } catch (URISyntaxException ex) {
-            throw new IOException("login fail", ex);
+        } else {
+            client.addCookie(profile.getLoginProfile().getCookies());
         }
+
         return client;
     }
 
@@ -244,4 +186,21 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
             throw new InterruptedException("中止要求を受け付けました");
         }
     }
+
+    /**
+     * ニコニコ動画サービスに連続アクセスするとはじかれるため, 前回のアクセス開始時刻から一定期間は
+     * 次のアクセスに行かないよう待機する必要があります.
+     * @throws InterruptedException 中断されました.
+     */
+    private void waitAndGo() throws InterruptedException {
+        synchronized (timeLockObj) {
+            final long now = new Date().getTime();
+            final long needSleep = (waitDownload * 1000L) - (now - lastStartTime);
+            if (needSleep > 0L) {
+                publish(new DownloadProgress(DownloadStatus.PROCESS, -1.0, "過剰アクセス抑制待機 " + needSleep / 1000));
+                Thread.sleep(needSleep);
+            }
+            lastStartTime = new Date().getTime();
+        }
+    }
 }