|
|
@ -4,7 +4,10 @@ import com.olexyn.ensync.Execute;
|
|
|
|
import com.olexyn.ensync.Tools;
|
|
|
|
import com.olexyn.ensync.Tools;
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.File;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* A SyncDirectory is an occurrence of a particular directory somewhere across the filesystems.
|
|
|
|
* A SyncDirectory is an occurrence of a particular directory somewhere across the filesystems.
|
|
|
@ -30,8 +33,7 @@ public class SyncDirectory {
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @see SyncMap
|
|
|
|
* @see SyncMap
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public SyncDirectory(String path,
|
|
|
|
public SyncDirectory(String path, SyncMap syncMap) {
|
|
|
|
SyncMap syncMap) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.path = path;
|
|
|
|
this.path = path;
|
|
|
|
this.syncMap = syncMap;
|
|
|
|
this.syncMap = syncMap;
|
|
|
@ -39,8 +41,6 @@ public class SyncDirectory {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Get the current state by using the `find` command.
|
|
|
|
* Get the current state by using the `find` command.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -54,7 +54,7 @@ public class SyncDirectory {
|
|
|
|
List<String> pathList = tools.brToListString(find.output);
|
|
|
|
List<String> pathList = tools.brToListString(find.output);
|
|
|
|
|
|
|
|
|
|
|
|
for (String filePath : pathList) {
|
|
|
|
for (String filePath : pathList) {
|
|
|
|
SyncFile file = new SyncFile(filePath);
|
|
|
|
SyncFile file = new SyncFile(this, filePath);
|
|
|
|
|
|
|
|
|
|
|
|
filemap.put(filePath, file);
|
|
|
|
filemap.put(filePath, file);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -71,7 +71,7 @@ public class SyncDirectory {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public Map<String, SyncFile> readStateFile() {
|
|
|
|
public Map<String, SyncFile> readStateFile() {
|
|
|
|
Map<String, SyncFile> filemap = new HashMap<>();
|
|
|
|
Map<String, SyncFile> filemap = new HashMap<>();
|
|
|
|
List<String> lines = tools.fileToLines(new File(stateFilePath(path)));
|
|
|
|
List<String> lines = tools.fileToLines(new File(tools.stateFilePath(path)));
|
|
|
|
|
|
|
|
|
|
|
|
for (String line : lines) {
|
|
|
|
for (String line : lines) {
|
|
|
|
// this is a predefined format: "modification-time path"
|
|
|
|
// this is a predefined format: "modification-time path"
|
|
|
@ -79,7 +79,7 @@ public class SyncDirectory {
|
|
|
|
long modTime = Long.parseLong(modTimeString);
|
|
|
|
long modTime = Long.parseLong(modTimeString);
|
|
|
|
|
|
|
|
|
|
|
|
String sFilePath = line.replace(modTimeString + " ", "");
|
|
|
|
String sFilePath = line.replace(modTimeString + " ", "");
|
|
|
|
SyncFile sfile = new SyncFile(sFilePath);
|
|
|
|
SyncFile sfile = new SyncFile(this, sFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
sfile.setStateFileTime(modTime);
|
|
|
|
sfile.setStateFileTime(modTime);
|
|
|
|
|
|
|
|
|
|
|
@ -98,7 +98,6 @@ public class SyncDirectory {
|
|
|
|
* @return
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void makeListCreated() {
|
|
|
|
public void makeListCreated() {
|
|
|
|
listCreated = new ArrayList<>();
|
|
|
|
|
|
|
|
Map<String, SyncFile> fromA = findState();
|
|
|
|
Map<String, SyncFile> fromA = findState();
|
|
|
|
Map<String, SyncFile> substractB = readStateFile();
|
|
|
|
Map<String, SyncFile> substractB = readStateFile();
|
|
|
|
|
|
|
|
|
|
|
@ -106,22 +105,14 @@ public class SyncDirectory {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String stateFilePath(String path) {
|
|
|
|
|
|
|
|
return "/tmp/ensync/state" + path.replace("/", "-");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Compare the OLD and NEW pools.
|
|
|
|
* Compare the OLD and NEW pools.
|
|
|
|
* List is cleared and created each time.
|
|
|
|
* List is cleared and created each time.
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void makeListDeleted() {
|
|
|
|
public void makeListDeleted() {
|
|
|
|
listDeleted = new ArrayList<>();
|
|
|
|
|
|
|
|
Map<String, SyncFile> fromA = readStateFile();
|
|
|
|
Map<String, SyncFile> fromA = readStateFile();
|
|
|
|
Map<String, SyncFile> substractB = findState();
|
|
|
|
Map<String, SyncFile> substractB = findState();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
listDeleted = tools.mapMinus(fromA, substractB);
|
|
|
|
listDeleted = tools.mapMinus(fromA, substractB);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -129,24 +120,22 @@ public class SyncDirectory {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Compare the OLD and NEW pools.
|
|
|
|
* Compare the OLD and NEW pools.
|
|
|
|
* List is cleared and created each time.
|
|
|
|
* List is cleared and created each time.
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void makeListModified() {
|
|
|
|
public List<SyncFile> makeListModified() {
|
|
|
|
|
|
|
|
|
|
|
|
listModified = new ArrayList<>();
|
|
|
|
listModified = new ArrayList<>();
|
|
|
|
Map<String, SyncFile> oldMap = readStateFile();
|
|
|
|
Map<String, SyncFile> oldMap = readStateFile();
|
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, SyncFile> newFileEntry : findState().entrySet()) {
|
|
|
|
for (var newFileEntry : findState().entrySet()) {
|
|
|
|
// If KEY exists in OLD , thus FILE was NOT created.
|
|
|
|
|
|
|
|
String newFileKey = newFileEntry.getKey();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String newFileKey = newFileEntry.getKey();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If KEY exists in OLD , thus FILE was NOT created.
|
|
|
|
if (oldMap.containsKey(newFileKey)) {
|
|
|
|
if (oldMap.containsKey(newFileKey)) {
|
|
|
|
|
|
|
|
|
|
|
|
SyncFile newFile = newFileEntry.getValue();
|
|
|
|
SyncFile newFile = newFileEntry.getValue();
|
|
|
|
long lastModifiedNew = newFile.lastModified();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long lastModifiedNew = newFile.lastModified();
|
|
|
|
long lastModifiedOld = oldMap.get(newFileKey).stateFileTime();
|
|
|
|
long lastModifiedOld = oldMap.get(newFileKey).stateFileTime();
|
|
|
|
|
|
|
|
|
|
|
|
if (lastModifiedNew > lastModifiedOld) {
|
|
|
|
if (lastModifiedNew > lastModifiedOld) {
|
|
|
@ -154,7 +143,7 @@ public class SyncDirectory {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return listModified;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -177,26 +166,24 @@ public class SyncDirectory {
|
|
|
|
outputList.add("" + lastModified + " " + filePath);
|
|
|
|
outputList.add("" + lastModified + " " + filePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tools.writeStringListToFile(stateFilePath(path), outputList);
|
|
|
|
tools.writeStringListToFile(tools.stateFilePath(path), outputList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class Info {
|
|
|
|
private class Info {
|
|
|
|
|
|
|
|
|
|
|
|
private String relativePath = null;
|
|
|
|
private String relativePath;
|
|
|
|
private String thisFilePath = null;
|
|
|
|
private String thisFilePath;
|
|
|
|
private String otherFilePath = null;
|
|
|
|
private String otherFilePath;
|
|
|
|
private File otherFile = null;
|
|
|
|
private File otherFile;
|
|
|
|
private String otherParentPath = null;
|
|
|
|
private String otherParentPath;
|
|
|
|
private File otherParentFile = null;
|
|
|
|
private File otherParentFile;
|
|
|
|
private long thisStateFileTime = 0;
|
|
|
|
private long thisStateFileTime;
|
|
|
|
private long thisTimeModified = 0;
|
|
|
|
private long thisFileTimeModified;
|
|
|
|
private long otherTimeModified = 0;
|
|
|
|
private long otherFileTimeModified;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Info(SyncDirectory thisSD,
|
|
|
|
private Info(SyncDirectory thisSD, SyncFile sFile, SyncDirectory otherSD) {
|
|
|
|
SyncFile sFile,
|
|
|
|
|
|
|
|
SyncDirectory otherSD) {
|
|
|
|
|
|
|
|
// Example:
|
|
|
|
// Example:
|
|
|
|
// syncDirectory /foo
|
|
|
|
// syncDirectory /foo
|
|
|
|
// otherSyncDirectory /bar
|
|
|
|
// otherSyncDirectory /bar
|
|
|
@ -216,18 +203,18 @@ public class SyncDirectory {
|
|
|
|
// thisFile does not exist in StateFile, a value of 0 can be seen as equal to "never existed".
|
|
|
|
// thisFile does not exist in StateFile, a value of 0 can be seen as equal to "never existed".
|
|
|
|
this.thisStateFileTime = 0;
|
|
|
|
this.thisStateFileTime = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.thisTimeModified = sFile.lastModified();
|
|
|
|
this.thisFileTimeModified = sFile.lastModified();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (otherFile.exists()) {
|
|
|
|
if (otherFile.exists()) {
|
|
|
|
|
|
|
|
|
|
|
|
this.otherTimeModified = otherFile.lastModified();
|
|
|
|
this.otherFileTimeModified = otherFile.lastModified();
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (otherSD.readStateFile().get(otherFilePath) != null) {
|
|
|
|
if (otherSD.readStateFile().get(otherFilePath) != null) {
|
|
|
|
this.otherTimeModified = otherSD.readStateFile().get(otherFilePath).stateFileTime();
|
|
|
|
this.otherFileTimeModified = otherSD.readStateFile().get(otherFilePath).stateFileTime();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.otherTimeModified = 0;
|
|
|
|
this.otherFileTimeModified = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -243,15 +230,14 @@ public class SyncDirectory {
|
|
|
|
|
|
|
|
|
|
|
|
if (createdFile.isFile()) {
|
|
|
|
if (createdFile.isFile()) {
|
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, SyncDirectory> otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
for (var otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
SyncDirectory otherSyncDirectory = otherEntry.getValue();
|
|
|
|
SyncDirectory otherSD = otherEntry.getValue();
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.equals(otherSyncDirectory)) {
|
|
|
|
if (this.equals(otherSD)) { continue; }
|
|
|
|
|
|
|
|
|
|
|
|
Info info = new Info(this, createdFile, otherSyncDirectory);
|
|
|
|
Info info = new Info(this, createdFile, otherSD);
|
|
|
|
|
|
|
|
|
|
|
|
createFile(info);
|
|
|
|
writeFile(info, this, createdFile, otherSD);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -265,25 +251,22 @@ public class SyncDirectory {
|
|
|
|
|
|
|
|
|
|
|
|
for (SyncFile deletedFile : listDeleted) {
|
|
|
|
for (SyncFile deletedFile : listDeleted) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
|
|
|
|
SyncDirectory otherSD = otherEntry.getValue();
|
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, SyncDirectory> otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
if (this.equals(otherSD)) { continue; }
|
|
|
|
SyncDirectory otherSyncDirectory = otherEntry.getValue();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.equals(otherSyncDirectory)) {
|
|
|
|
Info info = new Info(this, deletedFile, otherSD);
|
|
|
|
|
|
|
|
|
|
|
|
Info info = new Info(this, deletedFile, otherSyncDirectory);
|
|
|
|
|
|
|
|
if (info.otherFile.isFile()) {
|
|
|
|
if (info.otherFile.isFile()) {
|
|
|
|
|
|
|
|
|
|
|
|
// if the otherFile was created with ensync it will have the == TimeModified.
|
|
|
|
// if the otherFile was created with ensync it will have the == TimeModified.
|
|
|
|
if (info.thisStateFileTime >= info.otherTimeModified) {
|
|
|
|
if (info.thisStateFileTime >= info.otherFileTimeModified) {
|
|
|
|
String[] cmd = new String[]{"rm",
|
|
|
|
String[] cmd = new String[]{"rm",
|
|
|
|
"-r",
|
|
|
|
"-r",
|
|
|
|
info.otherFilePath};
|
|
|
|
info.otherFilePath};
|
|
|
|
x.execute(cmd);
|
|
|
|
x.execute(cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -295,19 +278,14 @@ public class SyncDirectory {
|
|
|
|
|
|
|
|
|
|
|
|
if (modifiedFile.isFile()) {
|
|
|
|
if (modifiedFile.isFile()) {
|
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, SyncDirectory> otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
for (var otherEntry : syncMap.syncDirectories.entrySet()) {
|
|
|
|
SyncDirectory otherSyncDirectory = otherEntry.getValue();
|
|
|
|
SyncDirectory otherSD = otherEntry.getValue();
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.equals(otherSyncDirectory)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Info info = new Info(this, modifiedFile, otherSyncDirectory);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.equals(otherSD)) { continue; }
|
|
|
|
|
|
|
|
|
|
|
|
createFile(info);
|
|
|
|
Info info = new Info(this, modifiedFile, otherSD);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writeFile(info, this, modifiedFile, otherSD);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -316,8 +294,11 @@ public class SyncDirectory {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void createFile(Info info) {
|
|
|
|
private void writeFile(Info info, SyncDirectory thisSD, SyncFile thisFile, SyncDirectory otherSD) {
|
|
|
|
if (!info.otherFile.exists() || info.thisTimeModified > info.otherTimeModified) {
|
|
|
|
|
|
|
|
|
|
|
|
File otherFile = new File(otherSD.path + thisFile.relativePath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!otherFile.exists() || info.thisFileTimeModified > info.otherFileTimeModified) {
|
|
|
|
if (!info.otherParentFile.exists()) {
|
|
|
|
if (!info.otherParentFile.exists()) {
|
|
|
|
String[] cmd = new String[]{"mkdir",
|
|
|
|
String[] cmd = new String[]{"mkdir",
|
|
|
|
"-p",
|
|
|
|
"-p",
|
|
|
@ -338,8 +319,6 @@ public class SyncDirectory {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|