}
/**@return 保存ファイル名の命名規則. */
- public String fileNamePattern() {
+ public String getFileNamePattern() {
return properties.getString(P_SAVEFILE_PATTERN, "{title}");
}
--- /dev/null
+/*
+ * 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;
+ }
+}
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;
/**
* ニコニコ動画から動画ファイルをダウンロードする.
* @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();
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();
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);
* ニコニコ動画から動画ファイルをダウンロードする.
* @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 ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
*/
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)
<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}: 動画タイトル
{id}: ニコニコ動画ID
{low}: エコノミー動画であれば"low"の文字列、通常動画は空文字列"/>
+ <Property name="text" type="java.lang.String" value="{title}: 動画タイトル
{id}: ニコニコ動画ID
{low}: エコノミー動画であれば"low"の文字列、通常動画は空文字列
【具体例】
[{id}]{title} (さきゅばす互換)
{id}{low}_{title} (NicoCache互換)"/>
</Properties>
</Component>
</SubComponents>
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());
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();
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);
.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))
);
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(
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;
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;
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;
}
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);
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);
}
}
}
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();
+ }
}
--- /dev/null
+/* $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);
+
+ }
+}