All checks were successful
KnarCraft/FFmpegConvert/pipeline/head This commit looks good
185 lines
6.7 KiB
Java
185 lines
6.7 KiB
Java
package net.knarcraft.ffmpegconverter.utility;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
|
|
/**
|
|
* A class which helps with file handling
|
|
*/
|
|
public final class FileUtil {
|
|
|
|
private FileUtil() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Gets the path described by the input, but changed to account for collisions
|
|
*
|
|
* @param folder <p>The folder containing the output file.</p>
|
|
* @param file <p>The input file.</p>
|
|
* @param outExtension <p>The extension of the output file.</p>
|
|
* @return <p>A file name with the new extension and without any collisions.</p>
|
|
*/
|
|
public static String getNonCollidingPath(File folder, File file, String outExtension) {
|
|
return FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
|
|
FileUtil.stripExtension(file.getName()) + "." + outExtension, outExtension);
|
|
}
|
|
|
|
/**
|
|
* Recursively lists all files in a folder
|
|
*
|
|
* @param folder <p>The folder to start from.</p>
|
|
* @param maxRecursions <p>Maximum number of recursions</p>
|
|
* @return A list of files
|
|
*/
|
|
public static File[] listFilesRecursive(File folder, String[] extensions, int maxRecursions) {
|
|
//Return if the target depth has been reached
|
|
if (maxRecursions == 0) {
|
|
return null;
|
|
}
|
|
//Get a list of all files which are folders and has one of the extensions specified
|
|
File[] foundFiles = folder.listFiles((file) -> file.isFile() &&
|
|
ListUtil.listContains(extensions, (item) -> file.getName().toLowerCase().endsWith(item)));
|
|
//Return if recursion is finished
|
|
if (maxRecursions == 1) {
|
|
return foundFiles;
|
|
}
|
|
//Get all folders in the directory
|
|
File[] subFolders = folder.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
|
//Return if the folder has no sub folders
|
|
if (subFolders == null) {
|
|
return foundFiles;
|
|
}
|
|
for (File subFolder : subFolders) {
|
|
//Get all relevant files contained within the sub folder
|
|
File[] nextLevel = listFilesRecursive(subFolder, extensions, maxRecursions - 1);
|
|
//Add found files to the output
|
|
if (nextLevel != null) {
|
|
if (foundFiles == null) {
|
|
foundFiles = nextLevel;
|
|
} else {
|
|
foundFiles = ListUtil.concatenate(foundFiles, nextLevel);
|
|
}
|
|
}
|
|
}
|
|
return foundFiles;
|
|
}
|
|
|
|
/**
|
|
* Reads a file's contents to a string list
|
|
*
|
|
* <p>The file must contain the number of lines to read in the first line.</p>
|
|
*
|
|
* @param fileName <p>The file to read.</p>
|
|
* @return <p>A string list where each element is one line of the file.</p>
|
|
* @throws IOException <p>If the file cannot be read.</p>
|
|
*/
|
|
public static String[] readFileLines(String fileName) throws IOException {
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(getResourceAsStream(fileName)));
|
|
int numberOfLines = Integer.parseInt(reader.readLine());
|
|
String[] lines = new String[numberOfLines];
|
|
for (int i = 0; i < lines.length; i++) {
|
|
lines[i] = reader.readLine();
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
/**
|
|
* Gets a resource as an InputStream
|
|
*
|
|
* @param resourceName <p>The name of the resource you want to read.</p>
|
|
* @return <p>An input stream which can be used to access the resource.</p>
|
|
*/
|
|
private static InputStream getResourceAsStream(String resourceName) {
|
|
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
|
return classloader.getResourceAsStream(resourceName);
|
|
}
|
|
|
|
/**
|
|
* Adds parentheses with an integer if the output file already exists
|
|
*
|
|
* @param targetPath <p>The path the file should ideally be saved at.</p>
|
|
* @param extension <p>The extension of the target file.</p>
|
|
* @return <p>A filename guaranteed not to collide with other files.</p>
|
|
*/
|
|
private static String getNonCollidingFilename(String targetPath, String extension) {
|
|
File newFile = new File(targetPath);
|
|
String fileName = stripExtension(targetPath).replaceAll("\\([0-9]+\\)$", "");
|
|
int i = 1;
|
|
while (newFile.exists()) {
|
|
newFile = new File(fileName + "(" + i++ + ")" + "." + extension);
|
|
}
|
|
return newFile.toString();
|
|
}
|
|
|
|
/**
|
|
* Gets the extension of the given filename
|
|
*
|
|
* @param file <p>The filename to check</p>
|
|
* @return <p>The file's extension</p>
|
|
*/
|
|
public static String getExtension(String file) {
|
|
if (file.contains(".")) {
|
|
return file.substring(file.lastIndexOf('.') + 1);
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the extension from a file name
|
|
*
|
|
* @param file <p>A filename.</p>
|
|
* @return <p>A filename without its extension.</p>
|
|
*/
|
|
public static String stripExtension(String file) {
|
|
return file.substring(0, file.lastIndexOf('.'));
|
|
}
|
|
|
|
/**
|
|
* Gets the locale specifying the language of the given file name
|
|
*
|
|
* @param fileName <p>The file name to check</p>
|
|
* @return <p>The locale, or null if no locale could be parsed</p>
|
|
*/
|
|
public static @Nullable String getLanguage(@NotNull String fileName) {
|
|
fileName = stripExtension(fileName);
|
|
|
|
String possibleLanguage = getExtension(fileName);
|
|
// NRK Nett-TV has a tendency to use nb-ttv for Norwegian for some reason
|
|
possibleLanguage = possibleLanguage.replace("nb-ttv", "nb-nor");
|
|
|
|
// TODO: Some languages are specified by using "-en" or "-English" or ".en" or ".English" at the end of file names
|
|
if (possibleLanguage.length() <= 1 || (possibleLanguage.length() >= 4 &&
|
|
(!possibleLanguage.contains("-") || possibleLanguage.length() >= 8))) {
|
|
return null;
|
|
}
|
|
|
|
// Hope the text is an actual valid language
|
|
if (!possibleLanguage.contains("-")) {
|
|
return possibleLanguage;
|
|
}
|
|
|
|
// Make sure the "-" has at least two characters on each side
|
|
String[] parts = possibleLanguage.split("-");
|
|
if (parts[0].length() < 2 || parts[1].length() < 2) {
|
|
return null;
|
|
}
|
|
|
|
if (parts[1].length() == 3) {
|
|
// Return three-letter country code
|
|
return parts[1].toLowerCase();
|
|
} else {
|
|
// Return en-US country code
|
|
return parts[0].substring(0, 2).toLowerCase() + "-" + parts[1].substring(0, 2).toUpperCase();
|
|
}
|
|
}
|
|
|
|
}
|