Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow for null directory to be passed to SharedTorrent.fromFile() constr... #103

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
82fb651
Fix read when message size wasn't read in one step
pankdm Apr 10, 2013
728edf8
Throw AnnounceException when current tracker client isn't available.
sroze Jul 18, 2013
9370d86
Fix order of uploaded/downloaded parameters in HTTPAnnounceRequestMes…
mpetazzoni Jul 22, 2013
1ad97ef
Merge pull request #45 from sroze/trackerless-patch
mpetazzoni Jul 22, 2013
2e643f4
add the ability to set upload/download rate-limits (in kB/sec.) on sh…
ptgoetz Jul 19, 2013
b15ea5e
add javadoc documentation for upload/download rate-limit functionality
ptgoetz Jul 22, 2013
73b78f2
reduce rate limit code duplication by refactoring code present in bot…
ptgoetz Jul 22, 2013
3ef9e9b
add example of upload/download rate limiting to the client usage sample.
ptgoetz Jul 22, 2013
13db7ab
add comments documenting the drawbacks/potential improvements for the…
ptgoetz Jul 22, 2013
00bc8f2
minor formatting/style modifications based on feedback from pull requ…
ptgoetz Jul 22, 2013
42775d5
Merge pull request #49 from ptgoetz/rate-limits
mpetazzoni Jul 23, 2013
59a2ec1
Fix a few styling issues from recent contributions
mpetazzoni Jul 23, 2013
c004fa8
Merge pull request #40 from pankdm/fix-incomplete-read
mpetazzoni Jul 23, 2013
64b8865
fixes Issue #47
oxlade39 Jul 22, 2013
a47a275
fixes turn/ttorrent#51
pwoodworth Jul 24, 2013
0dcb033
Merge pull request #50 from oxlade39/bug_fix
mpetazzoni Jul 24, 2013
bf4d679
Merge pull request #53 from pwoodworth/issue-51
mpetazzoni Jul 25, 2013
c1dbcd9
Update pom for compatibility with the maven-release-plugin
pwoodworth Jul 30, 2013
9e8abed
Use maven-shade-plugin to produce executable jar
pwoodworth Jul 30, 2013
5a499ce
Clean up javadoc problems
pwoodworth Jul 30, 2013
c06b110
Merge pull request #54 from pwoodworth/shaded
mpetazzoni Jul 31, 2013
f69190b
Merge pull request #55 from pwoodworth/releaseplugin
mpetazzoni Jul 31, 2013
89a6754
Merge pull request #56 from pwoodworth/javadoc
mpetazzoni Jul 31, 2013
0080296
Fix pom parent relative path
pwoodworth Aug 14, 2013
9e09ee5
Adding more platform agnostic shell scripts
pwoodworth Aug 15, 2013
d50eb99
Removing old shell scripts
pwoodworth Aug 15, 2013
86f4a2f
Merge pull request #57 from pwoodworth/scripts
mpetazzoni Aug 16, 2013
1c8dbfc
Move entry-point main methods to separate package
pwoodworth Aug 26, 2013
d33c361
Merge pull request #59 from pwoodworth/climove
mpetazzoni Aug 26, 2013
dbfd004
Fixes turn/ttorrent#42
pwoodworth Aug 28, 2013
06a3dfc
Merge pull request #60 from pwoodworth/issue-42
mpetazzoni Aug 28, 2013
dd8e7c9
Use commons-io throughout
pwoodworth Sep 11, 2013
f72705f
Merge pull request #63 from pwoodworth/commonsio
mpetazzoni Sep 12, 2013
d243274
Use commons-codec for hex and digest encoding
pwoodworth Aug 28, 2013
6fd448f
Merge pull request #64 from pwoodworth/codec
mpetazzoni Sep 17, 2013
869f664
Fix Piece compareTo ordering
pwoodworth Sep 20, 2013
32c66e1
Correcting improper use of Java 7 API
pwoodworth Sep 26, 2013
d787d9c
Merge pull request #65 from pwoodworth/piececompare
mpetazzoni Sep 30, 2013
cce0c02
Developer contact info updates
mpetazzoni Oct 24, 2013
01276bb
allow for null directory to be passed to SharedTorrent.fromFile() con…
Sep 5, 2014
d815e16
don't initialize if already done
Sep 5, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/ttorrent-torrent
Original file line number Diff line number Diff line change
@@ -15,4 +15,4 @@
# limitations under the License.

EXEFILE="${0%-torrent}"
MAINCLASS="com.turn.ttorrent.common.Torrent" "${EXEFILE}" "$@"
MAINCLASS="com.turn.ttorrent.cli.TorrentMain" "${EXEFILE}" "$@"
2 changes: 1 addition & 1 deletion bin/ttorrent-tracker
Original file line number Diff line number Diff line change
@@ -15,4 +15,4 @@
# limitations under the License.

