All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bt.cli.CliClient Maven / Gradle / Ivy

The newest version!
package bt.cli;

import bt.Bt;
import bt.data.Storage;
import bt.data.file.FileSystemStorage;
import bt.peerexchange.PeerExchangeModule;
import bt.runtime.BtClient;
import bt.runtime.BtRuntime;
import bt.tracker.http.HttpTrackerModule;
import com.googlecode.lanterna.input.KeyStroke;
import joptsimple.OptionException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;

public class CliClient  {

    private static final Logger LOGGER = LoggerFactory.getLogger(CliClient.class);

    static {
        registerLog4jShutdownHook();
    }

    public static void main(String[] args) throws IOException {

        Options options;
        try {
            options = Options.parse(args);
        } catch (OptionException e) {
            Options.printHelp(System.out);
            return;
        }

        new CliClient(options).resume();
    }

    private Options options;

    private BtRuntime runtime;
    private BtClient client;
    private SessionStatePrinter printer;

    private boolean running;

    private CliClient(Options options) {
        this.options = options;

        Collection keyBindings = Collections.singletonList(
                new KeyStrokeBinding(KeyStroke.fromString("p"), this::togglePause));

        this.runtime = BtRuntime.builder()
                .module(new PeerExchangeModule())
                .module(new HttpTrackerModule())
                .disableAutomaticShutdown()
                .build();

        Storage storage = new FileSystemStorage(options.getTargetDirectory());

        this.client = Bt.client(storage)
                .url(toUrl(options.getMetainfoFile()))
                .attachToRuntime(runtime);

        this.printer = SessionStatePrinter.createKeyInputAwarePrinter(
                client.getSession().getTorrent(), keyBindings);
    }

    void resume() {
        if (running) {
            return;
        }

        running = true;
        try {
            client.startAsync(state -> {
                printer.print(state);
                if (!options.shouldSeedAfterDownloaded() && state.getPiecesRemaining() == 0) {
                    runtime.shutdown();
                }
            }, 1000);
        } catch (Throwable e) {
            // in case the start request to the tracker fails
            printer.shutdown();
            printAndShutdown(e);
        }
    }

    void pause() {
        if (!running) {
            return;
        }

        try {
            client.stop();
        } catch (Throwable e) {
            LOGGER.warn("Unexpected error when stopping client", e);
        } finally {
            running = false;
        }
    }

    private static URL toUrl(File file) {
        try {
            return file.toURI().toURL();
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("Unexpected error", e);
        }
    }

    private void togglePause() {
        if (running) {
            pause();
        } else {
            resume();
        }
    }

    private static void printAndShutdown(Throwable e) {
        // ignore interruptions on shutdown
        if (!(e instanceof InterruptedException)) {
            LOGGER.error("Unexpected error, exiting...", e);
        }
        System.exit(1);
    }

    private static void registerLog4jShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                if( LogManager.getContext() instanceof LoggerContext) {
                    Configurator.shutdown((LoggerContext)LogManager.getContext());
                }
            }
        });
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy