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>
|
||||
<artifactId>ripme</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.6</version>
|
||||
<version>1.0.7</version>
|
||||
<name>ripme</name>
|
||||
<url>http://rip.rarchives.com</url>
|
||||
<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;
|
||||
|
||||
import java.awt.CheckboxMenuItem;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
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.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JScrollPane;
|
||||
@ -28,6 +38,7 @@ import javax.swing.JTextField;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
@ -83,13 +94,16 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
private static JButton configSaveDirButton;
|
||||
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() {
|
||||
mainFrame = new JFrame("RipMe v" + UpdateUtils.getThisJarVersion());
|
||||
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
//mainFrame.setPreferredSize(new Dimension(400, 180));
|
||||
//mainFrame.setResizable(false);
|
||||
mainFrame.setResizable(false);
|
||||
mainFrame.setLayout(new GridBagLayout());
|
||||
|
||||
createUI(mainFrame.getContentPane());
|
||||
@ -99,10 +113,12 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
Thread shutdownThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
saveConfig();
|
||||
shutdownCleanup();
|
||||
}
|
||||
};
|
||||
Runtime.getRuntime().addShutdownHook(shutdownThread);
|
||||
|
||||
ClipboardUtils.setClipboardAutoRip(Utils.getConfigBoolean("clipboard.autorip", false));
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@ -111,13 +127,15 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
saveHistory();
|
||||
public void shutdownCleanup() {
|
||||
Utils.setConfigBoolean("file.overwrite", configOverwriteCheckbox.isSelected());
|
||||
Utils.setConfigInteger("threads.size", Integer.parseInt(configThreadsText.getText()));
|
||||
Utils.setConfigInteger("download.retries", Integer.parseInt(configRetriesText.getText()));
|
||||
Utils.setConfigInteger("download.timeout", Integer.parseInt(configTimeoutText.getText()));
|
||||
Utils.setConfigBoolean("clipboard.autorip", ClipboardUtils.getClipboardAutoRip());
|
||||
saveHistory();
|
||||
Utils.saveConfig();
|
||||
ClipboardUtils.setClipboardAutoRip(false);
|
||||
}
|
||||
|
||||
private void status(String text) {
|
||||
@ -135,6 +153,50 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
}
|
||||
|
||||
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);
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
@ -148,7 +210,8 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
}
|
||||
|
||||
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());
|
||||
ripPanel.setBorder(emptyBorder);
|
||||
|
||||
@ -397,7 +460,7 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
}
|
||||
|
||||
private Thread ripAlbum(String urlString) {
|
||||
saveConfig();
|
||||
shutdownCleanup();
|
||||
if (urlString.toLowerCase().startsWith("gonewild:")) {
|
||||
urlString = "http://gonewild.com/user/" + urlString.substring(urlString.indexOf(':') + 1);
|
||||
}
|
||||
@ -418,23 +481,33 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
openButton.setVisible(false);
|
||||
statusLabel.setVisible(true);
|
||||
mainFrame.pack();
|
||||
AbstractRipper ripper = null;
|
||||
boolean failed = false;
|
||||
try {
|
||||
AbstractRipper 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;
|
||||
ripper = AbstractRipper.getRipper(url);
|
||||
} 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;
|
||||
failed = true;
|
||||
logger.error("Could not find ripper for URL " + url);
|
||||
error("Could not find ripper for given URL");
|
||||
}
|
||||
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 {
|
||||
@ -523,4 +596,9 @@ public class MainWindow implements Runnable, RipStatusHandler {
|
||||
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
|
||||
|
||||
twitter.max_requests = 10
|
||||
|
||||
clipboard.autorip = false
|
Loading…
Reference in New Issue
Block a user