1 /* 2 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 3 SPDX-License-Identifier: GPL-2.0-or-later 4 */ 5 6 #ifndef KTQUEUEMANAGER_H 7 #define KTQUEUEMANAGER_H 8 9 #include <set> 10 11 #include <KSharedConfig> 12 #include <QObject> 13 14 #include <interfaces/queuemanagerinterface.h> 15 #include <interfaces/torrentinterface.h> 16 #include <ktcore_export.h> 17 18 namespace bt 19 { 20 class SHA1Hash; 21 struct TrackerTier; 22 class WaitJob; 23 } 24 25 namespace kt 26 { 27 class KTCORE_EXPORT QueuePtrList : public QList<bt::TorrentInterface *> 28 { 29 public: 30 QueuePtrList(); 31 ~QueuePtrList(); 32 33 /** 34 * Sort based upon priority 35 */ 36 void sort(); 37 38 protected: 39 static bool biggerThan(bt::TorrentInterface *tc1, bt::TorrentInterface *tc2); 40 }; 41 42 /** 43 * @author Ivan Vasic 44 * @brief This class contains list of all TorrentControls and is responsible for starting/stopping them 45 */ 46 class KTCORE_EXPORT QueueManager : public QObject, public bt::QueueManagerInterface 47 { 48 Q_OBJECT 49 50 public: 51 QueueManager(); 52 ~QueueManager() override; 53 54 void append(bt::TorrentInterface *tc); 55 void remove(bt::TorrentInterface *tc); 56 void clear(); 57 58 /** 59 Save the state of the QueueManager 60 @param cfg The config 61 */ 62 void saveState(KSharedConfigPtr cfg); 63 64 /** 65 Load the state of the QueueManager 66 @param cfg The config 67 */ 68 void loadState(KSharedConfigPtr cfg); 69 70 /** 71 * Check if we need to decrease the priority of stalled torrents 72 * @param min_stall_time Stall time in minutes 73 * @param now The current time 74 */ 75 void checkStalledTorrents(bt::TimeStamp now, bt::Uint32 min_stall_time); 76 77 /** 78 * Start a torrent 79 * @param tc The torrent 80 * @return What happened 81 */ 82 bt::TorrentStartResponse start(bt::TorrentInterface *tc); 83 84 /** 85 * Stop a torrent 86 * @param tc The torrent 87 */ 88 void stop(bt::TorrentInterface *tc); 89 90 /** 91 * Start a list of torrents. 92 * @param todo The list of torrents 93 */ 94 void start(QList<bt::TorrentInterface *> &todo); 95 96 /** 97 * Stop a list of torrents 98 * @param todo The list of torrents 99 */ 100 void stop(QList<bt::TorrentInterface *> &todo); 101 102 /// Stop all torrents 103 void stopAll(); 104 105 /// Start all torrents 106 void startAll(); 107 108 /** 109 * Stop all running torrents 110 * @param wjob WaitJob which waits for stopped events to reach the tracker 111 */ 112 void onExit(bt::WaitJob *wjob); 113 114 /// Get the number of torrents count()115 int count() 116 { 117 return downloads.count(); 118 } 119 120 /// Get the number of downloads 121 int countDownloads(); 122 123 /// Get the number of seeds 124 int countSeeds(); 125 126 enum Flags { 127 SEEDS = 1, 128 DOWNLOADS = 2, 129 ALL = 3, 130 }; 131 132 /** 133 * Get the number of running torrents 134 * @param flags Which torrents to choose 135 */ 136 int getNumRunning(Flags flags = ALL); 137 138 /** 139 * Start the next torrent. 140 */ 141 void startNext(); 142 143 /** 144 If the QM is disabled this function needs to be called to start 145 all the torrents which were running at the time of the previous exit. 146 */ 147 void startAutoStartTorrents(); 148 149 typedef QList<bt::TorrentInterface *>::iterator iterator; 150 typedef QList<bt::TorrentInterface *>::const_iterator const_iterator; 151 152 iterator begin(); 153 iterator end(); 154 155 const_iterator begin() const; 156 const_iterator end() const; 157 158 /** 159 * Get the torrent at index idx in the list. 160 * @param idx Index of the torrent 161 * @return The torrent or 0 if the index is out of bounds 162 */ 163 const bt::TorrentInterface *getTorrent(bt::Uint32 idx) const; 164 165 /** 166 * Get the torrent at index idx in the list. 167 * @param idx Index of the torrent 168 * @return The torrent or 0 if the index is out of bounds 169 */ 170 bt::TorrentInterface *getTorrent(bt::Uint32 idx); 171 172 /** 173 * See if we already loaded a torrent. 174 * @param ih The info hash of a torrent 175 * @return true if we do, false if we don't 176 */ 177 bool alreadyLoaded(const bt::SHA1Hash &ih) const override; 178 179 /** 180 * Merge announce lists to a torrent 181 * @param ih The info_hash of the torrent to merge to 182 * @param trk First tier of trackers 183 */ 184 void mergeAnnounceList(const bt::SHA1Hash &ih, const bt::TrackerTier *trk) override; 185 186 /** 187 * Requested by each TorrentControl during its update to 188 * get permission on saving Stats file to disk. May be 189 * overriden to balance I/O operations. 190 * @param tc Pointer to TorrentControl instance 191 * @return true if file save is permitted, false otherwise 192 */ 193 194 bool permitStatsSync(bt::TorrentControl *tc) override; 195 196 /** 197 * Set the maximum number of downloads 198 * @param m Max downloads 199 */ 200 void setMaxDownloads(int m); 201 202 /** 203 * Set the maximum number of seeds 204 * @param m Max seeds 205 */ 206 void setMaxSeeds(int m); 207 208 /** 209 * Enable or disable keep seeding (after a torrent has finished) 210 * @param ks Keep seeding 211 */ 212 void setKeepSeeding(bool ks); 213 214 /** 215 * Sets global suspended state for QueueManager and stopps all running torrents. 216 * No torrents will be automatically started/stopped with QM. 217 */ 218 void setSuspendedState(bool suspend); 219 220 /// Get the suspended state getSuspendedState()221 bool getSuspendedState() const 222 { 223 return suspended_state; 224 } 225 226 /** 227 * Reindex the queue priorities. 228 */ 229 void reindexQueue(); 230 231 /** 232 * Check if a torrent has file conflicts with other torrents. 233 * If conflicting are found, a list of names of the conflicting torrents is filled in. 234 * @param tc The torrent 235 * @param conflicting List of conflicting torrents 236 */ 237 bool checkFileConflicts(bt::TorrentInterface *tc, QStringList &conflicting) const; 238 239 /** 240 * Places all torrents from downloads in the right order in queue. 241 * Use this when torrent priorities get changed 242 */ 243 void orderQueue(); 244 245 Q_SIGNALS: 246 /** 247 * User tried to enqueue a torrent that has reached max share ratio. It's not possible. 248 * Signal should be connected to SysTray slot which shows appropriate KPassivePopup info. 249 * @param tc The torrent in question. 250 */ 251 void queuingNotPossible(bt::TorrentInterface *tc); 252 253 /** 254 * Diskspace is running low. 255 * Signal should be connected to SysTray slot which shows appropriate KPassivePopup info. 256 * @param tc The torrent in question. 257 */ 258 void lowDiskSpace(bt::TorrentInterface *tc, bool stopped); 259 260 /// Emitted before the queue is reordered 261 void orderingQueue(); 262 263 /** 264 * Emitted when the QM has reordered it's queue 265 */ 266 void queueOrdered(); 267 268 /** 269 * Emitted when the suspended state changes. 270 * @param suspended The suspended state 271 */ 272 void suspendStateChanged(bool suspended); 273 274 public Q_SLOTS: 275 void torrentFinished(bt::TorrentInterface *tc); 276 void torrentAdded(bt::TorrentInterface *tc, bool start_torrent); 277 void torrentRemoved(bt::TorrentInterface *tc); 278 void torrentsRemoved(QList<bt::TorrentInterface *> &tors); 279 void torrentStopped(bt::TorrentInterface *tc); 280 void onLowDiskSpace(bt::TorrentInterface *tc, bool toStop); 281 void onOnlineStateChanged(bool); 282 283 private: 284 void startSafely(bt::TorrentInterface *tc); 285 void stopSafely(bt::TorrentInterface *tc, bt::WaitJob *wjob = nullptr); 286 void checkDiskSpace(QList<bt::TorrentInterface *> &todo); 287 void checkMaxSeedTime(QList<bt::TorrentInterface *> &todo); 288 void checkMaxRatio(QList<bt::TorrentInterface *> &todo); 289 void rearrangeQueue(); 290 bt::TorrentStartResponse startInternal(bt::TorrentInterface *tc); 291 bool checkLimits(bt::TorrentInterface *tc, bool interactive); 292 bool checkDiskSpace(bt::TorrentInterface *tc, bool interactive); 293 294 private: 295 QueuePtrList downloads; 296 std::set<bt::TorrentInterface *> suspended_torrents; 297 int max_downloads; 298 int max_seeds; 299 bool suspended_state; 300 bool keep_seeding; 301 bool exiting; 302 bool ordering; 303 QDateTime network_down_time; 304 bt::TimeStamp last_stats_sync_permitted; 305 }; 306 } 307 #endif 308