OSDN Git Service

ニコニコ動画サービスへの連続アクセス間隔をあける
[coroid/inqubus.git] / frontend / src / saccubus / worker / impl / download / Download.java
index 51810e1..044ce2c 100644 (file)
@@ -5,6 +5,7 @@ import static saccubus.worker.impl.download.DownloadStatus.*;
 import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.util.Date;
 import java.util.logging.Logger;
 import nicobrowser.GetFlvResult;
 import nicobrowser.NamePattern;
@@ -35,6 +36,8 @@ 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 Object timeLockObj = new Object();
+    private static volatile long lastStartTime = 0L;
     private final DownloadProfile profile;
     private final String videoId;
 
@@ -79,8 +82,9 @@ public class Download extends Worker<DownloadResult, DownloadProgress> {
 //    }
     @Override
     public DownloadResult work() throws Exception {
+        waitAndGo();
 
-        publish(new DownloadProgress(PROCESS, "ログイン中"));
+        publish(new DownloadProgress(PROCESS, 0.0, "ログイン中"));
 
         NicoHttpClient client = null;
         nicobrowser.VideoInfo vi = null;
@@ -132,7 +136,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)));
                 }
             });
 
@@ -244,4 +248,22 @@ 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();
+            // TODO 30秒間隔はコンフィグ設定できた方が良い
+            final long needSleep = (30 * 1000L) - (now - lastStartTime);
+            if(needSleep > 0L) {
+                publish(new DownloadProgress(DownloadStatus.PROCESS, 0.0, "過剰アクセス抑制待機 " + needSleep / 1000));
+                Thread.sleep(needSleep);
+            }
+            lastStartTime = new Date().getTime();
+        }
+    }
 }