diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 823fcd8e..90578da4 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -18,8 +18,8 @@ --> diff --git a/android/res/layout-xlarge-v11/part_details_header.xml b/android/res/layout-xlarge-v11/part_details_header.xml index 274d4f70..82aedfc6 100644 --- a/android/res/layout-xlarge-v11/part_details_header.xml +++ b/android/res/layout-xlarge-v11/part_details_header.xml @@ -12,6 +12,10 @@ android:shrinkColumns="1" android:stretchColumns="1"> + + + + diff --git a/android/res/layout/part_details_header.xml b/android/res/layout/part_details_header.xml index 19c72a91..94347e3f 100644 --- a/android/res/layout/part_details_header.xml +++ b/android/res/layout/part_details_header.xml @@ -11,6 +11,10 @@ android:layout_margin="5dip" android:shrinkColumns="1" android:stretchColumns="1"> + + + + diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 7fa20152..0f75c56b 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -283,6 +283,7 @@ Details Files +Added on: Size: State: Downloaded: diff --git a/android/src/org/transdroid/gui/DetailsListAdapter.java b/android/src/org/transdroid/gui/DetailsListAdapter.java index b17d2415..ae651768 100644 --- a/android/src/org/transdroid/gui/DetailsListAdapter.java +++ b/android/src/org/transdroid/gui/DetailsListAdapter.java @@ -10,6 +10,8 @@ import org.transdroid.daemon.TorrentFile; import org.transdroid.daemon.TorrentStatus; import org.transdroid.daemon.util.FileSizeConverter; +import android.text.format.DateFormat; +import android.text.format.DateUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; @@ -28,9 +30,9 @@ public class DetailsListAdapter extends MergeAdapter { private TorrentFileListAdapter filesAdapter; private View detailsfields; - private TextView name, state, size, downloaded, uploaded, rate, eta, peers, availability, label, trackers, trackershint, - errors, errorshint; - private TableRow availabilityRow, labelRow, trackers1Row, trackers2Row, errors1Row, errors2Row; + private TextView dateAdded, name, state, size, downloaded, uploaded, rate, eta, peers, availability, label, + trackers, trackershint, errors, errorshint; + private TableRow dateAddedRow, availabilityRow, labelRow, trackers1Row, trackers2Row, errors1Row, errors2Row; private ImageButton resumepause, startstop, remove, setlabel; private boolean showingTrackers = false; @@ -45,6 +47,7 @@ public class DetailsListAdapter extends MergeAdapter { detailsfields = detailsFragment.getActivity().getLayoutInflater().inflate(R.layout.part_details_header, null); addView(detailsfields); + dateAdded = (TextView) findViewById(R.id.details_dateadded); name = (TextView) findViewById(R.id.details_name); state = (TextView) findViewById(R.id.details_state); size = (TextView) findViewById(R.id.details_size); @@ -61,7 +64,8 @@ public class DetailsListAdapter extends MergeAdapter { errors = (TextView) findViewById(R.id.details_errors); errorshint = (TextView) findViewById(R.id.details_errorshint); errorshint.setOnClickListener(onErrorsExpandClick); - + + dateAddedRow = (TableRow) findViewById(R.id.detailsrow_dateadded); availabilityRow = (TableRow) findViewById(R.id.detailsrow_availability); labelRow = (TableRow) findViewById(R.id.detailsrow_label); trackers1Row = (TableRow) findViewById(R.id.detailsrow_trackers1); @@ -113,6 +117,12 @@ public class DetailsListAdapter extends MergeAdapter { // Update textviews according to the torrent data LocalTorrent local = LocalTorrent.fromTorrent(torrent); + if (torrent.getDateAdded() != null) { + dateAdded.setText(DateUtils.formatDateTime(detailsFragment.getActivity(), torrent.getDateAdded().getTime(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE)); + dateAddedRow.setVisibility(View.VISIBLE); + } else { + dateAddedRow.setVisibility(View.GONE); + } state.setText(torrent.getStatusCode().toString()); size.setText(FileSizeConverter.getSize(torrent.getTotalSize())); downloaded.setText(FileSizeConverter.getSize(torrent.getDownloadedEver()) + " (" + @@ -123,9 +133,11 @@ public class DetailsListAdapter extends MergeAdapter { if (torrent.getStatusCode() == TorrentStatus.Downloading) { eta.setText(local.getRemainingTimeString(detailsFragment.getResources(), true)); availability.setText(String.format(DECIMAL_FORMATTER, torrent.getAvailability() * 100) + "%"); + availabilityRow.setVisibility(View.VISIBLE); } else { eta.setText(""); availability.setText(""); + availabilityRow.setVisibility(View.GONE); } peers.setText(local.getProgressConnectionText(detailsFragment.getResources())); label.setText((torrent.getLabelName() == null || torrent.getLabelName().equals(""))? diff --git a/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java b/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java index 31d25583..a4f94b30 100644 --- a/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java +++ b/lib/src/org/transdroid/daemon/BitComet/BitCometAdapter.java @@ -474,6 +474,7 @@ public class BitCometAdapter implements IDaemonAdapter { distributed_copies, comment, dateAdded, + null, null)); } } @@ -550,6 +551,7 @@ public class BitCometAdapter implements IDaemonAdapter { 0f, label, dateAdded, + null, null)); // Not supported in the web interface id++; // Stop/start/etc. requests are made by ID, which is the order number in the returned XML list :-S diff --git a/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java b/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java index e9fec0f4..14e618bd 100644 --- a/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java +++ b/lib/src/org/transdroid/daemon/Bitflu/BitfluAdapter.java @@ -213,6 +213,7 @@ public class BitfluAdapter implements IDaemonAdapter { 0f, // Not available null, // label null, // Not available + null, // Not available null)); // Not available } } diff --git a/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java b/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java index c079d9eb..dbe6bea8 100644 --- a/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java +++ b/lib/src/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java @@ -280,6 +280,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { (float)tor.getDouble("distributed_copies") / 10, null, null, + null, null)); } diff --git a/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java b/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java index 4718c3cc..521333b7 100644 --- a/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java +++ b/lib/src/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java @@ -374,7 +374,8 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { (float) (tor.getLong(BT_DONE) / (float) tor.getLong(BT_SIZE)), Float.parseFloat(tor.getString(BT_COPYS)), null, - new Date(), + null, + null, null); torrents.add(new_t); diff --git a/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java b/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java index f24fde72..6324463b 100644 --- a/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java +++ b/lib/src/org/transdroid/daemon/Deluge/DelugeAdapter.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.apache.http.HttpEntity; @@ -125,6 +126,7 @@ public class DelugeAdapter implements IDaemonAdapter { private static final String RPC_PEERSCONNECTED = "num_peers"; private static final String RPC_PEERSKNOWN = "total_peers"; private static final String RPC_ETA = "eta"; + private static final String RPC_TIMEADDED = "time_added"; private static final String RPC_DOWNLOADEDEVER = "total_done"; private static final String RPC_UPLOADEDEVER = "total_uploaded"; @@ -145,7 +147,7 @@ public class DelugeAdapter implements IDaemonAdapter { RPC_NAME, RPC_STATUS, RPC_SAVEPATH, RPC_RATEDOWNLOAD, RPC_RATEUPLOAD, RPC_PEERSGETTING, RPC_PEERSSENDING, RPC_PEERSCONNECTED, RPC_PEERSKNOWN, RPC_ETA, RPC_DOWNLOADEDEVER, RPC_UPLOADEDEVER, - RPC_TOTALSIZE, RPC_PARTDONE, RPC_LABEL, RPC_MESSAGE }; + RPC_TOTALSIZE, RPC_PARTDONE, RPC_LABEL, RPC_MESSAGE, RPC_TIMEADDED }; private DaemonSettings settings; private DefaultHttpClient httpclient; @@ -570,6 +572,7 @@ public class DelugeAdapter implements IDaemonAdapter { ((float) tor.getDouble(RPC_PARTDONE)) / 100f, // Percentage to [0..1] 0f, // Not available tor.has(RPC_LABEL)? tor.getString(RPC_LABEL): null, + tor.has(RPC_TIMEADDED)? new Date(tor.getInt(RPC_TIMEADDED) * 1000L): null, null, tor.getString(RPC_MESSAGE))); // Not available } diff --git a/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java b/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java index 89e5b05d..fb55a519 100644 --- a/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java +++ b/lib/src/org/transdroid/daemon/Ktorrent/StatsParser.java @@ -84,6 +84,7 @@ public class StatsParser { 0f, null, // Not supported in the web interface null, // Not supported in the web interface + null, // Not supported in the web interface null)); // Not supported in the web interface id++; // Stop/start/etc. requests are made by ID, which is the order number in the returned XML list :-S diff --git a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java index ca07bbce..de205813 100644 --- a/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java +++ b/lib/src/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java @@ -392,6 +392,7 @@ public class QbittorrentAdapter implements IDaemonAdapter { (float)progress, 0f, null, + null, // Only available in /json/propertiesGeneral on a per-torrent basis, unfortunately null, null)); } diff --git a/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java b/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java index ba56a238..544096eb 100644 --- a/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java +++ b/lib/src/org/transdroid/daemon/Rtorrent/RtorrentAdapter.java @@ -299,6 +299,7 @@ public class RtorrentAdapter implements IDaemonAdapter { 0f, // TODO: Add availability data null, // See remark on rTorrent/groups above new Date((Long)info[11]), + null, error)); } else { @@ -327,6 +328,7 @@ public class RtorrentAdapter implements IDaemonAdapter { 0f, // TODO: Add availability data null, // See remark on rTorrent/groups above new Date((Integer)info[11]), + null, error)); } diff --git a/lib/src/org/transdroid/daemon/Tfb4rt/StatsParser.java b/lib/src/org/transdroid/daemon/Tfb4rt/StatsParser.java index 127e7232..af7f5cc7 100644 --- a/lib/src/org/transdroid/daemon/Tfb4rt/StatsParser.java +++ b/lib/src/org/transdroid/daemon/Tfb4rt/StatsParser.java @@ -79,6 +79,7 @@ public class StatsParser { 0f, null, // Not supported in the XML stats null, + null, null)); } else if (next == XmlPullParser.START_TAG && name.equals("transfer")){ diff --git a/lib/src/org/transdroid/daemon/Torrent.java b/lib/src/org/transdroid/daemon/Torrent.java index b9425d66..f35aecf0 100644 --- a/lib/src/org/transdroid/daemon/Torrent.java +++ b/lib/src/org/transdroid/daemon/Torrent.java @@ -113,7 +113,7 @@ public final class Torrent implements Parcelable, Comparable { public Torrent(long id, String hash, String name, TorrentStatus statusCode, String locationDir, int rateDownload, int rateUpload, int peersGettingFromUs, int peersSendingToUs, int peersConnected, int peersKnown, int eta, long downloadedEver, long uploadedEver, long totalSize, float partDone, float available, String label, - Date dateAdded, String error) { + Date dateAdded, Date realDateDone, String error) { this.id = id; this.hash = hash; this.name = name; @@ -136,14 +136,18 @@ public final class Torrent implements Parcelable, Comparable { this.label = label; this.dateAdded = dateAdded; - Calendar cal = Calendar.getInstance(); - if (eta == -1 || eta == -2) { - cal.clear(); - cal.set(9999, 12, 31); + if (realDateDone != null) { + this.dateDone = realDateDone; } else { - cal.add(Calendar.SECOND, eta); + Calendar cal = Calendar.getInstance(); + if (eta == -1 || eta == -2) { + cal.clear(); + cal.set(9999, 12, 31); + } else { + cal.add(Calendar.SECOND, eta); + } + this.dateDone = cal.getTime(); } - this.dateDone = cal.getTime(); this.error = error; } diff --git a/lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java b/lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java index c25202fd..f3670cb0 100644 --- a/lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java +++ b/lib/src/org/transdroid/daemon/Transmission/TransmissionAdapter.java @@ -498,7 +498,8 @@ public class TransmissionAdapter implements IDaemonAdapter { (total == 0? 0: have/(float)total), (total == 0? 0: (have+(float)tor.getLong(RPC_AVAILABLE))/(float)total), null, // No label/category/group support in the RPC API for now - new Date(tor.getLong(RPC_DATEADDED)), + new Date(tor.getLong(RPC_DATEADDED) * 1000L), + new Date(tor.getLong(RPC_DATEDONE) * 1000L), errorString)); } diff --git a/lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java b/lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java index bff9c46b..40b9214b 100644 --- a/lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java +++ b/lib/src/org/transdroid/daemon/Utorrent/UtorrentAdapter.java @@ -25,6 +25,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.apache.http.HttpResponse; @@ -463,6 +464,8 @@ public class UtorrentAdapter implements IDaemonAdapter { private static final int RPC_SEEDSCONNECTED_IDX = 14; private static final int RPC_SEEDSINSWARM_IDX = 15; private static final int RPC_AVAILABILITY_IDX = 16; + private static final int RPC_ADDEDON_IDX = 23; + private static final int RPC_COMPLETEDON_IDX = 24; private ArrayList parseJsonRetrieveTorrents(JSONArray results) throws JSONException { @@ -486,6 +489,10 @@ public class UtorrentAdapter implements IDaemonAdapter { } // Add the parsed torrent to the list TorrentStatus status = convertUtorrentStatus(tor.getInt(RPC_STATUS_IDX), downloaded); + long addedOn = tor.optInt(RPC_ADDEDON_IDX, -1) * 1000L; + long completedOn = tor.optInt(RPC_COMPLETEDON_IDX, -1) * 100L; + Date addedOnDate = addedOn == -1? null: new Date(addedOn); + Date completedOnDate = completedOn == -1? null: new Date(completedOn); torrents.add(new Torrent( i, // No ID but a hash is used tor.getString(RPC_HASH_IDX), @@ -505,7 +512,8 @@ public class UtorrentAdapter implements IDaemonAdapter { ((float) tor.getLong(RPC_PARTDONE)) / 1000f, // Integer in promille Math.min(available, 1f), // Can be > 100% if multiple peers have 100% tor.getString(RPC_LABEL_IDX).trim(), - null, // Not available + addedOnDate, + completedOnDate, // uTorrent doesn't give the error message, so just remind that there is some error status == TorrentStatus.Error? "See GUI for error message": null)); } diff --git a/lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java b/lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java index 7903b600..b19ca94d 100644 --- a/lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java +++ b/lib/src/org/transdroid/daemon/Vuze/VuzeAdapter.java @@ -405,6 +405,7 @@ public class VuzeAdapter implements IDaemonAdapter { Math.min(availability.floatValue(), 1f), null, // TODO: Implement Vuze label support new Date((Long) statsinfo.get("time_started")), // dateAdded + null, // Unsupported? error)); }