File indexing completed on 2025-01-05 04:37:17

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #ifndef BTTORRENTINTERFACE_H
0007 #define BTTORRENTINTERFACE_H
0008 
0009 #include <QPointer>
0010 #include <QSharedPointer>
0011 #include <QTextCodec>
0012 #include <QUrl>
0013 
0014 #include <interfaces/trackerslist.h>
0015 #include <ktorrent_export.h>
0016 #include <torrent/torrentfilestream.h>
0017 #include <torrent/torrentstats.h>
0018 #include <util/constants.h>
0019 
0020 #ifdef ERROR
0021 #undef ERROR
0022 #endif
0023 namespace bt
0024 {
0025 class Job;
0026 class BitSet;
0027 class SHA1Hash;
0028 class WaitJob;
0029 class PeerID;
0030 class MonitorInterface;
0031 class TorrentFileInterface;
0032 class PeerSource;
0033 class SHA1Hash;
0034 class WebSeedInterface;
0035 class JobQueue;
0036 class ChunkSelectorInterface;
0037 
0038 enum TorrentStartResponse {
0039     START_OK,
0040     USER_CANCELED,
0041     NOT_ENOUGH_DISKSPACE,
0042     MAX_SHARE_RATIO_REACHED,
0043     BUSY_WITH_JOB,
0044     QM_LIMITS_REACHED, // Max seeds or downloads reached
0045 };
0046 
0047 enum AutoStopReason {
0048     MAX_RATIO_REACHED,
0049     MAX_SEED_TIME_REACHED,
0050 };
0051 
0052 struct DHTNode {
0053     QString ip;
0054     bt::Uint16 port;
0055 };
0056 
0057 enum TorrentFeature {
0058     DHT_FEATURE,
0059     UT_PEX_FEATURE, // µTorrent peer exchange
0060 };
0061 
0062 /**
0063  * @author Joris Guisson
0064  * @brief Interface for an object which controls one torrent
0065  *
0066  * This class is the interface for an object which controls the
0067  * up- and download of one torrent.
0068  */
0069 class KTORRENT_EXPORT TorrentInterface : public QObject
0070 {
0071     Q_OBJECT
0072 public:
0073     TorrentInterface();
0074     ~TorrentInterface() override;
0075 
0076     /// Set the URL which the torrent was loaded from
0077     void setLoadUrl(const QUrl &u)
0078     {
0079         url = u;
0080     }
0081 
0082     /// Get the URL which the torrent was loaded from
0083     QUrl loadUrl() const
0084     {
0085         return url;
0086     }
0087 
0088     /**
0089      * Update the object, should be called periodically.
0090      */
0091     virtual void update() = 0;
0092 
0093     /**
0094      * Pause the torrent.
0095      */
0096     virtual void pause() = 0;
0097 
0098     /**
0099      * Unpause the torrent.
0100      */
0101     virtual void unpause() = 0;
0102 
0103     /**
0104      * Start the download of the torrent.
0105      */
0106     virtual void start() = 0;
0107 
0108     /**
0109      * Stop the download, closes all connections.
0110      * @param wjob WaitJob, used when KT is shutting down,
0111      * so that we can wait for all stopped events to reach the tracker
0112      */
0113     virtual void stop(bt::WaitJob *wjob = nullptr) = 0;
0114 
0115     /**
0116      * Update the tracker, this should normally handled internally.
0117      * We leave it public so that the user can do a manual announce.
0118      */
0119     virtual void updateTracker() = 0;
0120 
0121     /**
0122      * Scrape all or one tracker (private torrents)
0123      */
0124     virtual void scrapeTracker() = 0;
0125 
0126     /// Get the torrent's statistics
0127     const TorrentStats &getStats() const
0128     {
0129         return stats;
0130     }
0131 
0132     /**
0133      * Checks if torrent is multimedial and chunks needed for preview are downloaded
0134      * This only works for single file torrents
0135      * @return true if it is
0136      **/
0137     virtual bool readyForPreview() const = 0;
0138 
0139     /// See if this is a single file torrent and a multimedia files
0140     virtual bool isMultimedia() const = 0;
0141 
0142     /**
0143      * Get the torX directory of this torrent. Temporary stuff like the index
0144      * file get stored there.
0145      */
0146     virtual QString getTorDir() const = 0;
0147 
0148     /// Get the data directory of this torrent
0149     virtual QString getDataDir() const = 0;
0150 
0151     /**
0152      * Get the download running time of this torrent in seconds
0153      * @return Uint32 - time in seconds
0154      */
0155     virtual Uint32 getRunningTimeDL() const = 0;
0156 
0157     /**
0158      * Get the upload running time of this torrent in seconds
0159      * @return Uint32 - time in seconds
0160      */
0161     virtual Uint32 getRunningTimeUL() const = 0;
0162 
0163     /**
0164      * Change to a new torX dir. If this fails
0165      * we will fall back on the old directory.
0166      * @param new_dir The new directory
0167      * @return true upon succes
0168      */
0169     virtual bool changeTorDir(const QString &new_dir) = 0;
0170 
0171     enum ChangeOutputFlags {
0172         MOVE_FILES = 1,
0173         FULL_PATH = 2,
0174     };
0175 
0176     /**
0177      * Change to a new data dir. If this fails
0178      * we will fall back on the old directory.
0179      * @param new_dir The new directory
0180      * @param flags The OR of ChangeOutputFlags
0181      * @return true upon succes
0182      */
0183     virtual bool changeOutputDir(const QString &new_dir, int flags) = 0;
0184 
0185     /**
0186      * Roll back the previous changeDataDir call.
0187      * Does nothing if there was no previous changeDataDir call.
0188      */
0189     virtual void rollback() = 0;
0190 
0191     /**
0192      * Get a BitSet of the status of all Chunks
0193      */
0194     virtual const bt::BitSet &downloadedChunksBitSet() const = 0;
0195 
0196     /**
0197      * Get a BitSet of the availability of all Chunks
0198      */
0199     virtual const bt::BitSet &availableChunksBitSet() const = 0;
0200 
0201     /**
0202      * Get a BitSet of the excluded Chunks
0203      */
0204     virtual const bt::BitSet &excludedChunksBitSet() const = 0;
0205 
0206     /**
0207      * Get a bitset of only seed chunks
0208      */
0209     virtual const bt::BitSet &onlySeedChunksBitSet() const = 0;
0210 
0211     /// Set the monitor
0212     virtual void setMonitor(MonitorInterface *tmo) = 0;
0213 
0214     /// Get the number of files in a multifile torrent (0 if we do not have a multifile torrent)
0215     virtual Uint32 getNumFiles() const = 0;
0216 
0217     /**
0218      * Get the index'th file of a multifile torrent
0219      * @param index The index
0220      * @return The TorrentFileInterface (isNull() will be true in case of error)
0221      */
0222     virtual TorrentFileInterface &getTorrentFile(Uint32 index) = 0;
0223 
0224     /**
0225      * Const version of the previous one.
0226      * @param index The index of the file
0227      * @return The TorrentFileInterface (isNull() will be true in case of error)
0228      */
0229     virtual const TorrentFileInterface &getTorrentFile(Uint32 index) const = 0;
0230 
0231     /**
0232      * Move a torrent file to a new location.
0233      * @param files Map of files and their new location
0234      * @return true upon success
0235      */
0236     virtual bool moveTorrentFiles(const QMap<TorrentFileInterface *, QString> &files) = 0;
0237 
0238     /**
0239         Create a TorrentFileStream object. If the torrent is destroyed this object must also be
0240         destroyed.
0241         @param index Index of the file (in case of a single file torrent, this does not matter)
0242         @param streaming_mode Set to true if this needs to be streamed
0243             (note that only one streaming_mode per torrent is allowed)
0244         @param parent Parent of the TorrentFileStream
0245         @return A TorrentFileStream or 0 if index is not valid
0246     */
0247     virtual TorrentFileStream::Ptr createTorrentFileStream(bt::Uint32 index, bool streaming_mode, QObject *parent) = 0;
0248 
0249     /// Get a pointer to TrackersList object
0250     virtual TrackersList *getTrackersList() = 0;
0251 
0252     /// Get a pointer to TrackersList object
0253     virtual const TrackersList *getTrackersList() const = 0;
0254 
0255     /// Get the torrent queue number. Zero if not in queue
0256     virtual int getPriority() const = 0;
0257 
0258     /// Set the torrent queue number.
0259     virtual void setPriority(int p) = 0;
0260 
0261     /// Set the max share ratio
0262     virtual void setMaxShareRatio(float ratio) = 0;
0263 
0264     /// Get the max share ratio
0265     virtual float getMaxShareRatio() const = 0;
0266 
0267     /// Set the max seed time in hours (0 is no limit)
0268     virtual void setMaxSeedTime(float hours) = 0;
0269 
0270     /// Get the max seed time
0271     virtual float getMaxSeedTime() const = 0;
0272 
0273     /// Get the comments
0274     virtual QString getComments() const = 0;
0275 
0276     /// Update the status
0277     virtual void updateStatus() = 0;
0278 
0279     /// Is manual announce allowed?
0280     virtual bool announceAllowed() = 0;
0281 
0282     /**
0283      * Returns estimated time left for finishing download. Returned value is in seconds.
0284      * Uses TimeEstimator class to calculate this value.
0285      */
0286     virtual int getETA() = 0;
0287 
0288     /**
0289      * Verify the correctness of all data. If from and to are not a valid range, the
0290      * entire torrent will be checked.
0291      * @param auto_import Is this an automatic import
0292      * @param from Chunk to start from
0293      * @param to Chunk to end with
0294      */
0295     virtual Job *startDataCheck(bool auto_import, bt::Uint32 from, bt::Uint32 to) = 0;
0296 
0297     /**
0298      * Is storage mounted for this torrent
0299      * @param missing Filled with missing mount points (if any)
0300      * @return true if there are any missing, false otherwise
0301      **/
0302     virtual bool isStorageMounted(QStringList &missing) = 0;
0303 
0304     /**
0305      * Test all files and see if they are not missing.
0306      * If so put them in a list
0307      */
0308     virtual bool hasMissingFiles(QStringList &sl) = 0;
0309 
0310     /**
0311      * Recreate missing files.
0312      */
0313     virtual void recreateMissingFiles() = 0;
0314 
0315     /**
0316      * Mark missing files as do not download.
0317      */
0318     virtual void dndMissingFiles() = 0;
0319 
0320     /// Get the number of initial DHT nodes
0321     virtual Uint32 getNumDHTNodes() const = 0;
0322 
0323     /// Get a DHT node
0324     virtual const DHTNode &getDHTNode(Uint32 i) const = 0;
0325 
0326     /** Delete the data files of the torrent,
0327      * they will be lost permanently
0328      */
0329     virtual void deleteDataFiles() = 0;
0330 
0331     /// Checks if a seeding torrent has reached its maximum share ratio
0332     virtual bool overMaxRatio() = 0;
0333 
0334     /// Checks if a seeding torrent has reached it's max seed timery / will be ret
0335     virtual bool overMaxSeedTime() = 0;
0336 
0337     /// Handle an error
0338     virtual void handleError(const QString &err) = 0;
0339 
0340     /// Get the info_hash.
0341     virtual const bt::SHA1Hash &getInfoHash() const = 0;
0342 
0343     /**
0344      * Add a new PeerSource
0345      * @param ps
0346      */
0347     virtual void addPeerSource(PeerSource *ps) = 0;
0348 
0349     /**
0350      * Remove a nPeerSource
0351      * @param ps
0352      */
0353     virtual void removePeerSource(PeerSource *ps) = 0;
0354 
0355     /// Is a feature enabled
0356     virtual bool isFeatureEnabled(TorrentFeature tf) = 0;
0357 
0358     /// Disable or enable a feature
0359     virtual void setFeatureEnabled(TorrentFeature tf, bool on) = 0;
0360 
0361     /// Get our PeerID
0362     virtual const bt::PeerID &getOwnPeerID() const = 0;
0363 
0364     /// Set the traffic limits for this torrent
0365     virtual void setTrafficLimits(Uint32 up, Uint32 down) = 0;
0366 
0367     /// Get the traffic limits
0368     virtual void getTrafficLimits(Uint32 &up, Uint32 &down) = 0;
0369 
0370     /// Set the assured speeds
0371     virtual void setAssuredSpeeds(Uint32 up, Uint32 down) = 0;
0372 
0373     /// Get the assured speeds
0374     virtual void getAssuredSpeeds(Uint32 &up, Uint32 &down) = 0;
0375 
0376     /// Check if there is enough diskspace available for this torrent
0377     virtual bool checkDiskSpace(bool emit_sig = true) = 0;
0378 
0379     /// Get the text codec used in the torrent
0380     virtual const QTextCodec *getTextCodec() const = 0;
0381 
0382     /// Set the text codec
0383     virtual void changeTextCodec(QTextCodec *tc) = 0;
0384 
0385     /// Get the number of webseeds
0386     virtual Uint32 getNumWebSeeds() const = 0;
0387 
0388     /// Get a webseed (returns 0 if index is invalid)
0389     virtual const WebSeedInterface *getWebSeed(Uint32 i) const = 0;
0390 
0391     /// Get a webseed (returns 0 if index is invalid)
0392     virtual WebSeedInterface *getWebSeed(Uint32 i) = 0;
0393 
0394     /// Add a webseed (return false, if there is already a webseed with the same url)
0395     virtual bool addWebSeed(const QUrl &url) = 0;
0396 
0397     /// Remove a webseed (only user created ones can be removed)
0398     virtual bool removeWebSeed(const QUrl &url) = 0;
0399 
0400     /// Mark all existing files as downloaded (
0401     virtual void markExistingFilesAsDownloaded() = 0;
0402 
0403     /// Set the user modified file or toplevel directory name
0404     virtual void setUserModifiedFileName(const QString &n)
0405     {
0406         user_modified_name = n;
0407     }
0408 
0409     /// Gets the user modified file or toplevel directory name
0410     QString getUserModifiedFileName() const
0411     {
0412         return user_modified_name.isEmpty() ? stats.torrent_name : user_modified_name;
0413     }
0414 
0415     /// Set the displayed name
0416     virtual void setDisplayName(const QString &n) = 0;
0417 
0418     /// Gets the displayed name
0419     QString getDisplayName() const
0420     {
0421         return display_name.isEmpty() ? stats.torrent_name : display_name;
0422     }
0423 
0424     /// Set whether the QM can start a torrent.
0425     virtual void setAllowedToStart(bool on) = 0;
0426 
0427     /**
0428      * Can the torrent be started by the QM.
0429      * @return True if it can, false otherwise
0430      */
0431     bool isAllowedToStart() const
0432     {
0433         return stats.qm_can_start;
0434     }
0435 
0436     /**
0437      * Set whether the torrent is queued or not
0438      */
0439     virtual void setQueued(bool queued) = 0;
0440 
0441     /// Get the JobQueue of the torrent
0442     virtual const JobQueue *getJobQueue() const = 0;
0443 
0444     /// Set the ChunkSelector to use (0 resets to the default ChunkSelector)
0445     virtual void setChunkSelector(ChunkSelectorInterface *csel) = 0;
0446 
0447     /// After some network down time, the network is back up
0448     virtual void networkUp() = 0;
0449 
0450     /**
0451      * Get the move upon completion directory.
0452      * @param dir the directory an empty url disables this feature
0453      */
0454     virtual void setMoveWhenCompletedDir(const QString &dir) = 0;
0455 
0456     /**
0457      * Get the move upon completion directory.
0458      */
0459     virtual QString getMoveWhenCompletedDir() const = 0;
0460 
0461     /**
0462      * Enable or disable superseeding mode, does nothing if the torrent is not finished.
0463      */
0464     virtual void setSuperSeeding(bool on) = 0;
0465 
0466     typedef QSharedPointer<TorrentInterface> Ptr;
0467     typedef QPointer<TorrentInterface> WPtr;
0468 
0469 Q_SIGNALS:
0470     /**
0471      * Emitted when we have finished downloading.
0472      * @param me The object who emitted the signal
0473      */
0474     void finished(bt::TorrentInterface *me);
0475 
0476     /**
0477      * Emitted when a Torrent download is stopped by error
0478      * @param me The object who emitted the signal
0479      * @param msg Error message
0480      */
0481     void stoppedByError(bt::TorrentInterface *me, QString msg);
0482 
0483     /**
0484      * Emitted when maximum share ratio for this torrent is changed
0485      * @param me The object which emitted the signal.
0486      */
0487     void maxRatioChanged(bt::TorrentInterface *me);
0488 
0489     /**
0490      * Emitted then torrent is stopped from seeding by KTorrent.
0491      * Happens when torrent has reached maximum share ratio and maybe we'll add something more...
0492      * @param me The object which emitted the signal.
0493      * @param reason The reason why it was aut stopped
0494      */
0495     void seedingAutoStopped(bt::TorrentInterface *me, bt::AutoStopReason reason);
0496 
0497     /**
0498      * Emitted just before the torrent is started, this should be used to do some
0499      * checks on the files in the cache.
0500      * @param me The torrent which emitted the signal
0501      * @param ret The return value
0502      */
0503     void aboutToBeStarted(bt::TorrentInterface *me, bool &ret);
0504 
0505     /**
0506      * Emitted when missing files have been marked as dnd.
0507      * The intention of this signal is to update the GUI.
0508      * @param me The torrent which emitted the signal
0509      */
0510     void missingFilesMarkedDND(bt::TorrentInterface *me);
0511 
0512     /**
0513      * A corrupted chunk has been found during upload.
0514      * @param me The torrent which emitted the signal
0515      */
0516     void corruptedDataFound(bt::TorrentInterface *me);
0517 
0518     /**
0519      * Disk is running out of space.
0520      * @param me The torrent which emitted the signal
0521      * @param toStop should this torrent be stopped or not
0522      */
0523     void diskSpaceLow(bt::TorrentInterface *me, bool toStop);
0524 
0525     /**
0526      * Torrent has been stopped
0527      * @param me The torrent which emitted the signal
0528      */
0529     void torrentStopped(bt::TorrentInterface *me);
0530 
0531     /**
0532      * Signal emitted when the torrent needs a data check
0533      * @param me The torrent
0534      * */
0535     void needDataCheck(bt::TorrentInterface *me);
0536 
0537     /**
0538      * Emitted whenever the status of the torrent changes.
0539      * @param me the torrent
0540      */
0541     void statusChanged(bt::TorrentInterface *me);
0542 
0543     /**
0544      * Emitted when a chunk is downloaded.
0545      * @param me The torrent
0546      * @param chunk The chunk
0547      */
0548     void chunkDownloaded(bt::TorrentInterface *me, bt::Uint32 chunk);
0549 
0550     /**
0551      * Emitted when the torrent thinks the QM should update the queue
0552      */
0553     void updateQueue();
0554 
0555     /**
0556      * Emitted when all running jobs are done.
0557      * @param me the torrent
0558      */
0559     void runningJobsDone(bt::TorrentInterface *me);
0560 
0561 protected:
0562     TorrentStats stats;
0563     QString user_modified_name;
0564     QString display_name;
0565     QUrl url;
0566 };
0567 
0568 }
0569 
0570 #endif