OSDN Git Service

LoginInfoからProxyを分離
[coroid/inqubus.git] / frontend / src / saccubus / converter / Converter.java
1 package saccubus.converter;
2
3 import yukihane.saccubus.converter.profile.Profile;
4 import saccubus.converter.filegetter.FileInstanciator;
5 import java.io.File;
6 import java.io.IOException;
7 import java.util.concurrent.Callable;
8 import saccubus.ConvertStopFlag;
9 import yukihane.saccubus.converter.profile.FfmpegOption;
10 import saccubus.net.TextProgressListener;
11
12 /**
13  * <p>タイトル: さきゅばす</p>
14  *
15  * <p>説明: ニコニコ動画の動画をコメントつきで保存</p>
16  *
17  * <p>著作権: Copyright (c) 2007 PSI</p>
18  *
19  * <p>会社名: </p>
20  *
21  * @author 未入力
22  * @version 1.0
23  */
24 public class Converter extends AbstractCommand implements Runnable, Callable<Boolean> {
25
26     private static final String VIDEO_URL_PARSER = "http://www.nicovideo.jp/watch/";
27     private final Profile profile;
28     private final String movieId;
29     private final String time;
30
31     /**
32      * コンバータを構築します.
33      * @param url 対象となる動画のURL.
34      * @param time
35      * @param profile
36      * @param listener
37      * @param flag
38      */
39     public Converter(String url, String time, Profile profile,
40             TextProgressListener listener, ConvertStopFlag flag) {
41         super(listener, flag);
42         url = url.trim();
43         if (url.startsWith(VIDEO_URL_PARSER)) {
44             int index = url.indexOf('?', VIDEO_URL_PARSER.length());
45             if (index >= 0) {
46                 movieId = url.substring(VIDEO_URL_PARSER.length(), index);
47             } else {
48                 movieId = url.substring(VIDEO_URL_PARSER.length());
49             }
50         } else {
51             movieId = url;
52         }
53         this.time = time;
54         this.profile = profile;
55     }
56
57     public Boolean call() throws Exception {
58         boolean result = false;
59         try {
60             result = runConvert();
61         } finally {
62             getStopFlag().finished();
63         }
64         return Boolean.valueOf(result);
65     }
66
67     public void run() {
68         try {
69             call();
70         } catch (Exception ex) {
71             String text = (ex.getMessage() != null) ? ex.getMessage() : "予期しないエラー発生のため中断しました。";
72             sendText(text);
73             ex.printStackTrace();
74         }
75     }
76
77     private boolean runConvert() throws IOException, InterruptedException {
78         if (!shouldRun(profile)) {
79             sendText("何もすることがありません");
80             return true;
81         }
82
83         validSetting();
84         final FfmpegOption ov = profile.getFfmpeg().getFfmpegOption();
85
86         sendText("ログイン中");
87
88         final FileInstanciator fi = createInstanciator();
89
90         stopFlagReturn();
91
92         final File videoFile = fi.getVideoFile(getListener());
93
94         stopFlagReturn();
95
96         File commentFile = fi.getCommentFile(getListener());
97
98         stopFlagReturn();
99
100         File tcommFile = fi.getTcommFile(getListener());
101
102         if (!profile.needsConvert()) {
103             sendText("動画・コメントを保存し、変換は行いませんでした。");
104             return true;
105         }
106
107         if (!videoFile.isFile()) {
108             throw new IOException("入力動画ファイルが存在しません:" + videoFile.getPath());
109         }
110
111         if (profile.getOutputFileSetting().isAddComment()) {
112             if (!commentFile.isFile()) {
113                 throw new IOException("入力コメントファイルが存在しません:" + commentFile.getPath());
114             }
115         } else {
116             commentFile = null;
117         }
118
119         if (profile.getOutputFileSetting().isAddTcomment()) {
120             if (!tcommFile.isFile()) {
121                 throw new IOException("入力投稿者コメントファイルが存在しません" + tcommFile.getPath());
122             }
123         } else {
124             tcommFile = null;
125         }
126
127         /*ビデオ名の確定*/
128         File convertedVideoFile;
129         if (!profile.getOutputFileSetting().getFile().isFile()) {
130             String conv_name = fi.getVideoTitle();
131             if (profile.getOutputFileSetting().isAppendPrefixVideoId()) {
132                 conv_name = getVideoIDWithBracket() + conv_name;
133             }
134             convertedVideoFile = new File(profile.getOutputFileSetting().getFile().getFile(),
135                     conv_name + ov.getExtOption());
136         } else {
137             String filename = profile.getOutputFileSetting().getFile().getFile().getPath();
138             if (!filename.endsWith(ov.getExtOption())) {
139                 filename = filename.substring(0, filename.lastIndexOf('.')) + ov.getExtOption();
140                 convertedVideoFile = new File(filename);
141             } else {
142                 convertedVideoFile = profile.getOutputFileSetting().getFile().getFile();
143             }
144         }
145
146         boolean res = new FfmpegCommand(getListener(), getStopFlag(), commentFile, tcommFile, videoFile,
147                 convertedVideoFile, profile.getFfmpeg(), profile.getGeneralSetting()).execute();
148         if (res) {
149             if (profile.getCommentSetting().isDelete()) {
150                 commentFile.delete();
151             }
152             if (profile.getVideoSetting().isDelete()) {
153                 videoFile.delete();
154             }
155             if (profile.getTcommentSetting().isDelete()) {
156                 tcommFile.delete();
157             }
158         }
159         return res;
160     }
161
162     private FileInstanciator createInstanciator() throws IOException {
163         FileInstanciator fi;
164
165         FileInstanciator.InstanciationType videoType = new FileInstanciator.InstanciationType(profile.getVideoSetting());
166
167         FileInstanciator.CommentInstanciationType commentType = new FileInstanciator.CommentInstanciationType(profile.
168                 getCommentSetting(), profile.getCommentGetInfo().isselfAdjustCommentNum(), profile.getCommentGetInfo().
169                 getBackComment());
170
171         FileInstanciator.InstanciationType tcommType = new FileInstanciator.InstanciationType(
172                 profile.getTcommentSetting());
173
174         fi = FileInstanciator.create(getStopFlag(), videoType, commentType, tcommType, profile.getLoginInfo(), profile.
175                 getProxySetting(), movieId, time);
176         return fi;
177     }
178
179     /**
180      * (ネットワーク設定以外の)設定を検証する.
181      * @throws IllegalArgumentException 設定に不備がある場合.
182      */
183     private void validSetting() {
184         if (profile.needsConvert()) {
185             File a = profile.getFfmpeg().getFfmpeg();
186             if (!a.canRead()) {
187                 throw new IllegalArgumentException("FFmpegが見つかりません。");
188             }
189             if (profile.getFfmpeg().getVhook().getPath().indexOf(' ') >= 0) {
190                 throw new IllegalArgumentException("すいません。現在vhookライブラリには半角空白は使えません。");
191             }
192             a = profile.getFfmpeg().getVhook();
193             if (!a.canRead()) {
194                 throw new IllegalArgumentException("Vhookライブラリが見つかりません。");
195             }
196             a = profile.getFfmpeg().getFont();
197             if (!a.canRead()) {
198                 throw new IllegalArgumentException("フォントが見つかりません。");
199             }
200         } else {
201             if (profile.getVideoSetting().isDelete()) {
202                 throw new IllegalArgumentException("変換しないのに、動画削除しちゃって良いんですか?");
203             }
204             if (profile.getCommentSetting().isDelete()) {
205                 throw new IllegalArgumentException("変換しないのに、コメント削除しちゃって良いんですか?");
206             }
207             if (profile.getTcommentSetting().isDelete()) {
208                 throw new IllegalArgumentException("変換しないのに、投稿者コメント削除しちゃって良いんですか?");
209             }
210         }
211     }
212
213     private String getVideoIDWithBracket() {
214         return "[" + movieId + "]";
215     }
216
217     public boolean isConverted() {
218         return getStopFlag().isFinished();
219     }
220
221     @Override
222     public ConvertStopFlag getStopFlag() {
223         return super.getStopFlag();
224     }
225
226     /** @return 何か実行すべき処理があればtrue. */
227     private static boolean shouldRun(Profile profile) {
228         return profile.getOutputFileSetting().isConvert() || needsDownload(profile);
229     }
230
231     /** @return 何かダウンロードするものがあればtrue. */
232     private static boolean needsDownload(Profile profile) {
233         return (profile.getVideoSetting().isDownload() || profile.getCommentSetting().isDownload() || profile.
234                 getTcommentSetting().isDownload());
235     }
236 }