mirror of https://github.com/zlatinb/muwire
wip on server-side handling of browse v2
parent
5a172d1eaf
commit
1d8f0f74af
|
@ -115,10 +115,10 @@ class BrowseManager {
|
|||
tempTree.list(path, topLevelItems)
|
||||
}
|
||||
|
||||
int itemCount = topLevelItems.dirs.size() + topLevelItems.files.size()
|
||||
topLevelItems.files.values().each {it.hit(browser, System.currentTimeMillis(), "Browse Host")}
|
||||
OutputStream os = endpoint.getOutputStream()
|
||||
os.write("ItemCount:${itemCount}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Files:${topLevelItems.files.size()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Dirs:${topLevelItems.dirs.size()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
|
||||
JsonOutput jsonOutput = new JsonOutput()
|
||||
|
@ -158,8 +158,8 @@ class BrowseManager {
|
|||
def cb = new ListCallback()
|
||||
tempTree.list(requestedPath, cb)
|
||||
|
||||
itemCount = cb.dirs.size() + cb.files.size()
|
||||
os.write("ItemCount:${itemCount}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Files:${cb.files.size()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Dirs:${cb.dirs.size()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
|
||||
gzos = new GZIPOutputStream(os)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.muwire.core.search
|
||||
|
||||
import com.muwire.core.Constants
|
||||
import com.muwire.core.EventBus
|
||||
import com.muwire.core.Persona
|
||||
import com.muwire.core.connection.Endpoint
|
||||
|
@ -23,7 +24,7 @@ class BrowseSession implements Runnable {
|
|||
private final EventBus eventBus
|
||||
private final I2PConnector connector
|
||||
private final Persona me
|
||||
private volatile Thread currentThrad
|
||||
private volatile Thread currentThread
|
||||
private volatile boolean closed
|
||||
|
||||
BrowseSession(EventBus eventBus, I2PConnector connector, UIBrowseEvent event, Persona me) {
|
||||
|
@ -36,7 +37,7 @@ class BrowseSession implements Runnable {
|
|||
void run() {
|
||||
if (closed)
|
||||
return
|
||||
currentThrad = Thread.currentThread()
|
||||
currentThread = Thread.currentThread()
|
||||
Endpoint endpoint = null
|
||||
try {
|
||||
eventBus.publish(new BrowseStatusEvent(host : event.host, status : BrowseStatus.CONNECTING,
|
||||
|
@ -46,6 +47,7 @@ class BrowseSession implements Runnable {
|
|||
os.write("BROWSE\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Persona:${me.toBase64()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Path:true\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("Version:${Constants.BROWSE_VERSION}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
|
||||
InputStream is = endpoint.getInputStream()
|
||||
|
@ -70,41 +72,92 @@ class BrowseSession implements Runnable {
|
|||
if (profileHeader.getPersona() != event.host)
|
||||
throw new IOException("Sender profile mismatch")
|
||||
}
|
||||
|
||||
int version = 1
|
||||
if (headers.containsKey("Version"))
|
||||
version = Integer.parseInt(headers['Version'])
|
||||
|
||||
// at this stage, start pulling the results
|
||||
UUID uuid = event.uuid
|
||||
eventBus.publish(new BrowseStatusEvent(host: event.host, status : BrowseStatus.FETCHING,
|
||||
totalResults : results, uuid : uuid))
|
||||
log.info("Starting to fetch $results results with uuid $uuid")
|
||||
// if we're version 1 just pull everything
|
||||
if (version == 1) {
|
||||
eventBus.publish(new BrowseStatusEvent(host: event.host, status: BrowseStatus.FETCHING,
|
||||
totalResults: results, currentItems: results, uuid: uuid))
|
||||
log.info("Starting to fetch $results results with uuid $uuid")
|
||||
|
||||
JsonSlurper slurper = new JsonSlurper()
|
||||
DataInputStream dis = new DataInputStream(new GZIPInputStream(is))
|
||||
UIResultEvent[] batch = new UIResultEvent[Math.min(BATCH_SIZE, results)]
|
||||
int j = 0
|
||||
for (int i = 0; i < results; i++) {
|
||||
if (closed)
|
||||
return
|
||||
log.fine("parsing result $i at batch position $j")
|
||||
JsonSlurper slurper = new JsonSlurper()
|
||||
DataInputStream dis = new DataInputStream(new GZIPInputStream(is))
|
||||
UIResultEvent[] batch = new UIResultEvent[Math.min(BATCH_SIZE, results)]
|
||||
int j = 0
|
||||
for (int i = 0; i < results; i++) {
|
||||
if (closed)
|
||||
return
|
||||
log.fine("parsing result $i at batch position $j")
|
||||
|
||||
int size = dis.readUnsignedShort()
|
||||
byte [] tmp = new byte[size]
|
||||
dis.readFully(tmp)
|
||||
def json = slurper.parse(tmp)
|
||||
UIResultEvent result = ResultsParser.parse(event.host, uuid, json)
|
||||
result.chat = chat
|
||||
result.profileHeader = profileHeader
|
||||
batch[j++] = result
|
||||
def json = readJson(slurper, dis)
|
||||
UIResultEvent result = ResultsParser.parse(event.host, uuid, json)
|
||||
result.chat = chat
|
||||
result.profileHeader = profileHeader
|
||||
batch[j++] = result
|
||||
|
||||
|
||||
// publish piecemally
|
||||
if (j == batch.length) {
|
||||
eventBus.publish(new UIResultBatchEvent(results : batch, uuid : uuid))
|
||||
j = 0
|
||||
batch = new UIResultEvent[Math.min(results - i - 1, BATCH_SIZE)]
|
||||
log.fine("publishing batch, next batch size ${batch.length}")
|
||||
// publish piecemally
|
||||
if (j == batch.length) {
|
||||
eventBus.publish(new UIResultBatchEvent(results: batch, uuid: uuid))
|
||||
j = 0
|
||||
batch = new UIResultEvent[Math.min(results - i - 1, BATCH_SIZE)]
|
||||
log.fine("publishing batch, next batch size ${batch.length}")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (version == 2) {
|
||||
// version 2 should have Files and Dirs headers
|
||||
if (!headers.containsKey("Files"))
|
||||
throw new Exception("Files header missing")
|
||||
int files = Integer.parseInt(headers['Files'])
|
||||
if (!headers.containsKey("Dirs"))
|
||||
throw new Exception("Dirs header missing")
|
||||
int dirs = Integer.parseInt(headers['Dirs'])
|
||||
eventBus.publish(new BrowseStatusEvent(host: event.host, status: BrowseStatus.FETCHING,
|
||||
totalResults: results, currentItems: (files + dirs), uuid: uuid))
|
||||
log.info("starting to fetch top-level ${files} files and ${dirs} dirs with uuid $uuid")
|
||||
|
||||
JsonSlurper slurper = new JsonSlurper()
|
||||
DataInputStream dis = new DataInputStream(new GZIPInputStream(is))
|
||||
UIResultEvent[] batch = new UIResultEvent[Math.min(BATCH_SIZE, results)]
|
||||
int j = 0
|
||||
for (int i = 0; i < files; i ++) {
|
||||
if (closed)
|
||||
return
|
||||
log.fine("parsing result $i at batch position $j")
|
||||
|
||||
def json = readJson(slurper, dis)
|
||||
UIResultEvent result = ResultsParser.parse(event.host, uuid, json)
|
||||
result.chat = chat
|
||||
result.profileHeader = profileHeader
|
||||
batch[j++] = result
|
||||
|
||||
|
||||
// publish piecemally
|
||||
if (j == batch.length) {
|
||||
eventBus.publish(new UIResultBatchEvent(results: batch, uuid: uuid))
|
||||
j = 0
|
||||
batch = new UIResultEvent[Math.min(results - i - 1, BATCH_SIZE)]
|
||||
log.fine("publishing batch, next batch size ${batch.length}")
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < dirs; i++) {
|
||||
if (closed)
|
||||
return
|
||||
|
||||
def json = readJson(slurper, dis)
|
||||
if (!json.directory || json.path == null)
|
||||
throw new Exception("Invalid dir json")
|
||||
List<String> path = json.path.collect {DataUtil.readi18nString(Base64.decode(it))}
|
||||
def event = new UIBrowseDirEvent(uuid : uuid,
|
||||
path : path.toArray(new String[0]))
|
||||
eventBus.publish(event)
|
||||
}
|
||||
} else
|
||||
throw new Exception("unrecognized version $version")
|
||||
eventBus.publish(new BrowseStatusEvent(host: event.host, status : BrowseStatus.FINISHED, uuid : uuid))
|
||||
} catch (Exception bad) {
|
||||
if (!closed) {
|
||||
|
@ -112,14 +165,21 @@ class BrowseSession implements Runnable {
|
|||
eventBus.publish(new BrowseStatusEvent(host: event.host, status: BrowseStatus.FAILED, uuid: event.uuid))
|
||||
}
|
||||
} finally {
|
||||
currentThrad = null
|
||||
currentThread = null
|
||||
endpoint?.close()
|
||||
}
|
||||
}
|
||||
|
||||
private static def readJson(JsonSlurper slurper, DataInputStream dis) {
|
||||
int size = dis.readUnsignedShort()
|
||||
byte[] tmp = new byte[size]
|
||||
dis.readFully(tmp)
|
||||
slurper.parse(tmp)
|
||||
}
|
||||
|
||||
void close() {
|
||||
log.info("closing browse session for UUID ${event.uuid}")
|
||||
closed = true
|
||||
currentThrad?.interrupt()
|
||||
currentThread?.interrupt()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,6 @@ class BrowseStatusEvent extends Event {
|
|||
BrowseStatus status
|
||||
BrowseSession session
|
||||
int totalResults
|
||||
int currentItems
|
||||
UUID uuid
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.muwire.core.search
|
||||
|
||||
import com.muwire.core.Event
|
||||
|
||||
class UIBrowseDirEvent extends Event {
|
||||
UUID uuid
|
||||
String[] path
|
||||
}
|
|
@ -105,8 +105,10 @@ class BrowseController {
|
|||
}
|
||||
for(BrowseStatusEvent event : statusCopy) {
|
||||
model.status = event.status
|
||||
if (event.status == BrowseStatus.FETCHING)
|
||||
if(event.status == BrowseStatus.FETCHING) {
|
||||
model.currentBatch = event.currentItems
|
||||
model.totalResults = event.totalResults
|
||||
}
|
||||
}
|
||||
if (!statusCopy.isEmpty()) {
|
||||
if ((model.status == BrowseStatus.FINISHED || model.status == BrowseStatus.FAILED) &&
|
||||
|
|
|
@ -508,7 +508,8 @@ ADD_COMMENT_SINGLE=Add comment to {0}
|
|||
ADD_COMMENT_TOO_LONG=Comment too long
|
||||
ADD_COMMENT_TOO_LONG_BODY=Your comment is too long - {0} characters. The maximum length is {1} characters.
|
||||
|
||||
## Browse dialog
|
||||
## Browse pane
|
||||
BROWSE_TOTAL_FILES=Total files
|
||||
|
||||
## Close Warning prompt
|
||||
CLOSE_MUWIRE_QUESTION=Close MuWire?
|
||||
|
|
|
@ -27,6 +27,7 @@ class BrowseModel {
|
|||
@Observable boolean downloadActionEnabled
|
||||
@Observable boolean viewDetailsActionEnabled
|
||||
@Observable int totalResults
|
||||
@Observable int currentBatch
|
||||
@Observable int resultCount
|
||||
@Observable boolean filterEnabled
|
||||
@Observable boolean clearFilterEnabled
|
||||
|
|
|
@ -67,9 +67,11 @@ class BrowseView {
|
|||
label(text: trans("STATUS") + ":")
|
||||
label(text: bind { trans(model.status.name()) })
|
||||
label(text: bind {
|
||||
model.totalResults == 0 ? "" :
|
||||
"$model.resultCount/$model.totalResults (" + Math.round(model.resultCount * 100 / model.totalResults)+ "%)"
|
||||
model.currentBatch == 0 ? "" :
|
||||
"$model.resultCount/$model.currentBatch (" + Math.round(model.resultCount * 100 / model.currentBatch)+ "%)"
|
||||
})
|
||||
label(text : trans("BROWSE_TOTAL_FILES") + ":")
|
||||
label(text: bind {model.totalResults})
|
||||
}
|
||||
panel(constraints: BorderLayout.EAST) {
|
||||
button(text: trans("VIEW_PROFILE"), toolTipText: trans("TOOLTIP_VIEW_PROFILE"), viewProfileAction)
|
||||
|
|
Loading…
Reference in New Issue