Мне понадобилось написать своей renamer для фото.
Зачем? Ведь есть куча бесплатного софта для пакетного переименовывания файлов. Я попробовал несколько, и в моем случае они были бесполезны, т.к. мне нужно было в качестве имени файла указывать инфу находящуюся в метаданных. А набор этих метаданных у разных форматов файлов разный (в моем случае JPG и MOV). Причем мне нужны были нужны метаданные, так как я переименовывал файлы скаченные с GooglePhoto, и у файла меняется ДатаСоздания и ДатаИзменения на текущую. И единственный способ узнать дату, когда сделано фото - это лезть в метаданные.
Я решил, что ChatGPT быстрее меня сможет найти библиотеки на java для этого, и поэтому обратился к нему. И, спойлер, он не подвёл.
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.quicktime.QuickTimeMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.mov.QuickTimeMovieHeaderDirectory;
public class RenameFilesExample {
public static void main(String[] args) {
String folderPath = "path/to/folder";
File folder = new File(folderPath);
if (!folder.isDirectory()) {
System.out.println("Specified path is not a folder");
return;
}
File[] files = folder.listFiles();
for (File file : files) {
try {
if (file.isFile()) {
String newName = getNewFileName(file);
File newFile = new File(folderPath + "/" + newName);
boolean success = file.renameTo(newFile);
if (!success) {
System.out.println("Could not rename file: " + file.getName());
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static String getNewFileName(File file) throws IOException {
String extension = getFileExtension(file.getName()).toLowerCase();
Metadata metadata;
String dateStr;
switch (extension) {
case "jpg":
case "jpeg":
metadata = ImageMetadataReader.readMetadata(file);
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
dateStr = formatDate(date);
break;
case "mov":
metadata = QuickTimeMetadataReader.readMetadata(file);
QuickTimeMovieHeaderDirectory headerDirectory = metadata.getFirstDirectoryOfType(QuickTimeMovieHeaderDirectory.class);
date = headerDirectory.getDate(QuickTimeMovieHeaderDirectory.TAG_CREATION_TIME);
dateStr = formatDate(date);
break;
default:
dateStr = "";
break;
}
return dateStr + "." + extension;
}
private static String getFileExtension(String fileName) {
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex == -1 || dotIndex == fileName.length() - 1) {
return "";
} else {
return fileName.substring(dotIndex + 1);
}
}
private static String formatDate(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
}
}
Тут я создал проект и скопировал себе этот код. Но оказалось, что одна из библиотек, которую использовать ChatGPT отсутcвует в mvn central.
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.quicktime.QuickTimeMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import org.mp4parser.IsoFile;
import org.mp4parser.boxes.iso14496.part12.MovieHeaderBox;
public class RenameFilesExample {
public static void main(String[] args) {
String folderPath = "path/to/folder";
File folder = new File(folderPath);
if (!folder.isDirectory()) {
System.out.println("Specified path is not a folder");
return;
}
File[] files = folder.listFiles();
for (File file : files) {
try {
if (file.isFile()) {
String newName = getNewFileName(file);
File newFile = new File(folderPath + "/" + newName);
boolean success = file.renameTo(newFile);
if (!success) {
System.out.println("Could not rename file: " + file.getName());
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static String getNewFileName(File file) throws IOException {
String extension = getFileExtension(file.getName()).toLowerCase();
Metadata metadata;
String dateStr;
switch (extension) {
case "jpg":
case "jpeg":
metadata = ImageMetadataReader.readMetadata(file);
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
dateStr = formatDate(date);
break;
case "mov":
IsoFile isoFile = new IsoFile(file);
MovieHeaderBox movieHeaderBox = isoFile.getMovieBox().getMovieHeaderBox();
Date creationTime = new Date(movieHeaderBox.getCreationTime().getTime() * 1000);
dateStr = formatDate(creationTime);
break;
default:
dateStr = "";
break;
}
return dateStr + "." + extension;
}
private static String getFileExtension(String fileName) {
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex == -1 || dotIndex == fileName.length() - 1) {
return "";
} else {
return fileName.substring(dotIndex + 1);
}
}
private static String formatDate(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
}
}
В итоге я взял этот код, последние версии использованных в нем библиотек и вставил путь в папке с тысячами фоток и видео. И вуаля.
Получается, за 20 мин я получил от ChatGPT рабочий софт, который отлично выполнил необходимую мне задачу. Имхо, на поиски существующего софта и настройку его работы ушло бы сильно больше времени.
Ну и конечно я запушил этот код на gitHub.
Комментарии (7)
SimSonic
13.04.2023 10:51+1Тоже за 2 недели раза три помог мне найти решение, над которым не хотелось ломать голову.
Squoworode
13.04.2023 10:51+7Total Commander в пакетном переименовании спокойно использует любые метаданные, как доступные системе, так и формируемые плагинами
b00
13.04.2023 10:51+1Прямо с импортов - подвёл. Давно устаревшее API дат подсунул. Ну, т.е., в контексте задачи "одноразовый скрипт" - он справился. Хотя зачем на Java её решать тогда...
snobit
13.04.2023 10:51+3String folderPath = "path/to/folder";
Каждый раз будете в коде менять папку?return dateStr + "." + extension;
Может вернуть ".", что тогда будет?
В качестве замене гугла может и не плохо, но головой думать все еще надо.ZenDayawrk
13.04.2023 10:51Недавно надо было писать скрипт небольшой на поше, он его написал, но местами он был не оптимизирован, я попытался научить GPT назвав места где можно улучшить, дальше я продолжил уточнять детали моего алгоритма у GPT и он дополнял существующий скрипт с моими правками, а через 3 вопроса-ответа он снова забил на мои правки и писал те строки которые изначально были им встроены :)
Так что думать надо)
akhmelev
13.04.2023 10:51Ну и конечно я запушил этот код на gitHub.
...чтобы следующие версии роботов после скана кодовой базы учились уже у роботов, а не у людей. Шел две тысячи двадцать девятый год и skynet был на распутье...
fire64
Chatgpt достаточно удобен для написания простых скриптов и небольших программ.
Сам использую его для написания Python скриптов для автоматизации действий.