Compare commits
22 Commits
download-m
...
download-m
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3b23dc29c4 | ||
![]() |
c0645b670e | ||
![]() |
30613fe530 | ||
![]() |
e7822f6edc | ||
![]() |
7e5c9ba115 | ||
![]() |
647fa3a481 | ||
![]() |
538eca9297 | ||
![]() |
e73a23d4a4 | ||
![]() |
76e41a0383 | ||
![]() |
7045927666 | ||
![]() |
5fb3086b42 | ||
![]() |
2de18227c1 | ||
![]() |
bd12a1de3d | ||
![]() |
a3a91050c8 | ||
![]() |
6c1cc28e49 | ||
![]() |
b6e5b54f05 | ||
![]() |
a6e559ec67 | ||
![]() |
f11badb824 | ||
![]() |
44da44ff6f | ||
![]() |
aae3fc29ca | ||
![]() |
c30aa19d8b | ||
![]() |
8923c6ff7d |
13
README.md
13
README.md
@@ -37,8 +37,8 @@ The first time you run MuWire it will ask you to select a nickname. This nickna
|
||||
* why is MuWire slow ?
|
||||
|
||||
- too few sources you're downloading from
|
||||
- you can increse the number of tunnels by using more tunnels via Options->I2P Inbound/Outbound Quantity
|
||||
the default is 4 and you could raise it and even can go up as high as 16 ( Caution !!!!)
|
||||
- you can increase the number of tunnels by using more tunnels via Options->I2P Inbound/Outbound Quantity
|
||||
the default is 4 and you could raise up to as high as 16 ( Caution !!!!)
|
||||
|
||||
* my search is not returning (enough) results !
|
||||
|
||||
@@ -46,4 +46,11 @@ The first time you run MuWire it will ask you to select a nickname. This nickna
|
||||
- keywords and hash(es) are NOT regexed or wildcarded so they have to be complete
|
||||
so searching for 'musi' will not return results with 'music' - you have to search for 'music'
|
||||
- ALL keywords have to match
|
||||
- only use <SPACE> for keyword separation
|
||||
- only use space for keyword separation
|
||||
- if you already have the file in question it is not displayed ( can be changed via Options )
|
||||
|
||||
* what's this right click -> 'Copy hash to clipboard' for ?
|
||||
|
||||
- if you have a specific file you wish to share or download you can use the hash as a unique identifier
|
||||
to make sure you have exactly the right file.
|
||||
- you can share this hash with others to ensure they are getting the right file
|
||||
|
5
TODO.md
5
TODO.md
@@ -4,10 +4,6 @@ Not in any particular order yet
|
||||
|
||||
### Big Items
|
||||
|
||||
##### Alternate Locations
|
||||
|
||||
This helps peers discover new sources for a file while the download is in progress. Also makes sharing of partial files possible.
|
||||
|
||||
##### Bloom Filters
|
||||
|
||||
This reduces query traffic by not sending last hop queries to peers that definitely do not have the file
|
||||
@@ -38,7 +34,6 @@ To enable parsing of metadata from known file types and the user editing it or a
|
||||
|
||||
### Small Items
|
||||
|
||||
* Detect if router is dead and show warning or exit
|
||||
* Wrapper of some kind for in-place upgrades
|
||||
* Download file sequentially
|
||||
* Unsharing of files
|
||||
|
@@ -35,7 +35,7 @@ class Cli {
|
||||
|
||||
Core core
|
||||
try {
|
||||
core = new Core(props, home, "0.3.4")
|
||||
core = new Core(props, home, "0.3.6")
|
||||
} catch (Exception bad) {
|
||||
bad.printStackTrace(System.out)
|
||||
println "Failed to initialize core, exiting"
|
||||
|
@@ -53,7 +53,7 @@ class CliDownloader {
|
||||
|
||||
Core core
|
||||
try {
|
||||
core = new Core(props, home, "0.3.4")
|
||||
core = new Core(props, home, "0.3.6")
|
||||
} catch (Exception bad) {
|
||||
bad.printStackTrace(System.out)
|
||||
println "Failed to initialize core, exiting"
|
||||
|
@@ -16,6 +16,8 @@ import com.muwire.core.download.DownloadManager
|
||||
import com.muwire.core.download.SourceDiscoveredEvent
|
||||
import com.muwire.core.download.UIDownloadCancelledEvent
|
||||
import com.muwire.core.download.UIDownloadEvent
|
||||
import com.muwire.core.download.UIDownloadPausedEvent
|
||||
import com.muwire.core.download.UIDownloadResumedEvent
|
||||
import com.muwire.core.files.FileDownloadedEvent
|
||||
import com.muwire.core.files.FileHashedEvent
|
||||
import com.muwire.core.files.FileHasher
|
||||
@@ -48,6 +50,7 @@ import net.i2p.client.I2PSession
|
||||
import net.i2p.client.streaming.I2PSocketManager
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory
|
||||
import net.i2p.client.streaming.I2PSocketOptions
|
||||
import net.i2p.client.streaming.I2PSocketManager.DisconnectListener
|
||||
import net.i2p.crypto.DSAEngine
|
||||
import net.i2p.crypto.SigType
|
||||
import net.i2p.data.Destination
|
||||
@@ -124,6 +127,7 @@ public class Core {
|
||||
}
|
||||
socketManager.getDefaultOptions().setReadTimeout(60000)
|
||||
socketManager.getDefaultOptions().setConnectTimeout(30000)
|
||||
socketManager.addDisconnectListener({eventBus.publish(new RouterDisconnectedEvent())} as DisconnectListener)
|
||||
i2pSession = socketManager.getSession()
|
||||
|
||||
def destination = new Destination()
|
||||
@@ -169,7 +173,7 @@ public class Core {
|
||||
eventBus.register(SearchEvent.class, fileManager)
|
||||
|
||||
log.info("initializing mesh manager")
|
||||
MeshManager meshManager = new MeshManager(fileManager)
|
||||
MeshManager meshManager = new MeshManager(fileManager, home)
|
||||
eventBus.register(SourceDiscoveredEvent.class, meshManager)
|
||||
|
||||
log.info "initializing persistence service"
|
||||
@@ -215,7 +219,9 @@ public class Core {
|
||||
eventBus.register(FileDownloadedEvent.class, downloadManager)
|
||||
eventBus.register(UIDownloadCancelledEvent.class, downloadManager)
|
||||
eventBus.register(SourceDiscoveredEvent.class, downloadManager)
|
||||
|
||||
eventBus.register(UIDownloadPausedEvent.class, downloadManager)
|
||||
eventBus.register(UIDownloadResumedEvent.class, downloadManager)
|
||||
|
||||
log.info("initializing upload manager")
|
||||
UploadManager uploadManager = new UploadManager(eventBus, fileManager, meshManager, downloadManager)
|
||||
|
||||
@@ -291,7 +297,7 @@ public class Core {
|
||||
}
|
||||
}
|
||||
|
||||
Core core = new Core(props, home, "0.3.4")
|
||||
Core core = new Core(props, home, "0.3.6")
|
||||
core.startServices()
|
||||
|
||||
// ... at the end, sleep or execute script
|
||||
|
@@ -30,8 +30,8 @@ class MuWireSettings {
|
||||
nickname = props.getProperty("nickname","MuWireUser")
|
||||
downloadLocation = new File((String)props.getProperty("downloadLocation",
|
||||
System.getProperty("user.home")))
|
||||
downloadRetryInterval = Integer.parseInt(props.getProperty("downloadRetryInterval","5"))
|
||||
updateCheckInterval = Integer.parseInt(props.getProperty("updateCheckInterval","36"))
|
||||
downloadRetryInterval = Integer.parseInt(props.getProperty("downloadRetryInterval","1"))
|
||||
updateCheckInterval = Integer.parseInt(props.getProperty("updateCheckInterval","24"))
|
||||
shareDownloadedFiles = Boolean.parseBoolean(props.getProperty("shareDownloadedFiles","true"))
|
||||
|
||||
watchedDirectories = new HashSet<>()
|
||||
|
@@ -0,0 +1,4 @@
|
||||
package com.muwire.core
|
||||
|
||||
class RouterDisconnectedEvent extends Event {
|
||||
}
|
@@ -90,6 +90,14 @@ public class DownloadManager {
|
||||
persistDownloaders()
|
||||
}
|
||||
|
||||
public void onUIDownloadPausedEvent(UIDownloadPausedEvent e) {
|
||||
persistDownloaders()
|
||||
}
|
||||
|
||||
public void onUIDownloadResumedEvent(UIDownloadResumedEvent e) {
|
||||
persistDownloaders()
|
||||
}
|
||||
|
||||
void resume(Downloader downloader) {
|
||||
executor.execute({downloader.download() as Runnable})
|
||||
}
|
||||
@@ -119,8 +127,12 @@ public class DownloadManager {
|
||||
|
||||
def downloader = new Downloader(eventBus, this, me, file, (long)json.length,
|
||||
infoHash, json.pieceSizePow2, connector, destinations, incompletes, pieces)
|
||||
if (json.paused != null)
|
||||
downloader.paused = json.paused
|
||||
downloaders.put(infoHash, downloader)
|
||||
downloader.download()
|
||||
downloader.readPieces()
|
||||
if (!downloader.paused)
|
||||
downloader.download()
|
||||
eventBus.publish(new DownloadStartedEvent(downloader : downloader))
|
||||
}
|
||||
}
|
||||
@@ -174,6 +186,8 @@ public class DownloadManager {
|
||||
json.hashList = Base64.encode(infoHash.hashList)
|
||||
else
|
||||
json.hashRoot = Base64.encode(infoHash.getRoot())
|
||||
|
||||
json.paused = downloader.paused
|
||||
writer.println(JsonOutput.toJson(json))
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ import net.i2p.util.ConcurrentHashSet
|
||||
|
||||
@Log
|
||||
public class Downloader {
|
||||
public enum DownloadState { CONNECTING, HASHLIST, DOWNLOADING, FAILED, CANCELLED, FINISHED }
|
||||
public enum DownloadState { CONNECTING, HASHLIST, DOWNLOADING, FAILED, CANCELLED, PAUSED, FINISHED }
|
||||
private enum WorkerState { CONNECTING, HASHLIST, DOWNLOADING, FINISHED}
|
||||
|
||||
private static final ExecutorService executorService = Executors.newCachedThreadPool({r ->
|
||||
@@ -53,7 +53,7 @@ public class Downloader {
|
||||
private final Set<Destination> successfulDestinations = new ConcurrentHashSet<>()
|
||||
|
||||
|
||||
private volatile boolean cancelled
|
||||
private volatile boolean cancelled, paused
|
||||
private final AtomicBoolean eventFired = new AtomicBoolean()
|
||||
private boolean piecesFileClosed
|
||||
|
||||
@@ -136,6 +136,9 @@ public class Downloader {
|
||||
public DownloadState getCurrentState() {
|
||||
if (cancelled)
|
||||
return DownloadState.CANCELLED
|
||||
if (paused)
|
||||
return DownloadState.PAUSED
|
||||
|
||||
boolean allFinished = true
|
||||
activeWorkers.values().each {
|
||||
allFinished &= it.currentState == WorkerState.FINISHED
|
||||
@@ -183,6 +186,11 @@ public class Downloader {
|
||||
pieces.clearAll()
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
paused = true
|
||||
stop()
|
||||
}
|
||||
|
||||
void stop() {
|
||||
activeWorkers.values().each {
|
||||
it.cancel()
|
||||
@@ -199,6 +207,8 @@ public class Downloader {
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
paused = false
|
||||
readPieces()
|
||||
destinations.each { destination ->
|
||||
def worker = activeWorkers.get(destination)
|
||||
if (worker != null) {
|
||||
|
@@ -0,0 +1,6 @@
|
||||
package com.muwire.core.download
|
||||
|
||||
import com.muwire.core.Event
|
||||
|
||||
class UIDownloadPausedEvent extends Event {
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
package com.muwire.core.download
|
||||
|
||||
import com.muwire.core.Event
|
||||
|
||||
class UIDownloadResumedEvent extends Event {
|
||||
}
|
@@ -1,18 +1,30 @@
|
||||
package com.muwire.core.mesh
|
||||
|
||||
import java.util.stream.Collectors
|
||||
|
||||
import com.muwire.core.Constants
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.Persona
|
||||
import com.muwire.core.download.Pieces
|
||||
import com.muwire.core.download.SourceDiscoveredEvent
|
||||
import com.muwire.core.files.FileManager
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import net.i2p.data.Base64
|
||||
|
||||
class MeshManager {
|
||||
|
||||
private static final int EXPIRATION = 60 * 60 * 1000
|
||||
|
||||
private final Map<InfoHash, Mesh> meshes = Collections.synchronizedMap(new HashMap<>())
|
||||
private final FileManager fileManager
|
||||
private final File home
|
||||
|
||||
MeshManager(FileManager fileManager) {
|
||||
MeshManager(FileManager fileManager, File home) {
|
||||
this.fileManager = fileManager
|
||||
this.home = home
|
||||
load()
|
||||
}
|
||||
|
||||
Mesh get(InfoHash infoHash) {
|
||||
@@ -38,6 +50,47 @@ class MeshManager {
|
||||
Mesh mesh = meshes.get(e.infoHash)
|
||||
if (mesh == null)
|
||||
return
|
||||
mesh.sources.add(e.source)
|
||||
if (mesh.sources.add(e.source))
|
||||
save()
|
||||
}
|
||||
|
||||
private void save() {
|
||||
File meshFile = new File(home, "mesh.json")
|
||||
synchronized(meshes) {
|
||||
meshFile.withPrintWriter { writer ->
|
||||
meshes.values().each { mesh ->
|
||||
def json = [:]
|
||||
json.timestamp = System.currentTimeMillis()
|
||||
json.infoHash = Base64.encode(mesh.infoHash.getRoot())
|
||||
json.sources = mesh.sources.stream().map({it.toBase64()}).collect(Collectors.toList())
|
||||
json.nPieces = mesh.pieces.nPieces
|
||||
writer.println(JsonOutput.toJson(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
File meshFile = new File(home, "mesh.json")
|
||||
if (!meshFile.exists())
|
||||
return
|
||||
long now = System.currentTimeMillis()
|
||||
JsonSlurper slurper = new JsonSlurper()
|
||||
meshFile.eachLine {
|
||||
def json = slurper.parseText(it)
|
||||
if (now - json.timestamp > EXPIRATION)
|
||||
return
|
||||
InfoHash infoHash = new InfoHash(Base64.decode(json.infoHash))
|
||||
Pieces pieces = new Pieces(json.nPieces, Constants.DOWNLOAD_SEQUENTIAL_RATIO)
|
||||
|
||||
Mesh mesh = new Mesh(infoHash, pieces)
|
||||
json.sources.each { source ->
|
||||
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(source)))
|
||||
mesh.sources.add(persona)
|
||||
}
|
||||
|
||||
if (!mesh.sources.isEmpty())
|
||||
meshes.put(infoHash, mesh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
group = com.muwire
|
||||
version = 0.3.4
|
||||
version = 0.3.6
|
||||
groovyVersion = 2.4.15
|
||||
slf4jVersion = 1.7.25
|
||||
spockVersion = 1.1-groovy-2.4
|
||||
|
@@ -17,6 +17,8 @@ import com.muwire.core.Core
|
||||
import com.muwire.core.download.DownloadStartedEvent
|
||||
import com.muwire.core.download.UIDownloadCancelledEvent
|
||||
import com.muwire.core.download.UIDownloadEvent
|
||||
import com.muwire.core.download.UIDownloadPausedEvent
|
||||
import com.muwire.core.download.UIDownloadResumedEvent
|
||||
import com.muwire.core.search.QueryEvent
|
||||
import com.muwire.core.search.SearchEvent
|
||||
import com.muwire.core.trust.TrustEvent
|
||||
@@ -164,6 +166,14 @@ class MainFrameController {
|
||||
void resume() {
|
||||
def downloader = model.downloads[selectedDownload()].downloader
|
||||
downloader.resume()
|
||||
core.eventBus.publish(new UIDownloadResumedEvent())
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void pause() {
|
||||
def downloader = model.downloads[selectedDownload()].downloader
|
||||
downloader.pause()
|
||||
core.eventBus.publish(new UIDownloadPausedEvent())
|
||||
}
|
||||
|
||||
private void markTrust(String tableName, TrustLevel level, def list) {
|
||||
|
@@ -77,9 +77,9 @@ class OptionsController {
|
||||
model.font = text
|
||||
uiSettings.font = text
|
||||
|
||||
boolean showMonitor = view.monitorCheckbox.model.isSelected()
|
||||
model.showMonitor = showMonitor
|
||||
uiSettings.showMonitor = showMonitor
|
||||
// boolean showMonitor = view.monitorCheckbox.model.isSelected()
|
||||
// model.showMonitor = showMonitor
|
||||
// uiSettings.showMonitor = showMonitor
|
||||
|
||||
boolean clearCancelledDownloads = view.clearCancelledDownloadsCheckbox.model.isSelected()
|
||||
model.clearCancelledDownloads = clearCancelledDownloads
|
||||
@@ -93,9 +93,9 @@ class OptionsController {
|
||||
model.excludeLocalResult = excludeLocalResult
|
||||
uiSettings.excludeLocalResult = excludeLocalResult
|
||||
|
||||
boolean showSearchHashes = view.showSearchHashesCheckbox.model.isSelected()
|
||||
model.showSearchHashes = showSearchHashes
|
||||
uiSettings.showSearchHashes = showSearchHashes
|
||||
// boolean showSearchHashes = view.showSearchHashesCheckbox.model.isSelected()
|
||||
// model.showSearchHashes = showSearchHashes
|
||||
// uiSettings.showSearchHashes = showSearchHashes
|
||||
|
||||
File uiSettingsFile = new File(core.home, "gui.properties")
|
||||
uiSettingsFile.withOutputStream {
|
||||
|
@@ -11,6 +11,7 @@ import com.muwire.core.Core
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.MuWireSettings
|
||||
import com.muwire.core.Persona
|
||||
import com.muwire.core.RouterDisconnectedEvent
|
||||
import com.muwire.core.connection.ConnectionAttemptStatus
|
||||
import com.muwire.core.connection.ConnectionEvent
|
||||
import com.muwire.core.connection.DisconnectionEvent
|
||||
@@ -67,6 +68,8 @@ class MainFrameModel {
|
||||
@Observable boolean trustButtonsEnabled
|
||||
@Observable boolean cancelButtonEnabled
|
||||
@Observable boolean retryButtonEnabled
|
||||
@Observable boolean pauseButtonEnabled
|
||||
@Observable String resumeButtonText
|
||||
|
||||
private final Set<InfoHash> infoHashes = new HashSet<>()
|
||||
|
||||
@@ -135,6 +138,7 @@ class MainFrameModel {
|
||||
core.eventBus.register(UpdateAvailableEvent.class, this)
|
||||
core.eventBus.register(FileDownloadedEvent.class, this)
|
||||
core.eventBus.register(FileUnsharedEvent.class, this)
|
||||
core.eventBus.register(RouterDisconnectedEvent.class, this)
|
||||
|
||||
timer.schedule({
|
||||
if (core.shutdown.get())
|
||||
@@ -166,6 +170,8 @@ class MainFrameModel {
|
||||
watched.addAll(core.muOptions.watchedDirectories)
|
||||
builder.getVariable("watched-directories-table").model.fireTableDataChanged()
|
||||
watched.each { core.eventBus.publish(new FileSharedEvent(file : new File(it))) }
|
||||
|
||||
resumeButtonText = "Retry"
|
||||
}
|
||||
})
|
||||
|
||||
@@ -339,6 +345,14 @@ class MainFrameModel {
|
||||
}
|
||||
}
|
||||
|
||||
void onRouterDisconnectedEvent(RouterDisconnectedEvent e) {
|
||||
runInsideUIAsync {
|
||||
JOptionPane.showMessageDialog(null, "MuWire lost connection to the I2P router and will now exit.",
|
||||
"Connection to I2P router lost", JOptionPane.WARNING_MESSAGE)
|
||||
System.exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
void onFileDownloadedEvent(FileDownloadedEvent e) {
|
||||
if (!core.muOptions.shareDownloadedFiles)
|
||||
return
|
||||
|
@@ -135,8 +135,9 @@ class MainFrameView {
|
||||
}
|
||||
}
|
||||
panel (constraints : BorderLayout.SOUTH) {
|
||||
button(text: "Pause", enabled : bind {model.pauseButtonEnabled}, pauseAction)
|
||||
button(text: "Cancel", enabled : bind {model.cancelButtonEnabled }, cancelAction )
|
||||
button(text: "Retry", enabled : bind {model.retryButtonEnabled}, resumeAction)
|
||||
button(text: bind { model.resumeButtonText }, enabled : bind {model.retryButtonEnabled}, resumeAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,6 +296,7 @@ class MainFrameView {
|
||||
if (selectedRow < 0) {
|
||||
model.cancelButtonEnabled = false
|
||||
model.retryButtonEnabled = false
|
||||
model.pauseButtonEnabled = false
|
||||
return
|
||||
}
|
||||
def downloader = model.downloads[selectedRow]?.downloader
|
||||
@@ -305,15 +307,25 @@ class MainFrameView {
|
||||
case Downloader.DownloadState.DOWNLOADING :
|
||||
case Downloader.DownloadState.HASHLIST:
|
||||
model.cancelButtonEnabled = true
|
||||
model.pauseButtonEnabled = true
|
||||
model.retryButtonEnabled = false
|
||||
break
|
||||
case Downloader.DownloadState.FAILED:
|
||||
model.cancelButtonEnabled = true
|
||||
model.retryButtonEnabled = true
|
||||
model.resumeButtonText = "Retry"
|
||||
model.pauseButtonEnabled = false
|
||||
break
|
||||
case Downloader.DownloadState.PAUSED:
|
||||
model.cancelButtonEnabled = true
|
||||
model.retryButtonEnabled = true
|
||||
model.resumeButtonText = "Resume"
|
||||
model.pauseButtonEnabled = false
|
||||
break
|
||||
default:
|
||||
model.cancelButtonEnabled = false
|
||||
model.retryButtonEnabled = false
|
||||
model.pauseButtonEnabled = false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -421,21 +433,32 @@ class MainFrameView {
|
||||
int selected = selectedDownloaderRow()
|
||||
if (selected < 0)
|
||||
return
|
||||
boolean pauseEnabled = false
|
||||
boolean cancelEnabled = false
|
||||
boolean retryEnabled = false
|
||||
String resumeText = "Retry"
|
||||
Downloader downloader = model.downloads[selected].downloader
|
||||
switch(downloader.currentState) {
|
||||
case Downloader.DownloadState.DOWNLOADING:
|
||||
case Downloader.DownloadState.HASHLIST:
|
||||
case Downloader.DownloadState.CONNECTING:
|
||||
pauseEnabled = true
|
||||
cancelEnabled = true
|
||||
retryEnabled = false
|
||||
break
|
||||
case Downloader.DownloadState.FAILED:
|
||||
pauseEnabled = false
|
||||
cancelEnabled = true
|
||||
retryEnabled = true
|
||||
break
|
||||
case Downloader.DownloadState.PAUSED:
|
||||
pauseEnabled = false
|
||||
cancelEnabled = true
|
||||
retryEnabled = true
|
||||
resumeText = "Resume"
|
||||
break
|
||||
default :
|
||||
pauseEnabled = false
|
||||
cancelEnabled = false
|
||||
retryEnabled = false
|
||||
}
|
||||
@@ -450,6 +473,12 @@ class MainFrameView {
|
||||
})
|
||||
menu.add(copyHashToClipboard)
|
||||
|
||||
if (pauseEnabled) {
|
||||
JMenuItem pause = new JMenuItem("Pause")
|
||||
pause.addActionListener({mvcGroup.controller.pause()})
|
||||
menu.add(pause)
|
||||
}
|
||||
|
||||
if (cancelEnabled) {
|
||||
JMenuItem cancel = new JMenuItem("Cancel")
|
||||
cancel.addActionListener({mvcGroup.controller.cancel()})
|
||||
@@ -457,7 +486,7 @@ class MainFrameView {
|
||||
}
|
||||
|
||||
if (retryEnabled) {
|
||||
JMenuItem retry = new JMenuItem("Retry")
|
||||
JMenuItem retry = new JMenuItem(resumeText)
|
||||
retry.addActionListener({mvcGroup.controller.resume()})
|
||||
menu.add(retry)
|
||||
}
|
||||
|
@@ -89,16 +89,16 @@ class OptionsView {
|
||||
lnfField = textField(text : bind {model.lnf}, columns : 4, constraints : gbc(gridx : 1, gridy : 1))
|
||||
label(text : "Font", constraints : gbc(gridx: 0, gridy : 2))
|
||||
fontField = textField(text : bind {model.font}, columns : 4, constraints : gbc(gridx : 1, gridy:2))
|
||||
label(text : "Show Monitor", constraints : gbc(gridx :0, gridy: 3))
|
||||
monitorCheckbox = checkBox(selected : bind {model.showMonitor}, constraints : gbc(gridx : 1, gridy: 3))
|
||||
// label(text : "Show Monitor", constraints : gbc(gridx :0, gridy: 3))
|
||||
// monitorCheckbox = checkBox(selected : bind {model.showMonitor}, constraints : gbc(gridx : 1, gridy: 3))
|
||||
label(text : "Clear Cancelled Downloads", constraints: gbc(gridx: 0, gridy:4))
|
||||
clearCancelledDownloadsCheckbox = checkBox(selected : bind {model.clearCancelledDownloads}, constraints : gbc(gridx : 1, gridy:4))
|
||||
label(text : "Clear Finished Downloads", constraints: gbc(gridx: 0, gridy:5))
|
||||
clearFinishedDownloadsCheckbox = checkBox(selected : bind {model.clearFinishedDownloads}, constraints : gbc(gridx : 1, gridy:5))
|
||||
label(text : "Exclude Local Files From Results", constraints: gbc(gridx:0, gridy:6))
|
||||
excludeLocalResultCheckbox = checkBox(selected : bind {model.excludeLocalResult}, constraints : gbc(gridx: 1, gridy : 6))
|
||||
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))
|
||||
// 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))
|
||||
}
|
||||
buttonsPanel = builder.panel {
|
||||
gridBagLayout()
|
||||
|
@@ -12,12 +12,12 @@ class UISettings {
|
||||
|
||||
UISettings(Properties props) {
|
||||
lnf = props.getProperty("lnf", "system")
|
||||
showMonitor = Boolean.parseBoolean(props.getProperty("showMonitor", "true"))
|
||||
showMonitor = Boolean.parseBoolean(props.getProperty("showMonitor", "false"))
|
||||
font = props.getProperty("font",null)
|
||||
clearCancelledDownloads = Boolean.parseBoolean(props.getProperty("clearCancelledDownloads","false"))
|
||||
clearCancelledDownloads = Boolean.parseBoolean(props.getProperty("clearCancelledDownloads","true"))
|
||||
clearFinishedDownloads = Boolean.parseBoolean(props.getProperty("clearFinishedDownloads","false"))
|
||||
excludeLocalResult = Boolean.parseBoolean(props.getProperty("excludeLocalResult","false"))
|
||||
showSearchHashes = Boolean.parseBoolean(props.getProperty("showSearchHashes","false"))
|
||||
excludeLocalResult = Boolean.parseBoolean(props.getProperty("excludeLocalResult","true"))
|
||||
showSearchHashes = Boolean.parseBoolean(props.getProperty("showSearchHashes","true"))
|
||||
}
|
||||
|
||||
void write(OutputStream out) throws IOException {
|
||||
|
61
logging/1_logging.properties
Normal file
61
logging/1_logging.properties
Normal file
@@ -0,0 +1,61 @@
|
||||
############################################################
|
||||
# Default Logging Configuration File
|
||||
#
|
||||
# You can use a different file by specifying a filename
|
||||
# with the java.util.logging.config.file system property.
|
||||
# For example java -Djava.util.logging.config.file=myfile
|
||||
############################################################
|
||||
|
||||
############################################################
|
||||
# Global properties
|
||||
############################################################
|
||||
|
||||
# "handlers" specifies a comma separated list of log Handler
|
||||
# classes. These handlers will be installed during VM startup.
|
||||
# Note that these classes must be on the system classpath.
|
||||
# By default we only configure a ConsoleHandler, which will only
|
||||
# show messages at the INFO and above levels.
|
||||
handlers= java.util.logging.FileHandler
|
||||
|
||||
# To also add the FileHandler, use the following line instead.
|
||||
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
|
||||
|
||||
# Default global logging level.
|
||||
# This specifies which kinds of events are logged across
|
||||
# all loggers. For any given facility this global level
|
||||
# can be overriden by a facility specific level
|
||||
# Note that the ConsoleHandler also has a separate level
|
||||
# setting to limit messages printed to the console.
|
||||
.level= SEVERE
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
# default file output is in user's home directory.
|
||||
java.util.logging.FileHandler.pattern = MuWire.log
|
||||
java.util.logging.FileHandler.limit = 50000000
|
||||
java.util.logging.FileHandler.count = 1
|
||||
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Limit the message that are printed on the console to INFO and above.
|
||||
java.util.logging.ConsoleHandler.level = INFO
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Example to customize the SimpleFormatter output format
|
||||
# to print one-line log message like this:
|
||||
# <level>: <log message> [<date/time>]
|
||||
#
|
||||
#java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
|
||||
|
||||
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$s %2$s %5$s %6$s %n
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
# For example, set the com.xyz.foo logger to only log SEVERE
|
||||
# messages:
|
||||
com.xyz.foo.level = SEVERE
|
61
logging/2_logging.properties
Normal file
61
logging/2_logging.properties
Normal file
@@ -0,0 +1,61 @@
|
||||
############################################################
|
||||
# Default Logging Configuration File
|
||||
#
|
||||
# You can use a different file by specifying a filename
|
||||
# with the java.util.logging.config.file system property.
|
||||
# For example java -Djava.util.logging.config.file=myfile
|
||||
############################################################
|
||||
|
||||
############################################################
|
||||
# Global properties
|
||||
############################################################
|
||||
|
||||
# "handlers" specifies a comma separated list of log Handler
|
||||
# classes. These handlers will be installed during VM startup.
|
||||
# Note that these classes must be on the system classpath.
|
||||
# By default we only configure a ConsoleHandler, which will only
|
||||
# show messages at the INFO and above levels.
|
||||
handlers= java.util.logging.FileHandler
|
||||
|
||||
# To also add the FileHandler, use the following line instead.
|
||||
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
|
||||
|
||||
# Default global logging level.
|
||||
# This specifies which kinds of events are logged across
|
||||
# all loggers. For any given facility this global level
|
||||
# can be overriden by a facility specific level
|
||||
# Note that the ConsoleHandler also has a separate level
|
||||
# setting to limit messages printed to the console.
|
||||
.level= WARNING
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
# default file output is in user's home directory.
|
||||
java.util.logging.FileHandler.pattern = MuWire.log
|
||||
java.util.logging.FileHandler.limit = 50000000
|
||||
java.util.logging.FileHandler.count = 1
|
||||
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Limit the message that are printed on the console to INFO and above.
|
||||
java.util.logging.ConsoleHandler.level = INFO
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Example to customize the SimpleFormatter output format
|
||||
# to print one-line log message like this:
|
||||
# <level>: <log message> [<date/time>]
|
||||
#
|
||||
#java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
|
||||
|
||||
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$s %2$s %5$s %6$s %n
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
# For example, set the com.xyz.foo logger to only log SEVERE
|
||||
# messages:
|
||||
com.xyz.foo.level = SEVERE
|
61
logging/3_logging.properties
Normal file
61
logging/3_logging.properties
Normal file
@@ -0,0 +1,61 @@
|
||||
############################################################
|
||||
# Default Logging Configuration File
|
||||
#
|
||||
# You can use a different file by specifying a filename
|
||||
# with the java.util.logging.config.file system property.
|
||||
# For example java -Djava.util.logging.config.file=myfile
|
||||
############################################################
|
||||
|
||||
############################################################
|
||||
# Global properties
|
||||
############################################################
|
||||
|
||||
# "handlers" specifies a comma separated list of log Handler
|
||||
# classes. These handlers will be installed during VM startup.
|
||||
# Note that these classes must be on the system classpath.
|
||||
# By default we only configure a ConsoleHandler, which will only
|
||||
# show messages at the INFO and above levels.
|
||||
handlers= java.util.logging.FileHandler
|
||||
|
||||
# To also add the FileHandler, use the following line instead.
|
||||
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
|
||||
|
||||
# Default global logging level.
|
||||
# This specifies which kinds of events are logged across
|
||||
# all loggers. For any given facility this global level
|
||||
# can be overriden by a facility specific level
|
||||
# Note that the ConsoleHandler also has a separate level
|
||||
# setting to limit messages printed to the console.
|
||||
.level= INFO
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
# default file output is in user's home directory.
|
||||
java.util.logging.FileHandler.pattern = MuWire.log
|
||||
java.util.logging.FileHandler.limit = 50000000
|
||||
java.util.logging.FileHandler.count = 1
|
||||
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Limit the message that are printed on the console to INFO and above.
|
||||
java.util.logging.ConsoleHandler.level = INFO
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Example to customize the SimpleFormatter output format
|
||||
# to print one-line log message like this:
|
||||
# <level>: <log message> [<date/time>]
|
||||
#
|
||||
#java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
|
||||
|
||||
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$s %2$s %5$s %6$s %n
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
# For example, set the com.xyz.foo logger to only log SEVERE
|
||||
# messages:
|
||||
com.xyz.foo.level = SEVERE
|
62
logging/4_logging.properties
Normal file
62
logging/4_logging.properties
Normal file
@@ -0,0 +1,62 @@
|
||||
############################################################
|
||||
# Default Logging Configuration File
|
||||
#
|
||||
# You can use a different file by specifying a filename
|
||||
# with the java.util.logging.config.file system property.
|
||||
# For example java -Djava.util.logging.config.file=myfile
|
||||
############################################################
|
||||
|
||||
############################################################
|
||||
# Global properties
|
||||
############################################################
|
||||
|
||||
# "handlers" specifies a comma separated list of log Handler
|
||||
# classes. These handlers will be installed during VM startup.
|
||||
# Note that these classes must be on the system classpath.
|
||||
# By default we only configure a ConsoleHandler, which will only
|
||||
# show messages at the INFO and above levels.
|
||||
handlers= java.util.logging.FileHandler
|
||||
|
||||
# To also add the FileHandler, use the following line instead.
|
||||
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
|
||||
|
||||
# Default global logging level.
|
||||
# This specifies which kinds of events are logged across
|
||||
# all loggers. For any given facility this global level
|
||||
# can be overriden by a facility specific level
|
||||
# Note that the ConsoleHandler also has a separate level
|
||||
# setting to limit messages printed to the console.
|
||||
.level= SEVERE
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
# default file output is in user's home directory.
|
||||
java.util.logging.FileHandler.pattern = MuWire.log
|
||||
java.util.logging.FileHandler.limit = 50000000
|
||||
java.util.logging.FileHandler.count = 1
|
||||
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Limit the message that are printed on the console to INFO and above.
|
||||
java.util.logging.ConsoleHandler.level = INFO
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Example to customize the SimpleFormatter output format
|
||||
# to print one-line log message like this:
|
||||
# <level>: <log message> [<date/time>]
|
||||
#
|
||||
#java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
|
||||
|
||||
java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$s %2$s %5$s %6$s %n
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
# For example, set the com.xyz.foo logger to only log SEVERE
|
||||
# messages:
|
||||
com.xyz.foo.level = SEVERE
|
||||
com.muwire.core.level = FINE
|
Reference in New Issue
Block a user