mirror of
https://github.com/Team4388/RidgeScout.git
synced 2026-06-09 00:37:59 -06:00
Make delete file menu. Add #8
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
package com.ridgebotics.ridgescout.ui.settings;
|
package com.ridgebotics.ridgescout.ui.settings;
|
||||||
|
|
||||||
import static android.view.View.VISIBLE;
|
|
||||||
import static android.widget.LinearLayout.HORIZONTAL;
|
import static android.widget.LinearLayout.HORIZONTAL;
|
||||||
import static android.widget.LinearLayout.VERTICAL;
|
import static android.widget.LinearLayout.VERTICAL;
|
||||||
import static androidx.navigation.fragment.FragmentKt.findNavController;
|
import static androidx.navigation.fragment.FragmentKt.findNavController;
|
||||||
@@ -32,13 +31,9 @@ import android.view.Gravity;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TableLayout;
|
|
||||||
import android.widget.TableRow;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -58,9 +53,7 @@ import com.ridgebotics.ridgescout.ui.views.TallyCounterView;
|
|||||||
import com.ridgebotics.ridgescout.utility.AlertManager;
|
import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||||
import com.ridgebotics.ridgescout.utility.DataManager;
|
import com.ridgebotics.ridgescout.utility.DataManager;
|
||||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
import com.ridgebotics.ridgescout.utility.ToDelete;
|
||||||
|
|
||||||
import org.w3c.dom.Text;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -98,17 +91,10 @@ public class SettingsFragment extends Fragment {
|
|||||||
|
|
||||||
ButtonSettingsItem corruptButton = new ButtonSettingsItem();
|
ButtonSettingsItem corruptButton = new ButtonSettingsItem();
|
||||||
corruptButton.addButton("find corrupted files", view -> {
|
corruptButton.addButton("find corrupted files", view -> {
|
||||||
new Thread(() -> {
|
ToDelete.findCorruptedFiles(getContext());
|
||||||
AlertManager.startLoading("Loading files...");
|
|
||||||
List<String> filenames = FileEditor.findCorruptedFiles();
|
|
||||||
AlertManager.stopLoading();
|
|
||||||
getActivity().runOnUiThread(() -> {
|
|
||||||
deleteFiles(filenames, true);
|
|
||||||
});
|
|
||||||
}).start();
|
|
||||||
});
|
});
|
||||||
corruptButton.addButton("delete files", view -> {
|
corruptButton.addButton("delete files", view -> {
|
||||||
deleteFiles(Arrays.asList(FileEditor.getFiles()), false);
|
ToDelete.deleteFiles(getContext(), Arrays.asList(FileEditor.getFiles()), false);
|
||||||
});
|
});
|
||||||
// corruptButton.setEnabled(!getEVCode().equals("unset"));
|
// corruptButton.setEnabled(!getEVCode().equals("unset"));
|
||||||
|
|
||||||
@@ -264,35 +250,7 @@ public class SettingsFragment extends Fragment {
|
|||||||
alert.create().show();
|
alert.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteFiles(List<String> files, boolean defaultOption) {
|
|
||||||
ScrollView sv = new ScrollView(getContext());
|
|
||||||
LinearLayout ll = new LinearLayout(getContext());
|
|
||||||
ll.setOrientation(VERTICAL);
|
|
||||||
sv.addView(ll);
|
|
||||||
|
|
||||||
CheckBox[] checkboxes = new CheckBox[files.size()];
|
|
||||||
|
|
||||||
for(int i =0; i < files.size(); i++){
|
|
||||||
CheckBox cb = new CheckBox(getContext());
|
|
||||||
cb.setText(files.get(i));
|
|
||||||
cb.setChecked(defaultOption);
|
|
||||||
ll.addView(cb);
|
|
||||||
checkboxes[i] = cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
|
|
||||||
alert.setTitle("Delete files");
|
|
||||||
alert.setView(sv);
|
|
||||||
alert.setNeutralButton("Cancel", null);
|
|
||||||
// alert.setPositiveButton("Save", (dialogInterface, i) -> {
|
|
||||||
// DataManager.scoutNotice = editText.getText().toString();
|
|
||||||
// DataManager.save_scout_notice();
|
|
||||||
// });
|
|
||||||
alert.setCancelable(false);
|
|
||||||
|
|
||||||
alert.create().show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView createText(String title) {
|
private TextView createText(String title) {
|
||||||
TextView tv = new TextView(getContext());
|
TextView tv = new TextView(getContext());
|
||||||
@@ -311,7 +269,7 @@ public class SettingsFragment extends Fragment {
|
|||||||
ll.addView(createText("Package: " + pInfo.packageName));
|
ll.addView(createText("Package: " + pInfo.packageName));
|
||||||
ll.addView(createText("Version: " + pInfo.versionName));
|
ll.addView(createText("Version: " + pInfo.versionName));
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
ll.addView(createText("Signature: " + (pInfo.signingInfo != null ? pInfo.signingInfo.toString() : "None")));
|
ll.addView(createText("Signature: " + (pInfo.signingInfo != null ? "True" : "False")));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
|||||||
@@ -49,7 +49,10 @@ public class FileSelectorFragment extends Fragment {
|
|||||||
meta_string_array = new String[]{
|
meta_string_array = new String[]{
|
||||||
"matches.fields",
|
"matches.fields",
|
||||||
"pits.fields",
|
"pits.fields",
|
||||||
evcode+".eventdata"
|
evcode+".eventdata",
|
||||||
|
evcode+".rescout",
|
||||||
|
evcode+".scoutnotice",
|
||||||
|
"todelete.colabarray",
|
||||||
};
|
};
|
||||||
|
|
||||||
String[] files = FileEditor.getEventFiles(evcode);
|
String[] files = FileEditor.getEventFiles(evcode);
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import static com.ridgebotics.ridgescout.utility.FileEditor.baseDir;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.ridgebotics.ridgescout.types.ColabArray;
|
||||||
import com.ridgebotics.ridgescout.utility.AlertManager;
|
import com.ridgebotics.ridgescout.utility.AlertManager;
|
||||||
import com.ridgebotics.ridgescout.utility.FileEditor;
|
import com.ridgebotics.ridgescout.utility.FileEditor;
|
||||||
import com.ridgebotics.ridgescout.utility.HttpGetFile;
|
import com.ridgebotics.ridgescout.utility.HttpGetFile;
|
||||||
import com.ridgebotics.ridgescout.utility.HttpPutFile;
|
import com.ridgebotics.ridgescout.utility.HttpPutFile;
|
||||||
import com.ridgebotics.ridgescout.utility.RequestTask;
|
import com.ridgebotics.ridgescout.utility.RequestTask;
|
||||||
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
import com.ridgebotics.ridgescout.utility.SettingsManager;
|
||||||
|
import com.ridgebotics.ridgescout.utility.ToDelete;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -96,6 +98,10 @@ public class HttpSync extends Thread {
|
|||||||
public void run() {
|
public void run() {
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
boolean sendMetaFiles = SettingsManager.getFTPSendMetaFiles();
|
boolean sendMetaFiles = SettingsManager.getFTPSendMetaFiles();
|
||||||
|
|
||||||
|
ToDelete.reload_todelete_list();
|
||||||
|
List<String> removeFiles = ToDelete.todelete_list.get();
|
||||||
|
|
||||||
String serverIP = SettingsManager.getFTPServer();
|
String serverIP = SettingsManager.getFTPServer();
|
||||||
String serverKey = SettingsManager.getFTPKey();
|
String serverKey = SettingsManager.getFTPKey();
|
||||||
|
|
||||||
@@ -113,6 +119,9 @@ public class HttpSync extends Thread {
|
|||||||
|
|
||||||
getLocalFileMetadata();
|
getLocalFileMetadata();
|
||||||
|
|
||||||
|
localFiles.removeIf(localFile -> removeFiles.contains(localFile.filename+","+localFile.checksum));
|
||||||
|
remoteFiles.removeIf(remoteFile -> removeFiles.contains(remoteFile.filename+","+remoteFile.checksum));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -187,7 +196,7 @@ public class HttpSync extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ToDelete.deleteFiles();
|
||||||
|
|
||||||
setUpdateIndicator("Finished, " + upCount + " Up, " + downCount + " Down");
|
setUpdateIndicator("Finished, " + upCount + " Up, " + downCount + " Down");
|
||||||
|
|
||||||
@@ -209,25 +218,6 @@ public class HttpSync extends Thread {
|
|||||||
return new Date(file.lastModified());
|
return new Date(file.lastModified());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSHA256Hash(String filePath) throws IOException, NoSuchAlgorithmException {
|
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
||||||
FileInputStream fis = new FileInputStream(filePath);
|
|
||||||
byte[] byteArray = new byte[1024];
|
|
||||||
int bytesCount = 0;
|
|
||||||
|
|
||||||
while ((bytesCount = fis.read(byteArray)) != -1) {
|
|
||||||
digest.update(byteArray, 0, bytesCount);
|
|
||||||
}
|
|
||||||
fis.close();
|
|
||||||
|
|
||||||
byte[] bytes = digest.digest();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (byte b : bytes) {
|
|
||||||
sb.append(String.format("%02x", b));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getLocalFileMetadata() {
|
private void getLocalFileMetadata() {
|
||||||
File localDir = new File(baseDir);
|
File localDir = new File(baseDir);
|
||||||
File[] localFileNames = localDir.listFiles();
|
File[] localFileNames = localDir.listFiles();
|
||||||
@@ -244,9 +234,10 @@ public class HttpSync extends Thread {
|
|||||||
tf.filename = file.getName();
|
tf.filename = file.getName();
|
||||||
tf.updated = getLocalFileUtcTimestamp(file);
|
tf.updated = getLocalFileUtcTimestamp(file);
|
||||||
try {
|
try {
|
||||||
tf.checksum = getSHA256Hash(file.getPath());
|
tf.checksum = FileEditor.getSHA256Hash(file.getName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
AlertManager.error("Failed to get hash of: " + file.getName(), e);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
localFiles.add(tf);
|
localFiles.add(tf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ import com.ridgebotics.ridgescout.types.ColabArray;
|
|||||||
import com.ridgebotics.ridgescout.types.frcEvent;
|
import com.ridgebotics.ridgescout.types.frcEvent;
|
||||||
import com.ridgebotics.ridgescout.types.input.FieldType;
|
import com.ridgebotics.ridgescout.types.input.FieldType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
// Static class to hold loaded data, for ease of access.
|
// Static class to hold loaded data, for ease of access.
|
||||||
public class DataManager {
|
public class DataManager {
|
||||||
public static String evcode;
|
public static String evcode;
|
||||||
@@ -63,6 +59,10 @@ public class DataManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static ColabArray rescout_list = new ColabArray();
|
public static ColabArray rescout_list = new ColabArray();
|
||||||
public static void reload_rescout_list(){
|
public static void reload_rescout_list(){
|
||||||
String filename = evcode + ".rescout";
|
String filename = evcode + ".rescout";
|
||||||
@@ -87,6 +87,11 @@ public class DataManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static String scoutNotice = "";
|
public static String scoutNotice = "";
|
||||||
|
|
||||||
public static void reload_scout_notice(){
|
public static void reload_scout_notice(){
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import java.io.IOException;
|
|||||||
import java.nio.BufferOverflowException;
|
import java.nio.BufferOverflowException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -326,6 +328,29 @@ public final class FileEditor {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String getSHA256Hash(String filePath) throws IOException, NoSuchAlgorithmException {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
FileInputStream fis = new FileInputStream(baseDir + filePath);
|
||||||
|
byte[] byteArray = new byte[1024];
|
||||||
|
int bytesCount = 0;
|
||||||
|
|
||||||
|
while ((bytesCount = fis.read(byteArray)) != -1) {
|
||||||
|
digest.update(byteArray, 0, bytesCount);
|
||||||
|
}
|
||||||
|
fis.close();
|
||||||
|
|
||||||
|
byte[] bytes = digest.digest();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : bytes) {
|
||||||
|
sb.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean setEvent(frcEvent event){
|
public static boolean setEvent(frcEvent event){
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
package com.ridgebotics.ridgescout.utility;
|
||||||
|
|
||||||
|
import static android.widget.LinearLayout.VERTICAL;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ScrollView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.ridgebotics.ridgescout.types.ColabArray;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ToDelete {
|
||||||
|
public static final String filename = "todelete.colabarray";
|
||||||
|
|
||||||
|
public static void findCorruptedFiles(Context c) {
|
||||||
|
new Thread(() -> {
|
||||||
|
AlertManager.startLoading("Loading files...");
|
||||||
|
List<String> filenames = FileEditor.findCorruptedFiles();
|
||||||
|
AlertManager.stopLoading();
|
||||||
|
((Activity) c).runOnUiThread(() -> {
|
||||||
|
deleteFiles(c, filenames, true);
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteFiles(Context c, List<String> files, boolean defaultOption) {
|
||||||
|
ScrollView sv = new ScrollView(c);
|
||||||
|
LinearLayout ll = new LinearLayout(c);
|
||||||
|
ll.setOrientation(VERTICAL);
|
||||||
|
sv.addView(ll);
|
||||||
|
|
||||||
|
CheckBox[] checkboxes = new CheckBox[files.size()];
|
||||||
|
|
||||||
|
for(int i =0; i < files.size(); i++){
|
||||||
|
CheckBox cb = new CheckBox(c);
|
||||||
|
cb.setText(files.get(i));
|
||||||
|
cb.setChecked(defaultOption);
|
||||||
|
ll.addView(cb);
|
||||||
|
checkboxes[i] = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AlertDialog.Builder alert = new AlertDialog.Builder(c);
|
||||||
|
alert.setTitle("Delete files");
|
||||||
|
alert.setView(sv);
|
||||||
|
alert.setNeutralButton("Cancel", null);
|
||||||
|
alert.setPositiveButton("Delete", (_dialogInterface, _i) -> {
|
||||||
|
List<String> delete_files = new ArrayList<>();
|
||||||
|
for(int i = 0; i < files.size(); i++) {
|
||||||
|
if(checkboxes[i].isChecked())
|
||||||
|
delete_files.add(files.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AlertDialog.Builder confirm = new AlertDialog.Builder(c);
|
||||||
|
alert.setTitle("Confirm");
|
||||||
|
TextView tv = new TextView(c);
|
||||||
|
tv.setText("Are you sure you want to delete " + delete_files.size() + " files?");
|
||||||
|
alert.setView(tv);
|
||||||
|
alert.setNeutralButton("Cancel", null);
|
||||||
|
alert.setPositiveButton("Delete", (dialogInterface, i) -> {
|
||||||
|
deleteFiles(delete_files);
|
||||||
|
});
|
||||||
|
alert.setCancelable(false);
|
||||||
|
alert.create().show();
|
||||||
|
});
|
||||||
|
alert.setCancelable(false);
|
||||||
|
alert.create().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColabArray todelete_list = new ColabArray();
|
||||||
|
public static void reload_todelete_list(){
|
||||||
|
if(!FileEditor.fileExist(ToDelete.filename)) {todelete_list = new ColabArray(); return;}
|
||||||
|
byte[] file = FileEditor.readFile(ToDelete.filename);
|
||||||
|
if(file == null) {todelete_list = new ColabArray(); return;}
|
||||||
|
|
||||||
|
try {
|
||||||
|
todelete_list = ColabArray.decode(file);
|
||||||
|
} catch (Exception e){
|
||||||
|
AlertManager.error("Error loading todelete list", e);
|
||||||
|
todelete_list = new ColabArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save_todelete_list() {
|
||||||
|
try {
|
||||||
|
FileEditor.writeFile(ToDelete.filename, todelete_list.encode());
|
||||||
|
} catch (Exception e){
|
||||||
|
AlertManager.error("Error saving todelete list", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void deleteFiles(List<String> toDelete) {
|
||||||
|
reload_todelete_list();
|
||||||
|
|
||||||
|
for(String file : toDelete) {
|
||||||
|
|
||||||
|
String hash;
|
||||||
|
try {
|
||||||
|
hash = FileEditor.getSHA256Hash(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
AlertManager.error("Failed to get hash of file: " + file, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
todelete_list.add(file+","+hash);
|
||||||
|
|
||||||
|
FileEditor.deleteFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
save_todelete_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteFiles() {
|
||||||
|
reload_todelete_list();
|
||||||
|
List<String> toDelete = todelete_list.get();
|
||||||
|
for(String filename : FileEditor.getFiles()){
|
||||||
|
try {
|
||||||
|
String hash = FileEditor.getSHA256Hash(filename);
|
||||||
|
|
||||||
|
if(toDelete.contains(filename+","+hash)) {
|
||||||
|
FileEditor.deleteFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
AlertManager.error("Failed to get hash of file: " + filename, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String localfile) {
|
||||||
|
try {
|
||||||
|
String hash = FileEditor.getSHA256Hash(localfile);
|
||||||
|
return contains(localfile, hash);
|
||||||
|
} catch (Exception e) {
|
||||||
|
AlertManager.error("Failed to get hash of file: " + localfile, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean contains(String filename, String hash){
|
||||||
|
return todelete_list.contains(filename+","+hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user