Work on improving ftp timestamp

This commit is contained in:
Astatin3
2024-10-07 20:16:42 -06:00
parent fb0718c4ec
commit fecf7e5d2b
4 changed files with 145 additions and 26 deletions
@@ -4,6 +4,9 @@ package com.ridgebotics.ridgescout.ui.transfer;
import static com.ridgebotics.ridgescout.utility.fileEditor.baseDir; import static com.ridgebotics.ridgescout.utility.fileEditor.baseDir;
import com.ridgebotics.ridgescout.utility.AlertManager; import com.ridgebotics.ridgescout.utility.AlertManager;
import com.ridgebotics.ridgescout.utility.BuiltByteParser;
import com.ridgebotics.ridgescout.utility.ByteBuilder;
import com.ridgebotics.ridgescout.utility.fileEditor;
import com.ridgebotics.ridgescout.utility.settingsManager; import com.ridgebotics.ridgescout.utility.settingsManager;
import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTP;
@@ -14,18 +17,25 @@ import org.apache.commons.net.ftp.FTPReply;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
public class FTPSync extends Thread { public class FTPSync extends Thread {
public static final String remoteBasePath = "/RidgeScout/"; public static final String remoteBasePath = "/RidgeScout/";
public static final String timestampsFilename = "timestamps";
public static final long timeTolerance = 60000; // One min public static final long timeTolerance = 60000; // One min
public static long lastSyncTime = 0; public static long lastSyncTime = 0;
private static Date curSyncTime;
public interface onResult { public interface onResult {
void onResult(boolean error, int upCount, int downCount); void onResult(boolean error, int upCount, int downCount);
} }
@@ -34,11 +44,13 @@ public class FTPSync extends Thread {
public static void sync(onResult onResult){ public static void sync(onResult onResult){
// DataManager.reload_event(); // DataManager.reload_event();
FTPSync ftpSync = new FTPSync(); // FTPSync ftpSync = new FTPSync();
ftpSync.onResult = onResult; // ftpSync.onResult = onResult;
ftpSync.start(); //
// lastSyncTime = new Date().getTime();
lastSyncTime = new Date().getTime(); // curSyncTime = new Date();
//
// ftpSync.start();
} }
FTPClient ftpClient; FTPClient ftpClient;
@@ -51,20 +63,16 @@ public class FTPSync extends Thread {
private int upCount = 0; private int upCount = 0;
private int downCount = 0; private int downCount = 0;
private void downloadFile(FTPFile remoteFile, File localFile) throws IOException { private void downloadFile(String remoteFile, File localFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(localFile)) { try (FileOutputStream fos = new FileOutputStream(localFile)) {
ftpClient.retrieveFile(remoteBasePath + remoteFile.getName(), fos); ftpClient.retrieveFile(remoteBasePath + remoteFile, fos);
} }
Date d = getUtcTimestamp(remoteFile);
System.out.println(d);
setLocalFileTimestamp(localFile, d);
} }
private void uploadFile(File localFile) throws IOException { private void uploadFile(File localFile) throws IOException {
try (FileInputStream fis = new FileInputStream(localFile)) { try (FileInputStream fis = new FileInputStream(localFile)) {
ftpClient.storeFile(remoteBasePath + localFile.getName(), fis); ftpClient.storeFile(remoteBasePath + localFile.getName(), fis);
} }
setLocalFileTimestamp(localFile, new Date());
} }
private FTPFile findRemoteFile(FTPFile[] remoteFiles, String fileName) { private FTPFile findRemoteFile(FTPFile[] remoteFiles, String fileName) {
@@ -92,16 +100,15 @@ public class FTPSync extends Thread {
// return n>0 ? n : -n; // return n>0 ? n : -n;
// } // }
private boolean toleranceCompareAfter(Date d1, Date d2){ // private boolean toleranceCompareAfter(Date d1, Date d2){
long diff = d1.getTime() - d2.getTime(); // long diff = d1.getTime() - d2.getTime();
System.out.println(diff); // System.out.println(diff);
return diff > timeTolerance; // return diff > timeTolerance;
} // }
public void run() { public void run() {
try { try {
// localTimeZone = TimeZone.getDefault();
ftpClient = new FTPClient(); ftpClient = new FTPClient();
InetAddress address = InetAddress.getByName(settingsManager.getFTPServer()); InetAddress address = InetAddress.getByName(settingsManager.getFTPServer());
ftpClient.connect(address); ftpClient.connect(address);
@@ -123,13 +130,14 @@ public class FTPSync extends Thread {
//// ////
// System.out.println("- " + t1.getTime() + (t1.after(t2) ? ">" : "<") + t2.getTime()); // System.out.println("- " + t1.getTime() + (t1.after(t2) ? ">" : "<") + t2.getTime());
if (remoteFile == null || toleranceCompareAfter(getLocalFileUtcTimestamp(localFile), (getUtcTimestamp(remoteFile)))) { // if (remoteFile == null || toleranceCompareAfter(getLocalFileUtcTimestamp(localFile), (getUtcTimestamp(remoteFile)))) {
uploadFile(localFile); // uploadFile(localFile);
System.out.println("Uploaded " + localFile.getName()); // System.out.println("Uploaded " + localFile.getName());
upCount++; // setLocalFileTimestamp(localFile, curSyncTime);
}else{ // upCount++;
System.out.println("Did not upload " + localFile.getName()); // }else{
} // System.out.println("Did not upload " + localFile.getName());
// }
} }
} }
} }
@@ -143,9 +151,11 @@ public class FTPSync extends Thread {
//// ////
// System.out.println("- " + t1 + (t1.after(t2) ? ">" : "<") + t2); // System.out.println("- " + t1 + (t1.after(t2) ? ">" : "<") + t2);
if (!localFile.exists() || toleranceCompareAfter(getUtcTimestamp(remoteFile), (getLocalFileUtcTimestamp(localFile)))) { if (!localFile.exists() || getUtcTimestamp(remoteFile).after((getLocalFileUtcTimestamp(localFile)))) {
downloadFile(remoteFile, localFile); downloadFile(remoteFile.getName(), localFile);
System.out.println("Downloaded " + localFile.getName()); System.out.println("Downloaded " + localFile.getName());
Date d = getUtcTimestamp(remoteFile);
setLocalFileTimestamp(localFile, d);
downCount++; downCount++;
}else{ }else{
System.out.println("Did not download " + remoteFile.getName()); System.out.println("Did not download " + remoteFile.getName());
@@ -160,4 +170,48 @@ public class FTPSync extends Thread {
onResult.onResult(false, upCount, downCount); onResult.onResult(false, upCount, downCount);
} }
} }
private boolean setTimestamps(Map<String, Date> timestamps){
try {
ByteBuilder bb = new ByteBuilder();
String[] filenames = timestamps.keySet().toArray(new String[0]);
for(int i = 0; i < filenames.length; i++){
bb.addString(filenames[i]);
bb.addLong(timestamps.get(filenames[i]).getTime());
}
fileEditor.writeFile(timestampsFilename, bb.build());
uploadFile(new File(baseDir + timestampsFilename));
return true;
} catch (ByteBuilder.buildingException | IOException e) {
e.printStackTrace();
return false;
}
}
private Map<String, Date> getTimestamps() {
try {
downloadFile(timestampsFilename, new File(baseDir + timestampsFilename));
byte[] data = fileEditor.readFile(timestampsFilename);
BuiltByteParser bbp = new BuiltByteParser(data);
List<BuiltByteParser.parsedObject> pa = bbp.parse();
Map<String, Date> output = new HashMap<>();
for(int i = 0; i < pa.size(); i+=2){
// System.out.println((long) pa.get(i).get());
output.put(
(String) ((BuiltByteParser.stringObject) pa).get(),
new Date((long) ((BuiltByteParser.longObject) pa).get())
);
}
return output;
}catch (IOException | BuiltByteParser.byteParsingExeption e){
AlertManager.error(e);
return new HashMap<>();
}
}
} }
@@ -10,6 +10,7 @@ public class BuiltByteParser {
public static final Integer stringType = 2; public static final Integer stringType = 2;
public static final Integer intArrayType = 3; public static final Integer intArrayType = 3;
public static final Integer stringArrayType = 4; public static final Integer stringArrayType = 4;
public static final Integer longType = 5;
public class byteParsingExeption extends Exception { public class byteParsingExeption extends Exception {
public byteParsingExeption() {} public byteParsingExeption() {}
@@ -58,6 +59,11 @@ public class BuiltByteParser {
public Integer getType(){return stringArrayType;} public Integer getType(){return stringArrayType;}
public Object get(){return arr;} public Object get(){return arr;}
} }
public class longObject extends parsedObject{
long num;
public Integer getType(){return longType;}
public Object get(){return num;}
}
public class rawObject extends parsedObject { public class rawObject extends parsedObject {
@@ -140,6 +146,11 @@ public class BuiltByteParser {
sa.arr = StringArr; sa.arr = StringArr;
objects.add(sa); objects.add(sa);
break; break;
case 5:
longObject lo = new longObject();
lo.num = fileEditor.fromBytesLong(block, length);
objects.add(lo);
break;
default: default:
rawObject ro = new rawObject(type); rawObject ro = new rawObject(type);
ro.bytes = block; ro.bytes = block;
@@ -9,6 +9,7 @@ public class ByteBuilder {
public static final int string_id = 2; public static final int string_id = 2;
public static final int int_arr_id = 3; public static final int int_arr_id = 3;
public static final int string_arr_id = 4; public static final int string_arr_id = 4;
public static final int long_id = 5;
ArrayList<byteType> bytesToBuild = new ArrayList<>(); ArrayList<byteType> bytesToBuild = new ArrayList<>();
@@ -153,6 +154,41 @@ public class ByteBuilder {
return this; return this;
} }
private class longType extends byteType {
public int precision;
public long num;
public byte getType(){return long_id;}
public int length(){return precision;}
public byte[] build(){
return fileEditor.toBytes(num, precision);
}
}
private int getLeastBytePrecision(long num){
if(num <= 1){return 1;}
return (int) Math.ceil(Math.log(Math.abs(num))/Math.log(8));
}
public ByteBuilder addLong(long num) throws buildingException {
// Get closest number of bytes
int precision = getLeastBytePrecision(num);
return addLong(num, precision);
}
public ByteBuilder addLong(long num, int precision) throws buildingException {
if(precision <= 0){throw new buildingException("Invalid precision: " + precision);}
if(precision > 65536){throw new buildingException("Precision too large (greter than 65536)");}
if(precision < getLeastBytePrecision(num)){throw new buildingException("Precision too small");}
if(num > Long.MAX_VALUE){throw new buildingException("Long overflow");}
if(num < Long.MIN_VALUE){throw new buildingException("Long overflow");}
longType longType = new longType();
longType.num = num;
longType.precision = precision;
bytesToBuild.add(longType);
return this;
}
private class rawType extends byteType { private class rawType extends byteType {
public int type; public int type;
public byte[] bytes; public byte[] bytes;
@@ -66,6 +66,17 @@ public final class fileEditor {
return bytes; return bytes;
} }
public static byte[] toBytes(long num, int byteCount){
if(num > (Math.pow(2,byteCount*8)-1)){
throw new BufferOverflowException();
}
byte[] bytes = new byte[byteCount];
for(int i=0;i<byteCount;i++){
bytes[i] = (byte)(num >> (i*8));
}
return bytes;
}
public static int fromBytes(byte[] bytes, int byteCount){ public static int fromBytes(byte[] bytes, int byteCount){
@@ -75,6 +86,13 @@ public final class fileEditor {
} }
return returnInt; return returnInt;
} }
public static long fromBytesLong(byte[] bytes, int byteCount){
long returnLong = 0;
for(int i=0;i<byteCount;i++){
returnLong |= (bytes[i] & 0xFFL) << (i*8);
}
return returnLong;
}