/*
* This file is part of Transdroid <http://www.transdroid.org>
*
* 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.daemon;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.transdroid.core.gui.log.Log;
import org.transdroid.daemon.DaemonException.ExceptionType;
import org.transdroid.daemon.task.AddByFileTask;
import org.transdroid.daemon.task.AddByMagnetUrlTask;
import org.transdroid.daemon.task.AddByUrlTask;
import org.transdroid.daemon.task.DaemonTask;
import org.transdroid.daemon.task.DaemonTaskFailureResult;
import org.transdroid.daemon.task.DaemonTaskResult;
import org.transdroid.daemon.task.DaemonTaskSuccessResult;
import org.transdroid.daemon.task.ForceRecheckTask;
import org.transdroid.daemon.task.GetFileListTask;
import org.transdroid.daemon.task.GetFileListTaskSuccessResult;
import org.transdroid.daemon.task.GetStatsTask;
import org.transdroid.daemon.task.GetStatsTaskSuccessResult;
import org.transdroid.daemon.task.GetTorrentDetailsTask;
import org.transdroid.daemon.task.GetTorrentDetailsTaskSuccessResult;
import org.transdroid.daemon.task.RetrieveTask;
import org.transdroid.daemon.task.RetrieveTaskSuccessResult;
import org.transdroid.daemon.task.SetAlternativeModeTask;
import org.transdroid.daemon.task.SetDownloadLocationTask;
import org.transdroid.daemon.task.SetFilePriorityTask;
import org.transdroid.daemon.task.SetLabelTask;
import org.transdroid.daemon.task.SetTrackersTask;
import android.net.Uri;
/**
* A dummy adapter that does not communicate with some server, but maintains a local list of dummy data (reset every
* time it is recreated) to simplify testing.
* @author erickok
*/
public class DummyAdapter implements IDaemonAdapter {
private static final String LOG_NAME = "Dummy daemon";
private DaemonSettings settings;
private List<Torrent> dummyTorrents;
private List<Label> dummyLabels;
private boolean alternativeModeEnabled = false;
private List<String> trackersList = new ArrayList<String>(Arrays.asList("udp://tracker.com/announce:80",
"https://torrents.org/announce:443"));
/**
* Initialises a dummy adapter with some dummy data that may be manipulated.
*/
public DummyAdapter(DaemonSettings settings) {
this.settings = settings;
this.dummyTorrents = new ArrayList<Torrent>();
this.dummyLabels = new ArrayList<Label>();
String[] names = new String[] { "Documentary ", "Book ", "CD Image ", "Mix tape ", "App " };
String[] labels = new String[] { "docs", "books", "isos", "music", "software" };
TorrentStatus[] statuses = new TorrentStatus[] { TorrentStatus.Seeding, TorrentStatus.Downloading,
TorrentStatus.Paused, TorrentStatus.Queued, TorrentStatus.Downloading, TorrentStatus.Seeding,
TorrentStatus.Error };
Random random = new Random();
for (int i = 1; i < 26; i++) {
String name = names[i % names.length] + Integer.toString(i);
TorrentStatus status = statuses[i % statuses.length];
int peersGetting = status == TorrentStatus.Downloading ? i * random.nextInt(16) : 0;
int peersSending = status == TorrentStatus.Downloading ? i * random.nextInt(16) : 0;
long size = (long) (1024D * 1024D * 1024D * i * random.nextDouble());
long left = status == TorrentStatus.Downloading ? (long) (size * random.nextDouble()) : 0;
int rateDownload = status == TorrentStatus.Downloading ? (int) (1024D * 100D * i * random.nextDouble())
: 0;
int rateUpload = status == TorrentStatus.Downloading || status == TorrentStatus.Seeding ?
(int) (1024D * 100D * i * random.nextDouble()) : 0;
this.dummyTorrents.add(
new Torrent(
i,
"torrent_" + i,
name,
status,
"/downloads/" + name.replace(" ", "_"),
rateDownload,
rateUpload,
peersGetting,
peersSending,
peersGetting + peersSending, // Total connections
(peersGetting + peersSending) * 2, // Twice the total connections
(int) (status == TorrentStatus.Downloading?
left / rateDownload: 0), // Eta
size - left,
(long)((double)(size - left) * 3D * random.nextDouble()), // Up to 3 times the amount downloaded
size,
(float)(size - left) / size, // Part done
1F, // Always 100% available
labels[i % labels.length],
new Date(System.currentTimeMillis() - (7 * 24 * 60 * 60 * 1000)), // Last week
null,
status == TorrentStatus.Error?
"Dummy error": null,
settings.getType()));
}
for (String label : labels) {
dummyLabels.add(new Label(label, 5));
}
}
@Override
public DaemonTaskResult executeTask(Log log, DaemonTask task) {
try {
switch (task.getMethod()) {
case Retrieve:
return new RetrieveTaskSuccessResult((RetrieveTask) task, dummyTorrents, dummyLabels);
case GetTorrentDetails:
return new GetTorrentDetailsTaskSuccessResult((GetTorrentDetailsTask) task, new TorrentDetails(
trackersList,
task.getTargetTorrent().getStatusCode() == TorrentStatus.Error ?
Arrays.asList("Trackers not working.", "Files not available.") : null));
case GetFileList:
Torrent t = task.getTargetTorrent();
List<TorrentFile> dummyFiles = new ArrayList<TorrentFile>();
Priority priorities[] = new Priority[] { Priority.Normal, Priority.Normal, Priority.High, Priority.Low,
Priority.Normal };
for (int i = 1; i < 16; i++) {
String fileName = "file_" + i + ".ext";
// Every file has equal part in the total size
long size = t.getTotalSize() / 25;
long done = t.getDownloadedEver() / 25;
Priority priority = priorities[i % priorities.length];
dummyFiles.add(new TorrentFile("file_" + i, t.getName() + " file " + i, fileName, t
.getLocationDir() + "/" + fileName, size, done, priority));
}
return new GetFileListTaskSuccessResult((GetFileListTask) task, dummyFiles);
case GetStats:
return new GetStatsTaskSuccessResult((GetStatsTask) task, alternativeModeEnabled, 1024L * 1024L *
1024L * 100);
case AddByFile:
String file = ((AddByFileTask) task).getFile();
log.d(LOG_NAME, "Adding torrent " + file);
File upload = new File(URI.create(file));
dummyTorrents.add(new Torrent(0, "torrent_file", upload.getName(), TorrentStatus.Queued, "/downloads/"
+ file, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1024 * 1024 * 1000, 0, 1F, "isos", new Date(), null, null,
settings.getType()));
return new DaemonTaskSuccessResult(task);
case AddByUrl:
String url = ((AddByUrlTask) task).getUrl();
log.d(LOG_NAME, "Adding torrent " + url);
if (url == null || url.equals(""))
throw new DaemonException(DaemonException.ExceptionType.ParsingFailed, "No url specified");
Uri uri = Uri.parse(url);
dummyTorrents.add(new Torrent(0, "torrent_byurl", uri.getLastPathSegment(), TorrentStatus.Queued,
"/downloads/" + uri.getLastPathSegment(), 0, 0, 0, 0, 0, 0, -1, 0, 0, 1024 * 1024 * 1000, 0,
1F, "music", new Date(), null, null, settings.getType()));
return new DaemonTaskSuccessResult(task);
case AddByMagnetUrl:
String magnet = ((AddByMagnetUrlTask) task).getUrl();
log.d(LOG_NAME, "Adding torrent " + magnet);
Uri magnetUri = Uri.parse(magnet);
dummyTorrents.add(new Torrent(0, "torrent_magnet", magnetUri.getLastPathSegment(),
TorrentStatus.Queued, "/downloads/" + magnetUri.getLastPathSegment(), 0, 0, 0, 0, 0, 0, -1, 0,
0, 1024 * 1024 * 1000, 0, 1F, "books", new Date(), null, null, settings.getType()));
return new DaemonTaskSuccessResult(task);
case Remove:
dummyTorrents.remove(task.getTargetTorrent());
return new DaemonTaskSuccessResult(task);
case Pause:
task.getTargetTorrent().mimicPause();
return new DaemonTaskSuccessResult(task);
case PauseAll:
for (Torrent torrent: dummyTorrents) {
torrent.mimicPause();
}
return new DaemonTaskSuccessResult(task);
case Resume:
task.getTargetTorrent().mimicPause();
return new DaemonTaskSuccessResult(task);
case ResumeAll:
for (Torrent torrent: dummyTorrents) {
torrent.mimicResume();
}
return new DaemonTaskSuccessResult(task);
case Stop:
task.getTargetTorrent().mimicStop();
return new DaemonTaskSuccessResult(task);
case StopAll:
for (Torrent torrent: dummyTorrents) {
torrent.mimicStop();
}
return new DaemonTaskSuccessResult(task);
case Start:
task.getTargetTorrent().mimicStart();
return new DaemonTaskSuccessResult(task);
case StartAll:
for (Torrent torrent: dummyTorrents) {
torrent.mimicStart();
}
return new DaemonTaskSuccessResult(task);
case SetFilePriorities:
SetFilePriorityTask prioTask = (SetFilePriorityTask) task;
for (TorrentFile forFile : prioTask.getForFiles()) {
forFile.mimicPriority(prioTask.getNewPriority());
}
return new DaemonTaskSuccessResult(task);
case SetTransferRates:
// No action, as the result in not visible anyway
return new DaemonTaskSuccessResult(task);
case SetLabel:
SetLabelTask labelTask = (SetLabelTask) task;
task.getTargetTorrent().mimicNewLabel(labelTask.getNewLabel());
return new DaemonTaskSuccessResult(task);
case SetTrackers:
trackersList = new ArrayList<String>(((SetTrackersTask)task).getNewTrackers());
return new DaemonTaskSuccessResult(task);
case ForceRecheck:
ForceRecheckTask recheckTask = (ForceRecheckTask) task;
// Pretend we rechecked this task by pausing it (or stopping, if it is paused) so we can see the result
if (recheckTask.getTargetTorrent().getStatusCode() == TorrentStatus.Paused) {
recheckTask.getTargetTorrent().mimicStop();
} else {
recheckTask.getTargetTorrent().mimicPause();
}
return new DaemonTaskSuccessResult(task);
case SetDownloadLocation:
task.getTargetTorrent().mimicNewLocation(((SetDownloadLocationTask) task).getNewLocation());
return new DaemonTaskSuccessResult(task);
case SetAlternativeMode:
alternativeModeEnabled = ((SetAlternativeModeTask) task).isAlternativeModeEnabled();
return new DaemonTaskSuccessResult(task);
default:
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.MethodUnsupported,
task.getMethod() + " is not supported by " + getType()));
}
} catch (DaemonException e) {
return new DaemonTaskFailureResult(task, e);
}
}
@Override
public Daemon getType() {
return settings.getType();
}
@Override
public DaemonSettings getSettings() {
return this.settings;
}
}