Package net.plan99.payfile.client

Source Code of net.plan99.payfile.client.CLI

/**
* Author: Mike Hearn <mhearn@bitcoinfoundation.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.plan99.payfile.client;

import asg.cliche.Command;
import asg.cliche.Param;
import asg.cliche.ShellFactory;
import com.google.bitcoin.core.*;
import com.google.bitcoin.kits.WalletAppKit;
import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.params.TestNet3Params;
import com.google.bitcoin.protocols.channels.StoredPaymentChannelClientStates;
import com.google.bitcoin.utils.BriefLogFormatter;
import joptsimple.BuiltinHelpFormatter;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
import java.util.List;

import static joptsimple.util.RegexMatcher.regex;

public class CLI {
    public static NetworkParameters params;
    private static String filePrefix;

    private PayFileClient client;
    private List<PayFileClient.File> files;
    private WalletAppKit appkit;

    public CLI(Socket socket) throws IOException {
        appkit = new WalletAppKit(params, new File("."), filePrefix + "payfile-cli") {
            @Override
            protected void addWalletExtensions() throws Exception {
                super.addWalletExtensions();
                wallet().addExtension(new StoredPaymentChannelClientStates(wallet(), peerGroup()));
            }
        };

        if (params == RegTestParams.get()) {
            appkit.connectToLocalHost();   // You should run a regtest mode bitcoind locally.
        } else if (params == MainNetParams.get()) {
            // Checkpoints are block headers that ship inside our app: for a new user, we pick the last header
            // in the checkpoints file and then download the rest from the network. It makes things much faster.
            // Checkpoint files are made using the BuildCheckpoints tool and usually we have to download the
            // last months worth or more (takes a few seconds).
            appkit.setCheckpoints(getClass().getResourceAsStream("checkpoints"));
        }

        appkit.setBlockingStartup(false)
                .setUserAgent("Payfile CLI","1.0")
                .startAndWait();

        appkit.wallet().allowSpendingUnconfirmedTransactions();
        appkit.wallet().addEventListener(new AbstractWalletEventListener() {
            @Override
            public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
                System.out.println("Received money: " + Utils.bitcoinValueToFriendlyString(tx.getValueSentToMe(appkit.wallet())));
            }
        });
        System.out.println("Send coins to " + appkit.wallet().getKeys().get(0).toAddress(params));
        System.out.println("Your balance is " + Utils.bitcoinValueToFriendlyString(appkit.wallet().getBalance()));
        client = new PayFileClient(socket, appkit.wallet());
    }

    public void shutdown() {
        client.disconnect();
        appkit.stopAndWait();
    }

    @Command(description = "Show the files advertised by the remote server")
    public void ls() throws Exception {
        files = client.queryFiles().get();
        for (PayFileClient.File file : files) {
            String priceMessage = Utils.bitcoinValueToFriendlyString(BigInteger.valueOf(file.getPrice()));
            String affordability = file.isAffordable() ? "" : ", unaffordable";
            String str = String.format("%d)  [%d bytes, %s%s] \"%s\" :  %s", file.getHandle(),
                    file.getSize(), priceMessage, affordability, file.getFileName(), file.getDescription());
            System.out.println(str);
        }
    }

    @Command(description = "Download the given file ID to the given directory")
    public void get(
            @Param(name="handle", description="Numeric ID of the file") int handle,
            @Param(name="directory", description="Directory to save the file to") String directory) throws Exception {
        if (files == null) {
            System.out.println("Fetching file list ...");
            files = client.queryFiles().get();
        }
        File dir = new File(directory);
        if (!dir.isDirectory()) {
            System.out.println(directory + " is not a directory");
            return;
        }
        String fileName = null;
        PayFileClient.File serverFile = null;
        for (PayFileClient.File f : files) {
            if (f.getHandle() == handle) {
                fileName = f.getFileName();
                serverFile = f;
                break;
            }
        }
        if (serverFile == null) {
            System.out.println("Unknown file handle " + handle);
            return;
        }
        File output = new File(dir, fileName);
        final PayFileClient.File fServerFile = serverFile;
        FileOutputStream stream = new FileOutputStream(output) {
            @Override
            public void write(byte[] b) throws IOException {
                super.write(b);
                final long bytesDownloaded = fServerFile.getBytesDownloaded();
                double percentDone = bytesDownloaded / (double) fServerFile.getSize() * 100;
                System.out.println(String.format("Downloaded %d kilobytes [%.2f%% done]", bytesDownloaded / 1024, percentDone));
            }
        };
        client.downloadFile(serverFile, stream).get();
        System.out.println(String.format("Downloaded %s successfully.", fileName));
        System.out.println(String.format("You have %s remaining.", Utils.bitcoinValueToFriendlyString(client.getRemainingBalance())));
    }

    @Command(description = "Print info about your wallet")
    public void wallet() {
        System.out.println(appkit.wallet().toString(false, true, true, appkit.chain()));
        System.out.println("Total remaining: " + Utils.bitcoinValueToFriendlyString(client.getRemainingBalance()));
    }

    public static void main(String[] args) throws Exception {
        BriefLogFormatter.init();
        //Logger.getLogger("").setLevel(Level.OFF);
        // allow client to choose another network for testing by passing through an argument.
        OptionParser parser = new OptionParser();
        parser.accepts("network").withRequiredArg().withValuesConvertedBy(regex("(mainnet)|(testnet)|(regtest)")).defaultsTo("mainnet");
        parser.accepts("server").withRequiredArg().required();
        parser.accepts("help").forHelp();
        parser.formatHelpWith(new BuiltinHelpFormatter(120, 10));
        OptionSet options;

        try {
            options = parser.parse(args);
        } catch (OptionException e) {
            System.err.println(e.getMessage());
            System.err.println("");
            parser.printHelpOn(System.err);
            return;
        }

        if (options.has("help")) {
            parser.printHelpOn(System.out);
            return;
        }

        if (options.valueOf("network").equals(("testnet"))) {
            params = TestNet3Params.get();
            filePrefix = "testnet-";
        } else if (options.valueOf("network").equals(("mainnet"))) {
            params = MainNetParams.get();
            filePrefix = "";
        } else if (options.valueOf("network").equals(("regtest"))) {
            params = RegTestParams.get();
            filePrefix = "regtest-";
        }

        String server = options.valueOf("server").toString();
        System.out.println("Connecting to " + server);
        Socket socket = new Socket(server, 18754);
        final CLI cli = new CLI(socket);
        ShellFactory.createConsoleShell(server, "PayFile", cli).commandLoop();
        cli.shutdown();
    }
}
TOP

Related Classes of net.plan99.payfile.client.CLI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.