2 package nicobrowser.config;
4 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.List;
12 import java.util.logging.Level;
13 import java.util.logging.Logger;
14 import java.util.regex.Matcher;
15 import java.util.regex.Pattern;
16 import org.apache.commons.configuration.Configuration;
17 import org.apache.commons.configuration.ConfigurationException;
18 import org.apache.commons.configuration.PropertiesConfiguration;
19 import org.apache.commons.io.FileUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
24 public final class Config {
26 private static Log log = LogFactory.getLog(Config.class);
27 private static Config instance;
28 private final PropertiesConfiguration properties;
29 private static final String APPLICATION_NAME = "nicobrowser";
30 private static final String CONFIG_NAME = APPLICATION_NAME + ".properties";
31 private static final String FEEDURL_NAME = "feedurl.txt";
32 private static final String MYLIST_CONFIG_NAME = "mylist.txt";
33 private static final File APP_HOME = new File(System.getProperty("user.home", "."), "." + APPLICATION_NAME);
34 private static final File CONFIG_FILE = new File(APP_HOME, CONFIG_NAME);
35 private static final File FEEDURL_FILE = new File(APP_HOME, FEEDURL_NAME);
36 private static final File MYLIST_CONFIG_FILE = new File(APP_HOME, MYLIST_CONFIG_NAME);
37 public static final String P_PATH_DB = "path.db";
38 public static final String P_PATH_SAVEFILE = "path.savefile";
39 public static final String P_SAVEFILE_PATTERN = "savefilename.pattern";
40 public static final String P_SAVEFILE_REPLACE_FROM = "savefilename.replace.from";
41 public static final String P_SAVEFILE_REPLACE_TO = "savefilename.replace.to";
42 public static final String P_FILE_ENCODING = "encoding";
43 public static final String P_NICOVIDEO_MAIL = "nicovideo.mail";
44 public static final String P_NICOVIDEO_PASSWORD = "nicovideo.password";
45 public static final String P_DOWNLOAD_RETRY = "download.retry";
46 public static final String P_DOWNLOAD_WAIT = "download.wait";
47 public static final String P_DOWNLOAD_LOW = "download.low";
48 public static final String P_DOWNLOAD_MYLIST = "download.mylist";
49 private static final int DEFAULT_MAX_RETRY = 3;
50 private static final int DEFAULT_WAIT_TIME = 15;
51 private static final boolean DEFAULT_LOW_FILE = true;
54 * プログラム実行に必要なコンフィグファイルを作成する.
55 * @return 今回コンフィグを作成したのであればtrue. 既に存在していたため, ファイル作成を行わなかった場合にはfalse.
56 * @throws java.io.IOException ファイル作成に失敗した.
58 public static boolean createNewConfigFiles() throws IOException {
59 boolean result = false;
60 if (!CONFIG_FILE.exists()) {
61 createNewConfigFile(CONFIG_FILE);
63 log.info("コンフィグファイルを作成しました: " + CONFIG_FILE.getCanonicalPath());
65 if (!FEEDURL_FILE.exists()) {
66 InputStream resource = null;
68 resource = ClassLoader.getSystemResourceAsStream("resources/" + FEEDURL_NAME);
69 createNewFileFromResource(resource, FEEDURL_FILE);
71 log.info("FEED URLファイルを作成しました: " + FEEDURL_FILE.getCanonicalPath());
73 if (resource != null) {
78 if (!MYLIST_CONFIG_FILE.exists()) {
79 InputStream resource = null;
81 resource = ClassLoader.getSystemResourceAsStream("resources/" + MYLIST_CONFIG_NAME);
82 createNewFileFromResource(resource, MYLIST_CONFIG_FILE);
83 log.info("MYLISTファイルを作成しました: " + MYLIST_CONFIG_FILE.getCanonicalPath());
85 if (resource != null) {
94 * 新しいプロパティを設定する. 新しいプロパティに値がない場合, 現在のままとなる.
98 public void updateConfigFile(Configuration p) throws ConfigurationException {
99 updatePropertyValue(p, P_NICOVIDEO_MAIL);
100 updatePropertyValue(p, P_NICOVIDEO_PASSWORD);
101 updatePropertyValue(p, P_FILE_ENCODING);
103 updatePropertyValue(p, P_PATH_DB);
104 updatePropertyValue(p, P_PATH_SAVEFILE);
105 updatePropertyValue(p, P_SAVEFILE_PATTERN);
106 updatePropertyValue(p, P_SAVEFILE_REPLACE_FROM);
107 updatePropertyValue(p, P_SAVEFILE_REPLACE_TO);
109 updatePropertyValue(p, P_DOWNLOAD_RETRY);
110 updatePropertyValue(p, P_DOWNLOAD_WAIT);
111 updatePropertyValue(p, P_DOWNLOAD_LOW);
113 updatePropertyValueArray(p, P_DOWNLOAD_MYLIST);
119 * 新しいプロパティを設定する. 新しいプロパティに値がない場合, 現在のままとなる.
120 * @param newProp 新規プロパティ.
121 * @param key 設定するプロパティキー.
123 private void updatePropertyValue(Configuration newProp, String key) {
124 String value = newProp.getString(key, properties.getString(key));
125 properties.setProperty(key, value);
128 private void updatePropertyValueArray(Configuration newProp, String key) {
129 String[] values = newProp.getStringArray(key);
130 if (values.length < 1) {
131 values = properties.getStringArray(key);
133 properties.setProperty(key, values);
136 private static void createNewConfigFile(File file) throws IOException {
137 ArrayList<CharSequence> props = new ArrayList<CharSequence>();
139 StringBuilder dbpath = new StringBuilder(P_PATH_DB + "=");
140 File dbDir = new File(APP_HOME, "db");
142 //Windowsのパス区切りバックスペースをエスケープするための処理も入れている.
143 dbpath.append(dbDir.getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"));
146 StringBuilder savepath = new StringBuilder(P_PATH_SAVEFILE + "=");
147 File saveDir = new File(APP_HOME, "flv");
149 savepath.append(saveDir.getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"));
152 props.add(P_SAVEFILE_PATTERN + "={title}");
153 props.add(P_SAVEFILE_REPLACE_FROM + "=\\/\\\\:*?\\\"<>|.");
154 props.add(P_SAVEFILE_REPLACE_TO + "=_");
156 props.add(P_FILE_ENCODING + "=" + System.getProperty("file.encoding"));
158 props.add(P_NICOVIDEO_MAIL + "=");
159 props.add(P_NICOVIDEO_PASSWORD + "=");
160 props.add(P_DOWNLOAD_RETRY + "=" + DEFAULT_MAX_RETRY);
161 props.add(P_DOWNLOAD_WAIT + "=" + DEFAULT_WAIT_TIME);
162 props.add(P_DOWNLOAD_LOW + "=" + DEFAULT_LOW_FILE);
163 props.add(P_DOWNLOAD_MYLIST + "=");
165 FileUtils.writeLines(file, props);
169 * リソースから新しいファイルを作成します. リソースファイルはUTF-8で記述する必要があります.
170 * 出力されるファイルはOSのネイティブエンコーディングになります.
171 * @param resource 入力リソース.
172 * @param dest 出力ファイル.
173 * @throws IOException 出力できなかった場合.
175 private static void createNewFileFromResource(InputStream resource, File dest) throws IOException {
176 List<String> list = new ArrayList<String>();
177 BufferedReader br = new BufferedReader(new InputStreamReader(resource, "UTF-8"));
179 String text = br.readLine();
185 FileUtils.writeLines(dest, list);
190 properties = new PropertiesConfiguration(CONFIG_FILE);
191 } catch (Exception ex) {
192 log.fatal("コンフィグの読み込みに失敗: " + CONFIG_FILE);
193 throw new RuntimeException(ex);
197 List urls = FileUtils.readLines(FEEDURL_FILE);
198 } catch (IOException ex) {
199 log.fatal("コンフィグの読み込みに失敗: " + CONFIG_FILE);
200 throw new RuntimeException(ex);
204 public static Config getInstance() {
205 if (instance == null) {
206 instance = new Config();
212 * @return ニコニコ動画ログインID.
214 public String getNicoMail() {
215 return properties.getString(P_NICOVIDEO_MAIL);
219 * @return ニコニコ動画ログインパスワード.
221 public String getNicoPassword() {
222 return properties.getString(P_NICOVIDEO_PASSWORD);
225 /** @return DBパス. コンフィグで設定した値(保存ディレクトリ)でなく, DBファイルのパスが変えることに注意. */
226 public String getDbFile() {
227 return new File(properties.getString(P_PATH_DB), "nicodb").getAbsolutePath();
230 /** @return 保存先の指定. */
231 public String getSrcSaveDir() {
232 return properties.getString(P_PATH_SAVEFILE);
235 /**@return 保存ファイル名の命名規則. */
236 public String getFileNamePattern() {
237 return properties.getString(P_SAVEFILE_PATTERN, "{title}");
240 public String getFileNameReplaceFrom() {
241 return properties.getString(P_SAVEFILE_REPLACE_FROM, "/\\:*?\"<>|.");
244 public String getFileNameReplaceTo() {
245 return properties.getString(P_SAVEFILE_REPLACE_TO, "_");
248 /** @return feedurl.txtの文字エンコーディング. */
249 public String getEncoding() {
250 String res = properties.getString(P_FILE_ENCODING, System.getProperty("file.encoding"));
255 * 失敗したダウンロードファイルの最大リトライ回数を取得する.
258 public int getMaxRetry() {
259 return properties.getInt(P_DOWNLOAD_RETRY, DEFAULT_MAX_RETRY);
263 * 前回ダウンロード開始から最低何秒後から次回ダウンロードを開始するか.
266 public int getWaitTime() {
267 return properties.getInt(P_DOWNLOAD_WAIT, DEFAULT_WAIT_TIME);
271 * エコノミー動画をダウンロードする必要があるか.
272 * @return エコノミー動画もダウンロード対称にする場合はtrue.
274 public boolean needLowFile() {
275 return properties.getBoolean(P_DOWNLOAD_LOW, DEFAULT_LOW_FILE);
278 public List<String> getDownLoadMyList() {
279 final List<String> mylists = new ArrayList<String>();
281 final List<?> lines = FileUtils.readLines(MYLIST_CONFIG_FILE);
282 final Pattern p = Pattern.compile("(^\\d+)");
283 for (Object l : lines) {
284 Matcher m = p.matcher(l.toString());
286 mylists.add(m.group(1));
289 } catch (IOException ex) {
290 Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "読み込みに失敗: " + MYLIST_CONFIG_NAME, ex);
292 String[] res = properties.getStringArray(P_DOWNLOAD_MYLIST);
293 mylists.addAll(Arrays.asList(res));
297 public List<NicoFeed> getNicoFeeds() {
298 List<NicoFeed> list = new ArrayList<NicoFeed>();
300 List<?> lines = FileUtils.readLines(FEEDURL_FILE, getEncoding());
301 for (Object line : lines) {
302 final String str = line.toString();
303 if (StringUtils.isBlank(str) || str.startsWith("#")) {
308 String[] values = str.split(",");
309 NicoFeed feed = new NicoFeed(values[0].trim(), Integer.parseInt(values[1].trim()));
312 } catch (IOException ex) {
313 log.error("ファイルが見つかりません: " + FEEDURL_FILE);
318 public static File getConfigfile() {
322 public static File getFeedUrlFile() {
326 public static File getMylistConfigFile() {
327 return MYLIST_CONFIG_FILE;
330 public static File getAppHome() {