Added icons, SystemTray menu, clipboard autorip

This commit is contained in:
4pr0n 2014-04-06 17:26:30 -07:00
parent 9856065ccd
commit a82ac14844
6 changed files with 194 additions and 25 deletions

View File

@ -4,7 +4,7 @@
<groupId>com.rarchives.ripme</groupId> <groupId>com.rarchives.ripme</groupId>
<artifactId>ripme</artifactId> <artifactId>ripme</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0.6</version> <version>1.0.7</version>
<name>ripme</name> <name>ripme</name>
<url>http://rip.rarchives.com</url> <url>http://rip.rarchives.com</url>
<properties> <properties>

View File

@ -0,0 +1,89 @@
package com.rarchives.ripme.ui;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ClipboardUtils {
private static AutoripThread autoripThread = new AutoripThread();
public static void setClipboardAutoRip(boolean enabled) {
if (enabled) {
autoripThread.kill();
autoripThread = new AutoripThread();
autoripThread.isRunning = true;
autoripThread.start();
} else {
autoripThread.kill();
}
}
public static boolean getClipboardAutoRip() {
return autoripThread.isRunning;
}
public static String getClipboardString() {
try {
return (String) Toolkit
.getDefaultToolkit()
.getSystemClipboard()
.getData(DataFlavor.stringFlavor);
} catch (HeadlessException e) {
e.printStackTrace();
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
class AutoripThread extends Thread {
public volatile boolean isRunning = false;
Set<String> rippedURLs = new HashSet<String>();
public void run() {
isRunning = true;
try {
while (isRunning) {
// Check clipboard
String clipboard = ClipboardUtils.getClipboardString();
if (clipboard != null) {
Pattern p = Pattern.compile(
"\\b(((ht|f)tp(s?)\\:\\/\\/|~\\/|\\/)|www.)" +
"(\\w+:\\w+@)?(([-\\w]+\\.)+(com|org|net|gov" +
"|mil|biz|info|mobi|name|aero|jobs|museum" +
"|travel|[a-z]{2}))(:[\\d]{1,5})?" +
"(((\\/([-\\w~!$+|.,=]|%[a-f\\d]{2})+)+|\\/)+|\\?|#)?" +
"((\\?([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
"([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)" +
"(&(?:[-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
"([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)*)*" +
"(#([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)?\\b");
Matcher m = p.matcher(clipboard);
while (m.find()) {
String url = m.group();
if (!rippedURLs.contains(url)) {
rippedURLs.add(url);
// TODO Start rip
MainWindow.ripAlbumStatic(url);
}
}
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void kill() {
isRunning = false;
}
}

View File

@ -1,26 +1,36 @@
package com.rarchives.ripme.ui; package com.rarchives.ripme.ui;
import java.awt.CheckboxMenuItem;
import java.awt.Color; import java.awt.Color;
import java.awt.Container; import java.awt.Container;
import java.awt.Desktop; import java.awt.Desktop;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File; import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.UIManager; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
@ -28,6 +38,7 @@ import javax.swing.JTextField;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet; import javax.swing.text.SimpleAttributeSet;
@ -83,13 +94,16 @@ public class MainWindow implements Runnable, RipStatusHandler {
private static JButton configSaveDirButton; private static JButton configSaveDirButton;
private static JTextField configRetriesText; private static JTextField configRetriesText;
// TODO Configuration components private static MenuItem trayMenuAbout;
private static MenuItem trayMenuExit;
private static CheckboxMenuItem trayMenuAutorip;
private static Image mainIcon;
public MainWindow() { public MainWindow() {
mainFrame = new JFrame("RipMe v" + UpdateUtils.getThisJarVersion()); mainFrame = new JFrame("RipMe v" + UpdateUtils.getThisJarVersion());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//mainFrame.setPreferredSize(new Dimension(400, 180)); mainFrame.setResizable(false);
//mainFrame.setResizable(false);
mainFrame.setLayout(new GridBagLayout()); mainFrame.setLayout(new GridBagLayout());
createUI(mainFrame.getContentPane()); createUI(mainFrame.getContentPane());
@ -99,10 +113,12 @@ public class MainWindow implements Runnable, RipStatusHandler {
Thread shutdownThread = new Thread() { Thread shutdownThread = new Thread() {
@Override @Override
public void run() { public void run() {
saveConfig(); shutdownCleanup();
} }
}; };
Runtime.getRuntime().addShutdownHook(shutdownThread); Runtime.getRuntime().addShutdownHook(shutdownThread);
ClipboardUtils.setClipboardAutoRip(Utils.getConfigBoolean("clipboard.autorip", false));
} }
public void run() { public void run() {
@ -111,13 +127,15 @@ public class MainWindow implements Runnable, RipStatusHandler {
mainFrame.setVisible(true); mainFrame.setVisible(true);
} }
public void saveConfig() { public void shutdownCleanup() {
saveHistory();
Utils.setConfigBoolean("file.overwrite", configOverwriteCheckbox.isSelected()); Utils.setConfigBoolean("file.overwrite", configOverwriteCheckbox.isSelected());
Utils.setConfigInteger("threads.size", Integer.parseInt(configThreadsText.getText())); Utils.setConfigInteger("threads.size", Integer.parseInt(configThreadsText.getText()));
Utils.setConfigInteger("download.retries", Integer.parseInt(configRetriesText.getText())); Utils.setConfigInteger("download.retries", Integer.parseInt(configRetriesText.getText()));
Utils.setConfigInteger("download.timeout", Integer.parseInt(configTimeoutText.getText())); Utils.setConfigInteger("download.timeout", Integer.parseInt(configTimeoutText.getText()));
Utils.setConfigBoolean("clipboard.autorip", ClipboardUtils.getClipboardAutoRip());
saveHistory();
Utils.saveConfig(); Utils.saveConfig();
ClipboardUtils.setClipboardAutoRip(false);
} }
private void status(String text) { private void status(String text) {
@ -135,6 +153,50 @@ public class MainWindow implements Runnable, RipStatusHandler {
} }
private void createUI(Container pane) { private void createUI(Container pane) {
// System tray
PopupMenu trayMenu = new PopupMenu();
trayMenuAbout = new MenuItem("About " + mainFrame.getTitle());
trayMenuAbout.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
String aboutBlurb = "<html><center> Download albums from various websites. <a href=\"http://rarchives.com\">rarchives.com</a>";
JOptionPane.showMessageDialog(null,
aboutBlurb,
mainFrame.getTitle(),
JOptionPane.PLAIN_MESSAGE,
new ImageIcon(mainIcon));
}
});
trayMenuExit = new MenuItem("Exit");
trayMenuExit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
trayMenuAutorip = new CheckboxMenuItem("Clipboard Autorip");
trayMenuAutorip.setState(ClipboardUtils.getClipboardAutoRip());
trayMenuAutorip.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
ClipboardUtils.setClipboardAutoRip(trayMenuAutorip.getState());
}
});
trayMenu.add(trayMenuAbout);
trayMenu.addSeparator();
trayMenu.add(trayMenuAutorip);
trayMenu.addSeparator();
trayMenu.add(trayMenuExit);
try {
mainIcon = ImageIO.read(getClass().getClassLoader().getResource("icon.png"));
TrayIcon trayIcon = new TrayIcon(mainIcon);
trayIcon.setToolTip(mainFrame.getTitle());
trayIcon.setPopupMenu(trayMenu);
SystemTray.getSystemTray().add(trayIcon);
} catch (Exception e) {
e.printStackTrace();
}
EmptyBorder emptyBorder = new EmptyBorder(5, 5, 5, 5); EmptyBorder emptyBorder = new EmptyBorder(5, 5, 5, 5);
GridBagConstraints gbc = new GridBagConstraints(); GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH; gbc.fill = GridBagConstraints.BOTH;
@ -148,7 +210,8 @@ public class MainWindow implements Runnable, RipStatusHandler {
} }
ripTextfield = new JTextField("", 20); ripTextfield = new JTextField("", 20);
ripButton = new JButton("Rip"); ImageIcon ripIcon = new ImageIcon(mainIcon.getScaledInstance(20, 20, Image.SCALE_SMOOTH));
ripButton = new JButton("<html><b>Rip</b></html>", ripIcon);
JPanel ripPanel = new JPanel(new GridBagLayout()); JPanel ripPanel = new JPanel(new GridBagLayout());
ripPanel.setBorder(emptyBorder); ripPanel.setBorder(emptyBorder);
@ -397,7 +460,7 @@ public class MainWindow implements Runnable, RipStatusHandler {
} }
private Thread ripAlbum(String urlString) { private Thread ripAlbum(String urlString) {
saveConfig(); shutdownCleanup();
if (urlString.toLowerCase().startsWith("gonewild:")) { if (urlString.toLowerCase().startsWith("gonewild:")) {
urlString = "http://gonewild.com/user/" + urlString.substring(urlString.indexOf(':') + 1); urlString = "http://gonewild.com/user/" + urlString.substring(urlString.indexOf(':') + 1);
} }
@ -418,8 +481,17 @@ public class MainWindow implements Runnable, RipStatusHandler {
openButton.setVisible(false); openButton.setVisible(false);
statusLabel.setVisible(true); statusLabel.setVisible(true);
mainFrame.pack(); mainFrame.pack();
AbstractRipper ripper = null;
boolean failed = false;
try {
ripper = AbstractRipper.getRipper(url);
} catch (Exception e) {
failed = true;
logger.error("Could not find ripper for URL " + url);
error("Could not find ripper for given URL");
}
if (!failed) {
try { try {
AbstractRipper ripper = AbstractRipper.getRipper(url);
ripTextfield.setText(ripper.getURL().toExternalForm()); ripTextfield.setText(ripper.getURL().toExternalForm());
status("Starting rip..."); status("Starting rip...");
ripper.setObserver((RipStatusHandler) this); ripper.setObserver((RipStatusHandler) this);
@ -429,13 +501,14 @@ public class MainWindow implements Runnable, RipStatusHandler {
} catch (Exception e) { } catch (Exception e) {
logger.error("[!] Error while ripping: " + e.getMessage(), e); logger.error("[!] Error while ripping: " + e.getMessage(), e);
error("Unable to rip this URL: " + e.getMessage()); error("Unable to rip this URL: " + e.getMessage());
}
}
ripButton.setEnabled(true); ripButton.setEnabled(true);
ripTextfield.setEnabled(true); ripTextfield.setEnabled(true);
statusProgress.setValue(0); statusProgress.setValue(0);
mainFrame.pack(); mainFrame.pack();
return null; return null;
} }
}
class RipButtonHandler implements ActionListener { class RipButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
@ -523,4 +596,9 @@ public class MainWindow implements Runnable, RipStatusHandler {
return false; return false;
} }
} }
public static void ripAlbumStatic(String url) {
ripTextfield.setText(url);
ripButton.doClick();
}
} }

BIN
src/main/resources/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/main/resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -20,3 +20,5 @@ tumblr.auth = v5kUqGQXUtmF7K0itri1DGtgTs0VQpbSEbh1jxYgj9d2Sq18F8
gw.api = gonewild gw.api = gonewild
twitter.max_requests = 10 twitter.max_requests = 10
clipboard.autorip = false