Advertise browse/feed/chat abilities in download headers
This commit is contained in:
1
TODO.md
1
TODO.md
@ -18,7 +18,6 @@ This helps with scalability
|
|||||||
* Enum i18n
|
* Enum i18n
|
||||||
* Ability to share trust list only with trusted users
|
* Ability to share trust list only with trusted users
|
||||||
* Confidential files visible only to certain users
|
* Confidential files visible only to certain users
|
||||||
* Advertise file feed and browseability in upload headers
|
|
||||||
* Download queue with priorities
|
* Download queue with priorities
|
||||||
* Use tracker pings - either embedded logic or external mwtrackerd to add more sources to downloads
|
* Use tracker pings - either embedded logic or external mwtrackerd to add more sources to downloads
|
||||||
|
|
||||||
|
@ -362,8 +362,17 @@ public class Core {
|
|||||||
eventBus.register(QueryEvent.class, searchManager)
|
eventBus.register(QueryEvent.class, searchManager)
|
||||||
eventBus.register(ResultsEvent.class, searchManager)
|
eventBus.register(ResultsEvent.class, searchManager)
|
||||||
|
|
||||||
|
log.info("initializing chat manager")
|
||||||
|
chatManager = new ChatManager(eventBus, me, i2pConnector, trustService, props)
|
||||||
|
eventBus.with {
|
||||||
|
register(UIConnectChatEvent.class, chatManager)
|
||||||
|
register(UIDisconnectChatEvent.class, chatManager)
|
||||||
|
register(ChatMessageEvent.class, chatManager)
|
||||||
|
register(ChatDisconnectionEvent.class, chatManager)
|
||||||
|
}
|
||||||
|
|
||||||
log.info("initializing download manager")
|
log.info("initializing download manager")
|
||||||
downloadManager = new DownloadManager(eventBus, trustService, meshManager, props, i2pConnector, home, me)
|
downloadManager = new DownloadManager(eventBus, trustService, meshManager, props, i2pConnector, home, me, chatServer)
|
||||||
eventBus.register(UIDownloadEvent.class, downloadManager)
|
eventBus.register(UIDownloadEvent.class, downloadManager)
|
||||||
eventBus.register(UIDownloadFeedItemEvent.class, downloadManager)
|
eventBus.register(UIDownloadFeedItemEvent.class, downloadManager)
|
||||||
eventBus.register(UILoadedEvent.class, downloadManager)
|
eventBus.register(UILoadedEvent.class, downloadManager)
|
||||||
@ -382,16 +391,6 @@ public class Core {
|
|||||||
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)
|
||||||
|
|
||||||
|
|
||||||
log.info("initializing chat manager")
|
|
||||||
chatManager = new ChatManager(eventBus, me, i2pConnector, trustService, props)
|
|
||||||
eventBus.with {
|
|
||||||
register(UIConnectChatEvent.class, chatManager)
|
|
||||||
register(UIDisconnectChatEvent.class, chatManager)
|
|
||||||
register(ChatMessageEvent.class, chatManager)
|
|
||||||
register(ChatDisconnectionEvent.class, chatManager)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("initializing acceptor")
|
log.info("initializing acceptor")
|
||||||
I2PAcceptor i2pAcceptor = new I2PAcceptor(i2pSocketManager)
|
I2PAcceptor i2pAcceptor = new I2PAcceptor(i2pSocketManager)
|
||||||
connectionAcceptor = new ConnectionAcceptor(eventBus, connectionManager, props,
|
connectionAcceptor = new ConnectionAcceptor(eventBus, connectionManager, props,
|
||||||
|
@ -60,6 +60,10 @@ class ChatServer {
|
|||||||
echo(getWelcome(),me.destination)
|
echo(getWelcome(),me.destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() {
|
||||||
|
running.get()
|
||||||
|
}
|
||||||
|
|
||||||
private String getWelcome() {
|
private String getWelcome() {
|
||||||
String welcome = DEFAULT_WELCOME
|
String welcome = DEFAULT_WELCOME
|
||||||
if (settings.chatWelcomeFile != null)
|
if (settings.chatWelcomeFile != null)
|
||||||
|
@ -23,6 +23,8 @@ import com.muwire.core.InfoHash
|
|||||||
import com.muwire.core.MuWireSettings
|
import com.muwire.core.MuWireSettings
|
||||||
import com.muwire.core.Persona
|
import com.muwire.core.Persona
|
||||||
import com.muwire.core.UILoadedEvent
|
import com.muwire.core.UILoadedEvent
|
||||||
|
import com.muwire.core.chat.ChatManager
|
||||||
|
import com.muwire.core.chat.ChatServer
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
@ -35,16 +37,17 @@ public class DownloadManager {
|
|||||||
private final EventBus eventBus
|
private final EventBus eventBus
|
||||||
private final TrustService trustService
|
private final TrustService trustService
|
||||||
private final MeshManager meshManager
|
private final MeshManager meshManager
|
||||||
private final MuWireSettings muSettings
|
final MuWireSettings muSettings
|
||||||
private final I2PConnector connector
|
private final I2PConnector connector
|
||||||
private final Executor executor
|
private final Executor executor
|
||||||
private final File home
|
private final File home
|
||||||
private final Persona me
|
private final Persona me
|
||||||
|
private final ChatServer chatServer
|
||||||
|
|
||||||
private final Map<InfoHash, Downloader> downloaders = new ConcurrentHashMap<>()
|
private final Map<InfoHash, Downloader> downloaders = new ConcurrentHashMap<>()
|
||||||
|
|
||||||
public DownloadManager(EventBus eventBus, TrustService trustService, MeshManager meshManager, MuWireSettings muSettings,
|
public DownloadManager(EventBus eventBus, TrustService trustService, MeshManager meshManager, MuWireSettings muSettings,
|
||||||
I2PConnector connector, File home, Persona me) {
|
I2PConnector connector, File home, Persona me, ChatServer chatServer) {
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.trustService = trustService
|
this.trustService = trustService
|
||||||
this.meshManager = meshManager
|
this.meshManager = meshManager
|
||||||
@ -52,6 +55,7 @@ public class DownloadManager {
|
|||||||
this.connector = connector
|
this.connector = connector
|
||||||
this.home = home
|
this.home = home
|
||||||
this.me = me
|
this.me = me
|
||||||
|
this.chatServer = chatServer
|
||||||
|
|
||||||
this.executor = Executors.newCachedThreadPool({ r ->
|
this.executor = Executors.newCachedThreadPool({ r ->
|
||||||
Thread rv = new Thread(r)
|
Thread rv = new Thread(r)
|
||||||
@ -94,7 +98,7 @@ public class DownloadManager {
|
|||||||
incompletes.mkdirs()
|
incompletes.mkdirs()
|
||||||
|
|
||||||
Pieces pieces = getPieces(infoHash, size, pieceSize, sequential)
|
Pieces pieces = getPieces(infoHash, size, pieceSize, sequential)
|
||||||
def downloader = new Downloader(eventBus, this, me, target, size,
|
def downloader = new Downloader(eventBus, this, chatServer, me, target, size,
|
||||||
infoHash, pieceSize, connector, destinations,
|
infoHash, pieceSize, connector, destinations,
|
||||||
incompletes, pieces)
|
incompletes, pieces)
|
||||||
downloaders.put(infoHash, downloader)
|
downloaders.put(infoHash, downloader)
|
||||||
@ -158,7 +162,7 @@ public class DownloadManager {
|
|||||||
|
|
||||||
Pieces pieces = getPieces(infoHash, (long)json.length, json.pieceSizePow2, sequential)
|
Pieces pieces = getPieces(infoHash, (long)json.length, json.pieceSizePow2, sequential)
|
||||||
|
|
||||||
def downloader = new Downloader(eventBus, this, me, file, (long)json.length,
|
def downloader = new Downloader(eventBus, this, chatServer, me, file, (long)json.length,
|
||||||
infoHash, json.pieceSizePow2, connector, destinations, incompletes, pieces)
|
infoHash, json.pieceSizePow2, connector, destinations, incompletes, pieces)
|
||||||
if (json.paused != null)
|
if (json.paused != null)
|
||||||
downloader.paused = json.paused
|
downloader.paused = json.paused
|
||||||
|
@ -37,13 +37,15 @@ class DownloadSession {
|
|||||||
private final long fileLength
|
private final long fileLength
|
||||||
private final Set<Integer> available
|
private final Set<Integer> available
|
||||||
private final MessageDigest digest
|
private final MessageDigest digest
|
||||||
|
private final boolean browse, feed, chat
|
||||||
|
|
||||||
private final AtomicLong dataSinceLastRead
|
private final AtomicLong dataSinceLastRead
|
||||||
|
|
||||||
private MappedByteBuffer mapped
|
private MappedByteBuffer mapped
|
||||||
|
|
||||||
DownloadSession(EventBus eventBus, String meB64, Pieces pieces, InfoHash infoHash, Endpoint endpoint, File file,
|
DownloadSession(EventBus eventBus, String meB64, Pieces pieces, InfoHash infoHash, Endpoint endpoint, File file,
|
||||||
int pieceSize, long fileLength, Set<Integer> available, AtomicLong dataSinceLastRead) {
|
int pieceSize, long fileLength, Set<Integer> available, AtomicLong dataSinceLastRead,
|
||||||
|
boolean browse, boolean feed, boolean chat) {
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.meB64 = meB64
|
this.meB64 = meB64
|
||||||
this.pieces = pieces
|
this.pieces = pieces
|
||||||
@ -54,6 +56,9 @@ class DownloadSession {
|
|||||||
this.fileLength = fileLength
|
this.fileLength = fileLength
|
||||||
this.available = available
|
this.available = available
|
||||||
this.dataSinceLastRead = dataSinceLastRead
|
this.dataSinceLastRead = dataSinceLastRead
|
||||||
|
this.browse = browse
|
||||||
|
this.feed = feed
|
||||||
|
this.chat = chat
|
||||||
try {
|
try {
|
||||||
digest = MessageDigest.getInstance("SHA-256")
|
digest = MessageDigest.getInstance("SHA-256")
|
||||||
} catch (NoSuchAlgorithmException impossible) {
|
} catch (NoSuchAlgorithmException impossible) {
|
||||||
@ -94,6 +99,12 @@ class DownloadSession {
|
|||||||
os.write("GET $root\r\n".getBytes(StandardCharsets.US_ASCII))
|
os.write("GET $root\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
os.write("Range: $start-$end\r\n".getBytes(StandardCharsets.US_ASCII))
|
os.write("Range: $start-$end\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
os.write("X-Persona: $meB64\r\n".getBytes(StandardCharsets.US_ASCII))
|
os.write("X-Persona: $meB64\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
|
if (browse)
|
||||||
|
os.write("Browse: true\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
|
if (feed)
|
||||||
|
os.write("Feed: true\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
|
if (chat)
|
||||||
|
os.write("Chat: true\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
String xHave = DataUtil.encodeXHave(pieces.getDownloaded(), pieces.nPieces)
|
String xHave = DataUtil.encodeXHave(pieces.getDownloaded(), pieces.nPieces)
|
||||||
os.write("X-Have: $xHave\r\n\r\n".getBytes(StandardCharsets.US_ASCII))
|
os.write("X-Have: $xHave\r\n\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||||
os.flush()
|
os.flush()
|
||||||
|
@ -2,6 +2,8 @@ package com.muwire.core.download
|
|||||||
|
|
||||||
import com.muwire.core.InfoHash
|
import com.muwire.core.InfoHash
|
||||||
import com.muwire.core.Persona
|
import com.muwire.core.Persona
|
||||||
|
import com.muwire.core.chat.ChatManager
|
||||||
|
import com.muwire.core.chat.ChatServer
|
||||||
import com.muwire.core.connection.Endpoint
|
import com.muwire.core.connection.Endpoint
|
||||||
|
|
||||||
import java.nio.file.AtomicMoveNotSupportedException
|
import java.nio.file.AtomicMoveNotSupportedException
|
||||||
@ -41,6 +43,7 @@ public class Downloader {
|
|||||||
|
|
||||||
private final EventBus eventBus
|
private final EventBus eventBus
|
||||||
private final DownloadManager downloadManager
|
private final DownloadManager downloadManager
|
||||||
|
private final ChatServer chatServer
|
||||||
private final Persona me
|
private final Persona me
|
||||||
private final File file
|
private final File file
|
||||||
private final Pieces pieces
|
private final Pieces pieces
|
||||||
@ -68,13 +71,14 @@ public class Downloader {
|
|||||||
private int speedPos = 0
|
private int speedPos = 0
|
||||||
private int speedAvg = 0
|
private int speedAvg = 0
|
||||||
|
|
||||||
public Downloader(EventBus eventBus, DownloadManager downloadManager,
|
public Downloader(EventBus eventBus, DownloadManager downloadManager, ChatServer chatServer,
|
||||||
Persona me, File file, long length, InfoHash infoHash,
|
Persona me, File file, long length, InfoHash infoHash,
|
||||||
int pieceSizePow2, I2PConnector connector, Set<Destination> destinations,
|
int pieceSizePow2, I2PConnector connector, Set<Destination> destinations,
|
||||||
File incompletes, Pieces pieces) {
|
File incompletes, Pieces pieces) {
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.me = me
|
this.me = me
|
||||||
this.downloadManager = downloadManager
|
this.downloadManager = downloadManager
|
||||||
|
this.chatServer = chatServer
|
||||||
this.file = file
|
this.file = file
|
||||||
this.infoHash = infoHash
|
this.infoHash = infoHash
|
||||||
this.length = length
|
this.length = length
|
||||||
@ -373,10 +377,16 @@ public class Downloader {
|
|||||||
setInfoHash(received)
|
setInfoHash(received)
|
||||||
}
|
}
|
||||||
currentState = WorkerState.DOWNLOADING
|
currentState = WorkerState.DOWNLOADING
|
||||||
|
|
||||||
|
boolean browse = downloadManager.muSettings.browseFiles
|
||||||
|
boolean feed = downloadManager.muSettings.fileFeed && downloadManager.muSettings.advertiseFeed
|
||||||
|
boolean chat = chatServer.isRunning() && downloadManager.muSettings.advertiseChat
|
||||||
|
|
||||||
boolean requestPerformed
|
boolean requestPerformed
|
||||||
while(!pieces.isComplete()) {
|
while(!pieces.isComplete()) {
|
||||||
currentSession = new DownloadSession(eventBus, me.toBase64(), pieces, getInfoHash(),
|
currentSession = new DownloadSession(eventBus, me.toBase64(), pieces, getInfoHash(),
|
||||||
endpoint, incompleteFile, pieceSize, length, available, dataSinceLastRead)
|
endpoint, incompleteFile, pieceSize, length, available, dataSinceLastRead,
|
||||||
|
browse, feed, chat)
|
||||||
requestPerformed = currentSession.request()
|
requestPerformed = currentSession.request()
|
||||||
if (!requestPerformed)
|
if (!requestPerformed)
|
||||||
break
|
break
|
||||||
|
@ -46,7 +46,7 @@ class DownloadSessionTest {
|
|||||||
eventBus = new EventBus()
|
eventBus = new EventBus()
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSession(int size, def claimedPieces = []) {
|
private void initSession(int size, def claimedPieces = [], boolean browse = false, boolean feed = false, boolean chat = false) {
|
||||||
Random r = new Random()
|
Random r = new Random()
|
||||||
byte [] content = new byte[size]
|
byte [] content = new byte[size]
|
||||||
r.nextBytes(content)
|
r.nextBytes(content)
|
||||||
@ -78,7 +78,8 @@ class DownloadSessionTest {
|
|||||||
toUploader = new PipedOutputStream(fromDownloader)
|
toUploader = new PipedOutputStream(fromDownloader)
|
||||||
endpoint = new Endpoint(null, fromUploader, toUploader, null)
|
endpoint = new Endpoint(null, fromUploader, toUploader, null)
|
||||||
|
|
||||||
session = new DownloadSession(eventBus, "",pieces, infoHash, endpoint, target, pieceSize, size, available, new AtomicLong())
|
session = new DownloadSession(eventBus, "",pieces, infoHash, endpoint, target, pieceSize, size, available, new AtomicLong(),
|
||||||
|
browse, feed, chat)
|
||||||
downloadThread = new Thread( { perform() } as Runnable)
|
downloadThread = new Thread( { perform() } as Runnable)
|
||||||
downloadThread.setDaemon(true)
|
downloadThread.setDaemon(true)
|
||||||
downloadThread.start()
|
downloadThread.start()
|
||||||
|
@ -245,7 +245,7 @@ class MainFrameModel {
|
|||||||
core.eventBus.publish(new ContentControlEvent(term : it, regex: true, add: true))
|
core.eventBus.publish(new ContentControlEvent(term : it, regex: true, add: true))
|
||||||
}
|
}
|
||||||
|
|
||||||
chatServerRunning = core.chatServer.running.get()
|
chatServerRunning = core.chatServer.isRunning()
|
||||||
|
|
||||||
timer.schedule({
|
timer.schedule({
|
||||||
if (core.shutdown.get())
|
if (core.shutdown.get())
|
||||||
|
Reference in New Issue
Block a user