-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
turiot
committed
Jun 5, 2022
1 parent
90cd753
commit 1857c75
Showing
16 changed files
with
1,340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
The purpose of this small application is to synchronize two initially similar directories, but one of which has renamed and moved files, to apply the same modifications to the second. | ||
|
||
The typical use case is that of a backup on 'dir1' of 'dir2'; after classifying files in dir2 (renaming and moving files in sub-directories), if we make a new backup, we are offered copy+deletes on dir1 which is inefficient. | ||
|
||
The application detects the actions performed on dir2, relying on the size and the date of update (assumed unchanged by the classification), and proposes to perform the same renaming/moving operations on the target directory dir1. | ||
|
||
![sscreenshot](./screenshot.png "") | ||
|
||
Operating mode : choose directories 1 (target that will be modified) and 2 (model), press 'search'; select the items to update then press 'execute'. | ||
|
||
A setting allows to log the actions in a file, to round the times to the second and to choose the language. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<actions> | ||
<action> | ||
<actionName>run</actionName> | ||
<packagings> | ||
<packaging>jar</packaging> | ||
</packagings> | ||
<goals> | ||
<goal>process-classes</goal> | ||
<goal>org.codehaus.mojo:exec-maven-plugin:3.0.0:exec</goal> | ||
</goals> | ||
<properties> | ||
<exec.vmArgs></exec.vmArgs> | ||
<exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args> | ||
<exec.appArgs></exec.appArgs> | ||
<exec.mainClass>uriot.renmov.MainFrame</exec.mainClass> | ||
<exec.executable>java</exec.executable> | ||
</properties> | ||
</action> | ||
</actions> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>uriot</groupId> | ||
<artifactId>renmov</artifactId> | ||
<version>1.0</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>commons-io</groupId> | ||
<artifactId>commons-io</artifactId> | ||
<version>2.11.0</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-collections4</artifactId> | ||
<version>4.4</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-jar-plugin</artifactId> | ||
<version>2.4</version> | ||
<configuration> | ||
<archive> | ||
<manifestEntries> | ||
<version>${project.version}</version> | ||
</manifestEntries> | ||
<manifest> | ||
<mainClass>uriot.renmov.MainFrame</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>com.github.wvengen</groupId> | ||
<artifactId>proguard-maven-plugin</artifactId> | ||
<version>2.5.3</version> | ||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals><goal>proguard</goal></goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<injar>${project.build.finalName}.jar</injar> | ||
<libs> | ||
<lib>${java.home}/jmods/java.base.jmod</lib> | ||
<lib>${java.home}/jmods/java.logging.jmod</lib> | ||
<lib>${java.home}/jmods/java.desktop.jmod</lib> | ||
</libs> | ||
<includeDependencyInjar>true</includeDependencyInjar> | ||
<outjar>${project.build.finalName}-small.jar</outjar> | ||
<outputDirectory>${project.build.directory}</outputDirectory> | ||
<proguardInclude>${basedir}/proguard.conf</proguardInclude> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
-dontnote | ||
-dontwarn | ||
|
||
-forceprocessing | ||
-verbose | ||
|
||
# {{{ all three of these make the "don't touch anything" | ||
# these are listed in the order they happen in its flow | ||
# -dontshrink | ||
# -dontoptimize | ||
-dontobfuscate | ||
# }}} | ||
|
||
-adaptresourcefilenames **.properties,**.xml,META-INF/MANIFEST.MF,META-INF/spring.* | ||
-adaptresourcefilecontents **.properties,**.xml,META-INF/MANIFEST.MF,META-INF/spring.* | ||
|
||
-keep public class uriot.renmov.MainFrame { | ||
public static void main(java.lang.String[]); | ||
} | ||
|
||
-keep,allowshrinking class * extends java.io.Serializable | ||
-keepclassmembers class * extends java.io.Serializable { | ||
*; | ||
} | ||
|
||
-keepclassmembers enum * { | ||
public static **[] values(); | ||
public static ** valueOf(java.lang.String); | ||
} | ||
|
||
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package uriot.renmov; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.attribute.FileTime; | ||
import java.util.ArrayList; | ||
import java.util.ResourceBundle; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; | ||
import org.apache.commons.io.FileUtils; | ||
|
||
public class Controller { | ||
|
||
public Logger log; | ||
public Settings settings; | ||
public ResourceBundle bundle; | ||
|
||
void search(ArrayList<Item> items, String dir1, String dir2, int[] res) { | ||
items.clear(); | ||
|
||
if (!new File(dir1).exists() || !new File(dir2).exists()) { | ||
res[0] = 1; | ||
return; | ||
} | ||
|
||
var map = new ArrayListValuedHashMap<Criteria, Item>(); | ||
try (var walk = Files.walk(Path.of(new URI("file:///" + dir2)))) { | ||
walk.filter(Files::isRegularFile).map(path -> { | ||
var file = path.toFile(); | ||
Criteria key = null; | ||
try { | ||
var date = ((FileTime) Files.getAttribute(path, "creationTime")).toInstant(); | ||
key = new Criteria(date, file.length(), settings.roundToSecond); | ||
} | ||
catch (IOException ex) { | ||
log.log(Level.SEVERE, null, ex); | ||
res[0] = 2; | ||
} | ||
var item = new Item(key); | ||
item.path2 = file.getPath(); | ||
return item; | ||
}) | ||
.forEach(item -> { | ||
map.put(item.criteria, item); | ||
}); | ||
} | ||
catch (URISyntaxException | IOException ex) { | ||
log.log(Level.SEVERE, null, ex); | ||
res[0] = 2; | ||
} | ||
|
||
try (var walk = Files.walk(Path.of(new URI("file:///" + dir1)))) { | ||
walk.filter(Files::isRegularFile) | ||
.<Item>mapMulti((path, consumer) -> { | ||
var file1 = path.toFile(); | ||
Criteria key = null; | ||
try { | ||
var date = ((FileTime) Files.getAttribute(path, "creationTime")).toInstant(); | ||
key = new Criteria(date, file1.length(), settings.roundToSecond); | ||
} | ||
catch (IOException ex) { | ||
log.log(Level.SEVERE, null, ex); | ||
res[0] = 2; | ||
} | ||
var found = map.get(key); | ||
if (found != null && !found.isEmpty()) { | ||
found.forEach(item -> { | ||
var relPath1 = file1.getPath().substring(dir1.length() + 1); | ||
var relPath2 = item.path2.substring(dir2.length() + 1); | ||
if (!relPath1.equals(relPath2)) { | ||
var file2 = new File(item.path2); | ||
var d1 = relPath1.substring(0, relPath1.lastIndexOf(file1.getName())); | ||
var d2 = relPath2.substring(0, relPath2.lastIndexOf(file2.getName())); | ||
var out = new Item(item.criteria); | ||
out.select = found.size() <= 1; | ||
if (d1.equals(d2)) { | ||
out.action = bundle.getString("action.rename"); | ||
} | ||
else if (file1.getName().equals(file2.getName())) { | ||
out.action = bundle.getString("action.move"); | ||
} | ||
else { | ||
out.action = bundle.getString("action.both"); | ||
} | ||
out.path1 = file1.getPath(); | ||
out.path2 = item.path2; | ||
consumer.accept(out); | ||
} | ||
}); | ||
} | ||
}) | ||
.filter(item -> item != null) | ||
.forEach(item -> { | ||
items.add(item); | ||
}); | ||
} | ||
catch (URISyntaxException | IOException ex) { | ||
log.log(Level.SEVERE, null, ex); | ||
res[0] = 2; | ||
} | ||
} | ||
|
||
void execute(ArrayList<Item> items, String dir1, String dir2, int[] cpt) { | ||
var i = items.iterator(); | ||
while (i.hasNext()) { | ||
var item = i.next(); | ||
if (item.select) { | ||
var relPath2 = item.path2.substring(dir2.length() + 1); | ||
var relPath1 = dir1 + "/" + relPath2; | ||
log.log(Level.INFO, "{0} {1} to {2}", new Object[]{item.action, item.path1, relPath1}); | ||
try { | ||
FileUtils.moveFile(FileUtils.getFile(item.path1), FileUtils.getFile(relPath1)); | ||
cpt[0]++; | ||
} | ||
catch (IOException ex) { | ||
log.log(Level.SEVERE, null, ex); | ||
cpt[1]++; | ||
} | ||
i.remove(); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package uriot.renmov; | ||
|
||
import java.time.Instant; | ||
|
||
public class Criteria { | ||
public Instant date; | ||
public long size; | ||
private final long millis; | ||
|
||
public Criteria(Instant date, long size, boolean roundToSecond) { | ||
this.date = date; | ||
this.size = size; | ||
this.millis = roundToSecond ? date.toEpochMilli() / 1000L : date.toEpochMilli(); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
var hash = 7; | ||
hash = 71 * hash + (int) (this.size ^ (this.size >>> 32)); | ||
hash = 71 * hash + (int) (this.millis ^ (this.millis >>> 32)); | ||
return hash; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
var other = (Criteria) obj; | ||
if (this.size != other.size) { | ||
return false; | ||
} | ||
return other.millis == millis; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Criteria{" + "date=" + date + ", size=" + size + '}'; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package uriot.renmov; | ||
|
||
import java.time.Instant; | ||
|
||
public class Item { | ||
Criteria criteria; | ||
boolean select; | ||
String path1; | ||
String path2; | ||
String action; | ||
|
||
public Item(Criteria criteria) { | ||
this.criteria = criteria; | ||
select = true; | ||
} | ||
|
||
public static final String[] columnNames = { | ||
"Sél", "Fichier 1", "Fichier 2", "Date", "Taille", "Action" // i18n override | ||
}; | ||
|
||
public static final Class[] columnClasses = { | ||
Boolean.class, String.class, String.class, Instant.class, Long.class, String.class | ||
}; | ||
|
||
@Override | ||
public String toString() { | ||
return "Item{" + "criteria=" + criteria + ", select=" + select + ", path1=" + path1 + ", path2=" + path2 + ", action=" + action + '}'; | ||
} | ||
} |
Oops, something went wrong.