mpetazzoni / ttorrent

BitTorrent Java library with tracker and download client
http://mpetazzoni.github.com/ttorrent/
Apache License 2.0
1.38k stars 502 forks source link

Tracking new torrent files in the directory #218

Closed dev-talha-akbar closed 5 years ago

dev-talha-akbar commented 6 years ago

The example code from the official repository loads torrent files from a given directory and announce them to the tracker. Then, starts it. I was hoping that the tracker would look for new torrent files in the directory automatically but, it doesn't seem to do so.

I pulled in a DirectoryWatcher and listened to create event; filtering torrent files. Passing the reference of Tracker object, I can announce the new file but, it doesn't seem to do anything.

How can I make the tracker aware of possible new torrent files in the directory while it's running?

import com.turn.ttorrent.tracker.TrackedTorrent;
import com.turn.ttorrent.tracker.Tracker;
import io.methvin.watcher.DirectoryChangeEvent;
import io.methvin.watcher.DirectoryChangeListener;
import io.methvin.watcher.DirectoryWatcher;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Path;

public class DirectoryAwareTracker extends Tracker {
    private DirectoryWatcher watcher;

    private static final FilenameFilter torrentFilenameFilter = new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".torrent");
        }
    };

    DirectoryAwareTracker(InetSocketAddress address, Path directoryToWatch) throws IOException {
        super(address);

        File parent = new File(".");
        for (File f : parent.listFiles(torrentFilenameFilter)) {
            System.out.println("Loading torrent from " + f.getName());
            try {
                announce(TrackedTorrent.load(f));
            } catch (Exception e) {

            }
        }

        System.out.println("Starting tracker with {} announced torrents..." + getTrackedTorrents().size());

        start();

        watcher = DirectoryWatcher.create(directoryToWatch, new DirectoryChangeListener() {
            @Override
            public void onEvent(DirectoryChangeEvent directoryChangeEvent) throws IOException {
                switch (directoryChangeEvent.eventType()) {
                    case CREATE:
                        File newFile = new File(directoryChangeEvent.path().toString());
                        System.out.println(directoryChangeEvent.path().toString());
                        System.out.println(newFile.isFile());
                        System.out.println(newFile.getName().endsWith(".torrent"));
                        if (newFile.isFile() && newFile.getName().endsWith(".torrent")) {
                            try {
                                announce(TrackedTorrent.load(newFile));
                            } catch (Exception e) {

                            }
                        }
                        break;
                }
            }
        });
    }

    public void stopWatching() {
        try {
            watcher.close();
        }
        catch(Exception e) { }
    }

    public void watch() {
        watcher.watch();
    }
}
mpetazzoni commented 6 years ago

What do you mean by "it doesn't do anything"?

Do you see the Registered new torrent ... log line when a new torrent file is created in the directory? If so, what happens when you try to start a client downloading this torrent file (via this tracker)?

dev-talha-akbar commented 6 years ago

I see log lines with the TorrentFile generator class. The running tracker doesn't show any signs of knowing that a torrent file has been created in the directory even when I explicitly call announce() in the create event of directory watcher.

I have not written code for a client yet. I use uTorrent if I need to. But, I'm not sure how the tracker will give anything good to the client if it doesn't even have a record of that file.

Let me know if I can help with anything else.

Edit: According to your Tracker.java file, it should run the following statement regardless:

logger.info("Registered new torrent for '{}' with hash {}.", torrent.getName(), torrent.getHexInfoHash());

I am not sure about synchronized keyword used in the announce(). Maybe, announce() is never called. Because, I tried over-ridding your announce() method with a simpler log statement and it didn't call it either.

Also, When directory watcher starts, it runs synchronously.

mpetazzoni commented 6 years ago

Seems like you might need to debug your code some more. Your call to announce(TrackedTorrent.load(newFile)); might throw an exception but you're silently swallowing it. Maybe add a log statement in that catch block to see if that's your issue?

dev-talha-akbar commented 5 years ago

Yes, you were right. I tracked the issue by logging the exception. There was a NullPointerException being thrown. Upon further investigation, I found that the directory watcher fires CREATE event as soon as the file record is added to the file system when the contents of the file are not even present. To fix the issue, I am listening to MODIFY event from the directory watcher and it works!