log upload tab

This commit is contained in:
rusefi 2020-08-12 20:37:37 -04:00
parent 794b907f62
commit 17a7a89e28
7 changed files with 149 additions and 47 deletions

View File

@ -13,6 +13,7 @@ import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.jetbrains.annotations.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
@ -73,32 +74,33 @@ public class Online {
}
/**
* we are here in case of individual tune upload
* we are here in case of individual tune upload
*/
public static BasicFuture<UploadResult> uploadTune(Msq tune, AuthTokenPanel authTokenPanel, JComponent parent, FutureCallback<UploadResult> callback) {
try {
tune.writeXmlFile(outputXmlFileName);
} catch (JAXBException | IOException e) {
throw new IllegalStateException("While writing tune", e);
}
return uploadFile(parent, callback, outputXmlFileName);
}
@Nullable
public static BasicFuture<UploadResult> uploadFile(JComponent parent, FutureCallback<UploadResult> callback, final String fileName) {
BasicFuture<UploadResult> result = new BasicFuture<>(callback);
String authToken = authTokenPanel.getToken();
if (!authTokenPanel.hasToken()) {
authTokenPanel.showError(parent);
String authToken = AuthTokenPanel.getAuthToken();
if (!AuthTokenPanel.hasToken()) {
AuthTokenPanel.showError(parent);
return null;
}
new Thread(new Runnable() {
@Override
public void run() {
UploadResult array = doUpload(authToken, tune);
UploadResult array = upload(new File(fileName), authToken);
result.completed(array);
}
}).start();
return result;
}
private static UploadResult doUpload(String authToken, Msq tune) {
try {
tune.writeXmlFile(outputXmlFileName);
// todo: network upload should not happen on UI thread
return upload(new File(outputXmlFileName), authToken);
} catch (JAXBException | IOException ex) {
return new UploadResult(true, "IO error " + ex);
}
}
}

View File

@ -127,15 +127,15 @@ public class AuthTokenPanel {
return content;
}
public boolean hasToken() {
return AutoTokenUtil.isToken(authTokenTestField.getText());
public static boolean hasToken() {
return AutoTokenUtil.isToken(getAuthToken());
}
public String getToken() {
return authTokenTestField.getText();
}
public void showError(JComponent parent) {
public static void showError(JComponent parent) {
JOptionPane.showMessageDialog(parent, "Does not work without auth token, see below.");
}
}

View File

@ -1,27 +1,125 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.rusefi.TsTuneReader;
import com.rusefi.autoupdate.AutoupdateUtil;
import com.rusefi.tools.online.Online;
import com.rusefi.tools.online.UploadResult;
import com.rusefi.ui.util.FrameHelper;
import org.apache.http.concurrent.FutureCallback;
import org.jetbrains.annotations.NotNull;
import org.mockito.stubbing.Answer;
import org.putgemin.VerticalFlowLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Objects;
import java.util.function.Supplier;
import static org.mockito.Mockito.*;
public class LogUploadSelector {
private final JPanel content = new JPanel(new VerticalFlowLayout());
private final JPanel content = new JPanel(new BorderLayout());
private final JLabel uploadState = new JLabel();
private final JPanel fileList = new JPanel(new VerticalFlowLayout());
public static final Answer<?> NEGATIVE_ANSWER = invocation -> {
throw new UnsupportedOperationException("Not mocked " + invocation);
};
private final Supplier<ControllerAccess> controllerAccessSupplier;
public static void main(String[] args) {
new FrameHelper().showFrame(new LogUploadSelector().getContent());
String projectName = "mre_f4";
ControllerAccess controllerAccess = mock(ControllerAccess.class, NEGATIVE_ANSWER);
doReturn(new String[]{projectName}).when(controllerAccess).getEcuConfigurationNames();
new FrameHelper().showFrame(new LogUploadSelector(() -> controllerAccess).getContent());
}
public LogUploadSelector() {
String projectName = "dev";
String folder = getLogsFolderDir(projectName);
public LogUploadSelector(Supplier<ControllerAccess> controllerAccessSupplier) {
this.controllerAccessSupplier = controllerAccessSupplier;
for (String fileName : new File(folder).list((dir, name) -> name.endsWith(".mlg"))) {
System.out.println(fileName);
JButton refresh = new JButton("Refresh");
refresh.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
refresh();
}
});
JPanel topPanel = new JPanel(new FlowLayout());
topPanel.add(refresh);
JPanel filePanel = new JPanel(new BorderLayout());
filePanel.add(fileList, BorderLayout.CENTER);
JScrollPane fileScroll = new JScrollPane(filePanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
content.add(topPanel, BorderLayout.NORTH);
content.add(fileScroll, BorderLayout.CENTER);
content.add(uploadState, BorderLayout.SOUTH);
refresh();
}
private void refresh() {
fileList.removeAll();
String folder = getLogsFolderDir(controllerAccessSupplier.get().getEcuConfigurationNames()[0]);
for (String fileName : Objects.requireNonNull(new File(folder).list((dir, name) -> name.endsWith(".mlg")))) {
JPanel panel = new JPanel(new FlowLayout());
JButton delete = new JButton("Delete");
JButton upload = new JButton("Upload");
final String fullFileName = folder + File.separator + fileName;
panel.add(delete);
panel.add(upload);
delete.addActionListener(new AbstractAction() {
@SuppressWarnings("ResultOfMethodCallIgnored")
@Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "Are you sure you want to remove " + fileName,
"rusEfi", JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
new File(fullFileName).delete();
}
}
});
upload.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Online.uploadFile(content, new FutureCallback<UploadResult>() {
@Override
public void completed(UploadResult uploadResult) {
SwingUtilities.invokeLater(() -> UploadView.setResult(uploadResult, uploadState));
}
@Override
public void failed(Exception e) {
}
@Override
public void cancelled() {
}
}, fullFileName);
}
});
panel.add(new JLabel(fileName));
fileList.add(panel);
}
AutoupdateUtil.trueLayout(content);
}
@NotNull
@ -29,8 +127,7 @@ public class LogUploadSelector {
return TsTuneReader.getProjectsDir() + File.separator + projectName + File.separator + "DataLogs";
}
private JComponent getContent() {
public JComponent getContent() {
return content;
}
}

