import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
+import javax.swing.table.TableModel;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.lang.builder.ToStringBuilder;
import saccubus.MainFrame_AboutBox;
import yukihane.inqubus.manager.TaskStatus;
import yukihane.inqubus.model.Target;
import yukihane.inqubus.model.TargetsTableModel;
+import yukihane.inqubus.thumbnail.Repository;
+import yukihane.inqubus.thumbnail.Thumbnail;
/**
*
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(MainFrame.class);
+ private final Repository thumbRepository = new Repository();
private final TargetsTableModel targetModel = new TargetsTableModel();
private final TaskManage taskManager;
private final Thread videoFileWatcherThread;
final JPanel pnlMain = new JPanel();
final JScrollPane scrDisplay = new JScrollPane();
- tblDisplay = new JTable(targetModel, new TargetsColumnModel());
+ tblDisplay = new JTable(targetModel, new TargetsColumnModel()) {
+
+ @Override
+ public String getToolTipText(MouseEvent e) {
+ int row = convertRowIndexToModel(rowAtPoint(e.getPoint()));
+ TableModel m = getModel();
+ final String videoId = (String) m.getValueAt(row, 0);
+ try {
+ final Thumbnail thumbnail = thumbRepository.getThumnail(videoId);
+ if (thumbnail == null) {
+ return videoId + ": 動画情報未取得";
+ }
+
+ final URL imageUrl = thumbnail.getImageFile().toURI().toURL();
+
+ return "<html>" + videoId + ": " + thumbnail.getTitle()
+ + " (" + thumbnail.getLength() + ")" + "<br/>"
+ + "<img src=\"" + imageUrl + "\"/>"
+ + "</html>";
+ } catch (Throwable ex) {
+ logger.warn(null, ex);
+ return videoId + ": 情報取得できません";
+ }
+ }
+ };
tblDisplay.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
final JPanel pnlButton = new JPanel();
final JPanel pnlInputMain = new JPanel();
final InqubusConvertProfile convProf = new InqubusConvertProfile();
logger.debug(downProf.toString());
logger.debug(convProf.toString());
+
+ final File tempDir = new File(Config.INSTANCE.getSystemTempDir());
+ thumbRepository.request(downProf.getProxyProfile(), tempDir, id);
+
final RequestProcess rp = new RequestProcess(downProf, id, convProf);
taskManager.add(rp);
targetModel.addTarget(new Target(rp));
--- /dev/null
+package yukihane.inqubus.thumbnail;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import javax.imageio.ImageIO;
+import nicobrowser.NicoHttpClient;
+import nicobrowser.util.RssContent;
+import nicobrowser.util.RssContentParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import saccubus.worker.profile.ProxyProfile;
+
+/**
+ *
+ * @author yuki
+ */
+public class Repository {
+
+ private static final Logger logger = LoggerFactory.getLogger(Repository.class);
+ private final ExecutorService executorService = Executors.newCachedThreadPool();
+ private final Map<String, Thumbnail> thumbnailMap = new HashMap<>();
+
+ public void request(ProxyProfile proxy, File tempDir, String videoId) {
+ synchronized (thumbnailMap) {
+ final Thumbnail value = thumbnailMap.get(videoId);
+ if (value != null) {
+ return;
+ }
+ }
+
+ executorService.execute(new ThumnailFetchWorker(proxy, tempDir, videoId));
+ }
+
+ public Thumbnail getThumnail(String videoId) {
+ synchronized (thumbnailMap) {
+ return thumbnailMap.get(videoId);
+ }
+ }
+
+ private class ThumnailFetchWorker implements Runnable {
+
+ private final ProxyProfile proxy;
+ private final String videoId;
+ private final File tempDir;
+
+ private ThumnailFetchWorker(ProxyProfile proxy, File tempDir, String videoId) {
+ this.proxy = proxy;
+ this.videoId = videoId;
+ this.tempDir = tempDir;
+ }
+
+ @Override
+ public void run() {
+ work();
+ }
+
+ private void work() {
+ final NicoHttpClient client = createClient(proxy);
+
+ try (InputStream is = client.getThumbInfo(videoId)) {
+ final RssContent cont = new RssContentParser().parse(is);
+ final URL thumbUrl = new URL(cont.getThumbnail_url());
+
+ final File imageFile;
+ try (InputStream imageStream = client.get(thumbUrl)) {
+ final BufferedImage image = ImageIO.read(imageStream);
+ imageFile = File.createTempFile("thumb", ".jpg", tempDir);
+ imageFile.deleteOnExit();
+ ImageIO.write(image, "jpeg", imageFile);
+ }
+ final Thumbnail thumb = new Thumbnail(cont.getTitle(), cont.getLength(), imageFile);
+
+ synchronized (thumbnailMap) {
+ thumbnailMap.put(videoId, thumb);
+ }
+ } catch (IOException ex) {
+ logger.error(null, ex);
+ }
+ }
+
+ private NicoHttpClient createClient(ProxyProfile proxy) {
+ if (proxy.use()) {
+ return new NicoHttpClient(proxy.getHost(), proxy.getPort());
+ } else {
+ return new NicoHttpClient();
+ }
+ }
+ }
+}
--- /dev/null
+package yukihane.inqubus.thumbnail;
+
+import java.io.File;
+import javax.swing.ImageIcon;
+
+/**
+ *
+ * @author yuki
+ */
+public class Thumbnail {
+
+ private final String title;
+ private final String length;
+ private final File imageFile;
+
+ Thumbnail(String title, String length, File imageFile) {
+ this.title = title;
+ this.length = length;
+ this.imageFile = imageFile;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getLength() {
+ return length;
+ }
+
+ public File getImageFile() {
+ return imageFile;
+ }
+}