1/* 2 * This file Copyright (C) Mnemosyne LLC 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 6 * as published by the Free Software Foundation. 7 * 8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 9 * 10 * $Id: torrent.h 13553 2012-10-07 17:51:56Z jordan $ 11 */ 12 13#ifndef QTR_TORRENT_H 14#define QTR_TORRENT_H 15 16#include <QObject> 17#include <QIcon> 18#include <QMetaType> 19#include <QDateTime> 20#include <QString> 21#include <QStringList> 22#include <QList> 23#include <QTemporaryFile> 24#include <QVariant> 25 26#include <libtransmission/transmission.h> 27 28#include "speed.h" 29#include "types.h" 30 31extern "C" 32{ 33 struct tr_benc; 34} 35 36class Prefs; 37class QPixmap; 38class QStyle; 39 40struct Peer 41{ 42 QString address; 43 QString clientName; 44 bool clientIsChoked; 45 bool clientIsInterested; 46 QString flagStr; 47 bool isDownloadingFrom; 48 bool isEncrypted; 49 bool isIncoming; 50 bool isUploadingTo; 51 bool peerIsChoked; 52 bool peerIsInterested; 53 int port; 54 double progress; 55 Speed rateToClient; 56 Speed rateToPeer; 57}; 58 59typedef QList<Peer> PeerList; 60Q_DECLARE_METATYPE(Peer) 61Q_DECLARE_METATYPE(PeerList) 62 63struct TrackerStat 64{ 65 QString announce; 66 int announceState; 67 int downloadCount; 68 bool hasAnnounced; 69 bool hasScraped; 70 QString host; 71 int id; 72 bool isBackup; 73 int lastAnnouncePeerCount; 74 QString lastAnnounceResult; 75 int lastAnnounceStartTime; 76 bool lastAnnounceSucceeded; 77 int lastAnnounceTime; 78 bool lastAnnounceTimedOut; 79 QString lastScrapeResult; 80 int lastScrapeStartTime; 81 bool lastScrapeSucceeded; 82 int lastScrapeTime; 83 bool lastScrapeTimedOut; 84 int leecherCount; 85 int nextAnnounceTime; 86 int nextScrapeTime; 87 int scrapeState; 88 int seederCount; 89 int tier; 90 QPixmap getFavicon( ) const; 91}; 92 93typedef QList<TrackerStat> TrackerStatsList; 94Q_DECLARE_METATYPE(TrackerStat) 95Q_DECLARE_METATYPE(TrackerStatsList) 96 97struct TrFile 98{ 99 TrFile(): index(-1), priority(0), wanted(true), size(0), have(0) { } 100 int index; 101 int priority; 102 bool wanted; 103 uint64_t size; 104 uint64_t have; 105 QString filename; 106}; 107 108typedef QList<TrFile> FileList; 109Q_DECLARE_METATYPE(TrFile) 110Q_DECLARE_METATYPE(FileList) 111 112 113class Torrent: public QObject 114{ 115 Q_OBJECT; 116 117 public: 118 119 enum 120 { 121 ID, 122 UPLOAD_SPEED, 123 DOWNLOAD_SPEED, 124 DOWNLOAD_DIR, 125 ACTIVITY, 126 NAME, 127 ERROR, 128 ERROR_STRING, 129 SIZE_WHEN_DONE, 130 LEFT_UNTIL_DONE, 131 HAVE_UNCHECKED, 132 HAVE_VERIFIED, 133 DESIRED_AVAILABLE, 134 TOTAL_SIZE, 135 PIECE_SIZE, 136 PIECE_COUNT, 137 PEERS_GETTING_FROM_US, 138 PEERS_SENDING_TO_US, 139 WEBSEEDS_SENDING_TO_US, 140 PERCENT_DONE, 141 METADATA_PERCENT_DONE, 142 PERCENT_VERIFIED, 143 DATE_ACTIVITY, 144 DATE_ADDED, 145 DATE_STARTED, 146 DATE_CREATED, 147 PEERS_CONNECTED, 148 ETA, 149 RATIO, 150 DOWNLOADED_EVER, 151 UPLOADED_EVER, 152 FAILED_EVER, 153 TRACKERS, 154 TRACKERSTATS, 155 MIME_ICON, 156 SEED_RATIO_LIMIT, 157 SEED_RATIO_MODE, 158 SEED_IDLE_LIMIT, 159 SEED_IDLE_MODE, 160 DOWN_LIMIT, 161 DOWN_LIMITED, 162 UP_LIMIT, 163 UP_LIMITED, 164 HONORS_SESSION_LIMITS, 165 PEER_LIMIT, 166 HASH_STRING, 167 IS_FINISHED, 168 IS_PRIVATE, 169 IS_STALLED, 170 COMMENT, 171 CREATOR, 172 MANUAL_ANNOUNCE_TIME, 173 PEERS, 174 TORRENT_FILE, 175 BANDWIDTH_PRIORITY, 176 QUEUE_POSITION, 177 178 PROPERTY_COUNT 179 }; 180 181 public: 182 Torrent( Prefs&, int id ); 183 virtual ~Torrent( ); 184 185 signals: 186 void torrentChanged( int id ); 187 void torrentCompleted( int id ); 188 189 private: 190 191 enum Group 192 { 193 INFO, // info fields that only need to be loaded once 194 STAT, // commonly-used stats that should be refreshed often 195 STAT_EXTRA, // rarely used; only refresh if details dialog is open 196 DERIVED // doesn't come from RPC 197 }; 198 199 struct Property 200 { 201 int id; 202 const char * key; 203 int type; 204 int group; 205 }; 206 207 static Property myProperties[]; 208 209 bool magnetTorrent; 210 211 public: 212 typedef QList<const char*> KeyList; 213 static const KeyList& getInfoKeys( ); 214 static const KeyList& getStatKeys( ); 215 static const KeyList& getExtraStatKeys( ); 216 217 private: 218 static KeyList buildKeyList( Group group ); 219 220 private: 221 QVariant myValues[PROPERTY_COUNT]; 222 223 int getInt ( int key ) const; 224 bool getBool ( int key ) const; 225 QTime getTime ( int key ) const; 226 QIcon getIcon ( int key ) const; 227 double getDouble ( int key ) const; 228 qulonglong getSize ( int key ) const; 229 QString getString ( int key ) const; 230 QDateTime getDateTime ( int key ) const; 231 232 bool setInt ( int key, int value ); 233 bool setBool ( int key, bool value ); 234 bool setIcon ( int key, const QIcon& ); 235 bool setDouble ( int key, double ); 236 bool setString ( int key, const char * ); 237 bool setSize ( int key, qulonglong ); 238 bool setDateTime ( int key, const QDateTime& ); 239 240 public: 241 int getBandwidthPriority( ) const { return getInt( BANDWIDTH_PRIORITY ); } 242 int id( ) const { return getInt( ID ); } 243 QString name( ) const { return getString( NAME ); } 244 QString creator( ) const { return getString( CREATOR ); } 245 QString comment( ) const { return getString( COMMENT ); } 246 QString getPath( ) const { return getString( DOWNLOAD_DIR ); } 247 QString getError( ) const; 248 QString hashString( ) const { return getString( HASH_STRING ); } 249 QString torrentFile( ) const { return getString( TORRENT_FILE ); } 250 bool hasError( ) const { return !getError( ).isEmpty( ); } 251 bool isDone( ) const { return getSize( LEFT_UNTIL_DONE ) == 0; } 252 bool isSeed( ) const { return haveVerified() >= totalSize(); } 253 bool isPrivate( ) const { return getBool( IS_PRIVATE ); } 254 bool getSeedRatio( double& setme ) const; 255 uint64_t haveVerified( ) const { return getSize( HAVE_VERIFIED ); } 256 uint64_t haveUnverified( ) const { return getSize( HAVE_UNCHECKED ); } 257 uint64_t desiredAvailable( ) const { return getSize( DESIRED_AVAILABLE ); } 258 uint64_t haveTotal( ) const { return haveVerified( ) + haveUnverified(); } 259 uint64_t totalSize( ) const { return getSize( TOTAL_SIZE ); } 260 uint64_t sizeWhenDone( ) const { return getSize( SIZE_WHEN_DONE ); } 261 uint64_t leftUntilDone( ) const { return getSize( LEFT_UNTIL_DONE ); } 262 uint64_t pieceSize( ) const { return getSize( PIECE_SIZE ); } 263 bool hasMetadata( ) const { return getDouble( METADATA_PERCENT_DONE ) >= 1.0; } 264 bool isMagnet( ) const { return magnetTorrent; } 265 int pieceCount( ) const { return getInt( PIECE_COUNT ); } 266 double ratio( ) const { return getDouble( RATIO ); } 267 double percentComplete( ) const { return haveTotal() / (double)totalSize(); } 268 double percentDone( ) const { return getDouble( PERCENT_DONE ); } 269 double metadataPercentDone( ) const { return getDouble( METADATA_PERCENT_DONE ); } 270 uint64_t downloadedEver( ) const { return getSize( DOWNLOADED_EVER ); } 271 uint64_t uploadedEver( ) const { return getSize( UPLOADED_EVER ); } 272 uint64_t failedEver( ) const { return getSize( FAILED_EVER ); } 273 int compareTracker( const Torrent& ) const; 274 int compareSeedRatio( const Torrent& ) const; 275 int compareRatio( const Torrent& ) const; 276 int compareETA( const Torrent& ) const; 277 bool hasETA( ) const { return getETA( ) >= 0; } 278 int getETA( ) const { return getInt( ETA ); } 279 QDateTime lastActivity( ) const { return getDateTime( DATE_ACTIVITY ); } 280 QDateTime lastStarted( ) const { return getDateTime( DATE_STARTED ); } 281 QDateTime dateAdded( ) const { return getDateTime( DATE_ADDED ); } 282 QDateTime dateCreated( ) const { return getDateTime( DATE_CREATED ); } 283 QDateTime manualAnnounceTime( ) const { return getDateTime( MANUAL_ANNOUNCE_TIME ); } 284 bool canManualAnnounce( ) const { return isReadyToTransfer() && (manualAnnounceTime()<=QDateTime::currentDateTime()); } 285 int peersWeAreDownloadingFrom( ) const { return getInt( PEERS_SENDING_TO_US ); } 286 int webseedsWeAreDownloadingFrom( ) const { return getInt( WEBSEEDS_SENDING_TO_US ); } 287 int peersWeAreUploadingTo( ) const { return getInt( PEERS_GETTING_FROM_US ); } 288 bool isUploading( ) const { return peersWeAreUploadingTo( ) > 0; } 289 int connectedPeers( ) const { return getInt( PEERS_CONNECTED ); } 290 int connectedPeersAndWebseeds( ) const { return connectedPeers( ) + getInt( WEBSEEDS_SENDING_TO_US ); } 291 Speed downloadSpeed( ) const { return Speed::fromBps( getSize( DOWNLOAD_SPEED ) ); } 292 Speed uploadSpeed( ) const { return Speed::fromBps( getSize( UPLOAD_SPEED ) ); } 293 double getVerifyProgress( ) const { return getDouble( PERCENT_VERIFIED ); } 294 bool hasFileSubstring( const QString& substr ) const; 295 bool hasTrackerSubstring( const QString& substr ) const; 296 Speed uploadLimit( ) const { return Speed::fromKBps( getInt( UP_LIMIT ) ); } 297 Speed downloadLimit( ) const { return Speed::fromKBps( getInt( DOWN_LIMIT ) ); } 298 bool uploadIsLimited( ) const { return getBool( UP_LIMITED ); } 299 bool downloadIsLimited( ) const { return getBool( DOWN_LIMITED ); } 300 bool honorsSessionLimits( ) const { return getBool( HONORS_SESSION_LIMITS ); } 301 int peerLimit( ) const { return getInt( PEER_LIMIT ); } 302 double seedRatioLimit( ) const { return getDouble( SEED_RATIO_LIMIT ); } 303 tr_ratiolimit seedRatioMode( ) const { return (tr_ratiolimit) getInt( SEED_RATIO_MODE ); } 304 int seedIdleLimit( ) const { return getInt( SEED_IDLE_LIMIT ); } 305 tr_idlelimit seedIdleMode( ) const { return (tr_idlelimit) getInt( SEED_IDLE_MODE ); } 306 TrackerStatsList trackerStats( ) const{ return myValues[TRACKERSTATS].value<TrackerStatsList>(); } 307 QStringList trackers() const { return myValues[TRACKERS].value<QStringList>(); } 308 PeerList peers( ) const{ return myValues[PEERS].value<PeerList>(); } 309 const FileList& files( ) const { return myFiles; } 310 int queuePosition( ) const { return getInt( QUEUE_POSITION ); } 311 bool isStalled( ) const { return getBool( IS_STALLED ); } 312 313 public: 314 QString activityString( ) const; 315 tr_torrent_activity getActivity( ) const { return (tr_torrent_activity) getInt( ACTIVITY ); } 316 bool isFinished( ) const { return getBool( IS_FINISHED ); } 317 bool isPaused( ) const { return getActivity( ) == TR_STATUS_STOPPED; } 318 bool isWaitingToVerify( ) const { return getActivity( ) == TR_STATUS_CHECK_WAIT; } 319 bool isVerifying( ) const { return getActivity( ) == TR_STATUS_CHECK; } 320 bool isDownloading( ) const { return getActivity( ) == TR_STATUS_DOWNLOAD; } 321 bool isWaitingToDownload( ) const { return getActivity( ) == TR_STATUS_DOWNLOAD_WAIT; } 322 bool isSeeding( ) const { return getActivity( ) == TR_STATUS_SEED; } 323 bool isWaitingToSeed( ) const { return getActivity( ) == TR_STATUS_SEED_WAIT; } 324 bool isReadyToTransfer( ) const { return getActivity()==TR_STATUS_DOWNLOAD || getActivity()==TR_STATUS_SEED; } 325 bool isQueued( ) const { return isWaitingToDownload() || isWaitingToSeed(); } 326 void notifyComplete( ) const; 327 328 public: 329 void update( tr_benc * dict ); 330 void setMagnet( bool magnet ) { magnetTorrent = magnet; } 331 332 private: 333 const char * getMimeTypeString( ) const; 334 void updateMimeIcon( ); 335 336 public: 337 QIcon getMimeTypeIcon( ) const { return getIcon( MIME_ICON ); } 338 339 private: 340 Prefs& myPrefs; 341 FileList myFiles; 342}; 343 344Q_DECLARE_METATYPE(const Torrent*) 345 346#endif 347 348