diff --git a/java_console/build.xml b/java_console/build.xml index 9b1d0115b4..598a3d5063 100644 --- a/java_console/build.xml +++ b/java_console/build.xml @@ -13,7 +13,7 @@ + classpath="../java_tools/configuration_definition/lib/snakeyaml.jar:lib/jaxb-api.jar:lib/httpclient.jar:lib/httpmime.jar:lib/httpcore.jar:lib/jSerialComm.jar:lib/jcip-annotations-1.0.jar:lib/jlatexmath-1.0.6.jar:lib/swing-layout-1.0.jar:lib/jep.jar:lib/log4j.jar:lib/junit.jar:lib/jssc.jar:lib/SteelSeries-3.9.30.jar:lib/annotations.jar:lib/miglayout-4.0.jar:lib/surfaceplotter-2.0.1.jar"> diff --git a/java_console/inifile/src/com/rusefi/tune/xml/Msq.java b/java_console/inifile/src/com/rusefi/tune/xml/Msq.java index df432bedf3..b477355d4c 100644 --- a/java_console/inifile/src/com/rusefi/tune/xml/Msq.java +++ b/java_console/inifile/src/com/rusefi/tune/xml/Msq.java @@ -3,6 +3,7 @@ package com.rusefi.tune.xml; import com.opensr5.ConfigurationImage; import com.opensr5.ini.IniFileModel; import com.opensr5.ini.field.IniField; +import com.rusefi.ui.storage.PersistentConfiguration; import com.rusefi.xml.XmlUtil; import org.jetbrains.annotations.NotNull; @@ -10,11 +11,12 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import java.io.File; import java.io.IOException; @XmlRootElement public class Msq { - public static final String outputXmlFileName = "output.msq"; + public static final String outputXmlFileName = PersistentConfiguration.RUSEFI_SETTINGS_FOLDER + File.separator + "output.msq"; private final Page page = new Page(); diff --git a/java_console/shared_ui/src/com/rusefi/ui/storage/Node.java b/java_console/inifile/src/com/rusefi/ui/storage/Node.java similarity index 100% rename from java_console/shared_ui/src/com/rusefi/ui/storage/Node.java rename to java_console/inifile/src/com/rusefi/ui/storage/Node.java diff --git a/java_console/shared_ui/src/com/rusefi/ui/storage/PersistentConfiguration.java b/java_console/inifile/src/com/rusefi/ui/storage/PersistentConfiguration.java similarity index 74% rename from java_console/shared_ui/src/com/rusefi/ui/storage/PersistentConfiguration.java rename to java_console/inifile/src/com/rusefi/ui/storage/PersistentConfiguration.java index 18debeb3eb..73ad2e6a8b 100644 --- a/java_console/shared_ui/src/com/rusefi/ui/storage/PersistentConfiguration.java +++ b/java_console/inifile/src/com/rusefi/ui/storage/PersistentConfiguration.java @@ -9,7 +9,8 @@ import java.util.Map; public class PersistentConfiguration { private static final PersistentConfiguration INSTANCE = new PersistentConfiguration(); - private static final String RUSEFI_SETTINGS_FOLDER = System.getProperty("user.home") + File.separator + ".rusEFI"; + public static final String RUSEFI_SETTINGS_FOLDER = System.getProperty("user.home") + File.separator + ".rusEFI"; + private static boolean hookRegistered; static { new File(RUSEFI_SETTINGS_FOLDER).mkdirs(); @@ -25,7 +26,22 @@ public class PersistentConfiguration { } private PersistentConfiguration() { - Runtime.getRuntime().addShutdownHook(new Thread(() -> getConfig().save())); + registerShutdownHook(); + } + + /** + * Does not work under TS plugin looks like TS does a violent System.exit? + */ + public static synchronized void registerShutdownHook() { + if (hookRegistered) { + hookRegistered = true; + return; + } + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + System.out.println("Shutdown hook..."); + getConfig().save(); + System.out.println("Shutdown hook!"); + })); } @SuppressWarnings("unchecked") diff --git a/java_console/shared_ui/shared_ui.iml b/java_console/shared_ui/shared_ui.iml index c17054b4e6..c51500b928 100644 --- a/java_console/shared_ui/shared_ui.iml +++ b/java_console/shared_ui/shared_ui.iml @@ -8,5 +8,7 @@ + + \ No newline at end of file diff --git a/java_console/ui/src/com/rusefi/tools/online/Online.java b/java_console/shared_ui/src/com/rusefi/tools/online/Online.java similarity index 58% rename from java_console/ui/src/com/rusefi/tools/online/Online.java rename to java_console/shared_ui/src/com/rusefi/tools/online/Online.java index fb4477f90a..869ed72a6b 100644 --- a/java_console/ui/src/com/rusefi/tools/online/Online.java +++ b/java_console/shared_ui/src/com/rusefi/tools/online/Online.java @@ -1,5 +1,7 @@ package com.rusefi.tools.online; +import com.rusefi.tune.xml.Msq; +import com.rusefi.ui.AuthTokenPanel; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; @@ -10,8 +12,12 @@ import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; +import javax.swing.*; +import javax.xml.bind.JAXBException; import java.io.*; +import static com.rusefi.ui.AuthTokenPanel.TOKEN_WARNING; + public class Online { private static final String url = "https://rusefi.com/online/upload.php"; @@ -34,4 +40,23 @@ public class Online { System.out.println(responseString); } + + public static void uploadTune(Msq tune, AuthTokenPanel authTokenPanel, JComponent parent) { + String authToken = authTokenPanel.getToken(); + if (authToken.contains(TOKEN_WARNING)) { + JOptionPane.showMessageDialog(parent, "Does not work without auth token"); + return; + } + new Thread(() -> doUpload(authToken, tune)).start(); + } + + private static void doUpload(String authToken, Msq tune) { + try { + tune.writeXmlFile(Msq.outputXmlFileName); + // todo: network upload should not happen on UI thread + upload(new File(Msq.outputXmlFileName), authToken); + } catch (JAXBException | IOException ex) { + throw new IllegalStateException(ex); + } + } } diff --git a/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java b/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java index 9abc83b6ce..9fbc176460 100644 --- a/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java +++ b/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java @@ -1,5 +1,9 @@ package com.rusefi.ui; +import com.rusefi.ui.storage.PersistentConfiguration; +import com.rusefi.ui.util.URLLabel; +import org.jetbrains.annotations.NotNull; + import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; @@ -9,6 +13,7 @@ import static com.rusefi.ui.storage.PersistentConfiguration.getConfig; public class AuthTokenPanel { public static final String TOKEN_WARNING = "Please copy token from your forum profile"; public static final String AUTH_TOKEN = "auth_token"; + private static final String TOKEN_PROFILE_URL = "https://rusefi.com/forum/ucp.php?i=254"; private JPanel content = new JPanel(new FlowLayout(FlowLayout.LEFT)); private JTextField textField = new JTextField(); @@ -16,24 +21,30 @@ public class AuthTokenPanel { public AuthTokenPanel() { textField.setPreferredSize(new Dimension(200, 24)); - String authToken = getConfig().getRoot().getProperty(AUTH_TOKEN); - if (authToken.trim().isEmpty()) - authToken = TOKEN_WARNING; - - textField.setText(authToken); + String authToken = getAuthToken(); JButton save = new JButton("Save"); save.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { getConfig().getRoot().setProperty(AUTH_TOKEN, textField.getText()); + PersistentConfiguration.getConfig().save(); } }); - content.add(textField); content.add(save); + if (authToken.trim().isEmpty()) { + authToken = TOKEN_WARNING; + content.add(new URLLabel("Get it here", TOKEN_PROFILE_URL)); + } + textField.setText(authToken); + } + + @NotNull + public static String getAuthToken() { + return getConfig().getRoot().getProperty(AUTH_TOKEN); } public JPanel getContent() { diff --git a/java_console/ui/src/com/rusefi/Launcher.java b/java_console/ui/src/com/rusefi/Launcher.java index 8498075a31..0ac9cf07de 100644 --- a/java_console/ui/src/com/rusefi/Launcher.java +++ b/java_console/ui/src/com/rusefi/Launcher.java @@ -16,6 +16,7 @@ import com.rusefi.ui.console.MainFrame; import com.rusefi.ui.console.TabbedPanel; import com.rusefi.ui.engine.EngineSnifferPanel; import com.rusefi.ui.logview.LogViewer; +import com.rusefi.ui.storage.PersistentConfiguration; import com.rusefi.ui.util.DefaultExceptionHandler; import com.rusefi.ui.util.JustOneInstance; import jssc.SerialPortList; @@ -185,6 +186,7 @@ public class Launcher extends rusEFIVersion { System.out.println("rusEfi UI console " + CONSOLE_VERSION); System.out.println("Compiled " + new Date(ConsoleTools.classBuildTimeMillis())); System.out.println("\n\n"); + PersistentConfiguration.registerShutdownHook(); if (ConsoleTools.runTool(args)) { return; diff --git a/java_console/ui/src/com/rusefi/ui/OnlineTab.java b/java_console/ui/src/com/rusefi/ui/OnlineTab.java index 801ca8ddb9..c6ffb15bd9 100644 --- a/java_console/ui/src/com/rusefi/ui/OnlineTab.java +++ b/java_console/ui/src/com/rusefi/ui/OnlineTab.java @@ -7,15 +7,8 @@ import com.rusefi.ui.util.Misc; import org.putgemin.VerticalFlowLayout; import javax.swing.*; -import javax.xml.bind.JAXBException; -import java.awt.*; import java.awt.event.ActionEvent; -import java.io.File; -import java.io.IOException; - -import static com.rusefi.ui.AuthTokenPanel.TOKEN_WARNING; -import static com.rusefi.ui.storage.PersistentConfiguration.getConfig; public class OnlineTab { @@ -32,19 +25,8 @@ public class OnlineTab { upload.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { - String text = authTokenPanel.getToken(); - if (text.contains(TOKEN_WARNING)) { - JOptionPane.showMessageDialog(content, "Does not work without auth token"); - return; - } Msq tune = Msq.toMsq(LinkManager.connector.getBinaryProtocol().getControllerConfiguration()); - try { - tune.writeXmlFile(Msq.outputXmlFileName); - // todo: network upload should not happen on UI thread - Online.upload(new File(Msq.outputXmlFileName), text); - } catch (JAXBException | IOException ex) { - throw new IllegalStateException(ex); - } + Online.uploadTune(tune, authTokenPanel, content); } }); content.add(upload); diff --git a/java_tools/ts_plugin/.idea/libraries/httpclient.xml b/java_tools/ts_plugin/.idea/libraries/httpclient.xml new file mode 100644 index 0000000000..3fedad0411 --- /dev/null +++ b/java_tools/ts_plugin/.idea/libraries/httpclient.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java_tools/ts_plugin/build.xml b/java_tools/ts_plugin/build.xml index 2f46d63709..826491418e 100644 --- a/java_tools/ts_plugin/build.xml +++ b/java_tools/ts_plugin/build.xml @@ -12,7 +12,7 @@ @@ -31,7 +31,6 @@ - @@ -42,10 +41,12 @@ - + - + + + \ No newline at end of file diff --git a/java_tools/ts_plugin/lib/commons-logging.jar b/java_tools/ts_plugin/lib/commons-logging.jar new file mode 100644 index 0000000000..93a3b9f6db Binary files /dev/null and b/java_tools/ts_plugin/lib/commons-logging.jar differ diff --git a/java_tools/ts_plugin/src/com/rusefi/TsPlugin.java b/java_tools/ts_plugin/src/com/rusefi/TsPlugin.java index f3bb7024af..6c62a8f324 100644 --- a/java_tools/ts_plugin/src/com/rusefi/TsPlugin.java +++ b/java_tools/ts_plugin/src/com/rusefi/TsPlugin.java @@ -5,6 +5,7 @@ import com.efiAnalytics.plugin.ecu.ControllerAccess; import com.efiAnalytics.plugin.ecu.ControllerException; import com.efiAnalytics.plugin.ecu.ControllerParameter; import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer; +import com.rusefi.tools.online.Online; import com.rusefi.tune.xml.Constant; import com.rusefi.tune.xml.Msq; import com.rusefi.ui.AuthTokenPanel; @@ -14,10 +15,8 @@ import org.putgemin.VerticalFlowLayout; import javax.swing.*; import javax.xml.bind.JAXBException; -import java.io.File; +import java.awt.event.ActionEvent; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; /** * by the way TS installs stuff into %user%\.efianalytics\TunerStudio\plugins folder @@ -26,9 +25,22 @@ public class TsPlugin implements ApplicationPlugin { private ControllerAccess controllerAccess; private final JPanel content = new JPanel(new VerticalFlowLayout()); + private final AuthTokenPanel tokenPanel = new AuthTokenPanel(); + public TsPlugin() { + content.add(new JLabel("" + rusEFIVersion.CONSOLE_VERSION)); content.add(Misc.getRusEFI_online_manual()); - content.add(new AuthTokenPanel().getContent()); + content.add(tokenPanel.getContent()); + + JButton upload = new JButton("Upload"); + upload.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + Msq tune = writeCurrentTune(controllerAccess); + Online.uploadTune(tune, tokenPanel, content); + } + }); + content.add(upload); } @Override @@ -55,11 +67,9 @@ public class TsPlugin implements ApplicationPlugin { public void initialize(ControllerAccess controllerAccess) { this.controllerAccess = controllerAccess; printEcuConfigurationNames(controllerAccess); - - uploadCurrentTune(controllerAccess); } - private static String uploadCurrentTune(ControllerAccess controllerAccess) { + private static Msq writeCurrentTune(ControllerAccess controllerAccess) { Msq msq = new Msq(); String configurationName = getConfigurationName(); ControllerParameterServer controllerParameterServer = controllerAccess.getControllerParameterServer(); @@ -89,10 +99,9 @@ public class TsPlugin implements ApplicationPlugin { msq.getPage().constant.add(new Constant(parameterName, cp.getUnits(), value)); } - Path tempDirWithPrefix = Files.createTempDirectory("rusefi_ts_plugin"); - String fileName = tempDirWithPrefix + File.separator + "plugin.xml"; + String fileName = Msq.outputXmlFileName; msq.writeXmlFile(fileName); - return fileName; + return msq; } catch (JAXBException | IOException | ControllerException e) { System.out.println("Error writing XML: " + e); return null; @@ -158,7 +167,7 @@ public class TsPlugin implements ApplicationPlugin { @Override public String getVersion() { - return "0.00000001"; + return Integer.toString(rusEFIVersion.CONSOLE_VERSION); } @Override