|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2005 by *
|
|
|
|
* Joris Guisson <joris.guisson@gmail.com> *
|
|
|
|
* Ivan Vasic <ivasic@gmail.com> *
|
|
|
|
* *
|
|
|
|
* This program 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 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program 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 this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef BTTORRENTCONTROL_H
|
|
|
|
#define BTTORRENTCONTROL_H
|
|
|
|
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <tqcstring.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
#include "globals.h"
|
|
|
|
#include <util/timer.h>
|
|
|
|
#include <interfaces/torrentinterface.h>
|
|
|
|
#include <interfaces/monitorinterface.h>
|
|
|
|
#include <interfaces/trackerslist.h>
|
|
|
|
|
|
|
|
class TQStringList;
|
|
|
|
class TQString;
|
|
|
|
|
|
|
|
namespace TDEIO
|
|
|
|
{
|
|
|
|
class Job;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace bt
|
|
|
|
{
|
|
|
|
class Choker;
|
|
|
|
class Torrent;
|
|
|
|
class PeerSourceManager;
|
|
|
|
class ChunkManager;
|
|
|
|
class PeerManager;
|
|
|
|
class Downloader;
|
|
|
|
class Uploader;
|
|
|
|
class Peer;
|
|
|
|
class BitSet;
|
|
|
|
class QueueManager;
|
|
|
|
class PreallocationThread;
|
|
|
|
class TimeEstimator;
|
|
|
|
class DataCheckerThread;
|
|
|
|
class WaitJob;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Joris Guisson
|
|
|
|
* @brief Controls just about everything
|
|
|
|
*
|
|
|
|
* This is the interface which any user gets to deal with.
|
|
|
|
* This class controls the uploading, downloading, choking,
|
|
|
|
* updating the tracker and chunk management.
|
|
|
|
*/
|
|
|
|
class TorrentControl : public kt::TorrentInterface
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
TorrentControl();
|
|
|
|
virtual ~TorrentControl();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a BitSet of the status of all Chunks
|
|
|
|
*/
|
|
|
|
const BitSet & downloadedChunksBitSet() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a BitSet of the availability of all Chunks
|
|
|
|
*/
|
|
|
|
const BitSet & availableChunksBitSet() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a BitSet of the excluded Chunks
|
|
|
|
*/
|
|
|
|
const BitSet & excludedChunksBitSet() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a BitSet of the only seed chunks
|
|
|
|
*/
|
|
|
|
const BitSet & onlySeedChunksBitSet() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the TorrentControl.
|
|
|
|
* @param qman The QueueManager
|
|
|
|
* @param torrent The filename of the torrent file
|
|
|
|
* @param tmpdir The directory to store temporary data
|
|
|
|
* @param datadir The directory to store the actual file(s)
|
|
|
|
* (only used the first time we load a torrent)
|
|
|
|
* @param default_save_dir Default save directory (null if not set)
|
|
|
|
* @throw Error when something goes wrong
|
|
|
|
*/
|
|
|
|
void init(QueueManager* qman,
|
|
|
|
const TQString & torrent,
|
|
|
|
const TQString & tmpdir,
|
|
|
|
const TQString & datadir,
|
|
|
|
const TQString & default_save_dir);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the TorrentControl.
|
|
|
|
* @param qman The QueueManager
|
|
|
|
* @param data The data of the torrent
|
|
|
|
* @param tmpdir The directory to store temporary data
|
|
|
|
* @param datadir The directory to store the actual file(s)
|
|
|
|
* (only used the first time we load a torrent)
|
|
|
|
* @param default_save_dir Default save directory (null if not set)
|
|
|
|
* @throw Error when something goes wrong
|
|
|
|
*/
|
|
|
|
void init(QueueManager* qman,
|
|
|
|
const TQByteArray & data,
|
|
|
|
const TQString & tmpdir,
|
|
|
|
const TQString & datadir,
|
|
|
|
const TQString & default_save_dir);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change to a new data dir. If this fails
|
|
|
|
* we will fall back on the old directory.
|
|
|
|
* @param new_dir The new directory
|
|
|
|
* @return true upon succes
|
|
|
|
*/
|
|
|
|
bool changeDataDir(const TQString & new_dir);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change torrents output directory. If this fails we will fall back on the old directory.
|
|
|
|
* @param new_dir The new directory
|
|
|
|
* @param moveFiles Wheather to actually move the files or just change the directory without moving them.
|
|
|
|
* @return true upon success.
|
|
|
|
*/
|
|
|
|
bool changeOutputDir(const TQString& new_dir, bool moveFiles = true);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Roll back the previous changeDataDir call.
|
|
|
|
* Does nothing if there was no previous changeDataDir call.
|
|
|
|
*/
|
|
|
|
void rollback();
|
|
|
|
|
|
|
|
/// Gets the TrackersList interface
|
|
|
|
kt::TrackersList* getTrackersList();
|
|
|
|
|
|
|
|
/// Gets the TrackersList interface
|
|
|
|
const kt::TrackersList* getTrackersList() const;
|
|
|
|
|
|
|
|
/// Get the data directory of this torrent
|
|
|
|
TQString getDataDir() const {return outputdir;}
|
|
|
|
|
|
|
|
/// Get the torX dir.
|
|
|
|
TQString getTorDir() const {return datadir;}
|
|
|
|
|
|
|
|
/// Set the monitor
|
|
|
|
void setMonitor(kt::MonitorInterface* tmo);
|
|
|
|
|
|
|
|
/// Get the Torrent.
|
|
|
|
const Torrent & getTorrent() const {return *tor;}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the download running time of this torrent in seconds
|
|
|
|
* @return Uint32 - time in seconds
|
|
|
|
*/
|
|
|
|
Uint32 getRunningTimeDL() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the upload running time of this torrent in seconds
|
|
|
|
* @return Uint32 - time in seconds
|
|
|
|
*/
|
|
|
|
Uint32 getRunningTimeUL() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if torrent is multimedial and chunks needed for preview are downloaded
|
|
|
|
* @param start_chunk The index of starting chunk to check
|
|
|
|
* @param end_chunk The index of the last chunk to check
|
|
|
|
* In case of single torrent file defaults can be used (0,1)
|
|
|
|
**/
|
|
|
|
bool readyForPreview(int start_chunk = 0, int end_chunk = 1);
|
|
|
|
|
|
|
|
/// Get the time to the next tracker update in seconds.
|
|
|
|
Uint32 getTimeToNextTrackerUpdate() const;
|
|
|
|
|
|
|
|
/// Get a short error message
|
|
|
|
TQString getShortErrorMessage() const {return error_msg;}
|
|
|
|
|
|
|
|
virtual Uint32 getNumFiles() const;
|
|
|
|
virtual kt::TorrentFileInterface & getTorrentFile(Uint32 index);
|
|
|
|
virtual void recreateMissingFiles();
|
|
|
|
virtual void dndMissingFiles();
|
|
|
|
virtual void addPeerSource(kt::PeerSource* ps);
|
|
|
|
virtual void removePeerSource(kt::PeerSource* ps);
|
|
|
|
|
|
|
|
int getPriority() const { return istats.priority; }
|
|
|
|
void setPriority(int p);
|
|
|
|
|
|
|
|
virtual bool overMaxRatio();
|
|
|
|
virtual void setMaxShareRatio(float ratio);
|
|
|
|
virtual float getMaxShareRatio() const { return stats.max_share_ratio; }
|
|
|
|
|
|
|
|
virtual bool overMaxSeedTime();
|
|
|
|
virtual void setMaxSeedTime(float hours);
|
|
|
|
virtual float getMaxSeedTime() const {return stats.max_seed_time;}
|
|
|
|
|
|
|
|
/// Tell the TorrentControl obj to preallocate diskspace in the next update
|
|
|
|
void setPreallocateDiskSpace(bool pa) {prealloc = pa;}
|
|
|
|
|
|
|
|
/// Make a string out of the status message
|
|
|
|
virtual TQString statusToString() const;
|
|
|
|
|
|
|
|
/// Checks if tracker announce is allowed (minimum interval 60 seconds)
|
|
|
|
bool announceAllowed();
|
|
|
|
|
|
|
|
void startDataCheck(bt::DataCheckerListener* lst,bool auto_import);
|
|
|
|
|
|
|
|
/// Test if the torrent has existing files, only works the first time a torrent is loaded
|
|
|
|
bool hasExistingFiles() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test all files and see if they are not missing.
|
|
|
|
* If so put them in a list
|
|
|
|
*/
|
|
|
|
bool hasMissingFiles(TQStringList & sl);
|
|
|
|
|
|
|
|
|
|
|
|
virtual Uint32 getNumDHTNodes() const;
|
|
|
|
virtual const kt::DHTNode & getDHTNode(Uint32 i) const;
|
|
|
|
virtual void deleteDataFiles();
|
|
|
|
virtual const SHA1Hash & getInfoHash() const;
|
|
|
|
virtual const bt::PeerID & getOwnPeerID() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the PeerSourceManager when it is going to start a new tracker.
|
|
|
|
*/
|
|
|
|
void resetTrackerStats();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns estimated time left for finishing download. Returned value is in seconds.
|
|
|
|
* Uses TimeEstimator class to calculate this value.
|
|
|
|
*/
|
|
|
|
Uint32 getETA();
|
|
|
|
|
|
|
|
/// Is a feature enabled
|
|
|
|
bool isFeatureEnabled(kt::TorrentFeature tf);
|
|
|
|
|
|
|
|
/// Disable or enable a feature
|
|
|
|
void setFeatureEnabled(kt::TorrentFeature tf,bool on);
|
|
|
|
|
|
|
|
/// Create all the necessary files
|
|
|
|
void createFiles();
|
|
|
|
|
|
|
|
///Checks if diskspace is low
|
|
|
|
bool checkDiskSpace(bool emit_sig = true);
|
|
|
|
|
|
|
|
virtual void setTrafficLimits(Uint32 up,Uint32 down);
|
|
|
|
virtual void getTrafficLimits(Uint32 & up,Uint32 & down);
|
|
|
|
|
|
|
|
///Get the PeerManager
|
|
|
|
const PeerManager * getPeerMgr() const;
|
|
|
|
|
|
|
|
/// Are we in the process of moving files
|
|
|
|
bool isMovingFiles() const {return moving_files;}
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
/**
|
|
|
|
* Update the object, should be called periodically.
|
|
|
|
*/
|
|
|
|
void update();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start the download of the torrent.
|
|
|
|
*/
|
|
|
|
void start();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the download, closes all connections.
|
|
|
|
* @param user wether or not the user did this explicitly
|
|
|
|
* @param wjob WaitJob to wait at exit for the completion of stopped requests
|
|
|
|
*/
|
|
|
|
void stop(bool user,WaitJob* wjob = 0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the tracker, this should normally handled internally.
|
|
|
|
* We leave it public so that the user can do a manual announce.
|
|
|
|
*/
|
|
|
|
void updateTracker();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The tracker status has changed.
|
|
|
|
* @param ns New status
|
|
|
|
*/
|
|
|
|
void trackerStatusChanged(const TQString & ns);
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void onNewPeer(Peer* p);
|
|
|
|
void onPeerRemoved(Peer* p);
|
|
|
|
void doChoking();
|
|
|
|
void onIOError(const TQString & msg);
|
|
|
|
void onPortPacket(const TQString & ip,Uint16 port);
|
|
|
|
/// Update the stats of the torrent.
|
|
|
|
void updateStats();
|
|
|
|
void corrupted(Uint32 chunk);
|
|
|
|
void moveDataFilesJobDone(TDEIO::Job* job);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void updateTracker(const TQString & ev,bool last_succes = true);
|
|
|
|
void updateStatusMsg();
|
|
|
|
void saveStats();
|
|
|
|
void loadStats();
|
|
|
|
void loadOutputDir();
|
|
|
|
void getSeederInfo(Uint32 & total,Uint32 & connected_to) const;
|
|
|
|
void getLeecherInfo(Uint32 & total,Uint32 & connected_to) const;
|
|
|
|
void migrateTorrent(const TQString & default_save_dir);
|
|
|
|
void continueStart();
|
|
|
|
virtual void handleError(const TQString & err);
|
|
|
|
|
|
|
|
void initInternal(QueueManager* qman,const TQString & tmpdir,
|
|
|
|
const TQString & ddir,const TQString & default_save_dir,bool first_time);
|
|
|
|
|
|
|
|
void checkExisting(QueueManager* qman);
|
|
|
|
void setupDirs(const TQString & tmpdir,const TQString & ddir);
|
|
|
|
void setupStats();
|
|
|
|
void setupData(const TQString & ddir);
|
|
|
|
virtual void afterDataCheck();
|
|
|
|
virtual bool isCheckingData(bool & finished) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Torrent* tor;
|
|
|
|
PeerSourceManager* psman;
|
|
|
|
ChunkManager* cman;
|
|
|
|
PeerManager* pman;
|
|
|
|
Downloader* down;
|
|
|
|
Uploader* up;
|
|
|
|
Choker* choke;
|
|
|
|
TimeEstimator* m_eta;
|
|
|
|
kt::MonitorInterface* tmon;
|
|
|
|
|
|
|
|
Timer choker_update_timer;
|
|
|
|
Timer stats_save_timer;
|
|
|
|
Timer stalled_timer;
|
|
|
|
|
|
|
|
TQString datadir;
|
|
|
|
TQString old_datadir;
|
|
|
|
TQString outputdir;
|
|
|
|
TQString error_msg;
|
|
|
|
|
|
|
|
TQString move_data_files_destination_path;
|
|
|
|
bool restart_torrent_after_move_data_files;
|
|
|
|
|
|
|
|
bool prealloc;
|
|
|
|
PreallocationThread* prealoc_thread;
|
|
|
|
DataCheckerThread* dcheck_thread;
|
|
|
|
TimeStamp last_diskspace_check;
|
|
|
|
bool moving_files;
|
|
|
|
|
|
|
|
struct InternalStats
|
|
|
|
{
|
|
|
|
TQDateTime time_started_dl;
|
|
|
|
TQDateTime time_started_ul;
|
|
|
|
Uint32 running_time_dl;
|
|
|
|
Uint32 running_time_ul;
|
|
|
|
Uint64 prev_bytes_dl;
|
|
|
|
Uint64 prev_bytes_ul;
|
|
|
|
Uint64 trk_prev_bytes_dl;
|
|
|
|
Uint64 trk_prev_bytes_ul;
|
|
|
|
Uint64 session_bytes_uploaded;
|
|
|
|
bool io_error;
|
|
|
|
bool custom_output_name;
|
|
|
|
Uint16 port;
|
|
|
|
int priority;
|
|
|
|
bool dht_on;
|
|
|
|
TimeStamp last_announce;
|
|
|
|
bool diskspace_warning_emitted;
|
|
|
|
};
|
|
|
|
|
|
|
|
Uint32 upload_gid; // group ID for upload
|
|
|
|
Uint32 upload_limit;
|
|
|
|
Uint32 download_gid; // group ID for download
|
|
|
|
Uint32 download_limit;
|
|
|
|
|
|
|
|
InternalStats istats;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|