All shared directories are watched directories. Fix manipulation of tree structure

This commit is contained in:
Zlatin Balevsky
2019-10-15 08:38:23 +01:00
parent 70fb789abf
commit f5bccd8126
8 changed files with 81 additions and 22 deletions

View File

@@ -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)

View File

@@ -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)) }

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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

View File

@@ -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))
} }
} }
} }

View 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()
}
}

View File

@@ -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