diff --git a/TODO.md b/TODO.md index c2fc90cd..b7fd3e3d 100644 --- a/TODO.md +++ b/TODO.md @@ -19,8 +19,6 @@ |Name|GitHub issue|Component(s)|Priority| |---|---|---|---| -|Add custom connection|N/A|Core, GUI|High| -|Export known hosts|N/A|Core, GUI|High| |Rewrite download peristence|167|Core|High| |Redesign options window|N/A|GUI|Medium| |Free space check before dnwnload|N/A|Core, GUI|Medium| diff --git a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy index 2201f248..8971a1d4 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/MainFrameController.groovy @@ -3,6 +3,7 @@ package com.muwire.gui import com.muwire.core.download.UIDownloadLinkEvent import com.muwire.core.files.DirectoryUnsharedEvent import com.muwire.core.files.directories.WatchedDirectory +import com.muwire.core.hostcache.HostDiscoveredEvent import com.muwire.core.messenger.UIFolderCreateEvent import com.muwire.core.messenger.UIFolderDeleteEvent import com.muwire.gui.MainFrameModel.UploaderWrapper @@ -13,7 +14,9 @@ import com.muwire.core.mulinks.MuLink import com.muwire.gui.profile.PersonaOrProfile import com.muwire.gui.profile.TrustPOP import com.muwire.gui.profile.ViewProfileHelper +import net.i2p.data.Destination +import javax.swing.JFileChooser import javax.swing.JTextField import java.util.regex.Pattern @@ -1164,6 +1167,67 @@ class MainFrameController { mvcGroup.createMVCGroup("update", "update", args).destroy() } } + + @ControllerAction + void importConnections() { + def chooser = new JFileChooser() + chooser.setDialogTitle(trans("IMPORT_CONNECTIONS_TITLE")) + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY) + int rv = chooser.showOpenDialog(null) + if (rv != JFileChooser.APPROVE_OPTION) + return + + int imported = 0 + File f = chooser.getSelectedFile() + try { + f.eachLine { + Destination destination = new Destination(it) + model.core.getEventBus().publish(new HostDiscoveredEvent(destination: destination, fromHostcache: true)) + imported++ + } + } catch (Exception ignored) {} + + if (imported == 0) { + JOptionPane.showMessageDialog(null, trans("IMPORT_CONNECTIONS_FAILED"), + trans("IMPORT_CONNECTIONS_FAILED"), JOptionPane.ERROR_MESSAGE) + } else { + JOptionPane.showMessageDialog(null, trans("IMPORT_CONNECTIONS_SUCCESS", imported), + trans("IMPORT_CONNECTIONS_IMPORTED"), JOptionPane.INFORMATION_MESSAGE) + } + } + + @ControllerAction + void exportConnections() { + def chooser = new JFileChooser() + chooser.setDialogTitle(trans("EXPORT_CONNECTIONS_TITLE")) + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY) + int rv = chooser.showSaveDialog(null) + if (rv != JFileChooser.APPROVE_OPTION) + return + + int exported = 0 + File f = chooser.getSelectedFile() + try { + f.withPrintWriter { + it.println(model.core.me.getDestination().toBase64()) // always export myself + exported++ + List goodHosts = model.core.getHostCache().getGoodHosts(Integer.MAX_VALUE) + for (Destination destination : goodHosts) { + it.println(destination.toBase64()) + exported++ + } + } + } catch (Exception ignored) {} + + if (exported == 0) { + JOptionPane.showMessageDialog(null, trans("EXPORT_CONNECTIONS_FAILED"), + trans("EXPORT_CONNECTIONS_FAILED"), JOptionPane.ERROR_MESSAGE) + } else { + JOptionPane.showMessageDialog(null, + trans("EXPORT_CONNECTIONS_SUCCESS", exported, f.getAbsolutePath()), + trans("EXPORT_CONNECTIONS_EXPORTED"), JOptionPane.INFORMATION_MESSAGE) + } + } void saveMuWireSettings() { core.saveMuSettings() diff --git a/gui/griffon-app/i18n/messages.properties b/gui/griffon-app/i18n/messages.properties index 861b069c..85ba9f16 100644 --- a/gui/griffon-app/i18n/messages.properties +++ b/gui/griffon-app/i18n/messages.properties @@ -90,6 +90,8 @@ CERTIFICATES=Certificates CHAT_ROOM_MONITOR=Chat Room Monitor SIGN_TOOL=Sign Tool COLLECTIONS=Collections +EXPORT_CONNECTIONS=Export Connections +IMPORT_CONNECTIONS=Import Connections # Top buttons SEARCHES=Searches @@ -744,6 +746,16 @@ PROFILE_VIEWER_PROFILE=Profile PROFILE_VIEWER_BLOCK=Block PROFILE_VIEWER_UPDATE=Update Profile +## Import/export connections +IMPORT_CONNECTIONS_TITLE=Select file with connections +IMPORT_CONNECTIONS_IMPORTED=Connections imported +IMPORT_CONNECTIONS_FAILED=Failed to import connections +IMPORT_CONNECTIONS_SUCCESS=Imported {0} connections +EXPORT_CONNECTIONS_TITLE=Select file to export to +EXPORT_CONNECTIONS_EXPORTED=Connections exported +EXPORT_CONNECTIONS_FAILED=Failed to export connections +EXPORT_CONNECTIONS_SUCCESS={0} connections exporte to {1} + ## Tooltips TOOLTIP_FILE_FEED_DISABLED=Your file feed is disabled diff --git a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy index ecba96b3..04939ea0 100644 --- a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy @@ -179,6 +179,10 @@ class MainFrameView { mvcGroup.createMVCGroup("Options", params).destroy() }) } + menu (text : trans("CONNECTIONS")) { + menuItem(trans("IMPORT_CONNECTIONS"), actionPerformed: {controller.importConnections()}) + menuItem(trans("EXPORT_CONNECTIONS"), actionPerformed: {controller.exportConnections()}) + } menu (text : trans("STATUS")) { menuItem("MuWire", actionPerformed : {mvcGroup.createMVCGroup("mu-wire-status").destroy()}) MuWireSettings muSettings = application.context.get("muwire-settings")