|
|
|
/*
|
|
|
|
* Copyright 2010-2018 Eric Kok et al.
|
|
|
|
*
|
|
|
|
* Transdroid is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Transdroid is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
package org.transdroid.core.gui.lists;
|
|
|
|
|
|
|
|
import java.util.Locale;
|
|
|
|
|
|
|
|
import org.transdroid.R;
|
|
|
|
import org.transdroid.daemon.DaemonException;
|
|
|
|
import org.transdroid.daemon.Torrent;
|
|
|
|
import org.transdroid.daemon.TorrentStatus;
|
|
|
|
import org.transdroid.daemon.util.FileSizeConverter;
|
|
|
|
import org.transdroid.daemon.util.TimespanConverter;
|
|
|
|
|
|
|
|
import android.content.res.Resources;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper around Torrent to provide some addition getters that give translatable or otherwise formatted Strings of
|
|
|
|
* torrent statistics.
|
|
|
|
*
|
|
|
|
* @author Eric Kok
|
|
|
|
*/
|
|
|
|
public class LocalTorrent {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates the LocalTorrent object so that the translatable/formattable version of a Torrent can be used.
|
|
|
|
*
|
|
|
|
* @param torrent The Torrent object
|
|
|
|
* @return The torrent wrapped as LocalTorrent object
|
|
|
|
*/
|
|
|
|
public static LocalTorrent fromTorrent(Torrent torrent) {
|
|
|
|
return new LocalTorrent(torrent);
|
|
|
|
}
|
|
|
|
|
|
|
|
private final Torrent t;
|
|
|
|
|
|
|
|
private LocalTorrent(Torrent torrent) {
|
|
|
|
this.t = torrent;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final String DECIMAL_FORMATTER = "%.1f";
|
|
|
|
private static final String DECIMAL_FORMATTER_2 = "%.2f";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds a string showing the upload/download seed ratio. If not downloading, it will base the ratio on the total
|
|
|
|
* size; so if you created the torrent yourself you will have downloaded 0 bytes, but the ratio will pretend you
|
|
|
|
* have 100%.
|
|
|
|
*
|
|
|
|
* @return A nicely formatted string containing the upload/download seed ratio
|
|
|
|
*/
|
|
|
|
public String getRatioString() {
|
|
|
|
long baseSize = t.getTotalSize();
|
|
|
|
if (t.getStatusCode() == TorrentStatus.Downloading) {
|
|
|
|
baseSize = t.getDownloadedEver();
|
|
|
|
}
|
|
|
|
if (baseSize <= 0) {
|
|
|
|
return String.format(Locale.getDefault(), DECIMAL_FORMATTER_2, 0d);
|
|
|
|
} else if (t.getRatio() == Double.POSITIVE_INFINITY) {
|
|
|
|
return "\u221E";
|
|
|
|
} else {
|
|
|
|
return String.format(Locale.getDefault(), DECIMAL_FORMATTER_2, t.getRatio());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a formatted string indicating the current progress in terms of transferred bytes
|
|
|
|
*
|
|
|
|
* @param r The context resources, to access translations
|
|
|
|
* @param withAvailability Whether to show file availability in-line
|
|
|
|
* @return A nicely formatted string indicating torrent status and, if applicable, progress in bytes
|
|
|
|
*/
|
|
|
|
public String getProgressSizeText(Resources r, boolean withAvailability) {
|
|
|
|
|
|
|
|
switch (t.getStatusCode()) {
|
|
|
|
case Waiting:
|
|
|
|
case Error:
|
|
|
|
// Not downloading yet
|
|
|
|
return r.getString(R.string.status_waitingtodl, FileSizeConverter.getSize(t.getTotalSize()));
|
|
|
|
case Checking:
|
|
|
|
return r.getString(R.string.status_checking);
|
|
|
|
case Downloading:
|
|
|
|
// Downloading
|
|
|
|
return r.getString(
|
|
|
|
R.string.status_size1,
|
|
|
|
FileSizeConverter.getSize(t.getDownloadedEver()),
|
|
|
|
FileSizeConverter.getSize(t.getTotalSize()),
|
|
|
|
String.format(DECIMAL_FORMATTER, t.getDownloadedPercentage() * 100)
|
|
|
|
+ "%"
|
|
|
|
+ (!withAvailability ? "" : "/"
|
|
|
|
+ String.format(DECIMAL_FORMATTER, t.getAvailability() * 100) + "%"));
|
|
|
|
case Seeding:
|
|
|
|
case Paused:
|
|
|
|
case Queued:
|
|
|
|
// Seeding or paused
|
|
|
|
return r.getString(R.string.status_size2, FileSizeConverter.getSize(t.getTotalSize()),
|
|
|
|
FileSizeConverter.getSize(t.getUploadedEver()));
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a formatted string indicating either the expected time to download (ETA) or, when seeding, the ratio
|
|
|
|
*
|
|
|
|
* @param r The context resources, to access translations
|
|
|
|
* @return A string like '~ 34 seconds', or 'RATIO 8.2' or an empty string
|
|
|
|
*/
|
|
|
|
public String getProgressEtaRatioText(Resources r) {
|
|
|
|
switch (t.getStatusCode()) {
|
|
|
|
case Downloading:
|
|
|
|
// Downloading
|
|
|
|
return getRemainingTimeString(r, true, false);
|
|
|
|
case Seeding:
|
|
|
|
case Paused:
|
|
|
|
case Queued:
|
|
|
|
// Seeding or paused
|
|
|
|
return r.getString(R.string.status_ratio, getRatioString());
|
|
|
|
case Waiting:
|
|
|
|
case Checking:
|
|
|
|
case Error:
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a formatted string indicating the torrent status and connected peers
|
|
|
|
*
|
|
|
|
* @param r The context resources, to access translations
|
|
|
|
* @return A string like 'Queued' or, when seeding or leeching, '2 OF 28 PEERS'
|
|
|
|
*/
|
|
|
|
public String getProgressConnectionText(Resources r) {
|
|
|
|
|
|
|
|
switch (t.getStatusCode()) {
|
|
|
|
case Waiting:
|
|
|
|
return r.getString(R.string.status_waiting);
|
|
|
|
case Checking:
|
|
|
|
return r.getString(R.string.status_checking);
|
|
|
|
case Downloading:
|
|
|
|
return r.getString(R.string.status_seeders, t.getSeedersConnected(), t.getSeedersKnown());
|
|
|
|
case Seeding:
|
|
|
|
return r.getString(R.string.status_leechers, t.getLeechersConnected(), t.getLeechersKnown());
|
|
|
|
case Paused:
|
|
|
|
return r.getString(R.string.status_paused);
|
|
|
|
case Queued:
|
|
|
|
return r.getString(R.string.status_stopped);
|
|
|
|
case Error:
|
|
|
|
return r.getString(R.string.status_error);
|
|
|
|
default:
|
|
|
|
return r.getString(R.string.status_unknown);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a formatted string indicating current transfer speeds for the torrent
|
|
|
|
*
|
|
|
|
* @param r The context resources, to access translations
|
|
|
|
* @return A string like '↓ 28KB/s ↑ 1.8MB/s', or an empty string when not transferrring
|
|
|
|
*/
|
|
|
|
public String getProgressSpeedText(Resources r) {
|
|
|
|
|
|
|
|
switch (t.getStatusCode()) {
|
|
|
|
case Waiting:
|
|
|
|
case Checking:
|
|
|
|
case Paused:
|
|
|
|
case Queued:
|
|
|
|
return "";
|
|
|
|
case Downloading:
|
|
|
|
return r.getString(R.string.status_speed_down, FileSizeConverter.getSize(t.getRateDownload()) + "/s") + " "
|
|
|
|
+ r.getString(R.string.status_speed_up, FileSizeConverter.getSize(t.getRateUpload()) + "/s");
|
|
|
|
case Seeding:
|
|
|
|
return r.getString(R.string.status_speed_up, FileSizeConverter.getSize(t.getRateUpload()) + "/s");
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getProgressStatusEta(Resources r) {
|
|
|
|
switch (t.getStatusCode()) {
|
|
|
|
case Waiting:
|
|
|
|
return r.getString(R.string.status_waiting).toUpperCase(Locale.getDefault());
|
|
|
|
case Checking:
|
|
|
|
return r.getString(R.string.status_checking).toUpperCase(Locale.getDefault());
|
|
|
|
case Error:
|
|
|
|
return r.getString(R.string.status_error).toUpperCase(Locale.getDefault());
|
|
|
|
case Downloading:
|
|
|
|
// Downloading
|
|
|
|
return r.getString(R.string.status_downloading).toUpperCase(Locale.getDefault()) + " ("
|
|
|
|
+ String.format(DECIMAL_FORMATTER, t.getDownloadedPercentage() * 100) + "%), "
|
|
|
|
+ getRemainingTimeString(r, false, true);
|
|
|
|
case Seeding:
|
|
|
|
return r.getString(R.string.status_seeding).toUpperCase(Locale.getDefault());
|
|
|
|
case Paused:
|
|
|
|
return r.getString(R.string.status_paused).toUpperCase(Locale.getDefault());
|
|
|
|
case Queued:
|
|
|
|
return r.getString(R.string.status_queued).toUpperCase(Locale.getDefault());
|
|
|
|
default:
|
|
|
|
return r.getString(R.string.status_unknown).toUpperCase(Locale.getDefault());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a formatted string indicating the remaining download time
|
|
|
|
*
|
|
|
|
* @param r The context resources, to access translations
|
|
|
|
* @param inDays Whether to show days or use hours for > 24 hours left instead
|
|
|
|
* @return A string like '4d 8h 34m 5s' or '2m 3s'
|
|
|
|
*/
|
|
|
|
public String getRemainingTimeString(Resources r, boolean abbreviate, boolean inDays) {
|
|
|
|
if (t.getEta() == -1 || t.getEta() == -2) {
|
|
|
|
return r.getString(R.string.status_unknowneta);
|
|
|
|
}
|
|
|
|
return r.getString(abbreviate ? R.string.status_eta : R.string.status_etalong,
|
|
|
|
TimespanConverter.getTime(t.getEta(), inDays));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert a DaemonException to a translatable human-readable error message
|
|
|
|
*
|
|
|
|
* @param e The exception that was thrown by the server
|
|
|
|
* @return A string resource ID to show to the user
|
|
|
|
*/
|
|
|
|
public static int getResourceForDaemonException(DaemonException e) {
|
|
|
|
switch (e.getType()) {
|
|
|
|
case MethodUnsupported:
|
|
|
|
return R.string.error_unsupported;
|
|
|
|
case ConnectionError:
|
|
|
|
return R.string.error_httperror;
|
|
|
|
case UnexpectedResponse:
|
|
|
|
return R.string.error_jsonresponseerror;
|
|
|
|
case ParsingFailed:
|
|
|
|
return R.string.error_jsonrequesterror;
|
|
|
|
case NotConnected:
|
|
|
|
return R.string.error_daemonnotconnected;
|
|
|
|
case AuthenticationFailure:
|
|
|
|
return R.string.error_401;
|
|
|
|
case FileAccessError:
|
|
|
|
return R.string.error_torrentfile;
|
|
|
|
default:
|
|
|
|
return R.string.error_httperror;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|