package com.frostwire.jlibtorrent;
import com.frostwire.jlibtorrent.swig.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents the information stored in a .torrent file
*
* @author gubatron
* @author aldenml
*/
public final class TorrentInfo {
private final torrent_info ti;
public TorrentInfo(torrent_info ti) {
this.ti = ti;
}
/**
* load the torrent file and decode it inside
* the constructor, for convenience. This might not be the most suitable for applications that
* want to be able to report detailed errors on what might go wrong.
*
* @param torrent
*/
public TorrentInfo(File torrent) {
this(new torrent_info(torrent.getAbsolutePath()));
}
public torrent_info getSwig() {
return this.ti;
}
/**
* The file_storage object contains the information on how to map the pieces to
* files. It is separated from the torrent_info object because when creating torrents
* a storage object needs to be created without having a torrent file. When renaming files
* in a storage, the storage needs to make its own copy of the file_storage in order
* to make its mapping differ from the one in the torrent file.
*
* @return
*/
public FileStorage getFiles() {
return new FileStorage(ti.files());
}
/**
* returns the original (unmodified) file storage for this torrent. This
* is used by the web server connection, which needs to request files with the original
* names. Filename may be chaged using ``torrent_info::rename_file()``.
*
* @return
*/
public FileStorage getOrigFiles() {
return new FileStorage(ti.orig_files());
}
/**
* Adds a tracker to the announce-list.
*
* @param url
*/
public void addTracker(String url) {
ti.add_tracker(url);
}
/**
* Adds a tracker to the announce-list. The ``tier`` determines the order in
* which the trackers are to be tried.
*
* @param url
* @param tier
*/
public void addTracker(String url, int tier) {
ti.add_tracker(url, tier);
}
/**
* will return a sorted vector of ``announce_entry``.
* <p/>
* Each announce entry contains a string, which is the tracker url, and a tier index. The
* tier index is the high-level priority. No matter which trackers that works or not, the
* ones with lower tier will always be tried before the one with higher tier number.
*
* @return
*/
public List<AnnounceEntry> getTrackers() {
announce_entry_vector v = ti.trackers();
int size = (int) v.size();
List<AnnounceEntry> l = new ArrayList<AnnounceEntry>(size);
for (int i = 0; i < size; i++) {
l.add(new AnnounceEntry(v.get(i)));
}
return l;
}
/**
* Adds one url to the list of url seeds. Currently, the only transport protocol supported for the url
* is http.
*
* @param url
*/
public void addUrlSeed(String url) {
ti.add_url_seed(url);
}
/**
* Adds one url to the list of url seeds. Currently, the only transport protocol supported for the url
* is http.
* <p/>
* The ``extern_auth`` argument can be used for other athorization schemese than
* basic HTTP authorization. If set, it will override any username and password
* found in the URL itself. The string will be sent as the HTTP authorization header's
* value (without specifying "Basic").
*
* @param url
* @param externAuth
*/
public void addUrlSeed(String url, String externAuth) {
ti.add_url_seed(url, externAuth);
}
/**
* Adds one url to the list of url seeds. Currently, the only transport protocol supported for the url
* is http.
* <p/>
* he ``extern_auth`` argument can be used for other athorization schemese than
* basic HTTP authorization. If set, it will override any username and password
* found in the URL itself. The string will be sent as the HTTP authorization header's
* value (without specifying "Basic").
* <p/>
* The ``extra_headers`` argument defaults to an empty list, but can be used to
* insert custom HTTP headers in the requests to a specific web seed.
*
* @param url
* @param externAuth
* @param extraHeaders
*/
public void addUrlSeed(String url, String externAuth, List<Pair<String, String>> extraHeaders) {
string_string_pair_vector v = new string_string_pair_vector();
for (int i = 0; i < extraHeaders.size(); i++) {
v.add(extraHeaders.get(i).to_string_string_pair());
}
ti.add_url_seed(url, externAuth, v);
}
/**
* Adds one url to the list of http seeds. Currently, the only transport protocol supported for the url
* is http.
*
* @param url
*/
public void addHttpSeed(String url) {
ti.add_url_seed(url);
}
/**
* Adds one url to the list of http seeds. Currently, the only transport protocol supported for the url
* is http.
* <p/>
* The ``extern_auth`` argument can be used for other athorization schemese than
* basic HTTP authorization. If set, it will override any username and password
* found in the URL itself. The string will be sent as the HTTP authorization header's
* value (without specifying "Basic").
*
* @param url
* @param externAuth
*/
public void addHttpSeed(String url, String externAuth) {
ti.add_url_seed(url, externAuth);
}
/**
* Adds one url to the list of http seeds. Currently, the only transport protocol supported for the url
* is http.
* <p/>
* he ``extern_auth`` argument can be used for other athorization schemese than
* basic HTTP authorization. If set, it will override any username and password
* found in the URL itself. The string will be sent as the HTTP authorization header's
* value (without specifying "Basic").
* <p/>
* The ``extra_headers`` argument defaults to an empty list, but can be used to
* insert custom HTTP headers in the requests to a specific web seed.
*
* @param url
* @param externAuth
* @param extraHeaders
*/
public void addHttpSeed(String url, String externAuth, List<Pair<String, String>> extraHeaders) {
string_string_pair_vector v = new string_string_pair_vector();
for (int i = 0; i < extraHeaders.size(); i++) {
v.add(extraHeaders.get(i).to_string_string_pair());
}
ti.add_url_seed(url, externAuth, v);
}
/**
* returns all url seeds and http seeds in the torrent. Each entry
* is a ``web_seed_entry`` and may refer to either a url seed or http seed.
*
* @return
*/
public List<WebSeedEntry> getWebSeeds() {
web_seed_entry_vector v = ti.web_seeds();
int size = (int) v.size();
List<WebSeedEntry> l = new ArrayList<WebSeedEntry>(size);
for (int i = 0; i < size; i++) {
l.add(new WebSeedEntry(v.get(i)));
}
return l;
}
/**
* The total number of bytes the torrent-file represents (all the files in it).
*
* @return
*/
public long getTotalSize() {
return this.ti.total_size();
}
/**
* The number of byte for each piece.
* <p/>
* The difference between piece_size() and piece_length() is that piece_size() takes
* the piece index as argument and gives you the exact size of that piece. It will always
* be the same as piece_length() except in the case of the last piece, which may be smaller.
*
* @return
*/
public int getPieceLength() {
return this.ti.piece_length();
}
/**
* The total number of pieces.
*
* @return
*/
public int getNumPieces() {
return ti.num_pieces();
}
/**
* returns the info-hash of the torrent.
*
* @return
*/
public Sha1Hash getInfoHash() {
return new Sha1Hash(ti.info_hash());
}
/**
* If you need index-access to files you can use the ``num_files()`` and ``file_at()``
* to access files using indices.
*
* @return
*/
public int getNumFiles() {
return ti.num_files();
}
/**
* If you need index-access to files you can use the ``num_files()`` and ``file_at()``
* to access files using indices.
*
* @return
*/
public FileEntry getFileAt(int index) {
return new FileEntry(ti.file_at(index));
}
/**
* Returns true if this torrent_info object has a torrent loaded.
* <p/>
* This is primarily used to determine if a magnet link has had its
* metadata resolved yet or not.
*
* @return
*/
public boolean isValid() {
return ti.is_valid();
}
/**
* returns true if this torrent is private. i.e., it should not be
* distributed on the trackerless network (the kademlia DHT).
*
* @return
*/
public boolean isPrivate() {
return ti.priv();
}
/**
* returns true if this is an i2p torrent. This is determined by whether
* or not it has a tracker whose URL domain name ends with ".i2p". i2p
* torrents disable the DHT and local peer discovery as well as talking
* to peers over anything other than the i2p network.
*
* @return
*/
public boolean isI2P() {
return ti.is_i2p();
}
public int getPieceSize(int index) {
return ti.piece_size(index);
}
/**
* takes a piece-index and returns the 20-bytes sha1-hash for that
* piece and ``info_hash()`` returns the 20-bytes sha1-hash for the info-section of the
* torrent file.
*
* @param index
* @return
*/
public Sha1Hash getHashForPiece(int index) {
return new Sha1Hash(ti.hash_for_piece(index));
}
/**
* returns the name of the torrent.
* <p/>
* the name is an UTF-8 encoded strings.
*
* @return
*/
public String getName() {
return ti.name();
}
/**
* returns the creation date of
* the torrent as time_t (`posix time`_). If there's no time stamp in the torrent file,
* a value of zero is returned.
*
* @return
*/
public int getCreationDate() {
return ti.get_creation_date();
}
/**
* returns the creator string in the torrent. If there is no creator string
* it will return an empty string.
*
* @return
*/
public String getCreator() {
return ti.creator();
}
/**
* returns the comment associated with the torrent. If there's no comment,
* it will return an empty string.
* <p/>
* the comment is an UTF-8 encoded strings.
*
* @return
*/
public String getComment() {
return ti.comment();
}
/**
* Generates a magnet URI from the specified torrent. If the torrent
* is invalid, null is returned.
* <p/>
* For more information about magnet links, see magnet-links_.
*
* @return
*/
public String makeMagnetUri() {
return ti.is_valid() ? libtorrent.make_magnet_uri(ti) : null;
}
public Entry toEntry() {
return new Entry(new create_torrent(ti).generate());
}
public byte[] bencode() {
return toEntry().bencode();
}
public static TorrentInfo bdecode(byte[] data) {
lazy_entry e = new lazy_entry();
error_code ec = new error_code();
int ret = lazy_entry.bdecode(Vectors.bytes2char_vector(data), e, ec);
if (ret == 0) {
return new TorrentInfo(new torrent_info(e));
} else {
throw new IllegalArgumentException("Can't decode data");
}
}
}