/* * This file Copyright (C) 2009-2014 Mnemosyne LLC * * It may be used under the GNU GPL versions 2 or 3 * or any future license endorsed by Mnemosyne LLC. * * $Id$ */ #ifndef QTR_TORRENT_H #define QTR_TORRENT_H #include #include #include #include #include #include #include #include #include #include #include #include "speed.h" #include "types.h" #ifdef ERROR #undef ERROR #endif extern "C" { struct tr_variant; } class Prefs; class QPixmap; class QStyle; struct Peer { bool clientIsChoked; bool clientIsInterested; bool isDownloadingFrom; bool isEncrypted; bool isIncoming; bool isUploadingTo; bool peerIsChoked; bool peerIsInterested; QString address; QString clientName; QString flagStr; int port; Speed rateToClient; Speed rateToPeer; double progress; }; typedef QList PeerList; Q_DECLARE_METATYPE(Peer) Q_DECLARE_METATYPE(PeerList) struct TrackerStat { bool hasAnnounced; bool hasScraped; bool isBackup; bool lastAnnounceSucceeded; bool lastAnnounceTimedOut; bool lastScrapeSucceeded; bool lastScrapeTimedOut; int announceState; int downloadCount; int id; int lastAnnouncePeerCount; int lastAnnounceStartTime; int lastAnnounceTime; int lastScrapeStartTime; int lastScrapeTime; int leecherCount; int nextAnnounceTime; int nextScrapeTime; int scrapeState; int seederCount; int tier; QString announce; QString host; QString lastAnnounceResult; QString lastScrapeResult; QPixmap getFavicon () const; }; typedef QList TrackerStatsList; Q_DECLARE_METATYPE(TrackerStat) Q_DECLARE_METATYPE(TrackerStatsList) struct TrFile { TrFile(): wanted(true), index(-1), priority(0), size(0), have(0) {} bool wanted; int index; int priority; QString filename; uint64_t size; uint64_t have; }; typedef QList FileList; Q_DECLARE_METATYPE(TrFile) Q_DECLARE_METATYPE(FileList) class Torrent: public QObject { Q_OBJECT public: enum { ID, UPLOAD_SPEED, DOWNLOAD_SPEED, DOWNLOAD_DIR, ACTIVITY, NAME, ERROR, ERROR_STRING, SIZE_WHEN_DONE, LEFT_UNTIL_DONE, HAVE_UNCHECKED, HAVE_VERIFIED, DESIRED_AVAILABLE, TOTAL_SIZE, PIECE_SIZE, PIECE_COUNT, PEERS_GETTING_FROM_US, PEERS_SENDING_TO_US, WEBSEEDS_SENDING_TO_US, PERCENT_DONE, METADATA_PERCENT_DONE, PERCENT_VERIFIED, DATE_ACTIVITY, DATE_ADDED, DATE_STARTED, DATE_CREATED, PEERS_CONNECTED, ETA, RATIO, DOWNLOADED_EVER, UPLOADED_EVER, FAILED_EVER, TRACKERS, HOSTS, TRACKERSTATS, MIME_ICON, SEED_RATIO_LIMIT, SEED_RATIO_MODE, SEED_IDLE_LIMIT, SEED_IDLE_MODE, DOWN_LIMIT, DOWN_LIMITED, UP_LIMIT, UP_LIMITED, HONORS_SESSION_LIMITS, PEER_LIMIT, HASH_STRING, IS_FINISHED, IS_PRIVATE, IS_STALLED, COMMENT, CREATOR, MANUAL_ANNOUNCE_TIME, PEERS, BANDWIDTH_PRIORITY, QUEUE_POSITION, PROPERTY_COUNT }; public: Torrent (Prefs&, int id); virtual ~Torrent (); signals: void torrentChanged (int id); void torrentCompleted (int id); private: enum Group { INFO, // info fields that only need to be loaded once STAT, // commonly-used stats that should be refreshed often STAT_EXTRA, // rarely used; only refresh if details dialog is open DERIVED // doesn't come from RPC }; struct Property { int id; tr_quark key; int type; int group; }; static Property myProperties[]; bool magnetTorrent; public: typedef QList KeyList; static const KeyList& getInfoKeys (); static const KeyList& getStatKeys (); static const KeyList& getExtraStatKeys (); private: static KeyList buildKeyList (Group group); private: QVariant myValues[PROPERTY_COUNT]; int getInt (int key) const; bool getBool (int key) const; QTime getTime (int key) const; QIcon getIcon (int key) const; double getDouble (int key) const; qulonglong getSize (int key) const; QString getString (int key) const; QDateTime getDateTime (int key) const; bool setInt (int key, int value); bool setBool (int key, bool value); bool setIcon (int key, const QIcon&); bool setDouble (int key, double); bool setString (int key, const char *); bool setSize (int key, qulonglong); bool setDateTime (int key, const QDateTime&); public: int getBandwidthPriority () const { return getInt (BANDWIDTH_PRIORITY); } int id () const { return getInt (ID); } QString name () const { return getString (NAME); } QString creator () const { return getString (CREATOR); } QString comment () const { return getString (COMMENT); } QString getPath () const { return getString (DOWNLOAD_DIR); } QString getError () const; QString hashString () const { return getString (HASH_STRING); } bool hasError () const { return !getError ().isEmpty (); } bool isDone () const { return getSize (LEFT_UNTIL_DONE) == 0; } bool isSeed () const { return haveVerified() >= totalSize(); } bool isPrivate () const { return getBool (IS_PRIVATE); } bool getSeedRatio (double& setme) const; uint64_t haveVerified () const { return getSize (HAVE_VERIFIED); } uint64_t haveUnverified () const { return getSize (HAVE_UNCHECKED); } uint64_t desiredAvailable () const { return getSize (DESIRED_AVAILABLE); } uint64_t haveTotal () const { return haveVerified () + haveUnverified(); } uint64_t totalSize () const { return getSize (TOTAL_SIZE); } uint64_t sizeWhenDone () const { return getSize (SIZE_WHEN_DONE); } uint64_t leftUntilDone () const { return getSize (LEFT_UNTIL_DONE); } uint64_t pieceSize () const { return getSize (PIECE_SIZE); } bool hasMetadata () const { return getDouble (METADATA_PERCENT_DONE) >= 1.0; } bool isMagnet () const { return magnetTorrent; } int pieceCount () const { return getInt (PIECE_COUNT); } double ratio () const { return getDouble (RATIO); } double percentComplete () const { return haveTotal() / (double)totalSize(); } double percentDone () const { return getDouble (PERCENT_DONE); } double metadataPercentDone () const { return getDouble (METADATA_PERCENT_DONE); } uint64_t downloadedEver () const { return getSize (DOWNLOADED_EVER); } uint64_t uploadedEver () const { return getSize (UPLOADED_EVER); } uint64_t failedEver () const { return getSize (FAILED_EVER); } int compareTracker (const Torrent&) const; int compareSeedRatio (const Torrent&) const; int compareRatio (const Torrent&) const; int compareETA (const Torrent&) const; bool hasETA () const { return getETA () >= 0; } int getETA () const { return getInt (ETA); } QDateTime lastActivity () const { return getDateTime (DATE_ACTIVITY); } QDateTime lastStarted () const { return getDateTime (DATE_STARTED); } QDateTime dateAdded () const { return getDateTime (DATE_ADDED); } QDateTime dateCreated () const { return getDateTime (DATE_CREATED); } QDateTime manualAnnounceTime () const { return getDateTime (MANUAL_ANNOUNCE_TIME); } bool canManualAnnounce () const { return isReadyToTransfer() && (manualAnnounceTime()<=QDateTime::currentDateTime()); } int peersWeAreDownloadingFrom () const { return getInt (PEERS_SENDING_TO_US); } int webseedsWeAreDownloadingFrom () const { return getInt (WEBSEEDS_SENDING_TO_US); } int peersWeAreUploadingTo () const { return getInt (PEERS_GETTING_FROM_US); } bool isUploading () const { return peersWeAreUploadingTo () > 0; } int connectedPeers () const { return getInt (PEERS_CONNECTED); } int connectedPeersAndWebseeds () const { return connectedPeers () + getInt (WEBSEEDS_SENDING_TO_US); } Speed downloadSpeed () const { return Speed::fromBps (getSize (DOWNLOAD_SPEED)); } Speed uploadSpeed () const { return Speed::fromBps (getSize (UPLOAD_SPEED)); } double getVerifyProgress () const { return getDouble (PERCENT_VERIFIED); } bool hasFileSubstring (const QString& substr) const; bool hasTrackerSubstring (const QString& substr) const; Speed uploadLimit () const { return Speed::fromKBps (getInt (UP_LIMIT)); } Speed downloadLimit () const { return Speed::fromKBps (getInt (DOWN_LIMIT)); } bool uploadIsLimited () const { return getBool (UP_LIMITED); } bool downloadIsLimited () const { return getBool (DOWN_LIMITED); } bool honorsSessionLimits () const { return getBool (HONORS_SESSION_LIMITS); } int peerLimit () const { return getInt (PEER_LIMIT); } double seedRatioLimit () const { return getDouble (SEED_RATIO_LIMIT); } tr_ratiolimit seedRatioMode () const { return (tr_ratiolimit) getInt (SEED_RATIO_MODE); } int seedIdleLimit () const { return getInt (SEED_IDLE_LIMIT); } tr_idlelimit seedIdleMode () const { return (tr_idlelimit) getInt (SEED_IDLE_MODE); } TrackerStatsList trackerStats () const{ return myValues[TRACKERSTATS].value(); } QStringList trackers() const { return myValues[TRACKERS].value(); } QStringList hosts() const { return myValues[HOSTS].value(); } PeerList peers () const{ return myValues[PEERS].value(); } const FileList& files () const { return myFiles; } int queuePosition () const { return getInt (QUEUE_POSITION); } bool isStalled () const { return getBool (IS_STALLED); } public: QString activityString () const; tr_torrent_activity getActivity () const { return (tr_torrent_activity) getInt (ACTIVITY); } bool isFinished () const { return getBool (IS_FINISHED); } bool isPaused () const { return getActivity () == TR_STATUS_STOPPED; } bool isWaitingToVerify () const { return getActivity () == TR_STATUS_CHECK_WAIT; } bool isVerifying () const { return getActivity () == TR_STATUS_CHECK; } bool isDownloading () const { return getActivity () == TR_STATUS_DOWNLOAD; } bool isWaitingToDownload () const { return getActivity () == TR_STATUS_DOWNLOAD_WAIT; } bool isSeeding () const { return getActivity () == TR_STATUS_SEED; } bool isWaitingToSeed () const { return getActivity () == TR_STATUS_SEED_WAIT; } bool isReadyToTransfer () const { return getActivity()==TR_STATUS_DOWNLOAD || getActivity()==TR_STATUS_SEED; } bool isQueued () const { return isWaitingToDownload() || isWaitingToSeed(); } void notifyComplete () const; public: void update (tr_variant * dict); void setMagnet (bool magnet) { magnetTorrent = magnet; } private: const char * getMimeTypeString () const; void updateMimeIcon (); public: QIcon getMimeTypeIcon () const { return getIcon (MIME_ICON); } private: Prefs& myPrefs; FileList myFiles; }; Q_DECLARE_METATYPE(const Torrent*) #endif