EXEFILE="${0%-tracker}"
MAINCLASS="com.turn.ttorrent.tracker.Tracker" "${EXEFILE}" "$@"
MAINCLASS="com.turn.ttorrent.cli.TrackerMain" "${EXEFILE}" "$@"
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.turn.ttorrent.client.Client</Main-Class>
<Main-Class>com.turn.ttorrent.cli.ClientMain</Main-Class>
</manifestEntries>
</transformer>
</transformers>
176 changes: 176 additions & 0 deletions src/main/java/com/turn/ttorrent/cli/ClientMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* Copyright (C) 2011-2013 Turn, Inc.
*
* 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 com.turn.ttorrent.cli;

import com.turn.ttorrent.client.Client;
import com.turn.ttorrent.client.SharedTorrent;

import java.io.File;
import java.io.PrintStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.UnsupportedAddressTypeException;
import java.util.Enumeration;

import jargs.gnu.CmdLineParser;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Command-line entry-point for starting a {@link Client}
*/
public class ClientMain {

private static final Logger logger =
LoggerFactory.getLogger(ClientMain.class);

/**
* Default data output directory.
*/
private static final String DEFAULT_OUTPUT_DIRECTORY = "/tmp";

/**
* Returns a usable {@link Inet4Address} for the given interface name.
*
* <p>
* If an interface name is given, return the first usable IPv4 address for
* that interface. If no interface name is given or if that interface
* doesn't have an IPv4 address, return's localhost address (if IPv4).
* </p>
*
* <p>
* It is understood this makes the client IPv4 only, but it is important to
* remember that most BitTorrent extensions (like compact peer lists from
* trackers and UDP tracker support) are IPv4-only anyway.
* </p>
*
* @param iface The network interface name.
* @return A usable IPv4 address as a {@link Inet4Address}.
* @throws UnsupportedAddressTypeException If no IPv4 address was available
* to bind on.
*/
private static Inet4Address getIPv4Address(String iface)
throws SocketException, UnsupportedAddressTypeException,
UnknownHostException {
if (iface != null) {
Enumeration<InetAddress> addresses =
NetworkInterface.getByName(iface).getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address) {
return (Inet4Address)addr;
}
}
}

InetAddress localhost = InetAddress.getLocalHost();
if (localhost instanceof Inet4Address) {
return (Inet4Address)localhost;
}

throw new UnsupportedAddressTypeException();
}

/**
* Display program usage on the given {@link PrintStream}.
*/
private static void usage(PrintStream s) {
s.println("usage: Client [options] <torrent>");
s.println();
s.println("Available options:");
s.println(" -h,--help Show this help and exit.");
s.println(" -o,--output DIR Read/write data to directory DIR.");
s.println(" -i,--iface IFACE Bind to interface IFACE.");
s.println(" -s,--seed SECONDS Time to seed after downloading (default: infinitely).");
s.println(" -d,--max-download KB/SEC Max download rate (default: unlimited).");
s.println(" -u,--max-upload KB/SEC Max upload rate (default: unlimited).");
s.println();
}

/**
* Main client entry point for stand-alone operation.
*/
public static void main(String[] args) {
BasicConfigurator.configure(new ConsoleAppender(
new PatternLayout("%d [%-25t] %-5p: %m%n")));

CmdLineParser parser = new CmdLineParser();
CmdLineParser.Option help = parser.addBooleanOption('h', "help");
CmdLineParser.Option output = parser.addStringOption('o', "output");
CmdLineParser.Option iface = parser.addStringOption('i', "iface");
CmdLineParser.Option seedTime = parser.addIntegerOption('s', "seed");
CmdLineParser.Option maxUpload = parser.addDoubleOption('u', "max-upload");
CmdLineParser.Option maxDownload = parser.addDoubleOption('d', "max-download");

try {
parser.parse(args);
} catch (CmdLineParser.OptionException oe) {
System.err.println(oe.getMessage());
usage(System.err);
System.exit(1);
}

// Display help and exit if requested
if (Boolean.TRUE.equals((Boolean)parser.getOptionValue(help))) {
usage(System.out);
System.exit(0);
}

String outputValue = (String)parser.getOptionValue(output,
DEFAULT_OUTPUT_DIRECTORY);
String ifaceValue = (String)parser.getOptionValue(iface);
int seedTimeValue = (Integer)parser.getOptionValue(seedTime, -1);

double maxDownloadRate = (Double)parser.getOptionValue(maxDownload, 0.0);
double maxUploadRate = (Double)parser.getOptionValue(maxUpload, 0.0);

String[] otherArgs = parser.getRemainingArgs();
if (otherArgs.length != 1) {
usage(System.err);
System.exit(1);
}

try {
Client c = new Client(
getIPv4Address(ifaceValue),
SharedTorrent.fromFile(
new File(otherArgs[0]),
new File(outputValue)));

c.setMaxDownloadRate(maxDownloadRate);
c.setMaxUploadRate(maxUploadRate);

// Set a shutdown hook that will stop the sharing/seeding and send
// a STOPPED announce request.
Runtime.getRuntime().addShutdownHook(
new Thread(new Client.ClientShutdown(c, null)));

c.share(seedTimeValue);
if (Client.ClientState.ERROR.equals(c.getState())) {
System.exit(1);
}
} catch (Exception e) {
logger.error("Fatal error: {}", e.getMessage(), e);
System.exit(2);
}
}
}
169 changes: 169 additions & 0 deletions src/main/java/com/turn/ttorrent/cli/TorrentMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* Copyright (C) 2011-2013 Turn, Inc.
*
* 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 com.turn.ttorrent.cli;

