diff --git a/2024week0-1728149849985.scoutbundle b/2024week0-1728149849985.scoutbundle new file mode 100644 index 0000000..7927e5d Binary files /dev/null and b/2024week0-1728149849985.scoutbundle differ diff --git a/README.md b/README.md index df164ef..c291264 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Ridgescout](https://github.com/Team4388/ScoutingApp2025/blob/main/metadata/en-US/images/FeatureGraphic.png?raw=true) +![Ridgescout](https://github.com/Team4388/ScoutingApp2025/blob/main/metadata/en-US/images/featureGraphic.png?raw=true) [Get it on F-Droid0 ? n : -n; +// } + + private boolean toleranceCompareAfter(Date d1, Date d2){ + long diff = d1.getTime() - d2.getTime(); + System.out.println(diff); + return diff > timeTolerance; + } + + public void run() { try { - FTPClient ftpClient = new FTPClient(); +// localTimeZone = TimeZone.getDefault(); + ftpClient = new FTPClient(); InetAddress address = InetAddress.getByName(settingsManager.getFTPServer()); ftpClient.connect(address); ftpClient.login("anonymous", null); ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); -// ftpClient.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE) - FTPFile[] remoteFilestmp = ftpClient.listFiles(remoteBasePath); - String[] localFilestmp = fileEditor.getEventFiles(evcode); + File localDir = new File(baseDir); + File[] localFiles = localDir.listFiles(); + FTPFile[] remoteFiles = ftpClient.listFiles(remoteBasePath); - FileDate[] remoteFiles = new FileDate[remoteFilestmp.length]; - for(int i = 0; i < remoteFilestmp.length; i++){ -// System.out.println(remoteFilestmp[i].getName()); - remoteFiles[i] = new FileDate(); - remoteFiles[i].filename = remoteFilestmp[i].getName(); - System.out.println(remoteFiles[i].filename); - remoteFiles[i].lastModified = remoteFilestmp[i].getTimestamp(); - } + if (localFiles != null) { + for (File localFile : localFiles) { + if (localFile.isFile()) { + FTPFile remoteFile = findRemoteFile(remoteFiles, localFile.getName()); +// +// Date t1 = getLocalFileUtcTimestamp(localFile); +// Date t2 = getUtcTimestamp(remoteFile); +//// +// System.out.println("- " + t1.getTime() + (t1.after(t2) ? ">" : "<") + t2.getTime()); - FileDate[] localFiles = new FileDate[localFilestmp.length]; - for(int i = 0; i < localFilestmp.length; i++){ -// sendFile(localFilestmp[i]); - String filename = "matches.fields"; - File f = new File(baseDir + filename); -// File f = new File(baseDir + localFilestmp[i]); -// System.out.println(f.exists()); -// FileInputStream fin = new FileInputStream(f); -// System.out.println(f.getName() + ", " + f.exists() + ", " + sendFile(ftpClient, f)); -// fin.close(); - -// System.out.println(ftpClient.getStatus()); - - - localFiles[i] = new FileDate(); - localFiles[i].filename = localFilestmp[i]; - localFiles[i].lastModified = fileEditor.getLastModified(localFilestmp[i]); - } - - FileAction[] localActions = compareDates(localFiles, fd2map(remoteFiles), false); - System.out.println(localActions.length); - for(int i = 0 ; i < localActions.length; i++){ - - System.out.println(localActions[i].filename + ", " + localActions[i].action); - switch (localActions[i].action){ - case SEND: - sendFile(ftpClient, localActions[i].filename); - fileEditor.setLastModified(localActions[i].filename, localActions[i].otherTimestamp); - break; - case RECIEVE: - - break; + if (remoteFile == null || toleranceCompareAfter(getLocalFileUtcTimestamp(localFile), (getUtcTimestamp(remoteFile)))) { + uploadFile(localFile); + System.out.println("Uploaded " + localFile.getName()); + upCount++; + }else{ + System.out.println("Did not upload " + localFile.getName()); + } + } } } + for (FTPFile remoteFile : remoteFiles) { + if (!remoteFile.isDirectory()) { + File localFile = new File(baseDir, remoteFile.getName()); + +// Date t1 = getLocalFileUtcTimestamp(localFile); +// Date t2 = getUtcTimestamp(remoteFile); +//// +// System.out.println("- " + t1 + (t1.after(t2) ? ">" : "<") + t2); + + if (!localFile.exists() || toleranceCompareAfter(getUtcTimestamp(remoteFile), (getLocalFileUtcTimestamp(localFile)))) { + downloadFile(remoteFile, localFile); + System.out.println("Downloaded " + localFile.getName()); + downCount++; + }else{ + System.out.println("Did not download " + remoteFile.getName()); + } + } + } } catch (Exception e) { AlertManager.error(e); - onResult.onResult(true); - AlertManager.toast("Error Syncing!"); + onResult.onResult(true, upCount, downCount); + } finally { + onResult.onResult(false, upCount, downCount); } -// } finally { -// AlertManager.toast("Synced!"); -// onResult.onResult(false); -// } - } - - private Map fd2map(FileDate[] fdarr){ - Map map = new HashMap<>(); - for(int i = 0; i < fdarr.length; i++) - map.put(fdarr[i].filename, fdarr[i].lastModified); - return map; - } - - private enum SyncAction { - SEND, - RECIEVE, - NONE - } - - private class FileAction { - String filename; - SyncAction action; - Calendar otherTimestamp; - public FileAction(String filename, SyncAction action, Calendar otherTimestamp){ - this.filename = filename; - this.action = action; - this.otherTimestamp = otherTimestamp; - } - } - - private FileAction[] compareDates(FileDate[] files, Map refrence, boolean reverse){ - FileAction[] actions = new FileAction[files.length]; - for(int i = 0; i < files.length; i++){ - Calendar ref = refrence.get(files[i].filename); - - System.out.println(ref); - - if(ref == null || files[i].lastModified.after(ref)) { - actions[i] = new FileAction(files[i].filename, !reverse ? SyncAction.SEND : SyncAction.RECIEVE, ref); - }else if(files[i].lastModified.before(ref)){ - actions[i] = new FileAction(files[i].filename, !reverse ? SyncAction.RECIEVE : SyncAction.SEND, ref); - }else { - actions[i] = new FileAction(files[i].filename, SyncAction.NONE, ref); - } - } - return actions; } } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TransferFragment.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TransferFragment.java index b116f65..b9abd4e 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TransferFragment.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/TransferFragment.java @@ -14,11 +14,14 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.ridgebotics.ridgescout.R; +import com.ridgebotics.ridgescout.utility.AlertManager; import com.ridgebotics.ridgescout.utility.settingsManager; import com.ridgebotics.ridgescout.databinding.FragmentTransferBinding; import com.ridgebotics.ridgescout.ui.transfer.bluetooth.BluetoothSenderFragment; import com.ridgebotics.ridgescout.ui.transfer.codes.CodeGeneratorView; +import java.util.Date; + public class TransferFragment extends Fragment { private FragmentTransferBinding binding; @@ -66,12 +69,31 @@ public class TransferFragment extends Fragment { alert.create().show(); }); + + if(!settingsManager.getWifiMode()) { + binding.TBAButton.setEnabled(false); + binding.SyncButton.setEnabled(false); + } + + if(!settingsManager.getFTPEnabled() || + new Date().getTime()-FTPSync.lastSyncTime < FTPSync.timeTolerance) { + binding.SyncButton.setEnabled(false); + } + + binding.SyncButton.setOnClickListener(v -> { + binding.SyncButton.setEnabled(false); + FTPSync.sync((error, upcount, downcount) -> getActivity().runOnUiThread(() -> { +// binding.SyncButton.setEnabled(true); + AlertManager.toast((!error ? "Synced! " : "Error Syncing. ") + upcount + " Up " + downcount + " Down"); + })); + }); + + if(evcode.equals("unset")){ binding.noEventError.setVisibility(View.VISIBLE); binding.uploadButton.setEnabled(false); binding.CSVButton.setEnabled(false); binding.downloadButton.setEnabled(true); - binding.SyncButton.setEnabled(false); return binding.getRoot(); } @@ -107,20 +129,6 @@ public class TransferFragment extends Fragment { builder.show(); }); - if(!settingsManager.getWifiMode()) { - binding.TBAButton.setEnabled(false); - binding.SyncButton.setEnabled(false); - } - - if(!settingsManager.getFTPEnabled()) { - binding.SyncButton.setEnabled(false); - } - - binding.SyncButton.setOnClickListener(v -> { - binding.SyncButton.setEnabled(false); - FTPSync.sync(error -> getActivity().runOnUiThread(() -> binding.SyncButton.setEnabled(true))); - }); - return binding.getRoot(); } diff --git a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/codes/CodeScannerView.java b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/codes/CodeScannerView.java index 71398c4..aecd20c 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/codes/CodeScannerView.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/ui/transfer/codes/CodeScannerView.java @@ -2,7 +2,9 @@ package com.ridgebotics.ridgescout.ui.transfer.codes; import static androidx.core.math.MathUtils.clamp; +import android.Manifest; import android.app.AlertDialog; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.media.Image; import android.os.Bundle; @@ -25,6 +27,7 @@ import androidx.camera.core.ImageProxy; import androidx.camera.core.Preview; import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.LifecycleOwner; @@ -150,6 +153,9 @@ public class CodeScannerView extends Fragment { this.lifecycle = getViewLifecycleOwner(); + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, 1); + } uiHandler = new Handler(); diff --git a/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java b/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java index f8becf4..61f867d 100644 --- a/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java +++ b/app/src/main/java/com/ridgebotics/ridgescout/utility/fileEditor.java @@ -15,6 +15,8 @@ import java.io.IOException; import java.nio.BufferOverflowException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -22,6 +24,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; +import java.util.TimeZone; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; @@ -30,6 +33,7 @@ public final class fileEditor { public final static String baseDir = "/data/data/com.ridgebotics.ridgescout/"; public static final byte internalDataVersion = 0x01; public static final int maxCompressedBlockSize = 4096; +// private TimeZone localTimeZone = TimeZone.getDefault(); @@ -190,22 +194,22 @@ public final class fileEditor { - public static Calendar getLastModified(String filepath){ - File f = new File(baseDir + filepath); - if(f.exists()){ - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(f.lastModified()); - return calendar; - } - return null; - } - - public static void setLastModified(String filepath, Calendar calendar){ - File f = new File(baseDir + filepath); - if(f.exists()){ - f.setLastModified(calendar.getTimeInMillis()); - } - } +// public static Calendar getLastModified(String filepath){ +// File f = new File(baseDir + filepath); +// if(f.exists()){ +// Calendar calendar = Calendar.getInstance(); +// calendar.setTimeInMillis(f.lastModified()); +// return calendar; +// } +// return null; +// } +// +// public static void setLastModified(String filepath, Calendar calendar){ +// File f = new File(baseDir + filepath); +// if(f.exists()){ +// f.setLastModified(calendar.getTimeInMillis()); +// } +// } @@ -214,6 +218,10 @@ public final class fileEditor { FileOutputStream output = new FileOutputStream(baseDir + filepath); output.write(data); output.close(); + +// Date d = new Date(); + + new File(baseDir + filepath).setLastModified(new Date().getTime()); return true; } catch (IOException e) {