ImgScroll/src/main/java/com/rarchives/ripme/utils/Utils.java

360 lines
13 KiB
Java
Raw Normal View History

package com.rarchives.ripme.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
2014-04-27 19:09:52 +02:00
import java.lang.reflect.Constructor;
2014-03-04 14:35:35 +01:00
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
2014-03-04 14:35:35 +01:00
import java.util.ArrayList;
import java.util.Enumeration;
2014-04-06 12:27:30 +02:00
import java.util.List;
2014-03-04 14:35:35 +01:00
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
2014-04-27 19:09:52 +02:00
import com.rarchives.ripme.ripper.AbstractRipper;
2014-03-09 09:20:22 +01:00
/**
* Common utility functions used in various places throughout the project.
*/
public class Utils {
2014-03-09 09:20:22 +01:00
public static final String RIP_DIRECTORY = "rips";
private static final String configFile = "rip.properties";
private static final Logger logger = Logger.getLogger(Utils.class);
2014-04-06 11:41:04 +02:00
private static PropertiesConfiguration config;
static {
try {
2014-04-06 11:41:04 +02:00
String configPath = getConfigPath();
File f = new File(configPath);
if (!f.exists()) {
// Use default bundled with .jar
configPath = configFile;
}
config = new PropertiesConfiguration(configPath);
logger.info("Loaded " + config.getPath());
} catch (Exception e) {
2014-02-28 04:49:28 +01:00
logger.error("[!] Failed to load properties file from " + configFile, e);
}
}
2014-03-09 09:20:22 +01:00
/**
* Get the root rips directory.
* @return
* Root directory to save rips to.
* @throws IOException
*/
2014-04-06 11:41:04 +02:00
public static File getWorkingDirectory() {
String currentDir = ".";
try {
currentDir = new File(".").getCanonicalPath() + File.separator + RIP_DIRECTORY + File.separator;
} catch (IOException e) {
logger.error("Error while finding working dir: ", e);
}
if (config != null) {
currentDir = getConfigString("rips.directory", currentDir);
}
File workingDir = new File(currentDir);
if (!workingDir.exists()) {
workingDir.mkdirs();
}
return workingDir;
}
public static String getConfigString(String key, String defaultValue) {
return config.getString(key, defaultValue);
}
public static int getConfigInteger(String key, int defaultValue) {
return config.getInt(key, defaultValue);
}
public static boolean getConfigBoolean(String key, boolean defaultValue) {
return config.getBoolean(key, defaultValue);
}
2014-04-06 12:27:30 +02:00
public static List<String> getConfigList(String key) {
List<String> result = new ArrayList<String>();
for (Object obj : config.getList(key, new ArrayList<String>())) {
if (obj instanceof String) {
result.add( (String) obj);
}
}
return result;
}
public static void setConfigBoolean(String key, boolean value) { config.setProperty(key, value); }
public static void setConfigString(String key, String value) { config.setProperty(key, value); }
public static void setConfigInteger(String key, int value) { config.setProperty(key, value); }
public static void setConfigList(String key, List<Object> list) {
config.clearProperty(key);
config.addProperty(key, list);
}
2014-04-06 11:41:04 +02:00
public static void saveConfig() {
try {
2014-04-06 12:39:30 +02:00
config.save(getConfigPath());
logger.info("Saved configuration to " + getConfigPath());
2014-04-06 11:41:04 +02:00
} catch (ConfigurationException e) {
logger.error("Error while saving configuration: ", e);
}
}
private static String getConfigPath() {
2014-04-06 12:39:30 +02:00
try {
return new File(".").getCanonicalPath() + File.separator + configFile;
} catch (Exception e) {
return "." + File.separator + configFile;
}
}
/**
* Removes the current working directory (CWD) from a File.
* @param saveAs
* The File path
* @return
* saveAs in relation to the CWD
*/
public static String removeCWD(File saveAs) {
2014-04-06 11:41:04 +02:00
String prettySaveAs = saveAs.toString();
try {
2014-04-06 11:41:04 +02:00
prettySaveAs = saveAs.getCanonicalPath();
String cwd = new File(".").getCanonicalPath() + File.separator;
2014-04-06 11:41:04 +02:00
prettySaveAs = prettySaveAs.replace(
cwd,
2014-04-06 11:41:04 +02:00
"." + File.separator);
} catch (Exception e) {
2014-04-06 11:41:04 +02:00
logger.error("Exception: ", e);
}
return prettySaveAs;
}
public static String stripURLParameter(String url, String parameter) {
int paramIndex = url.indexOf("?" + parameter);
boolean wasFirstParam = true;
if(paramIndex < 0) {
wasFirstParam = false;
paramIndex = url.indexOf("&" + parameter);
}
if(paramIndex > 0) {
int nextParam = url.indexOf("&", paramIndex+1);
if(nextParam != -1) {
String c = "&";
if(wasFirstParam) c = "?";
url = url.substring(0, paramIndex) + c + url.substring(nextParam+1, url.length());
} else {
url = url.substring(0, paramIndex);
}
}
return url;
}
2014-03-09 09:20:22 +01:00
/**
* Removes the current working directory from a given filename
* @param file
* @return
* 'file' without the leading current working directory
*/
public static String removeCWD(String file) {
return removeCWD(new File(file));
}
2014-03-04 14:35:35 +01:00
2014-03-09 09:20:22 +01:00
/**
* Get a list of all Classes within a package.
* Works with file system projects and jar files!
* Borrowed from StackOverflow, but I don't have a link :[
* @param pkgname
* The name of the package
* @return
* List of classes within the package
*/
2014-03-04 14:35:35 +01:00
public static ArrayList<Class<?>> getClassesForPackage(String pkgname) {
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
String relPath = pkgname.replace('.', '/');
URL resource = ClassLoader.getSystemClassLoader().getResource(relPath);
if (resource == null) {
throw new RuntimeException("No resource for " + relPath);
}
String fullPath = resource.getFile();
File directory = null;
try {
directory = new File(resource.toURI());
} catch (URISyntaxException e) {
throw new RuntimeException(pkgname + " (" + resource + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", e);
} catch (IllegalArgumentException e) {
directory = null;
}
if (directory != null && directory.exists()) {
// Get the list of the files contained in the package
String[] files = directory.list();
for (String file : files) {
if (file.endsWith(".class") && !file.contains("$")) {
String className = pkgname + '.' + file.substring(0, file.length() - 6);
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) {
throw new RuntimeException("ClassNotFoundException loading " + className);
}
}
}
}
else {
// Load from JAR
2014-03-04 14:35:35 +01:00
try {
2014-04-05 22:52:27 +02:00
String jarPath = fullPath
.replaceFirst("[.]jar[!].*", ".jar")
.replaceFirst("file:", "");
jarPath = URLDecoder.decode(jarPath, "UTF-8");
2014-03-04 14:35:35 +01:00
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while(entries.hasMoreElements()) {
JarEntry nextElement = entries.nextElement();
String entryName = nextElement.getName();
2014-03-04 14:35:35 +01:00
if(entryName.startsWith(relPath)
&& entryName.length() > (relPath.length() + "/".length())
&& !nextElement.isDirectory()) {
2014-03-04 14:35:35 +01:00
String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) {
logger.error("ClassNotFoundException loading " + className);
jarFile.close(); // Resource leak fix?
2014-03-04 14:35:35 +01:00
throw new RuntimeException("ClassNotFoundException loading " + className);
}
}
}
jarFile.close(); // Eclipse said not closing it would have a resource leak
2014-03-04 14:35:35 +01:00
} catch (IOException e) {
logger.error("Error while loading jar file:", e);
2014-03-04 14:35:35 +01:00
throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e);
}
}
return classes;
}
2014-04-06 11:41:04 +02:00
public static final int SHORTENED_PATH_LENGTH = 12;
public static String shortenPath(String path) {
return shortenPath(new File(path));
}
public static String shortenPath(File file) {
String path = removeCWD(file);
if (path.length() < SHORTENED_PATH_LENGTH * 2) {
return path;
}
return path.substring(0, SHORTENED_PATH_LENGTH)
+ "..."
+ path.substring(path.length() - SHORTENED_PATH_LENGTH);
}
public static String filesystemSafe(String text) {
2014-04-25 18:42:54 +02:00
text = text.replaceAll("[^a-zA-Z0-9.-]", "_")
.replaceAll("__", "_")
.replaceAll("_+$", "");
if (text.length() > 100) {
text = text.substring(0, 99);
2014-04-25 18:42:54 +02:00
}
return text;
}
public static String bytesToHumanReadable(int bytes) {
float fbytes = (float) bytes;
String[] mags = new String[] {"", "k", "m", "g", "t"};
int magIndex = 0;
while (fbytes >= 1024) {
fbytes /= 1024;
magIndex++;
}
return String.format("%.2f%sb", fbytes, mags[magIndex]);
}
2014-04-27 19:09:52 +02:00
public static List<String> getListOfAlbumRippers() throws Exception {
List<String> list = new ArrayList<String>();
for (Constructor<?> ripper : AbstractRipper.getRipperConstructors("com.rarchives.ripme.ripper.rippers")) {
list.add(ripper.getName());
}
return list;
}
public static List<String> getListOfVideoRippers() throws Exception {
List<String> list = new ArrayList<String>();
for (Constructor<?> ripper : AbstractRipper.getRipperConstructors("com.rarchives.ripme.ripper.rippers.video")) {
list.add(ripper.getName());
}
return list;
}
public static void playSound(String filename) {
URL resource = ClassLoader.getSystemClassLoader().getResource(filename);
try {
final Clip clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
clip.close();
}
}
});
clip.open(AudioSystem.getAudioInputStream(resource));
clip.start();
} catch (Exception e) {
logger.error("Failed to play sound " + filename, e);
}
}
/**
* Configures root logger, either for FILE output or just console.
*/
public static void configureLogger() {
LogManager.shutdown();
String logFile;
if (getConfigBoolean("log.save", false)) {
logFile = "log4j.file.properties";
}
else {
logFile = "log4j.properties";
}
InputStream stream = Utils.class.getClassLoader().getResourceAsStream(logFile);
if (stream == null) {
PropertyConfigurator.configure("src/main/resources/" + logFile);
} else {
PropertyConfigurator.configure(stream);
}
logger.info("Loaded " + logFile);
}
2014-06-26 08:01:07 +02:00
/**
* Gets list of strings between two strings.
* @param fullText Text to retrieve from.
* @param start String that precedes the desired text
* @param finish String that follows the desired text
* @return List of all strings that are between 'start' and 'finish'
*/
public static List<String> between(String fullText, String start, String finish) {
List<String> result = new ArrayList<String>();
int i, j;
i = fullText.indexOf(start);
while (i >= 0) {
i += start.length();
j = fullText.indexOf(finish, i);
if (j < 0) {
break;
}
result.add(fullText.substring(i, j));
i = fullText.indexOf(start, j + finish.length());
}
return result;
}
}