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;
*/
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);
}
/**
* @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;
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();
}
@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)));
}
});
} 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. */
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;
}
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();
+ }
+ }
}