diff --git a/core/src/main/groovy/com/muwire/core/files/FileHashedEvent.groovy b/core/src/main/groovy/com/muwire/core/files/FileHashedEvent.groovy index 57d46237..8aea59a2 100644 --- a/core/src/main/groovy/com/muwire/core/files/FileHashedEvent.groovy +++ b/core/src/main/groovy/com/muwire/core/files/FileHashedEvent.groovy @@ -1,8 +1,10 @@ package com.muwire.core.files import com.muwire.core.Event +import com.muwire.core.SharedFile class FileHashedEvent extends Event { - def sharedFile + SharedFile sharedFile + String error } diff --git a/core/src/main/groovy/com/muwire/core/files/HasherService.groovy b/core/src/main/groovy/com/muwire/core/files/HasherService.groovy index 04fc9910..fd570d15 100644 --- a/core/src/main/groovy/com/muwire/core/files/HasherService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/HasherService.groovy @@ -1,5 +1,42 @@ package com.muwire.core.files +import java.util.concurrent.Executor +import java.util.concurrent.Executors + +import com.muwire.core.SharedFile + class HasherService { + final FileHasher hasher + final def listener + Executor executor + + HasherService(FileHasher hasher, def listener) { + this.hasher = hasher + this.listener = listener + } + + void start() { + executor = Executors.newSingleThreadExecutor() + } + + void onFileSharedEvent(FileSharedEvent evt) { + executor.execute( { -> process(evt.file) } as Runnable) + } + + private void process(File f) { + f = f.getCanonicalFile() + if (f.isDirectory()) { + f.listFiles().each {onFileSharedEvent new FileSharedEvent(file: it) } + } else { + if (f.length() == 0) { + listener.publish new FileHashedEvent(error: "Not sharing empty file $f") + } else if (f.length() > FileHasher.MAX_SIZE) { + listener.publish new FileHashedEvent(error: "$f is too large to be shared ${f.length()}") + } else { + def hash = hasher.hashFile f + listener.publish new FileHashedEvent(sharedFile: new SharedFile(f, hash)) + } + } + } } diff --git a/core/src/test/groovy/com/muwire/core/files/HasherServiceTest.groovy b/core/src/test/groovy/com/muwire/core/files/HasherServiceTest.groovy new file mode 100644 index 00000000..98da621d --- /dev/null +++ b/core/src/test/groovy/com/muwire/core/files/HasherServiceTest.groovy @@ -0,0 +1,58 @@ +package com.muwire.core.files + +import java.util.concurrent.ArrayBlockingQueue +import java.util.concurrent.TimeUnit + +import org.junit.After +import org.junit.Before +import org.junit.Test + +class HasherServiceTest { + + HasherService service + FileHasher hasher + def listener = new ArrayBlockingQueue(100) { + void publish(def evt) { + offer evt + } + } + + @Before + void before() { + hasher = new FileHasher() + service = new HasherService(hasher, listener) + service.start() + } + + @After + void after() { + listener.clear() + } + + @Test + void testSingleFile() { + File f = new File("build.gradle") + service.onFileSharedEvent new FileSharedEvent(file: f) + Thread.sleep(100) + def hashed = listener.poll() + assert hashed instanceof FileHashedEvent + assert hashed.sharedFile.file == f.getCanonicalFile() + assert hashed.sharedFile.infoHash != null + assert listener.isEmpty() + } + + @Test + void testDirectory() { + File f = new File(".") + service.onFileSharedEvent new FileSharedEvent(file: f) + Set fileNames = new HashSet<>() + while (true) { + def hashed = listener.poll(100, TimeUnit.MILLISECONDS) + if (hashed == null) + break + fileNames.add(hashed.sharedFile?.file?.getName()) + } + assert fileNames.contains("build.gradle") + assert fileNames.contains("HasherServiceTest.groovy") + } +}