OSDN Git Service

ファイル命名規則を用いたファイル名の決定
authoryuki <yuki@bdf3b611-c98c-6041-8292-703d9c9adbe7>
Mon, 19 Apr 2010 11:59:52 +0000 (11:59 +0000)
committeryuki <yuki@bdf3b611-c98c-6041-8292-703d9c9adbe7>
Mon, 19 Apr 2010 11:59:52 +0000 (11:59 +0000)
git-svn-id: http://192.168.11.7/svn/repository/NicoBrowser/branches/dev20100419_filename@308 bdf3b611-c98c-6041-8292-703d9c9adbe7

src/nicobrowser/Config.java
src/nicobrowser/NamePattern.java [new file with mode: 0644]
src/nicobrowser/NicoHttpClient.java
src/nicobrowser/entity/NicoContent.java
src/nicobrowser/gui/config/ConfigFrame.form
src/nicobrowser/gui/config/ConfigFrame.java
src/nicobrowser/main/Main.java
src/nicobrowser/util/Util.java
test/nicobrowser/NamePatternTest.java [new file with mode: 0644]

index 6f57508..fd11219 100644 (file)
@@ -233,7 +233,7 @@ public final class Config {
     }
 
     /**@return 保存ファイル名の命名規則. */
-    public String fileNamePattern() {
+    public String getFileNamePattern() {
         return properties.getString(P_SAVEFILE_PATTERN, "{title}");
     }
 
diff --git a/src/nicobrowser/NamePattern.java b/src/nicobrowser/NamePattern.java
new file mode 100644 (file)
index 0000000..38a41df
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package nicobrowser;
+
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author yuki
+ */
+public class NamePattern {
+
+    private static final String titlePattern = "\\{title\\}";
+    private static final String idPattern = "\\{id\\}";
+    private static final String lowPattern = "\\{low\\}";
+    private final String pattern;
+    private final String title;
+
+    /**
+     * 保存ファイル名の命名規則.
+     * @param pattern 命名パターン.
+     * @param title ファイル名に用いるタイトル文字列. 禁則文字が入っていてはならない.
+     */
+    public NamePattern(String pattern, String title) {
+        this.pattern = pattern;
+        this.title = title;
+    }
+
+    public String getTitle(){
+        return title;
+    }
+
+    String createFileName(String id, boolean isNotLow) {
+        String res = pattern;
+        res = res.replaceAll(titlePattern, title);
+        res = res.replaceAll(idPattern, id);
+        String low = isNotLow ? "" : "low";
+        res = res.replaceAll(lowPattern, low);
+        return res;
+    }
+}
index 881163c..3b1c7da 100644 (file)
@@ -38,6 +38,7 @@ import javax.xml.parsers.ParserConfigurationException;
 import nicobrowser.entity.NicoContent.Status;
 import nicobrowser.util.Result;
 import nicobrowser.util.Util;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.http.HttpEntity;
@@ -565,13 +566,14 @@ public class NicoHttpClient {
     /**
      * ニコニコ動画から動画ファイルをダウンロードする.
      * @param vi getVideoInfoメソッドで取得したオブジェクト.
-     * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要.
+     * @param saveDir ダウンロードしたファイルを保存するディレクトリ.
+     * @param np 保存するファイル名の命名規則. 拡張子は別途付与されるため不要.
      * @param nowStatus ダウンロードしようとしている動画ファイルの, 現在のステータス.
      * @param needLowFile エコノミー動画をダウンロードするのであればtrue.
      * @return この処理を行った後の, 対象ファイルのステータス.
      * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
      */
-    public GetFlvResult getFlvFile(VideoInfo vi, String fileName, Status nowStatus, boolean needLowFile,
+    public GetFlvResult getFlvFile(VideoInfo vi, File saveDir, NamePattern np, Status nowStatus, boolean needLowFile,
             ProgressListener listener) throws IOException, URISyntaxException, HttpException, InterruptedException {
 
         final URL notifierUrl = vi.getSmileUrl();
@@ -591,12 +593,15 @@ public class NicoHttpClient {
                 return new GetFlvResult(null, nowStatus, userName);
             }
         }
+        final boolean isNotLow = !url.toString().contains("low");
+
+        final File downloadFile = new File(saveDir, np.createFileName(vi.getRealVideoId(), isNotLow));
 
         HttpGet get = new HttpGet(url.toURI());
         HttpResponse response = http.execute(get);
         String contentType = response.getEntity().getContentType().getValue();
         log.debug(contentType);
-        log.debug(fileName);
+        log.debug(downloadFile.toString());
         if ("text/plain".equals(contentType) || "text/html".equals(contentType)) {
             log.error("取得できませんでした. サーバが混みあっている可能性があります: " + vi.getRealVideoId());
             response.getEntity().consumeContent();
@@ -608,7 +613,7 @@ public class NicoHttpClient {
         final int BUF_SIZE = 1024 * 32;
         BufferedInputStream in = new BufferedInputStream(response.getEntity().getContent());
 
-        File file = new File(fileName + "." + ext);
+        File file = new File(downloadFile.toString() + "." + ext);
         log.info("保存します(" + fileSize / 1024 + "KB): " + file.getPath());
         FileOutputStream fos = new FileOutputStream(file);
         BufferedOutputStream out = new BufferedOutputStream(fos);
@@ -635,6 +640,23 @@ public class NicoHttpClient {
      * ニコニコ動画から動画ファイルをダウンロードする.
      * @param vi getVideoInfoメソッドで取得したオブジェクト.
      * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要.
+     * @param nowStatus ダウンロードしようとしている動画ファイルの, 現在のステータス.
+     * @param needLowFile エコノミー動画をダウンロードするのであればtrue.
+     * @return この処理を行った後の, 対象ファイルのステータス.
+     * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
+     */
+    public GetFlvResult getFlvFile(VideoInfo vi, String fileName, Status nowStatus, boolean needLowFile,
+            ProgressListener listener) throws IOException, URISyntaxException, HttpException, InterruptedException {
+        String file = FilenameUtils.getName(fileName);
+        String dir = fileName.substring(0, fileName.length() - file.length());
+        NamePattern np = new NamePattern(file, "");
+        return getFlvFile(vi, new File(dir), np, nowStatus, needLowFile, listener);
+    }
+
+    /**
+     * ニコニコ動画から動画ファイルをダウンロードする.
+     * @param vi getVideoInfoメソッドで取得したオブジェクト.
+     * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要.
      * @return この処理を行った後の, 対象ファイルのステータス.
      * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
      */
index fa3182d..19fa6d9 100644 (file)
@@ -75,33 +75,14 @@ public class NicoContent implements java.io.Serializable {
 
     public void setTitle(String title) {
         this.title = title;
-        setFileName(title);
     }
 
     public String getFileName() {
         return fileName;
     }
 
-    protected void setFileName(String fileName) {
-        if (fileName == null) {
-            this.fileName = null;
-            return;
-        }
-
-        StringBuilder str = new StringBuilder();
-        try {
-            for (int i = 0; i < fileName.length(); i++) {
-                char c = fileName.charAt(i);
-                if (c == '\\' || c == '/' || c == ':' || c == '*' || c == '?' ||
-                        c == '"' || c == '<' || c == '>' || c == '|' || c == '.') {
-                    c = '_';
-                }
-                str.append(c);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        this.fileName = str.toString();
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
     }
 
     @Column(nullable = false)
index 7b0e0af..bd403e1 100644 (file)
   <Layout>
     <DimensionLayout dim="0">
       <Group type="103" groupAlignment="0" attributes="0">
-          <Group type="102" alignment="0" attributes="0">
-              <Component id="jPanel5" max="32767" attributes="0"/>
-              <EmptySpace max="-2" attributes="0"/>
-          </Group>
-          <Group type="102" alignment="1" attributes="0">
-              <Group type="103" groupAlignment="1" attributes="0">
+          <Group type="102" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jPanel5" alignment="0" max="32767" attributes="0"/>
                   <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
                   <Component id="jPanel2" alignment="0" max="32767" attributes="0"/>
                   <Component id="jPanel4" alignment="0" max="32767" attributes="0"/>
               <Group type="102" alignment="1" attributes="0">
                   <Group type="103" groupAlignment="1" attributes="0">
                       <Component id="jScrollPane1" alignment="0" pref="452" max="32767" attributes="0"/>
-                      <Component id="jTextField1" alignment="1" pref="452" max="32767" attributes="0"/>
+                      <Component id="fileNamePatternField" alignment="1" pref="452" max="32767" attributes="0"/>
                   </Group>
                   <EmptySpace max="-2" attributes="0"/>
               </Group>
         <DimensionLayout dim="1">
           <Group type="103" groupAlignment="0" attributes="0">
               <Group type="102" alignment="0" attributes="0">
-                  <Component id="jTextField1" min="-2" max="-2" attributes="0"/>
+                  <Component id="fileNamePatternField" min="-2" max="-2" attributes="0"/>
                   <EmptySpace max="-2" attributes="0"/>
                   <Component id="jScrollPane1" min="-2" pref="71" max="-2" attributes="0"/>
               </Group>
         </DimensionLayout>
       </Layout>
       <SubComponents>
-        <Component class="javax.swing.JTextField" name="jTextField1">
+        <Component class="javax.swing.JTextField" name="fileNamePatternField">
         </Component>
         <Container class="javax.swing.JScrollPane" name="jScrollPane1">
           <AuxValues>
               <Properties>
                 <Property name="columns" type="int" value="20"/>
                 <Property name="editable" type="boolean" value="false"/>
-                <Property name="lineWrap" type="boolean" value="true"/>
                 <Property name="rows" type="int" value="5"/>
-                <Property name="text" type="java.lang.String" value="{title}: &#x52d5;&#x753b;&#x30bf;&#x30a4;&#x30c8;&#x30eb;&#xa;{id}: &#x30cb;&#x30b3;&#x30cb;&#x30b3;&#x52d5;&#x753b;ID&#xa;{low}: &#x30a8;&#x30b3;&#x30ce;&#x30df;&#x30fc;&#x52d5;&#x753b;&#x3067;&#x3042;&#x308c;&#x3070;&quot;low&quot;&#x306e;&#x6587;&#x5b57;&#x5217;&#x3001;&#x901a;&#x5e38;&#x52d5;&#x753b;&#x306f;&#x7a7a;&#x6587;&#x5b57;&#x5217;"/>
+                <Property name="text" type="java.lang.String" value="{title}: &#x52d5;&#x753b;&#x30bf;&#x30a4;&#x30c8;&#x30eb;&#xa;{id}: &#x30cb;&#x30b3;&#x30cb;&#x30b3;&#x52d5;&#x753b;ID&#xa;{low}: &#x30a8;&#x30b3;&#x30ce;&#x30df;&#x30fc;&#x52d5;&#x753b;&#x3067;&#x3042;&#x308c;&#x3070;&quot;low&quot;&#x306e;&#x6587;&#x5b57;&#x5217;&#x3001;&#x901a;&#x5e38;&#x52d5;&#x753b;&#x306f;&#x7a7a;&#x6587;&#x5b57;&#x5217;&#xa;&#x3010;&#x5177;&#x4f53;&#x4f8b;&#x3011;&#xa;[{id}]{title} (&#x3055;&#x304d;&#x3085;&#x3070;&#x3059;&#x4e92;&#x63db;)&#xa;{id}{low}_{title} (NicoCache&#x4e92;&#x63db;)"/>
               </Properties>
             </Component>
           </SubComponents>
index 0ec767c..90416fd 100644 (file)
@@ -42,6 +42,11 @@ public class ConfigFrame extends javax.swing.JFrame {
         dbPathField.setText(dbPath);
         flvPathField.setText(config.getSrcSaveDir());
 
+        // ファイル名 命名規則
+        String filePattern = config.getFileNamePattern();
+        fileNamePatternField.setText(filePattern);
+        jTextArea1.setCaretPosition(0);
+
         // 動作
         waitSpinner.setValue(config.getWaitTime());
         retrySpinner.setValue(config.getMaxRetry());
@@ -84,7 +89,7 @@ public class ConfigFrame extends javax.swing.JFrame {
         jPanel5 = new javax.swing.JPanel();
         savaButton = new javax.swing.JButton();
         jPanel6 = new javax.swing.JPanel();
-        jTextField1 = new javax.swing.JTextField();
+        fileNamePatternField = new javax.swing.JTextField();
         jScrollPane1 = new javax.swing.JScrollPane();
         jTextArea1 = new javax.swing.JTextArea();
 
@@ -282,9 +287,8 @@ public class ConfigFrame extends javax.swing.JFrame {
 
         jTextArea1.setColumns(20);
         jTextArea1.setEditable(false);
-        jTextArea1.setLineWrap(true);
         jTextArea1.setRows(5);
-        jTextArea1.setText("{title}: 動画タイトル\n{id}: ニコニコ動画ID\n{low}: エコノミー動画であれば\"low\"の文字列、通常動画は空文字列");
+        jTextArea1.setText("{title}: 動画タイトル\n{id}: ニコニコ動画ID\n{low}: エコノミー動画であれば\"low\"の文字列、通常動画は空文字列\n【具体例】\n[{id}]{title} (さきゅばす互換)\n{id}{low}_{title} (NicoCache互換)");
         jScrollPane1.setViewportView(jTextArea1);
 
         org.jdesktop.layout.GroupLayout jPanel6Layout = new org.jdesktop.layout.GroupLayout(jPanel6);
@@ -294,13 +298,13 @@ public class ConfigFrame extends javax.swing.JFrame {
             .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel6Layout.createSequentialGroup()
                 .add(jPanel6Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                     .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE)
-                    .add(jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE))
+                    .add(fileNamePatternField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE))
                 .addContainerGap())
         );
         jPanel6Layout.setVerticalGroup(
             jPanel6Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
             .add(jPanel6Layout.createSequentialGroup()
-                .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                .add(fileNamePatternField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                 .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 71, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
         );
@@ -310,15 +314,13 @@ public class ConfigFrame extends javax.swing.JFrame {
         layout.setHorizontalGroup(
             layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
             .add(layout.createSequentialGroup()
-                .add(jPanel5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addContainerGap())
-            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
-                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
-                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .add(jPanel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(jPanel5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .add(jPanel4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .add(jPanel6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                 .addContainerGap())
         );
         layout.setVerticalGroup(
@@ -409,6 +411,7 @@ public class ConfigFrame extends javax.swing.JFrame {
     private javax.swing.JTextField dbPathField;
     private javax.swing.JTextField feedFileField;
     private javax.swing.JLabel feedFileLabel;
+    private javax.swing.JTextField fileNamePatternField;
     private javax.swing.JButton flvPathButton;
     private javax.swing.JTextField flvPathField;
     private javax.swing.JTextField idField;
@@ -426,7 +429,6 @@ public class ConfigFrame extends javax.swing.JFrame {
     private javax.swing.JPanel jPanel6;
     private javax.swing.JScrollPane jScrollPane1;
     private javax.swing.JTextArea jTextArea1;
-    private javax.swing.JTextField jTextField1;
     private javax.swing.JCheckBox lowDownloadCheckBox;
     private javax.swing.JPasswordField passField;
     private javax.swing.JLabel passLabel;
index 1db8ca3..2126bee 100644 (file)
@@ -26,6 +26,7 @@ import nicobrowser.entity.NicoContent;
 import nicobrowser.entity.NicoContent.Status;
 import nicobrowser.gui.config.ConfigFrame;
 import nicobrowser.update.DBUpdater;
+import nicobrowser.util.Util;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.HelpFormatter;
@@ -190,12 +191,13 @@ public class Main {
                 }
                 prevDate = Calendar.getInstance().getTime();
                 File saveDir = new File(config.getSrcSaveDir());
-                NamePattern np = new NamePattern(config.fileNamePattern(), c.getFileName());
+                NamePattern np = new NamePattern(config.getFileNamePattern(), Util.getRegularFileName(c.getTitle()));
                 log.info("ファイルを取得します: " + c.getNicoId() + " " + c.getTitle());
                 try {
                     VideoInfo vi = instance.getVideoInfo(c.getNicoId());
                     GetFlvResult result = instance.getFlvFile(vi, saveDir, np, c.getStatus(), config.needLowFile(),
                             ProgressListener.EMPTY_LISTENER);
+
                     c.setAuthor(result.getAuthor());
                     Status status = result.getStatus();
                     c.setStatus(status);
@@ -226,7 +228,7 @@ public class Main {
                 setParameter(1, c.getNicoId());
         List<NicoContent> resList = query.getResultList();
         if (resList.isEmpty()) {
-            log.info("NEW! " + c.getNicoId() + " : " + c.getFileName());
+            log.info("NEW! " + c.getNicoId() + " : " + c.getTitle());
             manager.persist(c);
         }
     }
index ddf6e77..070946e 100644 (file)
@@ -72,4 +72,28 @@ public class Util {
         }
         return userName;
     }
+
+    /**
+     * ファイル名に使用できない文字を置換する.
+     */
+    public static String getRegularFileName(String title) {
+        if (title == null) {
+            return null;
+        }
+
+        StringBuilder str = new StringBuilder();
+        try {
+            for (int i = 0; i < title.length(); i++) {
+                char c = title.charAt(i);
+                if (c == '\\' || c == '/' || c == ':' || c == '*' || c == '?' || c == '"' || c == '<' || c == '>' || c
+                        == '|' || c == '.') {
+                    c = '_';
+                }
+                str.append(c);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return str.toString();
+    }
 }
diff --git a/test/nicobrowser/NamePatternTest.java b/test/nicobrowser/NamePatternTest.java
new file mode 100644 (file)
index 0000000..0326d98
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id$ */
+package nicobrowser;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class NamePatternTest {
+
+    /**
+     * Test of createFileName method, of class NamePattern.
+     */
+    @Test
+    public void testCreateFileName() {
+        final String title = "タイトル";
+        final String id = "sm9999";
+        String res;
+
+        System.out.println("createFileName");
+        NamePattern np = new NamePattern("{title}", title);
+        res = np.createFileName("sm9", true);
+        assertEquals(title, res);
+
+        NamePattern np2 = new NamePattern("[{id}]{title}", title);
+        res = np2.createFileName(id, false);
+        assertEquals("[sm9999]タイトル", res);
+
+        NamePattern np3 = new NamePattern("{id}{low}_{title}", title);
+        res = np3.createFileName(id, false);
+        assertEquals("sm9999low_タイトル", res);
+
+        NamePattern np4 = new NamePattern("{id}{low}_{title}", title);
+        res = np4.createFileName(id, true);
+        assertEquals("sm9999_タイトル", res);
+
+    }
+}