Added icons, SystemTray menu, clipboard autorip
This commit is contained in:
parent
9856065ccd
commit
a82ac14844
2
pom.xml
2
pom.xml
@ -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>
|
||||||
|
89
src/main/java/com/rarchives/ripme/ui/ClipboardUtils.java
Normal file
89
src/main/java/com/rarchives/ripme/ui/ClipboardUtils.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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,23 +481,33 @@ 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 {
|
try {
|
||||||
AbstractRipper ripper = AbstractRipper.getRipper(url);
|
ripper = AbstractRipper.getRipper(url);
|
||||||
ripTextfield.setText(ripper.getURL().toExternalForm());
|
|
||||||
status("Starting rip...");
|
|
||||||
ripper.setObserver((RipStatusHandler) this);
|
|
||||||
Thread t = new Thread(ripper);
|
|
||||||
t.start();
|
|
||||||
return t;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("[!] Error while ripping: " + e.getMessage(), e);
|
failed = true;
|
||||||
error("Unable to rip this URL: " + e.getMessage());
|
logger.error("Could not find ripper for URL " + url);
|
||||||
ripButton.setEnabled(true);
|
error("Could not find ripper for given URL");
|
||||||
ripTextfield.setEnabled(true);
|
|
||||||
statusProgress.setValue(0);
|
|
||||||
mainFrame.pack();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
if (!failed) {
|
||||||
|
try {
|
||||||
|
ripTextfield.setText(ripper.getURL().toExternalForm());
|
||||||
|
status("Starting rip...");
|
||||||
|
ripper.setObserver((RipStatusHandler) this);
|
||||||
|
Thread t = new Thread(ripper);
|
||||||
|
t.start();
|
||||||
|
return t;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[!] Error while ripping: " + e.getMessage(), e);
|
||||||
|
error("Unable to rip this URL: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ripButton.setEnabled(true);
|
||||||
|
ripTextfield.setEnabled(true);
|
||||||
|
statusProgress.setValue(0);
|
||||||
|
mainFrame.pack();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RipButtonHandler implements ActionListener {
|
class RipButtonHandler implements ActionListener {
|
||||||
@ -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
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
BIN
src/main/resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -20,3 +20,5 @@ tumblr.auth = v5kUqGQXUtmF7K0itri1DGtgTs0VQpbSEbh1jxYgj9d2Sq18F8
|
|||||||
gw.api = gonewild
|
gw.api = gonewild
|
||||||
|
|
||||||
twitter.max_requests = 10
|
twitter.max_requests = 10
|
||||||
|
|
||||||
|
clipboard.autorip = false
|
Loading…
Reference in New Issue
Block a user