- All Implemented Interfaces:
Runnable, EepGet.StatusListener, CoordinatorListener, ShutdownListener, StorageListener
Upon successful download, this Snark will be deleted and a "real" Snark created.
The methods return values similar to a Snark in magnet mode. A fake info hash, which is the SHA1 of the URL, is returned to prevent duplicates.
This Snark may be stopped and restarted, although a partially downloaded file is discarded.
Field Summary
FieldsModifier and TypeFieldDescriptionprivate booleanTrue while the fetch is being shown.private final I2PAppContextThe app context.private final FileDirectory the torrent downloads to.private EepGetThe client doing the fetch.private StringReason the fetch failed.private final byte[]Placeholder hash shown while fetching.private booleanTrue while the fetch thread runs.private final LogLogger for the torrent fetch.private final SnarkManagerThe manager the torrent is added to.private final StringName given to the torrent.private longBytes left to fetch, -1 until known.private longWhen the fetch started.private ThreadThe thread running the fetch.private longTotal size of the fetch, -1 until known.private longBytes fetched so far.private final StringThe URL the torrent is fetched from.private static final intTries allowed to fetch the torrent.Fields inherited from class Snark
_util, PROP_MAX_CONNECTIONS, storageCompletedModifier and TypeFieldDescriptionprotected final I2PSnarkUtilThe util.static final StringMaximum connections.booleanWhether the torrent storage has reported completion.Constructor Summary
ConstructorsConstructorDescriptionFetchAndAdd(I2PAppContext ctx, SnarkManager mgr, String url, File dataDir) Create the downloader; the caller should call _mgr.addDownloader(this), which starts things off.Method Summary
Modifier and TypeMethodDescriptionprivate StringTranslates a string for the page.private StringTranslates a string with one parameter.private voidTell SnarkManager to copy the torrent file over and add it to the Snarks list.(package private) static StringappendCause(String prefix, Throwable t) Append the exception message, stripped of HTML, to a localized notice.voidattemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Called when a download attempt fails.voidattempting(String url) Called when a download attempt is starting.voidbytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) Called when bytes are transferred during download.(package private) static longdownloaded(long total, long remaining) Bytes downloaded so far, given the reported total and remaining.private StringBuild the "failed to retrieve" user message, appending the sanitized failure cause if any.private Fileget()Fetch the torrent file from _url into a temp file, connecting the I2P tunnel on demand.The base name of the torrent.longThe torrent file size, or -1.longThe total number of bytes downloaded.longThe current download rate in bytes per second.byte[]The fake info hash (SHA1 of the URL), which makes re-downloading the same URL a duplicate.getName()The file name of the .torrent file.longThe torrent file bytes remaining, or -1 before the size is known.intThe peer count.longThe remaining bytes, or -1 when done so the web lists us as "complete" instead of "seeding".longThe torrent file size, or -1 before the size is known.intThe tracker seen peers count.voidheaderReceived(String url, int attemptNum, String key, String val) Called when an HTTP header is received.booleanCheck if the torrent is stopped.voidrun()Begin fetching; called bystartTorrent().voidBegin (or restart) the fetch on a fresh background thread.voidStop contacting the tracker and talking with peers.voidtransferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Called when a transfer completes successfully.voidtransferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Called when a transfer fails.private voidupdateState(long transferred, long remaining, long total, boolean active) Update the shared progress state reported by the Snark overrides.private static StringTurns a URL in the text into a link.Methods inherited from class Snark
addComments, addMessage, ban, getCheckingProgress, getComments, getDest, getID, getLastTrackerResponse, getMetaInfo, getNeeded, getPeerList, getPieceLength, getPieces, getRPCID, getScrapeLeechers, getScrapePartialSeeds, getScrapeSeeders, getSkippedLength, getStartedTime, getStorage, getSwarmPeerCount, getTrackerProblems, getTrackerURL, getUploaded, getUploadRate, gotMetaInfo, isAllocating, isAutoStoppable, isBanned, isChecking, isNotificationSent, isStarting, isStorageCompleted, overUploadLimit, peerChange, replaceMetaInfo, restartAcceptor, setAutoStoppable, setLastTrackerResponse, setNotificationSent, setStarting, setTrackerProblems, setTrackerSeenPeers, setWantedPieces, shutdown, stopTorrent, storageAllChecked, storageAllocated, storageChecked, storageCompleted, storageCreateFile, updatePiecePriorities, updateScrape, updateScrapeModifier and TypeMethodDescriptionbooleanaddComments(List<Comment> comments) Add to the current comment set for this torrent, creating it if it didn't previously exist.voidaddMessage(String message) StorageListener and CoordinatorListener callback.voidBan the given hash.doubleThe progress of file checking as a percentage.The current comment set for this torrent.getDest()The transient multi-dest destination, or null when multi-dest is disabled or the torrent is stopped.byte[]getID()The peer ID.longThe wall-clock time of the last valid tracker announce or scrape response, or 0 if none was ever received.The metainfo.longThe number of pieces still missing.The peer list.intgetPieceLength(int p) The piece length.intThe number of pieces.intgetRPCID()A unique ID for this torrent, useful for RPC.intThe best-known leech count from tracker scrapes.intThe best-known partial seed count from tracker scrapes.intThe best-known seed count from tracker scrapes.longBytes not received and set to skipped.longWhen did we start this torrent For RPC.The storage.intDistinct swarm peers seen recently (via announce, PEX or DHT) or currently connected, for the torrent view peer count.Not HTML escaped.The tracker URL.longThe total number of bytes uploaded.longThe current upload rate in bytes per second.voidgotMetaInfo(PeerCoordinator coordinator, MetaInfo metainfo) Called when the PeerCoordinator got the MetaInfo via magnet.booleanCheck if disk allocation (ballooning) is in progress.booleanCheck if the torrent is auto-stoppable.booleanIs the given hash banned?booleanCheck if file checking is in progress.booleanWhether a completion notification has already been sent for this torrent.booleanCheck if startup is in progress.booleanWhether the torrent storage has completed.booleanoverUploadLimit(int uploaders) CoordinatorListener callback to check if the total uploaders across all torrents exceeds the configured limit.voidpeerChange(PeerCoordinator coordinator, Peer peer) CoordinatorListener no-op.voidreplaceMetaInfo(MetaInfo metainfo) Call after editing torrent.booleanRestart the connection acceptor.voidsetAutoStoppable(boolean yes) Store whether the torrent is auto-stoppable.voidsetLastTrackerResponse(long t) Record a valid tracker announce or scrape response.voidsetNotificationSent(boolean sent) Mark that a completion notification has been sent.voidMark startup in progress.voidStore the tracker problems string.voidsetTrackerSeenPeers(int p) Store the tracker seen peers count.voidsetWantedPieces(Storage storage) StorageListener callback to update the coordinator's wanted piece set.voidshutdown()SnarkShutdown callback unused.voidstopTorrent(boolean fast) Stop contacting the tracker and talking with peers.voidstorageAllChecked(Storage storage) StorageListener callback called when all pieces have been checked.voidstorageAllocated(Storage storage, long length) No-op; deliberately empty.voidstorageChecked(Storage storage, int num, boolean checked) StorageListener callback called when a piece check completes.voidstorageCompleted(Storage storage) StorageListener callback called when the torrent has completed.voidstorageCreateFile(Storage storage, String name, long length) StorageListener no-op.voidRecalculate piece priorities.voidupdateScrape(int seeders, int leechers) Update the best-known swarm composition from a tracker scrape (BEP 15/48).voidupdateScrape(int seeders, int leechers, int partials) Update the best-known swarm composition from a tracker scrape (BEP 15/48/21).
Field Details
RETRIES
_ctx
The app context._log
Logger for the torrent fetch._mgr
The manager the torrent is added to._url
The URL the torrent is fetched from._fakeHash
private final byte[] _fakeHashPlaceholder hash shown while fetching._name
Name given to the torrent._dataDir
Directory the torrent downloads to._remaining
private volatile long _remainingBytes left to fetch, -1 until known._total
private volatile long _totalTotal size of the fetch, -1 until known._transferred
private volatile long _transferredBytes fetched so far._isRunning
private volatile boolean _isRunningTrue while the fetch thread runs._active
private volatile boolean _activeTrue while the fetch is being shown._started
private volatile long _startedWhen the fetch started._failCause
Reason the fetch failed._thread
The thread running the fetch._eepGet
The client doing the fetch.
Constructor Details
FetchAndAdd
Create the downloader; the caller should call _mgr.addDownloader(this), which starts things off.The fake info hash is the SHA1 of the URL, so downloading the same URL twice is detected as a duplicate.
- Parameters:
ctx- the I2P application context supplying the loggermgr- the manager that owns this downloaderurl- the torrent file URL to fetchdataDir- null to default to snark data directory
Method Details
run
failMessage
Build the "failed to retrieve" user message, appending the sanitized failure cause if any.- Returns:
- the localized failure message
get
Fetch the torrent file from _url into a temp file, connecting the I2P tunnel on demand. The returned temp file is registered for deletion on JVM exit.This is modeled on the equivalent logic in I2PSnarkUtil, but registers this class as a status listener so the web page shows live progress.
- Returns:
- the populated temp file, or null on failure (the temp file is already deleted)
add
Tell SnarkManager to copy the torrent file over and add it to the Snarks list. This Snark may then be deleted.- Parameters:
file- the downloaded torrent file to copy over and add
appendCause
startTorrent
public void startTorrent()Begin (or restart) the fetch on a fresh background thread.Because a partially downloaded file is discarded on stop, restart simply resets all progress state and fetches again from scratch.
- Overrides:
startTorrentin classSnark
stopTorrent
public void stopTorrent()Description copied from class:SnarkStop contacting the tracker and talking with peers.- Overrides:
stopTorrentin classSnark
isStopped
getName
getBaseName
Description copied from class:SnarkThe base name of the torrent.- Overrides:
getBaseNamein classSnark- Returns:
- base name of torrent [filtered version of getMetaInfo.
Snark.getName()], or a fake name if in magnet mode
getInfoHash
public byte[] getInfoHash()The fake info hash (SHA1 of the URL), which makes re-downloading the same URL a duplicate.- Overrides:
getInfoHashin classSnark- Returns:
- the fake info hash
getTotalLength
public long getTotalLength()The torrent file size, or -1 before the size is known.- Overrides:
getTotalLengthin classSnark- Returns:
- torrent file size or -1
getDataLength
public long getDataLength()The torrent file size, or -1. No padding information is available while fetching, so this equalsgetTotalLength().- Overrides:
getDataLengthin classSnark- Returns:
- torrent file size or -1
getRemainingLength
public long getRemainingLength()The remaining bytes, or -1 when done so the web lists us as "complete" instead of "seeding".- Overrides:
getRemainingLengthin classSnark- Returns:
- -1 when done so the web lists us as "complete" instead of "seeding"
getNeededLength
public long getNeededLength()The torrent file bytes remaining, or -1 before the size is known.- Overrides:
getNeededLengthin classSnark- Returns:
- torrent file bytes remaining or -1
getDownloadRate
public long getDownloadRate()Description copied from class:SnarkThe current download rate in bytes per second.- Overrides:
getDownloadRatein classSnark- Returns:
- download rate in bytes per second, or 0 if not available
getDownloaded
public long getDownloaded()Description copied from class:SnarkThe total number of bytes downloaded.- Overrides:
getDownloadedin classSnark- Returns:
- total bytes downloaded, or 0 if not available
downloaded
static long downloaded(long total, long remaining) Bytes downloaded so far, given the reported total and remaining.Before the first byte is received the total is -1 (size unknown); in that case 0 is reported rather than a bogus negative/positive value derived from the -1 sentinel.
- Parameters:
total- the total size, possibly -1 while the size is unknownremaining- the bytes remaining, possibly -1 while unknown- Returns:
- the bytes downloaded, 0 while the total is unknown
getPeerCount
public int getPeerCount()Description copied from class:SnarkThe peer count.- Overrides:
getPeerCountin classSnark- Returns:
- connected peers, 0 if the coordinator has not been created yet
getTrackerSeenPeers
public int getTrackerSeenPeers()Description copied from class:SnarkThe tracker seen peers count.- Overrides:
getTrackerSeenPeersin classSnark- Returns:
- count returned from tracker
attemptFailed
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Called when a download attempt fails.- Specified by:
attemptFailedin interfaceEepGet.StatusListener- Parameters:
url- the URL being downloadedbytesTransferred- bytes transferred so farbytesRemaining- bytes remaining to transfercurrentAttempt- the current attempt numbernumRetries- the maximum number of retriescause- the exception that caused the failure, or null- See Also:
bytesTransferred
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) Called when bytes are transferred during download.- Specified by:
bytesTransferredin interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total bytes transferred before this writecurrentWrite- number of bytes in this writebytesTransferred- total bytes transferred so farbytesRemaining- bytes remaining to transferurl- the URL being downloaded
transferComplete
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Called when a transfer completes successfully.- Specified by:
transferCompletein interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total bytes transferred before this callbytesTransferred- bytes transferred in this callbytesRemaining- bytes remaining (should be 0)url- the URL being downloadedoutputFile- the output file pathnotModified- true if the server returned 304- See Also:
transferFailed
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Called when a transfer fails.- Specified by:
transferFailedin interfaceEepGet.StatusListener- Parameters:
url- the URL being downloadedbytesTransferred- bytes transferred so farbytesRemaining- bytes remaining to transfercurrentAttempt- the current attempt number- See Also:
headerReceived
Called when an HTTP header is received. Not needed here.- Specified by:
headerReceivedin interfaceEepGet.StatusListener- Parameters:
url- the address the header arrived onattemptNum- zero-based index of the attempt the header arrived onkey- header keyval- header value
attempting
Called when a download attempt is starting. Not needed here.- Specified by:
attemptingin interfaceEepGet.StatusListener- Parameters:
url- the URL being attempted
updateState
private void updateState(long transferred, long remaining, long total, boolean active) Update the shared progress state reported by the Snark overrides.The remaining and total sizes are only updated once a known non-negative size is reported; a
totalof -1 leaves the last known total in place (used by the failure callbacks, which report remaining bytes but no total).- Parameters:
transferred- bytes transferred so farremaining- bytes remaining to transfertotal- the total size, or -1 to leave the current total unchangedactive- whether a transfer is currently in progress
_t
_t
urlify