Compare commits
17 Commits
muwire-0.4
...
auto-downl
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2f3d23bc34 | ||
![]() |
98dd80c4b8 | ||
![]() |
d9edb2e128 | ||
![]() |
de04b40b86 | ||
![]() |
7206a3d926 | ||
![]() |
98b98d8938 | ||
![]() |
294b8fcc2f | ||
![]() |
32f601a1b1 | ||
![]() |
8e3a398080 | ||
![]() |
720b9688b4 | ||
![]() |
e3066161c5 | ||
![]() |
a9aa3a524f | ||
![]() |
92848e818a | ||
![]() |
a7aa3008c0 | ||
![]() |
485325e824 | ||
![]() |
0df2a0e039 | ||
![]() |
fb7b4466c2 |
@@ -4,7 +4,7 @@ MuWire is an easy to use file-sharing program which offers anonymity using [I2P
|
|||||||
|
|
||||||
It is inspired by the LimeWire Gnutella client and developped by a former LimeWire developer.
|
It is inspired by the LimeWire Gnutella client and developped by a former LimeWire developer.
|
||||||
|
|
||||||
The current stable release - 0.2.5 is avaiable for download at http://muwire.com. You can find technical documentation in the "doc" folder.
|
The current stable release - 0.4.0 is avaiable for download at https://muwire.com. You can find technical documentation in the "doc" folder.
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ class Cli {
|
|||||||
|
|
||||||
Core core
|
Core core
|
||||||
try {
|
try {
|
||||||
core = new Core(props, home, "0.4.0")
|
core = new Core(props, home, "0.4.2")
|
||||||
} catch (Exception bad) {
|
} catch (Exception bad) {
|
||||||
bad.printStackTrace(System.out)
|
bad.printStackTrace(System.out)
|
||||||
println "Failed to initialize core, exiting"
|
println "Failed to initialize core, exiting"
|
||||||
|
@@ -53,7 +53,7 @@ class CliDownloader {
|
|||||||
|
|
||||||
Core core
|
Core core
|
||||||
try {
|
try {
|
||||||
core = new Core(props, home, "0.4.0")
|
core = new Core(props, home, "0.4.2")
|
||||||
} catch (Exception bad) {
|
} catch (Exception bad) {
|
||||||
bad.printStackTrace(System.out)
|
bad.printStackTrace(System.out)
|
||||||
println "Failed to initialize core, exiting"
|
println "Failed to initialize core, exiting"
|
||||||
|
@@ -2,6 +2,7 @@ apply plugin : 'application'
|
|||||||
mainClassName = 'com.muwire.core.Core'
|
mainClassName = 'com.muwire.core.Core'
|
||||||
applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties']
|
applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties']
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile 'net.i2p:router:0.9.40'
|
||||||
compile 'net.i2p.client:mstreaming:0.9.40'
|
compile 'net.i2p.client:mstreaming:0.9.40'
|
||||||
compile 'net.i2p.client:streaming:0.9.40'
|
compile 'net.i2p.client:streaming:0.9.40'
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ import com.muwire.core.files.FileUnsharedEvent
|
|||||||
import com.muwire.core.files.HasherService
|
import com.muwire.core.files.HasherService
|
||||||
import com.muwire.core.files.PersisterService
|
import com.muwire.core.files.PersisterService
|
||||||
import com.muwire.core.files.AllFilesLoadedEvent
|
import com.muwire.core.files.AllFilesLoadedEvent
|
||||||
|
import com.muwire.core.files.DirectoryUnsharedEvent
|
||||||
import com.muwire.core.files.DirectoryWatcher
|
import com.muwire.core.files.DirectoryWatcher
|
||||||
import com.muwire.core.hostcache.CacheClient
|
import com.muwire.core.hostcache.CacheClient
|
||||||
import com.muwire.core.hostcache.HostCache
|
import com.muwire.core.hostcache.HostCache
|
||||||
@@ -38,6 +39,7 @@ import com.muwire.core.search.ResultsEvent
|
|||||||
import com.muwire.core.search.ResultsSender
|
import com.muwire.core.search.ResultsSender
|
||||||
import com.muwire.core.search.SearchEvent
|
import com.muwire.core.search.SearchEvent
|
||||||
import com.muwire.core.search.SearchManager
|
import com.muwire.core.search.SearchManager
|
||||||
|
import com.muwire.core.search.UIResultBatchEvent
|
||||||
import com.muwire.core.trust.TrustEvent
|
import com.muwire.core.trust.TrustEvent
|
||||||
import com.muwire.core.trust.TrustService
|
import com.muwire.core.trust.TrustService
|
||||||
import com.muwire.core.update.UpdateClient
|
import com.muwire.core.update.UpdateClient
|
||||||
@@ -59,6 +61,9 @@ import net.i2p.data.PrivateKey
|
|||||||
import net.i2p.data.Signature
|
import net.i2p.data.Signature
|
||||||
import net.i2p.data.SigningPrivateKey
|
import net.i2p.data.SigningPrivateKey
|
||||||
|
|
||||||
|
import net.i2p.router.Router
|
||||||
|
import net.i2p.router.RouterContext
|
||||||
|
|
||||||
@Log
|
@Log
|
||||||
public class Core {
|
public class Core {
|
||||||
|
|
||||||
@@ -80,15 +85,62 @@ public class Core {
|
|||||||
private final DownloadManager downloadManager
|
private final DownloadManager downloadManager
|
||||||
private final DirectoryWatcher directoryWatcher
|
private final DirectoryWatcher directoryWatcher
|
||||||
final FileManager fileManager
|
final FileManager fileManager
|
||||||
|
final UploadManager uploadManager
|
||||||
|
|
||||||
|
private final Router router
|
||||||
|
|
||||||
final AtomicBoolean shutdown = new AtomicBoolean()
|
final AtomicBoolean shutdown = new AtomicBoolean()
|
||||||
|
|
||||||
public Core(MuWireSettings props, File home, String myVersion) {
|
public Core(MuWireSettings props, File home, String myVersion) {
|
||||||
this.home = home
|
this.home = home
|
||||||
this.muOptions = props
|
this.muOptions = props
|
||||||
log.info "Initializing I2P context"
|
|
||||||
I2PAppContext.getGlobalContext().logManager()
|
i2pOptions = new Properties()
|
||||||
I2PAppContext.getGlobalContext()._logManager = new MuWireLogManager()
|
def i2pOptionsFile = new File(home,"i2p.properties")
|
||||||
|
if (i2pOptionsFile.exists()) {
|
||||||
|
i2pOptionsFile.withInputStream { i2pOptions.load(it) }
|
||||||
|
|
||||||
|
if (!i2pOptions.containsKey("inbound.nickname"))
|
||||||
|
i2pOptions["inbound.nickname"] = "MuWire"
|
||||||
|
if (!i2pOptions.containsKey("outbound.nickname"))
|
||||||
|
i2pOptions["outbound.nickname"] = "MuWire"
|
||||||
|
} else {
|
||||||
|
i2pOptions["inbound.nickname"] = "MuWire"
|
||||||
|
i2pOptions["outbound.nickname"] = "MuWire"
|
||||||
|
i2pOptions["inbound.length"] = "3"
|
||||||
|
i2pOptions["inbound.quantity"] = "4"
|
||||||
|
i2pOptions["outbound.length"] = "3"
|
||||||
|
i2pOptions["outbound.quantity"] = "4"
|
||||||
|
i2pOptions["i2cp.tcp.host"] = "127.0.0.1"
|
||||||
|
i2pOptions["i2cp.tcp.port"] = "7654"
|
||||||
|
Random r = new Random()
|
||||||
|
int port = r.nextInt(60000) + 4000
|
||||||
|
i2pOptions["i2np.ntcp.port"] = String.valueOf(port)
|
||||||
|
i2pOptions["i2np.udp.port"] = String.valueOf(port)
|
||||||
|
i2pOptionsFile.withOutputStream { i2pOptions.store(it, "") }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.embeddedRouter) {
|
||||||
|
log.info "Initializing I2P context"
|
||||||
|
I2PAppContext.getGlobalContext().logManager()
|
||||||
|
I2PAppContext.getGlobalContext()._logManager = new MuWireLogManager()
|
||||||
|
router = null
|
||||||
|
} else {
|
||||||
|
log.info("launching embedded router")
|
||||||
|
Properties routerProps = new Properties()
|
||||||
|
routerProps.setProperty("i2p.dir.config", home.getAbsolutePath())
|
||||||
|
routerProps.setProperty("i2np.inboundKBytesPerSecond", String.valueOf(props.inBw))
|
||||||
|
routerProps.setProperty("i2np.outboundKBytesPerSecond", String.valueOf(props.outBw))
|
||||||
|
routerProps.setProperty("i2cp.disableInterface", "true")
|
||||||
|
routerProps.setProperty("i2np.ntcp.port", i2pOptions["i2np.ntcp.port"])
|
||||||
|
routerProps.setProperty("i2np.udp.port", i2pOptions["i2np.udp.port"])
|
||||||
|
routerProps.setProperty("i2np.udp.internalPort", i2pOptions["i2np.udp.port"])
|
||||||
|
router = new Router(routerProps)
|
||||||
|
I2PAppContext.getGlobalContext().metaClass = new RouterContextMetaClass()
|
||||||
|
router.runRouter()
|
||||||
|
while(!router.isRunning())
|
||||||
|
Thread.sleep(100)
|
||||||
|
}
|
||||||
|
|
||||||
log.info("initializing I2P socket manager")
|
log.info("initializing I2P socket manager")
|
||||||
def i2pClient = new I2PClientFactory().createClient()
|
def i2pClient = new I2PClientFactory().createClient()
|
||||||
@@ -100,25 +152,6 @@ public class Core {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i2pOptions = new Properties()
|
|
||||||
def i2pOptionsFile = new File(home,"i2p.properties")
|
|
||||||
if (i2pOptionsFile.exists()) {
|
|
||||||
i2pOptionsFile.withInputStream { i2pOptions.load(it) }
|
|
||||||
|
|
||||||
if (!i2pOptions.containsKey("inbound.nickname"))
|
|
||||||
i2pOptions["inbound.nickname"] = "MuWire"
|
|
||||||
if (!i2pOptions.containsKey("outbound.nickname"))
|
|
||||||
i2pOptions["outbound.nickname"] = "MuWire"
|
|
||||||
} else {
|
|
||||||
i2pOptions["inbound.nickname"] = "MuWire"
|
|
||||||
i2pOptions["outbound.nickname"] = "MuWire"
|
|
||||||
i2pOptions["inbound.length"] = "3"
|
|
||||||
i2pOptions["inbound.quantity"] = "4"
|
|
||||||
i2pOptions["outbound.length"] = "3"
|
|
||||||
i2pOptions["outbound.quantity"] = "4"
|
|
||||||
i2pOptions["i2cp.tcp.host"] = "127.0.0.1"
|
|
||||||
i2pOptions["i2cp.tcp.port"] = "7654"
|
|
||||||
}
|
|
||||||
|
|
||||||
// options like tunnel length and quantity
|
// options like tunnel length and quantity
|
||||||
I2PSession i2pSession
|
I2PSession i2pSession
|
||||||
@@ -172,6 +205,7 @@ public class Core {
|
|||||||
eventBus.register(FileDownloadedEvent.class, fileManager)
|
eventBus.register(FileDownloadedEvent.class, fileManager)
|
||||||
eventBus.register(FileUnsharedEvent.class, fileManager)
|
eventBus.register(FileUnsharedEvent.class, fileManager)
|
||||||
eventBus.register(SearchEvent.class, fileManager)
|
eventBus.register(SearchEvent.class, fileManager)
|
||||||
|
eventBus.register(DirectoryUnsharedEvent.class, fileManager)
|
||||||
|
|
||||||
log.info("initializing mesh manager")
|
log.info("initializing mesh manager")
|
||||||
MeshManager meshManager = new MeshManager(fileManager, home, props)
|
MeshManager meshManager = new MeshManager(fileManager, home, props)
|
||||||
@@ -200,7 +234,9 @@ public class Core {
|
|||||||
cacheClient = new CacheClient(eventBus,hostCache, connectionManager, i2pSession, props, 10000)
|
cacheClient = new CacheClient(eventBus,hostCache, connectionManager, i2pSession, props, 10000)
|
||||||
|
|
||||||
log.info("initializing update client")
|
log.info("initializing update client")
|
||||||
updateClient = new UpdateClient(eventBus, i2pSession, myVersion, props)
|
updateClient = new UpdateClient(eventBus, i2pSession, myVersion, props, fileManager, me)
|
||||||
|
eventBus.register(FileDownloadedEvent.class, updateClient)
|
||||||
|
eventBus.register(UIResultBatchEvent.class, updateClient)
|
||||||
|
|
||||||
log.info("initializing connector")
|
log.info("initializing connector")
|
||||||
I2PConnector i2pConnector = new I2PConnector(socketManager)
|
I2PConnector i2pConnector = new I2PConnector(socketManager)
|
||||||
@@ -224,7 +260,7 @@ public class Core {
|
|||||||
eventBus.register(UIDownloadResumedEvent.class, downloadManager)
|
eventBus.register(UIDownloadResumedEvent.class, downloadManager)
|
||||||
|
|
||||||
log.info("initializing upload manager")
|
log.info("initializing upload manager")
|
||||||
UploadManager uploadManager = new UploadManager(eventBus, fileManager, meshManager, downloadManager)
|
uploadManager = new UploadManager(eventBus, fileManager, meshManager, downloadManager)
|
||||||
|
|
||||||
log.info("initializing connection establisher")
|
log.info("initializing connection establisher")
|
||||||
connectionEstablisher = new ConnectionEstablisher(eventBus, i2pConnector, props, connectionManager, hostCache)
|
connectionEstablisher = new ConnectionEstablisher(eventBus, i2pConnector, props, connectionManager, hostCache)
|
||||||
@@ -238,6 +274,7 @@ public class Core {
|
|||||||
directoryWatcher = new DirectoryWatcher(eventBus, fileManager)
|
directoryWatcher = new DirectoryWatcher(eventBus, fileManager)
|
||||||
eventBus.register(FileSharedEvent.class, directoryWatcher)
|
eventBus.register(FileSharedEvent.class, directoryWatcher)
|
||||||
eventBus.register(AllFilesLoadedEvent.class, directoryWatcher)
|
eventBus.register(AllFilesLoadedEvent.class, directoryWatcher)
|
||||||
|
eventBus.register(DirectoryUnsharedEvent.class, directoryWatcher)
|
||||||
|
|
||||||
log.info("initializing hasher service")
|
log.info("initializing hasher service")
|
||||||
hasherService = new HasherService(new FileHasher(), eventBus, fileManager)
|
hasherService = new HasherService(new FileHasher(), eventBus, fileManager)
|
||||||
@@ -272,6 +309,23 @@ public class Core {
|
|||||||
directoryWatcher.stop()
|
directoryWatcher.stop()
|
||||||
log.info("shutting down connection manager")
|
log.info("shutting down connection manager")
|
||||||
connectionManager.shutdown()
|
connectionManager.shutdown()
|
||||||
|
if (router != null) {
|
||||||
|
log.info("shutting down embedded router")
|
||||||
|
router.shutdown(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class RouterContextMetaClass extends DelegatingMetaClass {
|
||||||
|
private final Object logManager = new MuWireLogManager()
|
||||||
|
RouterContextMetaClass() {
|
||||||
|
super(RouterContext.class)
|
||||||
|
}
|
||||||
|
|
||||||
|
Object invokeMethod(Object object, String name, Object[] args) {
|
||||||
|
if (name == "logManager")
|
||||||
|
return logManager
|
||||||
|
super.invokeMethod(object, name, args)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static main(args) {
|
static main(args) {
|
||||||
@@ -298,7 +352,7 @@ public class Core {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Core core = new Core(props, home, "0.4.0")
|
Core core = new Core(props, home, "0.4.2")
|
||||||
core.startServices()
|
core.startServices()
|
||||||
|
|
||||||
// ... at the end, sleep or execute script
|
// ... at the end, sleep or execute script
|
||||||
|
@@ -13,6 +13,7 @@ class MuWireSettings {
|
|||||||
boolean allowUntrusted
|
boolean allowUntrusted
|
||||||
int downloadRetryInterval
|
int downloadRetryInterval
|
||||||
int updateCheckInterval
|
int updateCheckInterval
|
||||||
|
boolean autoDownloadUpdate
|
||||||
String nickname
|
String nickname
|
||||||
File downloadLocation
|
File downloadLocation
|
||||||
CrawlerResponse crawlerResponse
|
CrawlerResponse crawlerResponse
|
||||||
@@ -21,6 +22,8 @@ class MuWireSettings {
|
|||||||
float downloadSequentialRatio
|
float downloadSequentialRatio
|
||||||
int hostClearInterval
|
int hostClearInterval
|
||||||
int meshExpiration
|
int meshExpiration
|
||||||
|
boolean embeddedRouter
|
||||||
|
int inBw, outBw
|
||||||
|
|
||||||
MuWireSettings() {
|
MuWireSettings() {
|
||||||
this(new Properties())
|
this(new Properties())
|
||||||
@@ -35,10 +38,14 @@ class MuWireSettings {
|
|||||||
System.getProperty("user.home")))
|
System.getProperty("user.home")))
|
||||||
downloadRetryInterval = Integer.parseInt(props.getProperty("downloadRetryInterval","1"))
|
downloadRetryInterval = Integer.parseInt(props.getProperty("downloadRetryInterval","1"))
|
||||||
updateCheckInterval = Integer.parseInt(props.getProperty("updateCheckInterval","24"))
|
updateCheckInterval = Integer.parseInt(props.getProperty("updateCheckInterval","24"))
|
||||||
|
autoDownloadUpdate = Boolean.parseBoolean(props.getProperty("autoDownloadUpdate","true"))
|
||||||
shareDownloadedFiles = Boolean.parseBoolean(props.getProperty("shareDownloadedFiles","true"))
|
shareDownloadedFiles = Boolean.parseBoolean(props.getProperty("shareDownloadedFiles","true"))
|
||||||
downloadSequentialRatio = Float.valueOf(props.getProperty("downloadSequentialRatio","0.8"))
|
downloadSequentialRatio = Float.valueOf(props.getProperty("downloadSequentialRatio","0.8"))
|
||||||
hostClearInterval = Integer.valueOf(props.getProperty("hostClearInterval","60"))
|
hostClearInterval = Integer.valueOf(props.getProperty("hostClearInterval","60"))
|
||||||
meshExpiration = Integer.valueOf(props.getProperty("meshExpiration","60"))
|
meshExpiration = Integer.valueOf(props.getProperty("meshExpiration","60"))
|
||||||
|
embeddedRouter = Boolean.valueOf(props.getProperty("embeddedRouter","false"))
|
||||||
|
inBw = Integer.valueOf(props.getProperty("inBw","256"))
|
||||||
|
outBw = Integer.valueOf(props.getProperty("outBw","128"))
|
||||||
|
|
||||||
watchedDirectories = new HashSet<>()
|
watchedDirectories = new HashSet<>()
|
||||||
if (props.containsKey("watchedDirectories")) {
|
if (props.containsKey("watchedDirectories")) {
|
||||||
@@ -57,10 +64,14 @@ class MuWireSettings {
|
|||||||
props.setProperty("downloadLocation", downloadLocation.getAbsolutePath())
|
props.setProperty("downloadLocation", downloadLocation.getAbsolutePath())
|
||||||
props.setProperty("downloadRetryInterval", String.valueOf(downloadRetryInterval))
|
props.setProperty("downloadRetryInterval", String.valueOf(downloadRetryInterval))
|
||||||
props.setProperty("updateCheckInterval", String.valueOf(updateCheckInterval))
|
props.setProperty("updateCheckInterval", String.valueOf(updateCheckInterval))
|
||||||
|
props.setProperty("autoDownloadUpdate", String.valueOf(autoDownloadUpdate))
|
||||||
props.setProperty("shareDownloadedFiles", String.valueOf(shareDownloadedFiles))
|
props.setProperty("shareDownloadedFiles", String.valueOf(shareDownloadedFiles))
|
||||||
props.setProperty("downloadSequentialRatio", String.valueOf(downloadSequentialRatio))
|
props.setProperty("downloadSequentialRatio", String.valueOf(downloadSequentialRatio))
|
||||||
props.setProperty("hostClearInterval", String.valueOf(hostClearInterval))
|
props.setProperty("hostClearInterval", String.valueOf(hostClearInterval))
|
||||||
props.setProperty("meshExpiration", String.valueOf(meshExpiration))
|
props.setProperty("meshExpiration", String.valueOf(meshExpiration))
|
||||||
|
props.setProperty("embeddedRouter", String.valueOf(embeddedRouter))
|
||||||
|
props.setProperty("inBw", String.valueOf(inBw))
|
||||||
|
props.setProperty("outBw", String.valueOf(outBw))
|
||||||
|
|
||||||
if (!watchedDirectories.isEmpty()) {
|
if (!watchedDirectories.isEmpty()) {
|
||||||
String encoded = watchedDirectories.stream().
|
String encoded = watchedDirectories.stream().
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
package com.muwire.core.files
|
||||||
|
|
||||||
|
import com.muwire.core.Event
|
||||||
|
|
||||||
|
class DirectoryUnsharedEvent extends Event {
|
||||||
|
File directory
|
||||||
|
}
|
@@ -35,6 +35,7 @@ class DirectoryWatcher {
|
|||||||
private final FileManager fileManager
|
private final FileManager fileManager
|
||||||
private final Thread watcherThread, publisherThread
|
private final Thread watcherThread, publisherThread
|
||||||
private final Map<File, Long> waitingFiles = new ConcurrentHashMap<>()
|
private final Map<File, Long> waitingFiles = new ConcurrentHashMap<>()
|
||||||
|
private final Map<File, WatchKey> watchedDirectories = new ConcurrentHashMap<>()
|
||||||
private WatchService watchService
|
private WatchService watchService
|
||||||
private volatile boolean shutdown
|
private volatile boolean shutdown
|
||||||
|
|
||||||
@@ -64,10 +65,16 @@ class DirectoryWatcher {
|
|||||||
if (!e.file.isDirectory())
|
if (!e.file.isDirectory())
|
||||||
return
|
return
|
||||||
Path path = e.file.getCanonicalFile().toPath()
|
Path path = e.file.getCanonicalFile().toPath()
|
||||||
path.register(watchService, kinds)
|
WatchKey wk = path.register(watchService, kinds)
|
||||||
|
watchedDirectories.put(e.file, wk)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onDirectoryUnsharedEvent(DirectoryUnsharedEvent e) {
|
||||||
|
WatchKey wk = watchedDirectories.remove(e.directory)
|
||||||
|
wk?.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
private void watch() {
|
private void watch() {
|
||||||
try {
|
try {
|
||||||
while(!shutdown) {
|
while(!shutdown) {
|
||||||
|
@@ -135,4 +135,16 @@ class FileManager {
|
|||||||
}
|
}
|
||||||
rv
|
rv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onDirectoryUnsharedEvent(DirectoryUnsharedEvent e) {
|
||||||
|
e.directory.listFiles().each {
|
||||||
|
if (it.isDirectory())
|
||||||
|
eventBus.publish(new DirectoryUnsharedEvent(directory : it))
|
||||||
|
else {
|
||||||
|
SharedFile sf = fileToSharedFile.get(it)
|
||||||
|
if (sf != null)
|
||||||
|
eventBus.publish(new FileUnsharedEvent(unsharedFile : sf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,15 @@ package com.muwire.core.update
|
|||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
|
|
||||||
import com.muwire.core.EventBus
|
import com.muwire.core.EventBus
|
||||||
|
import com.muwire.core.InfoHash
|
||||||
import com.muwire.core.MuWireSettings
|
import com.muwire.core.MuWireSettings
|
||||||
|
import com.muwire.core.Persona
|
||||||
|
import com.muwire.core.download.UIDownloadEvent
|
||||||
|
import com.muwire.core.files.FileDownloadedEvent
|
||||||
|
import com.muwire.core.files.FileManager
|
||||||
|
import com.muwire.core.search.QueryEvent
|
||||||
|
import com.muwire.core.search.SearchEvent
|
||||||
|
import com.muwire.core.search.UIResultBatchEvent
|
||||||
|
|
||||||
import groovy.json.JsonOutput
|
import groovy.json.JsonOutput
|
||||||
import groovy.json.JsonSlurper
|
import groovy.json.JsonSlurper
|
||||||
@@ -13,6 +21,7 @@ import net.i2p.client.I2PSessionMuxedListener
|
|||||||
import net.i2p.client.SendMessageOptions
|
import net.i2p.client.SendMessageOptions
|
||||||
import net.i2p.client.datagram.I2PDatagramDissector
|
import net.i2p.client.datagram.I2PDatagramDissector
|
||||||
import net.i2p.client.datagram.I2PDatagramMaker
|
import net.i2p.client.datagram.I2PDatagramMaker
|
||||||
|
import net.i2p.data.Base64
|
||||||
import net.i2p.util.VersionComparator
|
import net.i2p.util.VersionComparator
|
||||||
|
|
||||||
@Log
|
@Log
|
||||||
@@ -21,16 +30,24 @@ class UpdateClient {
|
|||||||
final I2PSession session
|
final I2PSession session
|
||||||
final String myVersion
|
final String myVersion
|
||||||
final MuWireSettings settings
|
final MuWireSettings settings
|
||||||
|
final FileManager fileManager
|
||||||
|
final Persona me
|
||||||
|
|
||||||
private final Timer timer
|
private final Timer timer
|
||||||
|
|
||||||
private long lastUpdateCheckTime
|
private long lastUpdateCheckTime
|
||||||
|
|
||||||
UpdateClient(EventBus eventBus, I2PSession session, String myVersion, MuWireSettings settings) {
|
private volatile InfoHash updateInfoHash
|
||||||
|
private volatile String version, signer
|
||||||
|
private volatile boolean updateDownloading
|
||||||
|
|
||||||
|
UpdateClient(EventBus eventBus, I2PSession session, String myVersion, MuWireSettings settings, FileManager fileManager, Persona me) {
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.session = session
|
this.session = session
|
||||||
this.myVersion = myVersion
|
this.myVersion = myVersion
|
||||||
this.settings = settings
|
this.settings = settings
|
||||||
|
this.fileManager = fileManager
|
||||||
|
this.me = me
|
||||||
timer = new Timer("update-client",true)
|
timer = new Timer("update-client",true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +60,24 @@ class UpdateClient {
|
|||||||
timer.cancel()
|
timer.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onUIResultBatchEvent(UIResultBatchEvent results) {
|
||||||
|
if (results.results[0].infohash != updateInfoHash)
|
||||||
|
return
|
||||||
|
if (updateDownloading)
|
||||||
|
return
|
||||||
|
updateDownloading = true
|
||||||
|
def file = new File(settings.downloadLocation, results.results[0].name)
|
||||||
|
def downloadEvent = new UIDownloadEvent(result: results.results[0], sources : results.results[0].sources, target : file)
|
||||||
|
eventBus.publish(downloadEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
void onFileDownloadedEvent(FileDownloadedEvent e) {
|
||||||
|
if (e.downloadedFile.infoHash != updateInfoHash)
|
||||||
|
return
|
||||||
|
updateDownloading = false
|
||||||
|
eventBus.publish(new UpdateDownloadedEvent(version : version, signer : signer))
|
||||||
|
}
|
||||||
|
|
||||||
private void checkUpdate() {
|
private void checkUpdate() {
|
||||||
final long now = System.currentTimeMillis()
|
final long now = System.currentTimeMillis()
|
||||||
if (lastUpdateCheckTime > 0) {
|
if (lastUpdateCheckTime > 0) {
|
||||||
@@ -106,8 +141,25 @@ class UpdateClient {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("new version $payload.version available, publishing event")
|
if (!settings.autoDownloadUpdate) {
|
||||||
eventBus.publish(new UpdateAvailableEvent(version : payload.version, signer : payload.signer, infoHash : payload.infoHash))
|
log.info("new version $payload.version available, publishing event")
|
||||||
|
eventBus.publish(new UpdateAvailableEvent(version : payload.version, signer : payload.signer, infoHash : payload.infoHash))
|
||||||
|
} else {
|
||||||
|
log.info("new version $payload.version available")
|
||||||
|
updateInfoHash = new InfoHash(Base64.decode(payload.infoHash))
|
||||||
|
if (fileManager.rootToFiles.containsKey(updateInfoHash))
|
||||||
|
eventBus.publish(new UpdateDownloadedEvent(version : payload.version, signer : payload.signer))
|
||||||
|
else {
|
||||||
|
updateDownloading = false
|
||||||
|
version = payload.version
|
||||||
|
signer = payload.signer
|
||||||
|
log.info("starting search for new version hash $payload.infoHash")
|
||||||
|
def searchEvent = new SearchEvent(searchHash : updateInfoHash.getRoot(), uuid : UUID.randomUUID(), oobInfohash : true)
|
||||||
|
def queryEvent = new QueryEvent(searchEvent : searchEvent, firstHop : true, replyTo : me.destination,
|
||||||
|
receivedOn : me.destination, originator : me)
|
||||||
|
eventBus.publish(queryEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.log(Level.WARNING,"Invalid datagram",e)
|
log.log(Level.WARNING,"Invalid datagram",e)
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
package com.muwire.core.update
|
||||||
|
|
||||||
|
import com.muwire.core.Event
|
||||||
|
|
||||||
|
class UpdateDownloadedEvent extends Event {
|
||||||
|
String version
|
||||||
|
String signer
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
package com.muwire.core;
|
package com.muwire.core;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
@@ -9,7 +10,8 @@ public class DownloadedFile extends SharedFile {
|
|||||||
|
|
||||||
private final Set<Destination> sources;
|
private final Set<Destination> sources;
|
||||||
|
|
||||||
public DownloadedFile(File file, InfoHash infoHash, int pieceSize, Set<Destination> sources) {
|
public DownloadedFile(File file, InfoHash infoHash, int pieceSize, Set<Destination> sources)
|
||||||
|
throws IOException {
|
||||||
super(file, infoHash, pieceSize);
|
super(file, infoHash, pieceSize);
|
||||||
this.sources = sources;
|
this.sources = sources;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package com.muwire.core;
|
package com.muwire.core;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SharedFile {
|
public class SharedFile {
|
||||||
|
|
||||||
@@ -8,10 +9,15 @@ public class SharedFile {
|
|||||||
private final InfoHash infoHash;
|
private final InfoHash infoHash;
|
||||||
private final int pieceSize;
|
private final int pieceSize;
|
||||||
|
|
||||||
public SharedFile(File file, InfoHash infoHash, int pieceSize) {
|
private final String cachedPath;
|
||||||
|
private final long cachedLength;
|
||||||
|
|
||||||
|
public SharedFile(File file, InfoHash infoHash, int pieceSize) throws IOException {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.infoHash = infoHash;
|
this.infoHash = infoHash;
|
||||||
this.pieceSize = pieceSize;
|
this.pieceSize = pieceSize;
|
||||||
|
this.cachedPath = file.getAbsolutePath();
|
||||||
|
this.cachedLength = file.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
@@ -35,6 +41,14 @@ public class SharedFile {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCachedPath() {
|
||||||
|
return cachedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCachedLength() {
|
||||||
|
return cachedLength;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return file.hashCode() ^ infoHash.hashCode();
|
return file.hashCode() ^ infoHash.hashCode();
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
group = com.muwire
|
group = com.muwire
|
||||||
version = 0.4.0
|
version = 0.4.2
|
||||||
groovyVersion = 2.4.15
|
groovyVersion = 2.4.15
|
||||||
slf4jVersion = 1.7.25
|
slf4jVersion = 1.7.25
|
||||||
spockVersion = 1.1-groovy-2.4
|
spockVersion = 1.1-groovy-2.4
|
||||||
|
@@ -26,4 +26,14 @@ mvcGroups {
|
|||||||
view = 'com.muwire.gui.OptionsView'
|
view = 'com.muwire.gui.OptionsView'
|
||||||
controller = 'com.muwire.gui.OptionsController'
|
controller = 'com.muwire.gui.OptionsController'
|
||||||
}
|
}
|
||||||
|
"mu-wire-status" {
|
||||||
|
model = 'com.muwire.gui.MuWireStatusModel'
|
||||||
|
view = 'com.muwire.gui.MuWireStatusView'
|
||||||
|
controller = 'com.muwire.gui.MuWireStatusController'
|
||||||
|
}
|
||||||
|
'i-2-p-status' {
|
||||||
|
model = 'com.muwire.gui.I2PStatusModel'
|
||||||
|
view = 'com.muwire.gui.I2PStatusView'
|
||||||
|
controller = 'com.muwire.gui.I2PStatusController'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,40 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonController
|
||||||
|
import griffon.core.controller.ControllerAction
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
import net.i2p.router.Router
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonController)
|
||||||
|
class I2PStatusController {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
I2PStatusModel model
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
I2PStatusView view
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void refresh() {
|
||||||
|
Core core = application.context.get("core")
|
||||||
|
Router router = core.router
|
||||||
|
model.networkStatus = router._context.commSystem().status.toStatusString()
|
||||||
|
model.ntcpConnections = router._context.commSystem().getTransports()["NTCP"].countPeers()
|
||||||
|
model.ssuConnections = router._context.commSystem().getTransports()["SSU"].countPeers()
|
||||||
|
model.participatingTunnels = router._context.tunnelManager().getParticipatingCount()
|
||||||
|
model.activePeers = router._context.profileOrganizer().countActivePeers()
|
||||||
|
model.receiveBps = router._context.bandwidthLimiter().getReceiveBps15s()
|
||||||
|
model.sendBps = router._context.bandwidthLimiter().getSendBps15s()
|
||||||
|
model.participatingBW = router._context.bandwidthLimiter().getCurrentParticipatingBandwidth()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void close() {
|
||||||
|
view.dialog.setVisible(false)
|
||||||
|
mvcGroup.destroy()
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,7 @@ import com.muwire.core.download.UIDownloadCancelledEvent
|
|||||||
import com.muwire.core.download.UIDownloadEvent
|
import com.muwire.core.download.UIDownloadEvent
|
||||||
import com.muwire.core.download.UIDownloadPausedEvent
|
import com.muwire.core.download.UIDownloadPausedEvent
|
||||||
import com.muwire.core.download.UIDownloadResumedEvent
|
import com.muwire.core.download.UIDownloadResumedEvent
|
||||||
|
import com.muwire.core.files.DirectoryUnsharedEvent
|
||||||
import com.muwire.core.search.QueryEvent
|
import com.muwire.core.search.QueryEvent
|
||||||
import com.muwire.core.search.SearchEvent
|
import com.muwire.core.search.SearchEvent
|
||||||
import com.muwire.core.trust.TrustEvent
|
import com.muwire.core.trust.TrustEvent
|
||||||
@@ -209,6 +210,18 @@ class MainFrameController {
|
|||||||
println "unsharing selected files"
|
println "unsharing selected files"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopWatchingDirectory() {
|
||||||
|
String directory = mvcGroup.view.getSelectedWatchedDirectory()
|
||||||
|
if (directory == null)
|
||||||
|
return
|
||||||
|
core.muOptions.watchedDirectories.remove(directory)
|
||||||
|
saveMuWireSettings()
|
||||||
|
core.eventBus.publish(new DirectoryUnsharedEvent(directory : new File(directory)))
|
||||||
|
|
||||||
|
model.watched.remove(directory)
|
||||||
|
builder.getVariable("watched-directories-table").model.fireTableDataChanged()
|
||||||
|
}
|
||||||
|
|
||||||
void saveMuWireSettings() {
|
void saveMuWireSettings() {
|
||||||
File f = new File(core.home, "MuWire.properties")
|
File f = new File(core.home, "MuWire.properties")
|
||||||
f.withOutputStream {
|
f.withOutputStream {
|
||||||
|
@@ -0,0 +1,45 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonController
|
||||||
|
import griffon.core.controller.ControllerAction
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonController)
|
||||||
|
class MuWireStatusController {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
MuWireStatusModel model
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
MuWireStatusView view
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void refresh() {
|
||||||
|
Core core = application.context.get("core")
|
||||||
|
|
||||||
|
int incoming = 0
|
||||||
|
int outgoing = 0
|
||||||
|
core.connectionManager.getConnections().each {
|
||||||
|
if (it.incoming)
|
||||||
|
incoming++
|
||||||
|
else
|
||||||
|
outgoing++
|
||||||
|
}
|
||||||
|
model.incomingConnections = incoming
|
||||||
|
model.outgoingConnections = outgoing
|
||||||
|
|
||||||
|
model.knownHosts = core.hostCache.hosts.size()
|
||||||
|
|
||||||
|
model.sharedFiles = core.fileManager.fileToSharedFile.size()
|
||||||
|
|
||||||
|
model.downloads = core.downloadManager.downloaders.size()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ControllerAction
|
||||||
|
void close() {
|
||||||
|
view.dialog.setVisible(false)
|
||||||
|
mvcGroup.destroy()
|
||||||
|
}
|
||||||
|
}
|
@@ -4,10 +4,15 @@ import griffon.core.artifact.GriffonController
|
|||||||
import griffon.core.controller.ControllerAction
|
import griffon.core.controller.ControllerAction
|
||||||
import griffon.inject.MVCMember
|
import griffon.inject.MVCMember
|
||||||
import griffon.metadata.ArtifactProviderFor
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
import groovy.util.logging.Log
|
||||||
|
|
||||||
|
import java.util.logging.Level
|
||||||
|
|
||||||
import javax.annotation.Nonnull
|
import javax.annotation.Nonnull
|
||||||
import javax.swing.JFileChooser
|
import javax.swing.JFileChooser
|
||||||
|
|
||||||
import com.muwire.core.Core
|
import com.muwire.core.Core
|
||||||
|
import com.muwire.core.MuWireSettings
|
||||||
|
|
||||||
@ArtifactProviderFor(GriffonController)
|
@ArtifactProviderFor(GriffonController)
|
||||||
class OptionsController {
|
class OptionsController {
|
||||||
@@ -20,6 +25,7 @@ class OptionsController {
|
|||||||
void save() {
|
void save() {
|
||||||
String text
|
String text
|
||||||
Core core = application.context.get("core")
|
Core core = application.context.get("core")
|
||||||
|
MuWireSettings settings = application.context.get("muwire-settings")
|
||||||
|
|
||||||
def i2pProps = core.i2pOptions
|
def i2pProps = core.i2pOptions
|
||||||
|
|
||||||
@@ -39,6 +45,17 @@ class OptionsController {
|
|||||||
model.outboundLength = text
|
model.outboundLength = text
|
||||||
i2pProps["outbound.length"] = text
|
i2pProps["outbound.length"] = text
|
||||||
|
|
||||||
|
if (settings.embeddedRouter) {
|
||||||
|
text = view.i2pNTCPPortField.text
|
||||||
|
model.i2pNTCPPort = text
|
||||||
|
i2pProps["i2np.ntcp.port"] = text
|
||||||
|
|
||||||
|
text = view.i2pUDPPortField.text
|
||||||
|
model.i2pUDPPort = text
|
||||||
|
i2pProps["i2np.udp.port"] = text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
File i2pSettingsFile = new File(core.home, "i2p.properties")
|
File i2pSettingsFile = new File(core.home, "i2p.properties")
|
||||||
i2pSettingsFile.withOutputStream {
|
i2pSettingsFile.withOutputStream {
|
||||||
i2pProps.store(it,"")
|
i2pProps.store(it,"")
|
||||||
@@ -47,13 +64,16 @@ class OptionsController {
|
|||||||
text = view.retryField.text
|
text = view.retryField.text
|
||||||
model.downloadRetryInterval = text
|
model.downloadRetryInterval = text
|
||||||
|
|
||||||
def settings = application.context.get("muwire-settings")
|
|
||||||
settings.downloadRetryInterval = Integer.valueOf(text)
|
settings.downloadRetryInterval = Integer.valueOf(text)
|
||||||
|
|
||||||
text = view.updateField.text
|
text = view.updateField.text
|
||||||
model.updateCheckInterval = text
|
model.updateCheckInterval = text
|
||||||
settings.updateCheckInterval = Integer.valueOf(text)
|
settings.updateCheckInterval = Integer.valueOf(text)
|
||||||
|
|
||||||
|
boolean autoDownloadUpdate = view.autoDownloadUpdateCheckbox.model.isSelected()
|
||||||
|
model.autoDownloadUpdate = autoDownloadUpdate
|
||||||
|
settings.autoDownloadUpdate = autoDownloadUpdate
|
||||||
|
|
||||||
boolean onlyTrusted = view.allowUntrustedCheckbox.model.isSelected()
|
boolean onlyTrusted = view.allowUntrustedCheckbox.model.isSelected()
|
||||||
model.onlyTrusted = onlyTrusted
|
model.onlyTrusted = onlyTrusted
|
||||||
settings.setAllowUntrusted(!onlyTrusted)
|
settings.setAllowUntrusted(!onlyTrusted)
|
||||||
@@ -65,6 +85,15 @@ class OptionsController {
|
|||||||
String downloadLocation = model.downloadLocation
|
String downloadLocation = model.downloadLocation
|
||||||
settings.downloadLocation = new File(downloadLocation)
|
settings.downloadLocation = new File(downloadLocation)
|
||||||
|
|
||||||
|
if (settings.embeddedRouter) {
|
||||||
|
text = view.inBwField.text
|
||||||
|
model.inBw = text
|
||||||
|
settings.inBw = Integer.valueOf(text)
|
||||||
|
text = view.outBwField.text
|
||||||
|
model.outBw = text
|
||||||
|
settings.outBw = Integer.valueOf(text)
|
||||||
|
}
|
||||||
|
|
||||||
File settingsFile = new File(core.home, "MuWire.properties")
|
File settingsFile = new File(core.home, "MuWire.properties")
|
||||||
settingsFile.withOutputStream {
|
settingsFile.withOutputStream {
|
||||||
settings.write(it)
|
settings.write(it)
|
||||||
|
@@ -48,6 +48,7 @@ class Ready extends AbstractLifecycleHandler {
|
|||||||
} else {
|
} else {
|
||||||
log.info("creating new properties")
|
log.info("creating new properties")
|
||||||
props = new MuWireSettings()
|
props = new MuWireSettings()
|
||||||
|
props.embeddedRouter = Boolean.parseBoolean(System.getProperties().getProperty("embeddedRouter"))
|
||||||
def nickname
|
def nickname
|
||||||
while (true) {
|
while (true) {
|
||||||
nickname = JOptionPane.showInputDialog(null,
|
nickname = JOptionPane.showInputDialog(null,
|
||||||
|
27
gui/griffon-app/models/com/muwire/gui/I2PStatusModel.groovy
Normal file
27
gui/griffon-app/models/com/muwire/gui/I2PStatusModel.groovy
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonModel
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.transform.Observable
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonModel)
|
||||||
|
class I2PStatusModel {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
I2PStatusController controller
|
||||||
|
|
||||||
|
@Observable int ntcpConnections
|
||||||
|
@Observable int ssuConnections
|
||||||
|
@Observable String networkStatus
|
||||||
|
@Observable int participatingTunnels
|
||||||
|
@Observable int activePeers
|
||||||
|
@Observable int receiveBps
|
||||||
|
@Observable int sendBps
|
||||||
|
@Observable int participatingBW
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
controller.refresh()
|
||||||
|
}
|
||||||
|
}
|
@@ -29,6 +29,7 @@ import com.muwire.core.search.UIResultEvent
|
|||||||
import com.muwire.core.trust.TrustEvent
|
import com.muwire.core.trust.TrustEvent
|
||||||
import com.muwire.core.trust.TrustService
|
import com.muwire.core.trust.TrustService
|
||||||
import com.muwire.core.update.UpdateAvailableEvent
|
import com.muwire.core.update.UpdateAvailableEvent
|
||||||
|
import com.muwire.core.update.UpdateDownloadedEvent
|
||||||
import com.muwire.core.upload.UploadEvent
|
import com.muwire.core.upload.UploadEvent
|
||||||
import com.muwire.core.upload.UploadFinishedEvent
|
import com.muwire.core.upload.UploadFinishedEvent
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ class MainFrameModel {
|
|||||||
MainFrameController controller
|
MainFrameController controller
|
||||||
@Inject @Nonnull GriffonApplication application
|
@Inject @Nonnull GriffonApplication application
|
||||||
@Observable boolean coreInitialized = false
|
@Observable boolean coreInitialized = false
|
||||||
|
@Observable boolean routerPresent
|
||||||
|
|
||||||
def results = new ConcurrentHashMap<>()
|
def results = new ConcurrentHashMap<>()
|
||||||
def downloads = []
|
def downloads = []
|
||||||
@@ -76,7 +78,7 @@ class MainFrameModel {
|
|||||||
|
|
||||||
private final Set<InfoHash> downloadInfoHashes = new HashSet<>()
|
private final Set<InfoHash> downloadInfoHashes = new HashSet<>()
|
||||||
|
|
||||||
volatile Core core
|
@Observable volatile Core core
|
||||||
|
|
||||||
private long lastRetryTime = System.currentTimeMillis()
|
private long lastRetryTime = System.currentTimeMillis()
|
||||||
|
|
||||||
@@ -124,6 +126,7 @@ class MainFrameModel {
|
|||||||
application.addPropertyChangeListener("core", {e ->
|
application.addPropertyChangeListener("core", {e ->
|
||||||
coreInitialized = (e.getNewValue() != null)
|
coreInitialized = (e.getNewValue() != null)
|
||||||
core = e.getNewValue()
|
core = e.getNewValue()
|
||||||
|
routerPresent = core.router != null
|
||||||
me = core.me.getHumanReadableName()
|
me = core.me.getHumanReadableName()
|
||||||
core.eventBus.register(UIResultEvent.class, this)
|
core.eventBus.register(UIResultEvent.class, this)
|
||||||
core.eventBus.register(UIResultBatchEvent.class, this)
|
core.eventBus.register(UIResultBatchEvent.class, this)
|
||||||
@@ -141,6 +144,7 @@ class MainFrameModel {
|
|||||||
core.eventBus.register(FileUnsharedEvent.class, this)
|
core.eventBus.register(FileUnsharedEvent.class, this)
|
||||||
core.eventBus.register(RouterDisconnectedEvent.class, this)
|
core.eventBus.register(RouterDisconnectedEvent.class, this)
|
||||||
core.eventBus.register(AllFilesLoadedEvent.class, this)
|
core.eventBus.register(AllFilesLoadedEvent.class, this)
|
||||||
|
core.eventBus.register(UpdateDownloadedEvent.class, this)
|
||||||
|
|
||||||
timer.schedule({
|
timer.schedule({
|
||||||
if (core.shutdown.get())
|
if (core.shutdown.get())
|
||||||
@@ -183,6 +187,14 @@ class MainFrameModel {
|
|||||||
watched.each { core.eventBus.publish(new FileSharedEvent(file : new File(it))) }
|
watched.each { core.eventBus.publish(new FileSharedEvent(file : new File(it))) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onUpdateDownloadedEvent(UpdateDownloadedEvent e) {
|
||||||
|
runInsideUIAsync {
|
||||||
|
JOptionPane.showMessageDialog(null, "MuWire $e.version has been downloaded. You can update now",
|
||||||
|
"Update Downloaded", JOptionPane.INFORMATION_MESSAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onUIResultEvent(UIResultEvent e) {
|
void onUIResultEvent(UIResultEvent e) {
|
||||||
MVCGroup resultsGroup = results.get(e.uuid)
|
MVCGroup resultsGroup = results.get(e.uuid)
|
||||||
resultsGroup?.model.handleResult(e)
|
resultsGroup?.model.handleResult(e)
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonModel
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.transform.Observable
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonModel)
|
||||||
|
class MuWireStatusModel {
|
||||||
|
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
MuWireStatusController controller
|
||||||
|
|
||||||
|
@Observable int incomingConnections
|
||||||
|
@Observable int outgoingConnections
|
||||||
|
@Observable int knownHosts
|
||||||
|
@Observable int sharedFiles
|
||||||
|
@Observable int downloads
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
controller.refresh()
|
||||||
|
}
|
||||||
|
}
|
@@ -11,6 +11,7 @@ import griffon.metadata.ArtifactProviderFor
|
|||||||
class OptionsModel {
|
class OptionsModel {
|
||||||
@Observable String downloadRetryInterval
|
@Observable String downloadRetryInterval
|
||||||
@Observable String updateCheckInterval
|
@Observable String updateCheckInterval
|
||||||
|
@Observable boolean autoDownloadUpdate
|
||||||
@Observable boolean onlyTrusted
|
@Observable boolean onlyTrusted
|
||||||
@Observable boolean shareDownloadedFiles
|
@Observable boolean shareDownloadedFiles
|
||||||
@Observable String downloadLocation
|
@Observable String downloadLocation
|
||||||
@@ -20,6 +21,8 @@ class OptionsModel {
|
|||||||
@Observable String inboundQuantity
|
@Observable String inboundQuantity
|
||||||
@Observable String outboundLength
|
@Observable String outboundLength
|
||||||
@Observable String outboundQuantity
|
@Observable String outboundQuantity
|
||||||
|
@Observable String i2pUDPPort
|
||||||
|
@Observable String i2pNTCPPort
|
||||||
|
|
||||||
// gui options
|
// gui options
|
||||||
@Observable boolean showMonitor
|
@Observable boolean showMonitor
|
||||||
@@ -30,10 +33,15 @@ class OptionsModel {
|
|||||||
@Observable boolean excludeLocalResult
|
@Observable boolean excludeLocalResult
|
||||||
@Observable boolean showSearchHashes
|
@Observable boolean showSearchHashes
|
||||||
|
|
||||||
|
// bw options
|
||||||
|
@Observable String inBw
|
||||||
|
@Observable String outBw
|
||||||
|
|
||||||
void mvcGroupInit(Map<String, String> args) {
|
void mvcGroupInit(Map<String, String> args) {
|
||||||
MuWireSettings settings = application.context.get("muwire-settings")
|
MuWireSettings settings = application.context.get("muwire-settings")
|
||||||
downloadRetryInterval = settings.downloadRetryInterval
|
downloadRetryInterval = settings.downloadRetryInterval
|
||||||
updateCheckInterval = settings.updateCheckInterval
|
updateCheckInterval = settings.updateCheckInterval
|
||||||
|
autoDownloadUpdate = settings.autoDownloadUpdate
|
||||||
onlyTrusted = !settings.allowUntrusted()
|
onlyTrusted = !settings.allowUntrusted()
|
||||||
shareDownloadedFiles = settings.shareDownloadedFiles
|
shareDownloadedFiles = settings.shareDownloadedFiles
|
||||||
downloadLocation = settings.downloadLocation.getAbsolutePath()
|
downloadLocation = settings.downloadLocation.getAbsolutePath()
|
||||||
@@ -43,6 +51,8 @@ class OptionsModel {
|
|||||||
inboundQuantity = core.i2pOptions["inbound.quantity"]
|
inboundQuantity = core.i2pOptions["inbound.quantity"]
|
||||||
outboundLength = core.i2pOptions["outbound.length"]
|
outboundLength = core.i2pOptions["outbound.length"]
|
||||||
outboundQuantity = core.i2pOptions["outbound.quantity"]
|
outboundQuantity = core.i2pOptions["outbound.quantity"]
|
||||||
|
i2pUDPPort = core.i2pOptions["i2np.udp.port"]
|
||||||
|
i2pNTCPPort = core.i2pOptions["i2np.ntcp.port"]
|
||||||
|
|
||||||
UISettings uiSettings = application.context.get("ui-settings")
|
UISettings uiSettings = application.context.get("ui-settings")
|
||||||
showMonitor = uiSettings.showMonitor
|
showMonitor = uiSettings.showMonitor
|
||||||
@@ -52,5 +62,10 @@ class OptionsModel {
|
|||||||
clearFinishedDownloads = uiSettings.clearFinishedDownloads
|
clearFinishedDownloads = uiSettings.clearFinishedDownloads
|
||||||
excludeLocalResult = uiSettings.excludeLocalResult
|
excludeLocalResult = uiSettings.excludeLocalResult
|
||||||
showSearchHashes = uiSettings.showSearchHashes
|
showSearchHashes = uiSettings.showSearchHashes
|
||||||
|
|
||||||
|
if (core.router != null) {
|
||||||
|
inBw = String.valueOf(settings.inBw)
|
||||||
|
outBw = String.valueOf(settings.outBw)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
78
gui/griffon-app/views/com/muwire/gui/I2PStatusView.groovy
Normal file
78
gui/griffon-app/views/com/muwire/gui/I2PStatusView.groovy
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonView
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
import javax.swing.JDialog
|
||||||
|
import javax.swing.JPanel
|
||||||
|
import javax.swing.SwingConstants
|
||||||
|
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.event.WindowAdapter
|
||||||
|
import java.awt.event.WindowEvent
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonView)
|
||||||
|
class I2PStatusView {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
FactoryBuilderSupport builder
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
I2PStatusModel model
|
||||||
|
|
||||||
|
def mainFrame
|
||||||
|
def dialog
|
||||||
|
def panel
|
||||||
|
def buttonsPanel
|
||||||
|
|
||||||
|
void initUI() {
|
||||||
|
mainFrame = application.windowManager.findWindow("main-frame")
|
||||||
|
|
||||||
|
dialog = new JDialog(mainFrame, "I2P Status", true)
|
||||||
|
|
||||||
|
panel = builder.panel {
|
||||||
|
gridBagLayout()
|
||||||
|
label(text : "Network status", constraints : gbc(gridx:0, gridy:0))
|
||||||
|
label(text : bind {model.networkStatus}, constraints : gbc(gridx: 1, gridy:0))
|
||||||
|
label(text : "NTCP Connections", constraints : gbc(gridx:0, gridy:1))
|
||||||
|
label(text : bind {model.ntcpConnections}, constraints : gbc(gridx: 1, gridy:1))
|
||||||
|
label(text : "SSU Connections", constraints : gbc(gridx:0, gridy:2))
|
||||||
|
label(text : bind {model.ssuConnections}, constraints : gbc(gridx: 1, gridy:2))
|
||||||
|
label(text : "Participating Tunnels", constraints : gbc(gridx:0, gridy:3))
|
||||||
|
label(text : bind {model.participatingTunnels}, constraints : gbc(gridx: 1, gridy:3))
|
||||||
|
label(text : "Participating Bandwidth", constraints : gbc(gridx:0, gridy:4))
|
||||||
|
label(text : bind {model.participatingBW}, constraints : gbc(gridx: 1, gridy:4))
|
||||||
|
label(text : "Active Peers", constraints : gbc(gridx:0, gridy:5))
|
||||||
|
label(text : bind {model.activePeers}, constraints : gbc(gridx: 1, gridy:5))
|
||||||
|
label(text : "Receive Bps (15 seconds)", constraints : gbc(gridx:0, gridy:6))
|
||||||
|
label(text : bind {model.receiveBps}, constraints : gbc(gridx: 1, gridy:6))
|
||||||
|
label(text : "Send Bps (15 seconds)", constraints : gbc(gridx:0, gridy:7))
|
||||||
|
label(text : bind {model.sendBps}, constraints : gbc(gridx: 1, gridy:7))
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonsPanel = builder.panel {
|
||||||
|
gridBagLayout()
|
||||||
|
button(text : "Refresh", constraints: gbc(gridx: 0, gridy: 0), refreshAction)
|
||||||
|
button(text : "Close", constraints : gbc(gridx : 1, gridy :0), closeAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
JPanel statusPanel = new JPanel()
|
||||||
|
statusPanel.setLayout(new BorderLayout())
|
||||||
|
statusPanel.add(panel, BorderLayout.CENTER)
|
||||||
|
statusPanel.add(buttonsPanel, BorderLayout.SOUTH)
|
||||||
|
|
||||||
|
dialog.getContentPane().add(statusPanel)
|
||||||
|
dialog.pack()
|
||||||
|
dialog.setLocationRelativeTo(mainFrame)
|
||||||
|
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
|
||||||
|
dialog.addWindowListener(new WindowAdapter() {
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
mvcGroup.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
}
|
@@ -22,6 +22,7 @@ import javax.swing.border.Border
|
|||||||
import javax.swing.table.DefaultTableCellRenderer
|
import javax.swing.table.DefaultTableCellRenderer
|
||||||
|
|
||||||
import com.muwire.core.Constants
|
import com.muwire.core.Constants
|
||||||
|
import com.muwire.core.MuWireSettings
|
||||||
import com.muwire.core.download.Downloader
|
import com.muwire.core.download.Downloader
|
||||||
import com.muwire.core.files.FileSharedEvent
|
import com.muwire.core.files.FileSharedEvent
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ class MainFrameView {
|
|||||||
def downloadsTable
|
def downloadsTable
|
||||||
def lastDownloadSortEvent
|
def lastDownloadSortEvent
|
||||||
def lastSharedSortEvent
|
def lastSharedSortEvent
|
||||||
|
def lastWatchedSortEvent
|
||||||
|
|
||||||
void initUI() {
|
void initUI() {
|
||||||
UISettings settings = application.context.get("ui-settings")
|
UISettings settings = application.context.get("ui-settings")
|
||||||
@@ -70,6 +72,11 @@ class MainFrameView {
|
|||||||
menu (text : "Options") {
|
menu (text : "Options") {
|
||||||
menuItem("Configuration", actionPerformed : {mvcGroup.createMVCGroup("Options")})
|
menuItem("Configuration", actionPerformed : {mvcGroup.createMVCGroup("Options")})
|
||||||
}
|
}
|
||||||
|
menu (text : "Status") {
|
||||||
|
menuItem("MuWire", actionPerformed : {mvcGroup.createMVCGroup("mu-wire-status")})
|
||||||
|
MuWireSettings muSettings = application.context.get("muwire-settings")
|
||||||
|
menuItem("I2P", enabled : bind {model.routerPresent}, actionPerformed: {mvcGroup.createMVCGroup("i-2-p-status")})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
borderLayout()
|
borderLayout()
|
||||||
panel (border: etchedBorder(), constraints : BorderLayout.NORTH) {
|
panel (border: etchedBorder(), constraints : BorderLayout.NORTH) {
|
||||||
@@ -167,8 +174,8 @@ class MainFrameView {
|
|||||||
scrollPane(constraints : BorderLayout.CENTER) {
|
scrollPane(constraints : BorderLayout.CENTER) {
|
||||||
table(id : "shared-files-table", autoCreateRowSorter: true) {
|
table(id : "shared-files-table", autoCreateRowSorter: true) {
|
||||||
tableModel(list : model.shared) {
|
tableModel(list : model.shared) {
|
||||||
closureColumn(header : "Name", preferredWidth : 500, type : String, read : {row -> row.file.getAbsolutePath()})
|
closureColumn(header : "Name", preferredWidth : 500, type : String, read : {row -> row.getCachedPath()})
|
||||||
closureColumn(header : "Size", preferredWidth : 100, type : Long, read : {row -> row.file.length() })
|
closureColumn(header : "Size", preferredWidth : 100, type : Long, read : {row -> row.getCachedLength() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,6 +404,27 @@ class MainFrameView {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// watched directories table
|
||||||
|
def watchedTable = builder.getVariable("watched-directories-table")
|
||||||
|
watchedTable.rowSorter.addRowSorterListener({evt -> lastWatchedSortEvent = evt})
|
||||||
|
watchedTable.rowSorter.setSortsOnUpdates(true)
|
||||||
|
JPopupMenu watchedMenu = new JPopupMenu()
|
||||||
|
JMenuItem stopWatching = new JMenuItem("Stop sharing")
|
||||||
|
stopWatching.addActionListener({mvcGroup.controller.stopWatchingDirectory()})
|
||||||
|
watchedMenu.add(stopWatching)
|
||||||
|
watchedTable.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
if (e.isPopupTrigger())
|
||||||
|
showPopupMenu(watchedMenu, e)
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (e.isPopupTrigger())
|
||||||
|
showPopupMenu(watchedMenu, e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showPopupMenu(JPopupMenu menu, MouseEvent event) {
|
private static void showPopupMenu(JPopupMenu menu, MouseEvent event) {
|
||||||
@@ -543,4 +571,14 @@ class MainFrameView {
|
|||||||
model.core.eventBus.publish(new FileSharedEvent(file : f))
|
model.core.eventBus.publish(new FileSharedEvent(file : f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getSelectedWatchedDirectory() {
|
||||||
|
def watchedTable = builder.getVariable("watched-directories-table")
|
||||||
|
int selectedRow = watchedTable.getSelectedRow()
|
||||||
|
if (selectedRow < 0)
|
||||||
|
return null
|
||||||
|
if (lastWatchedSortEvent != null)
|
||||||
|
selectedRow = watchedTable.rowSorter.convertRowIndexToModel(selectedRow)
|
||||||
|
model.watched[selectedRow]
|
||||||
|
}
|
||||||
}
|
}
|
73
gui/griffon-app/views/com/muwire/gui/MuWireStatusView.groovy
Normal file
73
gui/griffon-app/views/com/muwire/gui/MuWireStatusView.groovy
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.artifact.GriffonView
|
||||||
|
import griffon.inject.MVCMember
|
||||||
|
import griffon.metadata.ArtifactProviderFor
|
||||||
|
|
||||||
|
import javax.swing.JDialog
|
||||||
|
import javax.swing.JPanel
|
||||||
|
import javax.swing.SwingConstants
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.event.WindowAdapter
|
||||||
|
import java.awt.event.WindowEvent
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull
|
||||||
|
|
||||||
|
@ArtifactProviderFor(GriffonView)
|
||||||
|
class MuWireStatusView {
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
FactoryBuilderSupport builder
|
||||||
|
@MVCMember @Nonnull
|
||||||
|
MuWireStatusModel model
|
||||||
|
|
||||||
|
def mainFrame
|
||||||
|
def dialog
|
||||||
|
def panel
|
||||||
|
def buttonsPanel
|
||||||
|
|
||||||
|
void initUI() {
|
||||||
|
mainFrame = application.windowManager.findWindow("main-frame")
|
||||||
|
|
||||||
|
dialog = new JDialog(mainFrame, "MuWire Status", true)
|
||||||
|
|
||||||
|
panel = builder.panel {
|
||||||
|
gridBagLayout()
|
||||||
|
label(text : "Incoming connections", constraints : gbc(gridx:0, gridy:0))
|
||||||
|
label(text : bind {model.incomingConnections}, constraints : gbc(gridx:1, gridy:0))
|
||||||
|
label(text : "Outgoing connections", constraints : gbc(gridx:0, gridy:1))
|
||||||
|
label(text : bind {model.outgoingConnections}, constraints : gbc(gridx:1, gridy:1))
|
||||||
|
label(text : "Known hosts", constraints : gbc(gridx:0, gridy:2))
|
||||||
|
label(text : bind {model.knownHosts}, constraints : gbc(gridx:1, gridy:2))
|
||||||
|
label(text : "Shared files", constraints : gbc(gridx:0, gridy:3))
|
||||||
|
label(text : bind {model.sharedFiles}, constraints : gbc(gridx:1, gridy:3))
|
||||||
|
label(text : "Downloads", constraints : gbc(gridx:0, gridy:4))
|
||||||
|
label(text : bind {model.downloads}, constraints : gbc(gridx:1, gridy:4))
|
||||||
|
}
|
||||||
|
buttonsPanel = builder.panel {
|
||||||
|
gridBagLayout()
|
||||||
|
button(text : "Refresh", constraints: gbc(gridx: 0, gridy: 0), refreshAction)
|
||||||
|
button(text : "Close", constraints : gbc(gridx : 1, gridy :0), closeAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mvcGroupInit(Map<String,String> args) {
|
||||||
|
JPanel statusPanel = new JPanel()
|
||||||
|
statusPanel.setLayout(new BorderLayout())
|
||||||
|
statusPanel.add(panel, BorderLayout.CENTER)
|
||||||
|
statusPanel.add(buttonsPanel, BorderLayout.SOUTH)
|
||||||
|
|
||||||
|
dialog.getContentPane().add(statusPanel)
|
||||||
|
dialog.pack()
|
||||||
|
dialog.setLocationRelativeTo(mainFrame)
|
||||||
|
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
|
||||||
|
dialog.addWindowListener(new WindowAdapter() {
|
||||||
|
public void windowClosed(WindowEvent e) {
|
||||||
|
mvcGroup.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
}
|
@@ -9,6 +9,8 @@ import javax.swing.JPanel
|
|||||||
import javax.swing.JTabbedPane
|
import javax.swing.JTabbedPane
|
||||||
import javax.swing.SwingConstants
|
import javax.swing.SwingConstants
|
||||||
|
|
||||||
|
import com.muwire.core.Core
|
||||||
|
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.event.WindowAdapter
|
import java.awt.event.WindowAdapter
|
||||||
import java.awt.event.WindowEvent
|
import java.awt.event.WindowEvent
|
||||||
@@ -26,9 +28,11 @@ class OptionsView {
|
|||||||
def p
|
def p
|
||||||
def i
|
def i
|
||||||
def u
|
def u
|
||||||
|
def bandwidth
|
||||||
|
|
||||||
def retryField
|
def retryField
|
||||||
def updateField
|
def updateField
|
||||||
|
def autoDownloadUpdateCheckbox
|
||||||
def allowUntrustedCheckbox
|
def allowUntrustedCheckbox
|
||||||
def shareDownloadedCheckbox
|
def shareDownloadedCheckbox
|
||||||
|
|
||||||
@@ -36,6 +40,8 @@ class OptionsView {
|
|||||||
def inboundQuantityField
|
def inboundQuantityField
|
||||||
def outboundLengthField
|
def outboundLengthField
|
||||||
def outboundQuantityField
|
def outboundQuantityField
|
||||||
|
def i2pUDPPortField
|
||||||
|
def i2pNTCPPortField
|
||||||
|
|
||||||
def lnfField
|
def lnfField
|
||||||
def monitorCheckbox
|
def monitorCheckbox
|
||||||
@@ -45,6 +51,10 @@ class OptionsView {
|
|||||||
def excludeLocalResultCheckbox
|
def excludeLocalResultCheckbox
|
||||||
def showSearchHashesCheckbox
|
def showSearchHashesCheckbox
|
||||||
|
|
||||||
|
|
||||||
|
def inBwField
|
||||||
|
def outBwField
|
||||||
|
|
||||||
def buttonsPanel
|
def buttonsPanel
|
||||||
|
|
||||||
def mainFrame
|
def mainFrame
|
||||||
@@ -63,15 +73,18 @@ class OptionsView {
|
|||||||
updateField = textField(text : bind {model.updateCheckInterval }, columns : 2, constraints : gbc(gridx : 1, gridy: 1))
|
updateField = textField(text : bind {model.updateCheckInterval }, columns : 2, constraints : gbc(gridx : 1, gridy: 1))
|
||||||
label(text : "hours", constraints : gbc(gridx: 2, gridy : 1))
|
label(text : "hours", constraints : gbc(gridx: 2, gridy : 1))
|
||||||
|
|
||||||
label(text : "Allow only trusted connections", constraints : gbc(gridx: 0, gridy : 2))
|
label(text : "Download updates automatically", constraints: gbc(gridx :0, gridy : 2))
|
||||||
allowUntrustedCheckbox = checkBox(selected : bind {model.onlyTrusted}, constraints : gbc(gridx: 1, gridy : 2))
|
autoDownloadUpdateCheckbox = checkBox(selected : bind {model.autoDownloadUpdate}, constraints : gbc(gridx:1, gridy : 2))
|
||||||
|
|
||||||
label(text : "Share downloaded files", constraints : gbc(gridx : 0, gridy:3))
|
label(text : "Allow only trusted connections", constraints : gbc(gridx: 0, gridy : 3))
|
||||||
shareDownloadedCheckbox = checkBox(selected : bind {model.shareDownloadedFiles}, constraints : gbc(gridx :1, gridy:3))
|
allowUntrustedCheckbox = checkBox(selected : bind {model.onlyTrusted}, constraints : gbc(gridx: 1, gridy : 3))
|
||||||
|
|
||||||
label(text : "Save downloaded files to:", constraints: gbc(gridx:0, gridy:4))
|
label(text : "Share downloaded files", constraints : gbc(gridx : 0, gridy:4))
|
||||||
button(text : "Choose", constraints : gbc(gridx : 1, gridy:4), downloadLocationAction)
|
shareDownloadedCheckbox = checkBox(selected : bind {model.shareDownloadedFiles}, constraints : gbc(gridx :1, gridy:4))
|
||||||
label(text : bind {model.downloadLocation}, constraints: gbc(gridx:0, gridy:5, gridwidth:2))
|
|
||||||
|
label(text : "Save downloaded files to:", constraints: gbc(gridx:0, gridy:5))
|
||||||
|
button(text : "Choose", constraints : gbc(gridx : 1, gridy:5), downloadLocationAction)
|
||||||
|
label(text : bind {model.downloadLocation}, constraints: gbc(gridx:0, gridy:6, gridwidth:2))
|
||||||
|
|
||||||
}
|
}
|
||||||
i = builder.panel {
|
i = builder.panel {
|
||||||
@@ -85,6 +98,15 @@ class OptionsView {
|
|||||||
outboundLengthField = textField(text : bind {model.outboundLength}, columns : 2, constraints : gbc(gridx:1, gridy:3))
|
outboundLengthField = textField(text : bind {model.outboundLength}, columns : 2, constraints : gbc(gridx:1, gridy:3))
|
||||||
label(text : "Outbound Quantity", constraints : gbc(gridx:0, gridy:4))
|
label(text : "Outbound Quantity", constraints : gbc(gridx:0, gridy:4))
|
||||||
outboundQuantityField = textField(text : bind {model.outboundQuantity}, columns : 2, constraints : gbc(gridx:1, gridy:4))
|
outboundQuantityField = textField(text : bind {model.outboundQuantity}, columns : 2, constraints : gbc(gridx:1, gridy:4))
|
||||||
|
|
||||||
|
Core core = application.context.get("core")
|
||||||
|
if (core.router != null) {
|
||||||
|
label(text : "TCP Port", constraints : gbc(gridx :0, gridy: 5))
|
||||||
|
i2pNTCPPortField = textField(text : bind {model.i2pNTCPPort}, columns : 4, constraints : gbc(gridx:1, gridy:5))
|
||||||
|
label(text : "UDP Port", constraints : gbc(gridx :0, gridy: 6))
|
||||||
|
i2pUDPPortField = textField(text : bind {model.i2pUDPPort}, columns : 4, constraints : gbc(gridx:1, gridy:6))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
u = builder.panel {
|
u = builder.panel {
|
||||||
gridBagLayout()
|
gridBagLayout()
|
||||||
@@ -104,6 +126,16 @@ class OptionsView {
|
|||||||
// label(text : "Show Hash Searches In Monitor", constraints: gbc(gridx:0, gridy:7))
|
// label(text : "Show Hash Searches In Monitor", constraints: gbc(gridx:0, gridy:7))
|
||||||
// showSearchHashesCheckbox = checkBox(selected : bind {model.showSearchHashes}, constraints : gbc(gridx: 1, gridy: 7))
|
// showSearchHashesCheckbox = checkBox(selected : bind {model.showSearchHashes}, constraints : gbc(gridx: 1, gridy: 7))
|
||||||
}
|
}
|
||||||
|
bandwidth = builder.panel {
|
||||||
|
gridBagLayout()
|
||||||
|
label(text : "Changing these settings requires a restart", constraints : gbc(gridx : 0, gridy : 0, gridwidth: 2))
|
||||||
|
label(text : "Inbound bandwidth (KB)", constraints : gbc(gridx: 0, gridy : 1))
|
||||||
|
inBwField = textField(text : bind {model.inBw}, columns : 3, constraints : gbc(gridx : 1, gridy : 1))
|
||||||
|
label(text : "Outbound bandwidth (KB)", constraints : gbc(gridx: 0, gridy : 2))
|
||||||
|
outBwField = textField(text : bind {model.outBw}, columns : 3, constraints : gbc(gridx : 1, gridy : 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
buttonsPanel = builder.panel {
|
buttonsPanel = builder.panel {
|
||||||
gridBagLayout()
|
gridBagLayout()
|
||||||
button(text : "Save", constraints : gbc(gridx : 1, gridy: 2), saveAction)
|
button(text : "Save", constraints : gbc(gridx : 1, gridy: 2), saveAction)
|
||||||
@@ -116,6 +148,10 @@ class OptionsView {
|
|||||||
tabbedPane.addTab("MuWire", p)
|
tabbedPane.addTab("MuWire", p)
|
||||||
tabbedPane.addTab("I2P", i)
|
tabbedPane.addTab("I2P", i)
|
||||||
tabbedPane.addTab("GUI", u)
|
tabbedPane.addTab("GUI", u)
|
||||||
|
Core core = application.context.get("core")
|
||||||
|
if (core.router != null) {
|
||||||
|
tabbedPane.addTab("Bandwidth", bandwidth)
|
||||||
|
}
|
||||||
|
|
||||||
JPanel panel = new JPanel()
|
JPanel panel = new JPanel()
|
||||||
panel.setLayout(new BorderLayout())
|
panel.setLayout(new BorderLayout())
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonFestRule
|
||||||
|
import org.fest.swing.fixture.FrameFixture
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
class I2PStatusIntegrationTest {
|
||||||
|
static {
|
||||||
|
System.setProperty('griffon.swing.edt.violations.check', 'true')
|
||||||
|
System.setProperty('griffon.swing.edt.hang.monitor', 'true')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonFestRule fest = new GriffonFestRule()
|
||||||
|
|
||||||
|
private FrameFixture window
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not implemented yet!')
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonFestRule
|
||||||
|
import org.fest.swing.fixture.FrameFixture
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
class MuWireStatusIntegrationTest {
|
||||||
|
static {
|
||||||
|
System.setProperty('griffon.swing.edt.violations.check', 'true')
|
||||||
|
System.setProperty('griffon.swing.edt.hang.monitor', 'true')
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonFestRule fest = new GriffonFestRule()
|
||||||
|
|
||||||
|
private FrameFixture window
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not implemented yet!')
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonUnitRule
|
||||||
|
import griffon.core.test.TestFor
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
@TestFor(I2PStatusController)
|
||||||
|
class I2PStatusControllerTest {
|
||||||
|
private I2PStatusController controller
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonUnitRule griffon = new GriffonUnitRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not yet implemented!')
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
import griffon.core.test.GriffonUnitRule
|
||||||
|
import griffon.core.test.TestFor
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail
|
||||||
|
|
||||||
|
@TestFor(MuWireStatusController)
|
||||||
|
class MuWireStatusControllerTest {
|
||||||
|
private MuWireStatusController controller
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final GriffonUnitRule griffon = new GriffonUnitRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void smokeTest() {
|
||||||
|
fail('Not yet implemented!')
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user