All shared directories are watched directories. Fix manipulation of tree structure
This commit is contained in:
@@ -282,7 +282,7 @@ public class Core {
|
|||||||
i2pAcceptor, hostCache, trustService, searchManager, uploadManager, connectionEstablisher)
|
i2pAcceptor, hostCache, trustService, searchManager, uploadManager, connectionEstablisher)
|
||||||
|
|
||||||
log.info("initializing directory watcher")
|
log.info("initializing directory watcher")
|
||||||
directoryWatcher = new DirectoryWatcher(eventBus, fileManager)
|
directoryWatcher = new DirectoryWatcher(eventBus, fileManager, home, props)
|
||||||
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)
|
eventBus.register(DirectoryUnsharedEvent.class, directoryWatcher)
|
||||||
@@ -290,6 +290,8 @@ public class Core {
|
|||||||
log.info("initializing hasher service")
|
log.info("initializing hasher service")
|
||||||
hasherService = new HasherService(new FileHasher(), eventBus, fileManager)
|
hasherService = new HasherService(new FileHasher(), eventBus, fileManager)
|
||||||
eventBus.register(FileSharedEvent.class, hasherService)
|
eventBus.register(FileSharedEvent.class, hasherService)
|
||||||
|
eventBus.register(FileUnsharedEvent.class, hasherService)
|
||||||
|
eventBus.register(DirectoryUnsharedEvent.class, hasherService)
|
||||||
|
|
||||||
log.info("initializing trust subscriber")
|
log.info("initializing trust subscriber")
|
||||||
trustSubscriber = new TrustSubscriber(eventBus, i2pConnector, props)
|
trustSubscriber = new TrustSubscriber(eventBus, i2pConnector, props)
|
||||||
|
@@ -6,6 +6,7 @@ import com.muwire.core.hostcache.CrawlerResponse
|
|||||||
import com.muwire.core.util.DataUtil
|
import com.muwire.core.util.DataUtil
|
||||||
|
|
||||||
import net.i2p.data.Base64
|
import net.i2p.data.Base64
|
||||||
|
import net.i2p.util.ConcurrentHashSet
|
||||||
|
|
||||||
class MuWireSettings {
|
class MuWireSettings {
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ class MuWireSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> readEncodedSet(Properties props, String property) {
|
private static Set<String> readEncodedSet(Properties props, String property) {
|
||||||
Set<String> rv = new HashSet<>()
|
Set<String> rv = new ConcurrentHashSet<>()
|
||||||
if (props.containsKey(property)) {
|
if (props.containsKey(property)) {
|
||||||
String[] encoded = props.getProperty(property).split(",")
|
String[] encoded = props.getProperty(property).split(",")
|
||||||
encoded.each { rv << DataUtil.readi18nString(Base64.decode(it)) }
|
encoded.each { rv << DataUtil.readi18nString(Base64.decode(it)) }
|
||||||
|
@@ -13,6 +13,7 @@ import java.nio.file.WatchService
|
|||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
import com.muwire.core.EventBus
|
import com.muwire.core.EventBus
|
||||||
|
import com.muwire.core.MuWireSettings
|
||||||
import com.muwire.core.SharedFile
|
import com.muwire.core.SharedFile
|
||||||
|
|
||||||
import groovy.util.logging.Log
|
import groovy.util.logging.Log
|
||||||
@@ -31,6 +32,8 @@ class DirectoryWatcher {
|
|||||||
kinds = [ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE]
|
kinds = [ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final File home
|
||||||
|
private final MuWireSettings muOptions
|
||||||
private final EventBus eventBus
|
private final EventBus eventBus
|
||||||
private final FileManager fileManager
|
private final FileManager fileManager
|
||||||
private final Thread watcherThread, publisherThread
|
private final Thread watcherThread, publisherThread
|
||||||
@@ -39,7 +42,9 @@ class DirectoryWatcher {
|
|||||||
private WatchService watchService
|
private WatchService watchService
|
||||||
private volatile boolean shutdown
|
private volatile boolean shutdown
|
||||||
|
|
||||||
DirectoryWatcher(EventBus eventBus, FileManager fileManager) {
|
DirectoryWatcher(EventBus eventBus, FileManager fileManager, File home, MuWireSettings muOptions) {
|
||||||
|
this.home = home
|
||||||
|
this.muOptions = muOptions
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.fileManager = fileManager
|
this.fileManager = fileManager
|
||||||
this.watcherThread = new Thread({watch() } as Runnable, "directory-watcher")
|
this.watcherThread = new Thread({watch() } as Runnable, "directory-watcher")
|
||||||
@@ -64,15 +69,28 @@ class DirectoryWatcher {
|
|||||||
void onFileSharedEvent(FileSharedEvent e) {
|
void onFileSharedEvent(FileSharedEvent e) {
|
||||||
if (!e.file.isDirectory())
|
if (!e.file.isDirectory())
|
||||||
return
|
return
|
||||||
Path path = e.file.getCanonicalFile().toPath()
|
File canonical = e.file.getCanonicalFile()
|
||||||
|
Path path = canonical.toPath()
|
||||||
WatchKey wk = path.register(watchService, kinds)
|
WatchKey wk = path.register(watchService, kinds)
|
||||||
watchedDirectories.put(e.file, wk)
|
watchedDirectories.put(canonical, wk)
|
||||||
|
|
||||||
|
if (muOptions.watchedDirectories.add(canonical.toString()))
|
||||||
|
saveMuSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDirectoryUnsharedEvent(DirectoryUnsharedEvent e) {
|
void onDirectoryUnsharedEvent(DirectoryUnsharedEvent e) {
|
||||||
WatchKey wk = watchedDirectories.remove(e.directory)
|
WatchKey wk = watchedDirectories.remove(e.directory)
|
||||||
wk?.cancel()
|
wk?.cancel()
|
||||||
|
|
||||||
|
if (muOptions.watchedDirectories.remove(e.directory.toString()))
|
||||||
|
saveMuSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveMuSettings() {
|
||||||
|
File muSettingsFile = new File(home, "MuWire.properties")
|
||||||
|
muSettingsFile.withOutputStream {
|
||||||
|
muOptions.write(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void watch() {
|
private void watch() {
|
||||||
|
@@ -11,6 +11,7 @@ class HasherService {
|
|||||||
final FileHasher hasher
|
final FileHasher hasher
|
||||||
final EventBus eventBus
|
final EventBus eventBus
|
||||||
final FileManager fileManager
|
final FileManager fileManager
|
||||||
|
final Set<File> hashed = new HashSet<>()
|
||||||
Executor executor
|
Executor executor
|
||||||
|
|
||||||
HasherService(FileHasher hasher, EventBus eventBus, FileManager fileManager) {
|
HasherService(FileHasher hasher, EventBus eventBus, FileManager fileManager) {
|
||||||
@@ -24,13 +25,22 @@ class HasherService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onFileSharedEvent(FileSharedEvent evt) {
|
void onFileSharedEvent(FileSharedEvent evt) {
|
||||||
if (fileManager.fileToSharedFile.containsKey(evt.file.getCanonicalFile()))
|
File canonical = evt.file.getCanonicalFile()
|
||||||
|
if (fileManager.fileToSharedFile.containsKey(canonical))
|
||||||
return
|
return
|
||||||
executor.execute( { -> process(evt.file) } as Runnable)
|
if (hashed.add(canonical))
|
||||||
|
executor.execute( { -> process(canonical) } as Runnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
void onFileUnsharedEvent(FileUnsharedEvent evt) {
|
||||||
|
hashed.remove(evt.unsharedFile.file)
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDirectoryUnsharedEvent(DirectoryUnsharedEvent evt) {
|
||||||
|
hashed.remove(evt.directory)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(File f) {
|
private void process(File f) {
|
||||||
f = f.getCanonicalFile()
|
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
f.listFiles().each {eventBus.publish new FileSharedEvent(file: it) }
|
f.listFiles().each {eventBus.publish new FileSharedEvent(file: it) }
|
||||||
} else {
|
} else {
|
||||||
|
@@ -2,6 +2,7 @@ package com.muwire.gui
|
|||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ import com.muwire.core.content.ContentControlEvent
|
|||||||
import com.muwire.core.download.DownloadStartedEvent
|
import com.muwire.core.download.DownloadStartedEvent
|
||||||
import com.muwire.core.download.Downloader
|
import com.muwire.core.download.Downloader
|
||||||
import com.muwire.core.files.AllFilesLoadedEvent
|
import com.muwire.core.files.AllFilesLoadedEvent
|
||||||
|
import com.muwire.core.files.DirectoryUnsharedEvent
|
||||||
import com.muwire.core.files.FileDownloadedEvent
|
import com.muwire.core.files.FileDownloadedEvent
|
||||||
import com.muwire.core.files.FileHashedEvent
|
import com.muwire.core.files.FileHashedEvent
|
||||||
import com.muwire.core.files.FileHashingEvent
|
import com.muwire.core.files.FileHashingEvent
|
||||||
@@ -350,6 +352,7 @@ class MainFrameModel {
|
|||||||
runInsideUIAsync {
|
runInsideUIAsync {
|
||||||
shared.remove(e.unsharedFile)
|
shared.remove(e.unsharedFile)
|
||||||
loadedFiles = shared.size()
|
loadedFiles = shared.size()
|
||||||
|
|
||||||
def dmtn = fileToNode.remove(e.unsharedFile)
|
def dmtn = fileToNode.remove(e.unsharedFile)
|
||||||
if (dmtn != null) {
|
if (dmtn != null) {
|
||||||
loadedFiles = fileToNode.size()
|
loadedFiles = fileToNode.size()
|
||||||
@@ -359,12 +362,15 @@ class MainFrameModel {
|
|||||||
if (parent == treeRoot)
|
if (parent == treeRoot)
|
||||||
break
|
break
|
||||||
if (parent.getChildCount() == 0) {
|
if (parent.getChildCount() == 0) {
|
||||||
|
File file = parent.getUserObject().file
|
||||||
|
if (core.muOptions.watchedDirectories.contains(file.toString()))
|
||||||
|
core.eventBus.publish(new DirectoryUnsharedEvent(directory : parent.getUserObject().file))
|
||||||
dmtn = parent
|
dmtn = parent
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.refreshSharedFiles()
|
view.refreshSharedFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,22 +520,28 @@ class MainFrameModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void insertIntoTree(SharedFile file) {
|
private void insertIntoTree(SharedFile file) {
|
||||||
Path folder = file.getFile().toPath()
|
List<File> parents = new ArrayList<>()
|
||||||
folder = folder.subpath(0, folder.getNameCount() - 1)
|
File tmp = file.file.getParentFile()
|
||||||
|
while(tmp.getParent() != null) {
|
||||||
|
parents << tmp
|
||||||
|
tmp = tmp.getParentFile()
|
||||||
|
}
|
||||||
|
Collections.reverse(parents)
|
||||||
TreeNode node = treeRoot
|
TreeNode node = treeRoot
|
||||||
for(Path path : folder) {
|
for(File path : parents) {
|
||||||
boolean exists = false
|
boolean exists = false
|
||||||
def children = node.children()
|
def children = node.children()
|
||||||
def child = null
|
def child = null
|
||||||
while(children.hasMoreElements()) {
|
while(children.hasMoreElements()) {
|
||||||
child = children.nextElement()
|
child = children.nextElement()
|
||||||
if (child.getUserObject() == path.toString()) {
|
def userObject = child.getUserObject()
|
||||||
|
if (userObject != null && userObject.file == path) {
|
||||||
exists = true
|
exists = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
child = new DefaultMutableTreeNode(path.toString())
|
child = new DefaultMutableTreeNode(new InterimTreeNode(path))
|
||||||
node.add(child)
|
node.add(child)
|
||||||
}
|
}
|
||||||
node = child
|
node = child
|
||||||
|
@@ -418,10 +418,7 @@ class MainFrameView {
|
|||||||
public boolean importData(TransferHandler.TransferSupport support) {
|
public boolean importData(TransferHandler.TransferSupport support) {
|
||||||
def files = support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor)
|
def files = support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor)
|
||||||
files.each {
|
files.each {
|
||||||
if (it.isDirectory())
|
model.core.eventBus.publish(new FileSharedEvent(file : it))
|
||||||
watchDirectory(it)
|
|
||||||
else
|
|
||||||
model.core.eventBus.publish(new FileSharedEvent(file : it))
|
|
||||||
}
|
}
|
||||||
showUploadsWindow.call()
|
showUploadsWindow.call()
|
||||||
true
|
true
|
||||||
@@ -692,7 +689,7 @@ class MainFrameView {
|
|||||||
getLeafs(children.nextElement(), dest)
|
getLeafs(children.nextElement(), dest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def copyHashToClipboard() {
|
def copyHashToClipboard() {
|
||||||
def selectedFiles = selectedSharedFiles()
|
def selectedFiles = selectedSharedFiles()
|
||||||
if (selectedFiles == null)
|
if (selectedFiles == null)
|
||||||
@@ -863,7 +860,8 @@ class MainFrameView {
|
|||||||
int rv = chooser.showOpenDialog(null)
|
int rv = chooser.showOpenDialog(null)
|
||||||
if (rv == JFileChooser.APPROVE_OPTION) {
|
if (rv == JFileChooser.APPROVE_OPTION) {
|
||||||
chooser.getSelectedFiles().each {
|
chooser.getSelectedFiles().each {
|
||||||
model.core.eventBus.publish(new FileSharedEvent(file : it))
|
File canonical = it.getCanonicalFile()
|
||||||
|
model.core.eventBus.publish(new FileSharedEvent(file : canonical))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
gui/src/main/groovy/com/muwire/gui/InterimTreeNode.groovy
Normal file
18
gui/src/main/groovy/com/muwire/gui/InterimTreeNode.groovy
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.muwire.gui
|
||||||
|
|
||||||
|
class InterimTreeNode {
|
||||||
|
private final File file
|
||||||
|
InterimTreeNode(File file) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof InterimTreeNode))
|
||||||
|
return false
|
||||||
|
file == o.file
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
file.getName()
|
||||||
|
}
|
||||||
|
}
|
@@ -23,7 +23,7 @@ class SharedTreeRenderer extends DefaultTreeCellRenderer {
|
|||||||
|
|
||||||
def userObject = value.getUserObject()
|
def userObject = value.getUserObject()
|
||||||
def defaultRenderer = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus)
|
def defaultRenderer = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus)
|
||||||
if (userObject instanceof String || userObject == null)
|
if (userObject instanceof InterimTreeNode || userObject == null)
|
||||||
return defaultRenderer
|
return defaultRenderer
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user