import com.turn.ttorrent.common.Torrent;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;
import java.util.Arrays;

import jargs.gnu.CmdLineParser;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Command-line entry-point for reading and writing {@link Torrent} files.
*/
public class TorrentMain {

private static final Logger logger =
LoggerFactory.getLogger(TorrentMain.class);

/**
* Display program usage on the given {@link PrintStream}.
*/
private static void usage(PrintStream s) {
usage(s, null);
}

/**
* Display a message and program usage on the given {@link PrintStream}.
*/
private static void usage(PrintStream s, String msg) {
if (msg != null) {
s.println(msg);
s.println();
}

s.println("usage: Torrent [options] [file|directory]");
s.println();
s.println("Available options:");
s.println(" -h,--help Show this help and exit.");
s.println(" -t,--torrent FILE Use FILE to read/write torrent file.");
s.println();
s.println(" -c,--create Create a new torrent file using " +
"the given announce URL and data.");
s.println(" -a,--announce Tracker URL (can be repeated).");
s.println();
}

/**
* Torrent reader and creator.
*
* <p>
* You can use the {@code main()} function of this class to read or create
* torrent files. See usage for details.
* </p>
*
* TODO: support multiple announce URLs.
*/
public static void main(String[] args) {
BasicConfigurator.configure(new ConsoleAppender(
new PatternLayout("%-5p: %m%n")));

CmdLineParser parser = new CmdLineParser();
CmdLineParser.Option help = parser.addBooleanOption('h', "help");
CmdLineParser.Option filename = parser.addStringOption('t', "torrent");
CmdLineParser.Option create = parser.addBooleanOption('c', "create");
CmdLineParser.Option announce = parser.addStringOption('a', "announce");

try {
parser.parse(args);
} catch (CmdLineParser.OptionException oe) {
System.err.println(oe.getMessage());
usage(System.err);
System.exit(1);
}

// Display help and exit if requested
if (Boolean.TRUE.equals((Boolean)parser.getOptionValue(help))) {
usage(System.out);
System.exit(0);
}

String filenameValue = (String)parser.getOptionValue(filename);
if (filenameValue == null) {
usage(System.err, "Torrent file must be provided!");
System.exit(1);
}

Boolean createFlag = (Boolean)parser.getOptionValue(create);
String announceURL = (String)parser.getOptionValue(announce);

String[] otherArgs = parser.getRemainingArgs();

if (Boolean.TRUE.equals(createFlag) &&
(otherArgs.length != 1 || announceURL == null)) {
usage(System.err, "Announce URL and a file or directory must be " +
"provided to create a torrent file!");
System.exit(1);
}

OutputStream fos = null;
try {
if (Boolean.TRUE.equals(createFlag)) {
if (filenameValue != null) {
fos = new FileOutputStream(filenameValue);
} else {
fos = System.out;
}

URI announceURI = new URI(announceURL);
File source = new File(otherArgs[0]);
if (!source.exists() || !source.canRead()) {
throw new IllegalArgumentException(
"Cannot access source file or directory " +
source.getName());
}

String creator = String.format("%s (ttorrent)",
System.getProperty("user.name"));

Torrent torrent = null;
if (source.isDirectory()) {
File[] files = source.listFiles();
Arrays.sort(files);
torrent = Torrent.create(source, Arrays.asList(files),
announceURI, creator);
} else {
torrent = Torrent.create(source, announceURI, creator);
}

torrent.save(fos);
} else {
Torrent.load(new File(filenameValue), true);
}
} catch (Exception e) {
logger.error("{}", e.getMessage(), e);
System.exit(2);
} finally {
if (fos != null && fos != System.out) {
try {
fos.close();
} catch (IOException ioe) {
}
}
}
}
}
Loading