View File

@ -12,7 +12,7 @@ import java.util.function.Supplier;
/**
* {@link TsPluginLauncher} creates an instance of this class via reflection.
* @see UploadTab upload tune & TODO upload logs
* @see TuneUploadTab upload tune & TODO upload logs
* @see RemoteTab remote ECU access & control
* @see BroadcastTab offer your ECU for remove access & control
* @see PluginBodySandbox
@ -40,12 +40,14 @@ public class PluginEntry implements TsPluginBody {
return;
}
UploadTab uploadTab = new UploadTab(controllerAccessSupplier);
TuneUploadTab tuneUploadTab = new TuneUploadTab(controllerAccessSupplier);
LogUploadSelector logUploadTab = new LogUploadSelector(controllerAccessSupplier);
BroadcastTab broadcastTab = new BroadcastTab();
RemoteTab remoteTab = new RemoteTab();
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Upload", uploadTab.getContent());
tabbedPane.addTab("Tune Upload", tuneUploadTab.getContent());
tabbedPane.addTab("Log Upload", logUploadTab.getContent());
tabbedPane.addTab("Broadcast", broadcastTab.getContent());
tabbedPane.addTab("Remote ECU", remoteTab.getContent());
tabbedPane.addTab("Read SD Card", new SdCardReader(controllerAccessSupplier).getContent());

View File

@ -23,7 +23,10 @@ import java.util.Date;
import java.util.Map;
import java.util.function.Supplier;
public class UploadTab {
/**
*
*/
public class TuneUploadTab {
private final JComponent content = new JPanel(new VerticalFlowLayout());
// 2 seconds aggregation by default
private static final int AUTO_UPDATE_AGGREGATION = Integer.parseInt(System.getProperty("autoupload.aggregation", "2000"));
@ -54,7 +57,7 @@ public class UploadTab {
private final ControllerParameterChangeListener listener;
public UploadTab(Supplier<ControllerAccess> controllerAccessSupplier) {
public TuneUploadTab(Supplier<ControllerAccess> controllerAccessSupplier) {
this.controllerAccessSupplier = controllerAccessSupplier;
timer.stop();
@ -118,7 +121,7 @@ public class UploadTab {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
uploadView.setResult(array);
UploadView.setResult(array, uploadView.uploadState);
}
});
}

View File

@ -39,7 +39,7 @@ public class UploadView {
return PersistentConfiguration.getConfig().getRoot().getBoolProperty(AUTO_UPLOAD, false);
}
public void setResult(UploadResult result) {
public static void setResult(UploadResult result, JLabel uploadState) {
uploadState.setText(result.getFirstMessage());
uploadState.setVisible(true);
}

View File

@ -1,6 +1,7 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.efiAnalytics.plugin.ecu.ControllerException;
import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer;
import com.opensr5.ini.IniFileModel;
import com.rusefi.TsTuneReader;
@ -9,9 +10,9 @@ import com.rusefi.ui.util.FrameHelper;
import java.util.ArrayList;
import java.util.Objects;
import static com.rusefi.ts_plugin.LogUploadSelector.NEGATIVE_ANSWER;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
/**
* Sandbox for plugin body
@ -22,25 +23,22 @@ public class PluginBodySandbox {
private static final String PROJECT_NAME = "dev";
public static void main(String[] args) {
public static void main(String[] args) throws ControllerException {
String iniFile = TsTuneReader.getProjectModeFileName(PROJECT_NAME);
IniFileModel model = new IniFileModel().readIniFile(iniFile);
Objects.requireNonNull(model, "model");
java.util.List<String> fieldNamesList = new ArrayList<>(model.allIniFields.keySet());
String[] parameterNames = fieldNamesList.toArray(new String[0]);
ControllerParameterServer controllerParameterServer = mock(ControllerParameterServer.class, NEGATIVE_ANSWER);
doReturn(parameterNames).when(controllerParameterServer).getParameterNames(any());
doNothing().when(controllerParameterServer).subscribe(any(), any(), any());
ControllerParameterServer controllerParameterServer = mock(ControllerParameterServer.class);
when(controllerParameterServer.getParameterNames(any())).thenReturn(parameterNames);
ControllerAccess controllerAccess = mock(ControllerAccess.class, NEGATIVE_ANSWER);
doReturn(new String[]{PROJECT_NAME}).when(controllerAccess).getEcuConfigurationNames();
doReturn(controllerParameterServer).when(controllerAccess).getControllerParameterServer();
ControllerAccess controllerAccess = mock(ControllerAccess.class);
when(controllerAccess.getEcuConfigurationNames()).thenReturn(new String[]{PROJECT_NAME});
when(controllerAccess.getControllerParameterServer()).thenReturn(controllerParameterServer);
new FrameHelper().showFrame(new PluginEntry(() -> {
return controllerAccess;
}).getContent());
new FrameHelper().showFrame(new PluginEntry(() -> controllerAccess).getContent());
}
}