ability to download updates automatically

pull/5/head
Zlatin Balevsky 2019-06-29 09:23:27 +01:00
parent de04b40b86
commit d9edb2e128
8 changed files with 95 additions and 12 deletions

View File

@ -39,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
@ -233,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)

View File

@ -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
@ -37,6 +38,7 @@ 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"))
@ -62,6 +64,7 @@ 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))

View File

@ -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,23 @@ 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 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 +59,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 : payload.version, signer : payload.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 +140,23 @@ class UpdateClient {
return return
} }
if (!settings.autoDownloadUpdate) {
log.info("new version $payload.version available, publishing event") log.info("new version $payload.version available, publishing event")
eventBus.publish(new UpdateAvailableEvent(version : payload.version, signer : payload.signer, infoHash : payload.infoHash)) 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
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)

View File

@ -0,0 +1,8 @@
package com.muwire.core.update
import com.muwire.core.Event
class UpdateDownloadedEvent extends Event {
String version
String signer
}

View File

@ -70,6 +70,10 @@ class OptionsController {
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)

View File

@ -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
@ -143,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())
@ -185,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)

View File

@ -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
@ -40,6 +41,7 @@ class OptionsModel {
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()

View File

@ -32,6 +32,7 @@ class OptionsView {
def retryField def retryField
def updateField def updateField
def autoDownloadUpdateCheckbox
def allowUntrustedCheckbox def allowUntrustedCheckbox
def shareDownloadedCheckbox def shareDownloadedCheckbox
@ -72,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 {