log upload tab
This commit is contained in:
parent
794b907f62
commit
17a7a89e28
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue