void TorrentModel::handleTorrentUpdate(const QTorrentHandle &h) { const int row = torrentRow(h.hash()); if (row >= 0) { // This line changes the torrent name when magnet is retrieved. // When magnet link is added, "dn" parameter is used as name, but when metadata is retrieved // we change the name with the retrieved torrent name. m_torrents[row]->setData(TorrentModelItem::TR_NAME, h.name(), Qt::DisplayRole); m_torrents[row]->refreshStatus(h.status(torrent_handle::query_accurate_download_counters)); notifyTorrentChanged(row); } }
/** * Returns the files in a torrent in JSON format. * * The return value is a JSON-formatted list of dictionaries. * The dictionary keys are: * - "name": File name * - "size": File size * - "progress": File progress * - "priority": File priority * - "is_seed": Flag indicating if torrent is seeding/complete */ QByteArray btjson::getFilesForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(QVariantList, file_list, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); if (!h.has_metadata()) return json::toJson(file_list); const std::vector<int> priorities = h.file_priorities(); std::vector<size_type> fp; h.file_progress(fp); for (int i = 0; i < h.num_files(); ++i) { QVariantMap file_dict; QString fileName = h.filepath_at(i); if (fileName.endsWith(".!qB", Qt::CaseInsensitive)) fileName.chop(4); file_dict[KEY_FILE_NAME] = fsutils::toNativePath(fileName); const size_type size = h.filesize_at(i); file_dict[KEY_FILE_SIZE] = static_cast<qlonglong>(size); file_dict[KEY_FILE_PROGRESS] = (size > 0) ? (fp[i] / (double) size) : 1.; file_dict[KEY_FILE_PRIORITY] = priorities[i]; if (i == 0) file_dict[KEY_FILE_IS_SEED] = h.is_seed(); file_list.append(file_dict); } } catch (const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); return QByteArray(); } return json::toJson(file_list); }
/** * Returns the files in a torrent in JSON format. * * The return value is a JSON-formatted list of dictionaries. * The dictionary keys are: * - "name": File name * - "size": File size * - "progress": File progress * - "priority": File priority * - "is_seed": Flag indicating if torrent is seeding/complete */ QString btjson::getFilesForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(JsonList, file_list, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); if (!h.has_metadata()) return QString(); const std::vector<int> priorities = h.file_priorities(); std::vector<size_type> fp; h.file_progress(fp); for (int i = 0; i < h.num_files(); ++i) { JsonDict file_dict; QString fileName = h.filename_at(i); if (fileName.endsWith(".!qB", Qt::CaseInsensitive)) fileName.chop(4); file_dict.add(KEY_FILE_NAME, fileName); const size_type size = h.filesize_at(i); file_dict.add(KEY_FILE_SIZE, misc::friendlyUnit(size)); file_dict.add(KEY_FILE_PROGRESS, (size > 0) ? (fp[i] / (double) size) : 1.); file_dict.add(KEY_FILE_PRIORITY, priorities[i]); if (i == 0) file_dict.add(KEY_FILE_IS_SEED, h.is_seed()); file_list.append(file_dict); } } catch (const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what(); return QString(); } return file_list.toString(); }
bool QTorrentFilter::isTorrentResumed(const QTorrentHandle &h) const { const QTorrentState state = h.torrentState(); return state != QTorrentState::PausedUploading && state != QTorrentState::PausedDownloading; }
void TrackerList::moveSelectionUp() { QTorrentHandle h = properties->getCurrentTorrent(); if (!h.is_valid()) { clear(); return; } QList<QTreeWidgetItem *> selected_items = getSelectedTrackerItems(); if (selected_items.isEmpty()) return; bool change = false; foreach (QTreeWidgetItem *item, selected_items) { int index = indexOfTopLevelItem(item); if (index > NB_STICKY_ITEM) { insertTopLevelItem(index-1, takeTopLevelItem(index)); change = true; } }
void TorrentModel::handleTorrentAboutToBeRemoved(const QTorrentHandle &h) { const int row = torrentRow(h.hash()); if (row >= 0) { emit torrentAboutToBeRemoved(m_torrents.at(row)); } }
bool QTorrentFilter::torrentHasLabel(const QTorrentHandle &h) const { if (label_.isNull()) return true; else return TorrentPersistentData::instance()->getLabel(h.hash()) == label_; }
bool QTorrentFilter::isTorrentActive(const QTorrentHandle &h) const { const QTorrentState state = h.torrentState(); return state == QTorrentState::Downloading || state == QTorrentState::Uploading; }
void TorrentModel::handleTorrentUpdate(const QTorrentHandle &h) { const int row = torrentRow(h.hash()); if (row >= 0) { notifyTorrentChanged(row); } }
bool QTorrentFilter::isTorrentPaused(const QTorrentHandle &h) const { const QTorrentState state = h.torrentState(); return state == QTorrentState::PausedUploading || state == QTorrentState::Error; }
/** * Returns the web seeds for a torrent in JSON format. * * The return value is a JSON-formatted list of dictionaries. * The dictionary keys are: * - "url": Web seed URL */ QByteArray btjson::getWebSeedsForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(QVariantList, webSeedList, CACHE_DURATION_MS, hash); QTorrentHandle torrent = QBtSession::instance()->getTorrentHandle(hash); if (!torrent.is_valid()) { qWarning() << Q_FUNC_INFO << "Invalid torrent " << qPrintable(hash); return QByteArray(); } foreach (const QString &webseed, torrent.url_seeds()) { QVariantMap webSeedDict; webSeedDict[KEY_WEBSEED_URL] = webseed; webSeedList.append(webSeedDict); } return json::toJson(webSeedList); }
void TransferListWidget::torrentDoubleClicked(const QModelIndex& index) { const int row = mapToSource(index).row(); const QString hash = getHashFromRow(row); QTorrentHandle h = BTSession->getTorrentHandle(hash); if (!h.is_valid()) return; int action; if (h.is_seed()) { action = Preferences().getActionOnDblClOnTorrentFn(); } else { action = Preferences().getActionOnDblClOnTorrentDl(); } switch(action) { case TOGGLE_PAUSE: if (h.is_paused()) { h.resume(); } else { h.pause(); } break; case OPEN_DEST: const QString path = h.root_path(); openUrl(path); } }
bool QTorrentFilter::isTorrentSeeding(const QTorrentHandle &h) const { const QTorrentState state = h.torrentState(); return state == QTorrentState::Uploading || state == QTorrentState::StalledUploading || state == QTorrentState::CheckingUploading || state == QTorrentState::QueuedUploading; }
void TorrentModel::handleFinishedTorrent(const QTorrentHandle& h) { const int row = torrentRow(h.hash()); if (row < 0) return; // Update completion date m_torrents[row]->setData(TorrentModelItem::TR_SEED_DATE, QDateTime::currentDateTime(), Qt::DisplayRole); notifyTorrentChanged(row); }
void TorrentModel::addTorrent(const QTorrentHandle &h) { if (torrentRow(h.hash()) < 0) { beginInsertTorrent(m_torrents.size()); TorrentModelItem *item = new TorrentModelItem(h); connect(item, SIGNAL(labelChanged(QString,QString)), SLOT(handleTorrentLabelChange(QString,QString))); m_torrents << item; emit torrentAdded(item); endInsertTorrent(); } }
bool QTorrentFilter::isTorrentDownloading(const QTorrentHandle &h) const { const QTorrentState state = h.torrentState(); return state == QTorrentState::Downloading || state == QTorrentState::StalledDownloading || state == QTorrentState::CheckingDownloading || state == QTorrentState::PausedDownloading || state == QTorrentState::QueuedDownloading || state == QTorrentState::Error; }
void TorrentModel::handleTorrentAboutToBeRemoved(const QTorrentHandle &h) { const int row = torrentRow(h.hash()); qDebug() << Q_FUNC_INFO << row; if (row >= 0) { emit torrentAboutToBeRemoved(m_torrents.at(row)); beginRemoveTorrent(row); delete m_torrents[row]; m_torrents.removeAt(row); endRemoveTorrent(); } }
/** * Returns the properties for a torrent in JSON format. * * The return value is a JSON-formatted dictionary. * The dictionary keys are: * - "save_path": Torrent save path * - "creation_date": Torrent creation date * - "piece_size": Torrent piece size * - "comment": Torrent comment * - "total_wasted": Total data wasted for torrent * - "total_uploaded": Total data uploaded for torrent * - "total_uploaded_session": Total data uploaded this session * - "total_downloaded": Total data uploaded for torrent * - "total_downloaded_session": Total data downloaded this session * - "up_limit": Torrent upload limit * - "dl_limit": Torrent download limit * - "time_elapsed": Torrent elapsed time * - "seeding_time": Torrent elapsed time while complete * - "nb_connections": Torrent connection count * - "nb_connections_limit": Torrent connection count limit * - "share_ratio": Torrent share ratio */ QByteArray btjson::getPropertiesForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(QVariantMap, data, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters); if (!status.has_metadata) return QByteArray(); // Save path QString save_path = fsutils::toNativePath(TorrentPersistentData::instance()->getSavePath(hash)); if (save_path.isEmpty()) save_path = fsutils::toNativePath(h.save_path()); data[KEY_PROP_SAVE_PATH] = save_path; data[KEY_PROP_CREATION_DATE] = h.creation_date_unix(); data[KEY_PROP_PIECE_SIZE] = static_cast<qlonglong>(h.piece_length()); data[KEY_PROP_COMMENT] = h.comment(); data[KEY_PROP_WASTED] = static_cast<qlonglong>(status.total_failed_bytes + status.total_redundant_bytes); data[KEY_PROP_UPLOADED] = static_cast<qlonglong>(status.all_time_upload); data[KEY_PROP_UPLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_upload); data[KEY_PROP_DOWNLOADED] = static_cast<qlonglong>(status.all_time_download); data[KEY_PROP_DOWNLOADED_SESSION] = static_cast<qlonglong>(status.total_payload_download); data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? -1 : h.upload_limit(); data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? -1 : h.download_limit(); data[KEY_PROP_TIME_ELAPSED] = status.active_time; data[KEY_PROP_SEEDING_TIME] = status.seeding_time; data[KEY_PROP_CONNECT_COUNT] = status.num_connections; data[KEY_PROP_CONNECT_COUNT_LIMIT] = status.connections_limit; const qreal ratio = QBtSession::instance()->getRealRatio(status); data[KEY_PROP_RATIO] = ratio > QBtSession::MAX_RATIO ? -1 : ratio; } catch (const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); return QByteArray(); } return json::toJson(data); }
TorrentModelItem::TorrentModelItem(const QTorrentHandle &h) : m_torrent(h) , m_lastStatus(h.status(torrent_handle::query_accurate_download_counters)) , m_addedTime(TorrentPersistentData::getAddedDate(h.hash())) , m_seedTime(TorrentPersistentData::getSeedDate(h.hash())) , m_label(TorrentPersistentData::getLabel(h.hash())) , m_name(TorrentPersistentData::getName(h.hash())) , m_hash(h.hash()) { if (m_name.isEmpty()) m_name = h.name(); }
/** * Returns the trackers for a torrent in JSON format. * * The return value is a JSON-formatted list of dictionaries. * The dictionary keys are: * - "url": Tracker URL * - "status": Tracker status * - "num_peers": Tracker peer count * - "msg": Tracker message (last) */ QByteArray btjson::getTrackersForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(QVariantList, tracker_list, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); QHash<QString, TrackerInfos> trackers_data = QBtSession::instance()->getTrackersInfo(hash); std::vector<announce_entry> vect_trackers = h.trackers(); std::vector<announce_entry>::const_iterator it = vect_trackers.begin(); std::vector<announce_entry>::const_iterator end = vect_trackers.end(); for (; it != end; ++it) { QVariantMap tracker_dict; const QString tracker_url = misc::toQString(it->url); tracker_dict[KEY_TRACKER_URL] = tracker_url; const TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); QString status; if (it->verified) { status = tr("Working"); } else { if (it->updating && it->fails == 0) status = tr("Updating..."); else status = it->fails > 0 ? tr("Not working") : tr("Not contacted yet"); } tracker_dict[KEY_TRACKER_STATUS] = status; tracker_dict[KEY_TRACKER_PEERS] = static_cast<qulonglong>(trackers_data.value(tracker_url, TrackerInfos(tracker_url)).num_peers); tracker_dict[KEY_TRACKER_MSG] = data.last_message.trimmed(); tracker_list.append(tracker_dict); } } catch (const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << misc::toQStringU(e.what()); return QByteArray(); } return json::toJson(tracker_list); }
TorrentModelItem::TorrentModelItem(const QTorrentHandle &h) : m_torrent(h) , m_lastStatus(h.status(torrent_handle::query_accurate_download_counters)) , m_addedTime(TorrentPersistentData::instance()->getAddedDate(h.hash())) , m_label(TorrentPersistentData::instance()->getLabel(h.hash())) , m_name(TorrentPersistentData::instance()->getName(h.hash())) , m_hash(h.hash()) { if (m_name.isEmpty()) m_name = h.name(); // If name is empty show the hash. This happens when magnet isn't retrieved. if (m_name.isEmpty()) m_name = h.hash(); }
TorrentModelItem::TorrentModelItem(const QTorrentHandle &h) : m_torrent(h) , m_addedTime(TorrentPersistentData::getAddedDate(h.hash())) , m_seedTime(TorrentPersistentData::getSeedDate(h.hash())) , m_label(TorrentPersistentData::getLabel(h.hash())) , m_name(TorrentPersistentData::getName(h.hash())) , m_hash(h.hash()) { if (m_name.isEmpty()) m_name = h.name(); }
/** * Returns the properties for a torrent in JSON format. * * The return value is a JSON-formatted dictionary. * The dictionary keys are: * - "save_path": Torrent save path * - "creation_date": Torrent creation date * - "piece_size": Torrent piece size * - "comment": Torrent comment * - "total_wasted": Total data wasted for torrent * - "total_uploaded": Total data uploaded for torrent * - "total_downloaded": Total data uploaded for torrent * - "up_limit": Torrent upload limit * - "dl_limit": Torrent download limit * - "time_elapsed": Torrent elapsed time * - "nb_connections": Torrent connection count * - "share_ratio": Torrent share ratio */ QByteArray btjson::getPropertiesForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(QVariantMap, data, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters); if (!status.has_metadata) return QByteArray(); // Save path QString save_path = fsutils::toNativePath(TorrentPersistentData::getSavePath(hash)); if (save_path.isEmpty()) save_path = fsutils::toNativePath(h.save_path()); data[KEY_PROP_SAVE_PATH] = save_path; data[KEY_PROP_CREATION_DATE] = h.creation_date(); data[KEY_PROP_PIECE_SIZE] = misc::friendlyUnit(h.piece_length(), false, true); data[KEY_PROP_COMMENT] = h.comment(); data[KEY_PROP_WASTED] = misc::friendlyUnit(status.total_failed_bytes + status.total_redundant_bytes, false, true); data[KEY_PROP_UPLOADED] = QString(misc::friendlyUnit(status.all_time_upload, false, true) + " (" + misc::friendlyUnit(status.total_payload_upload, false, true) + " " + tr("this session") + ")"); data[KEY_PROP_DOWNLOADED] = QString(misc::friendlyUnit(status.all_time_download, false, true) + " (" + misc::friendlyUnit(status.total_payload_download, false, true) + " " + tr("this session") + ")"); data[KEY_PROP_UP_LIMIT] = h.upload_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.upload_limit(), true, true); data[KEY_PROP_DL_LIMIT] = h.download_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.download_limit(), true, true); QString elapsed_txt = misc::userFriendlyDuration(status.active_time); if (h.is_seed(status)) elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(status.seeding_time))+")"; data[KEY_PROP_TIME_ELAPSED] = elapsed_txt; data[KEY_PROP_CONNECT_COUNT] = QString(QString::number(status.num_connections) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(status.connections_limit)) + ")"); const qreal ratio = QBtSession::instance()->getRealRatio(status); data[KEY_PROP_RATIO] = ratio > 100. ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1, false); } catch(const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what(); return QByteArray(); } return json::toJson(data); }
/** * Returns the properties for a torrent in JSON format. * * The return value is a JSON-formatted dictionary. * The dictionary keys are: * - "save_path": Torrent save path * - "creation_date": Torrent creation date * - "piece_size": Torrent piece size * - "comment": Torrent comment * - "total_wasted": Total data wasted for torrent * - "total_uploaded": Total data uploaded for torrent * - "total_downloaded": Total data uploaded for torrent * - "up_limit": Torrent upload limit * - "dl_limit": Torrent download limit * - "time_elapsed": Torrent elapsed time * - "nb_connections": Torrent connection count * - "share_ratio": Torrent share ratio */ QString btjson::getPropertiesForTorrent(const QString& hash) { CACHED_VARIABLE_FOR_HASH(JsonDict, data, CACHE_DURATION_MS, hash); try { QTorrentHandle h = QBtSession::instance()->getTorrentHandle(hash); if (!h.has_metadata()) return QString(); // Save path QString save_path = TorrentPersistentData::getSavePath(hash); if (save_path.isEmpty()) save_path = h.save_path(); data.add(KEY_PROP_SAVE_PATH, save_path); data.add(KEY_PROP_CREATION_DATE, h.creation_date()); data.add(KEY_PROP_PIECE_SIZE, misc::friendlyUnit(h.piece_length())); data.add(KEY_PROP_COMMENT, h.comment()); data.add(KEY_PROP_WASTED, misc::friendlyUnit(h.total_failed_bytes() + h.total_redundant_bytes())); data.add(KEY_PROP_UPLOADED, QString(misc::friendlyUnit(h.all_time_upload()) + " (" + misc::friendlyUnit(h.total_payload_upload()) + " " + tr("this session") + ")")); data.add(KEY_PROP_DOWNLOADED, QString(misc::friendlyUnit(h.all_time_download()) + " (" + misc::friendlyUnit(h.total_payload_download()) + " " + tr("this session") + ")")); data.add(KEY_PROP_UP_LIMIT, h.upload_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.upload_limit(), true)); data.add(KEY_PROP_DL_LIMIT, h.download_limit() <= 0 ? QString::fromUtf8("∞") : misc::friendlyUnit(h.download_limit(), true)); QString elapsed_txt = misc::userFriendlyDuration(h.active_time()); if (h.is_seed()) elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")"; data.add(KEY_PROP_TIME_ELAPSED, elapsed_txt); data.add(KEY_PROP_CONNECT_COUNT, QString(QString::number(h.num_connections()) + " (" + tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit())) + ")")); const qreal ratio = QBtSession::instance()->getRealRatio(h.hash()); /* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9 ** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 */ data.add(KEY_PROP_RATIO, ratio > 100. ? QString::fromUtf8("∞") : QString::number((int)(ratio*10)/10.0, 'f', 1)); } catch(const std::exception& e) { qWarning() << Q_FUNC_INFO << "Invalid torrent: " << e.what(); return QString(); } return data.toString(); }
void TorrentPersistentData::saveTorrentPersistentData(const QTorrentHandle &h, const QString &save_path, const bool is_magnet) { Q_ASSERT(h.is_valid()); qDebug("Saving persistent data for %s", qPrintable(h.hash())); // Save persistent data QHash<QString, QVariant> data = all_data.value(h.hash()).toHash(); data["is_magnet"] = is_magnet; if (is_magnet) { data["magnet_uri"] = misc::toQString(make_magnet_uri(h)); } data["seed"] = h.is_seed(); data["priority"] = h.queue_position(); if (save_path.isEmpty()) { qDebug("TorrentPersistantData: save path is %s", qPrintable(h.save_path())); data["save_path"] = h.save_path(); } else { qDebug("TorrentPersistantData: overriding save path is %s", qPrintable(save_path)); data["save_path"] = save_path; // Override torrent save path (e.g. because it is a temp dir) } // Label data["label"] = TorrentTempData::getLabel(h.hash()); // Save data all_data[h.hash()] = data; markDirty(); qDebug("TorrentPersistentData: Saving save_path %s, hash: %s", qPrintable(h.save_path()), qPrintable(h.hash())); // Set Added date setAddedDate(h.hash(), QDateTime::currentDateTime()); // Finally, remove temp data TorrentTempData::deleteTempData(h.hash()); }
void TorrentPersistentData::savePriority(const QTorrentHandle &h) { QHash<QString, QVariant> data = all_data[h.hash()].toHash(); data["priority"] = h.queue_position(); all_data[h.hash()] = data; markDirty(); }
HttpServer::HttpServer(int msec, QObject* parent) : QTcpServer(parent), m_eventManager(new EventManager(this)) { const Preferences pref; m_username = pref.getWebUiUsername().toLocal8Bit(); m_passwordSha1 = pref.getWebUiPassword().toLocal8Bit(); m_localAuthEnabled = pref.isWebUiLocalAuthEnabled(); m_needsTranslation = !Preferences().getLocale().startsWith("en"); connect(m_eventManager, SIGNAL(localeChanged(QString)), SLOT(onLocaleChanged(QString))); // HTTPS-related #ifndef QT_NO_OPENSSL m_https = pref.isWebUiHttpsEnabled(); if (m_https) { m_certificate = QSslCertificate(pref.getWebUiHttpsCertificate()); m_key = QSslKey(pref.getWebUiHttpsKey(), QSsl::Rsa); } #endif // Add torrents std::vector<torrent_handle> torrents = QBtSession::instance()->getTorrents(); std::vector<torrent_handle>::iterator torrentIT; for (torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) { QTorrentHandle h = QTorrentHandle(*torrentIT); if (h.is_valid()) m_eventManager->addedTorrent(h); } //connect QBtSession::instance() to manager connect(QBtSession::instance(), SIGNAL(addedTorrent(QTorrentHandle)), m_eventManager, SLOT(addedTorrent(QTorrentHandle))); connect(QBtSession::instance(), SIGNAL(deletedTorrent(QString)), m_eventManager, SLOT(deletedTorrent(QString))); //set timer connect(&m_timer, SIGNAL(timeout()), SLOT(onTimer())); m_timer.start(msec); // Additional translations for Web UI QString a = tr("File"); a = tr("Edit"); a = tr("Help"); a = tr("Download Torrents from their URL or Magnet link"); a = tr("Only one link per line"); a = tr("Download local torrent"); a = tr("Torrent files were correctly added to download list."); a = tr("Point to torrent file"); a = tr("Download"); a = tr("Are you sure you want to delete the selected torrents from the transfer list and hard disk?"); a = tr("Download rate limit must be greater than 0 or disabled."); a = tr("Upload rate limit must be greater than 0 or disabled."); a = tr("Maximum number of connections limit must be greater than 0 or disabled."); a = tr("Maximum number of connections per torrent limit must be greater than 0 or disabled."); a = tr("Maximum number of upload slots per torrent limit must be greater than 0 or disabled."); a = tr("Unable to save program preferences, qBittorrent is probably unreachable."); a = tr("Language"); a = tr("Downloaded", "Is the file downloaded or not?"); a = tr("The port used for incoming connections must be greater than 1024 and less than 65535."); a = tr("The port used for the Web UI must be greater than 1024 and less than 65535."); a = tr("The Web UI username must be at least 3 characters long."); a = tr("The Web UI password must be at least 3 characters long."); a = tr("Save"); a = tr("qBittorrent client is not reachable"); a = tr("HTTP Server"); a = tr("The following parameters are supported:"); a = tr("Torrent path"); a = tr("Torrent name"); }
static QVariantMap toMap(const QTorrentHandle& h) { libtorrent::torrent_status status = h.status(torrent_handle::query_accurate_download_counters); QVariantMap ret; ret[KEY_TORRENT_HASH] = h.hash(); ret[KEY_TORRENT_NAME] = h.name(); ret[KEY_TORRENT_SIZE] = misc::friendlyUnit(status.total_wanted, false, true); // FIXME: Should pass as Number, not formatted String (for sorting). ret[KEY_TORRENT_PROGRESS] = (double)h.progress(status); ret[KEY_TORRENT_DLSPEED] = misc::friendlyUnit(status.download_payload_rate, true, true); // FIXME: Should be passed as a Number ret[KEY_TORRENT_UPSPEED] = misc::friendlyUnit(status.upload_payload_rate, true, true); // FIXME: Should be passed as a Number if (QBtSession::instance()->isQueueingEnabled() && h.queue_position(status) >= 0) ret[KEY_TORRENT_PRIORITY] = QString::number(h.queue_position(status)); else ret[KEY_TORRENT_PRIORITY] = "*"; QString seeds = QString::number(status.num_seeds); if (status.num_complete > 0) seeds += " ("+QString::number(status.num_complete)+")"; ret[KEY_TORRENT_SEEDS] = seeds; QString leechs = QString::number(status.num_peers - status.num_seeds); if (status.num_incomplete > 0) leechs += " ("+QString::number(status.num_incomplete)+")"; ret[KEY_TORRENT_LEECHS] = leechs; const qreal ratio = QBtSession::instance()->getRealRatio(status); ret[KEY_TORRENT_RATIO] = (ratio > 100.) ? QString::fromUtf8("∞") : misc::accurateDoubleToString(ratio, 1, false); QString eta; QString state; if (h.is_paused(status)) { if (h.has_error(status)) state = "error"; else state = h.is_seed(status) ? "pausedUP" : "pausedDL"; } else { if (QBtSession::instance()->isQueueingEnabled() && h.is_queued(status)) state = h.is_seed(status) ? "queuedUP" : "queuedDL"; else { switch (status.state) { case torrent_status::finished: case torrent_status::seeding: state = status.upload_payload_rate > 0 ? "uploading" : "stalledUP"; break; case torrent_status::allocating: case torrent_status::checking_files: case torrent_status::queued_for_checking: case torrent_status::checking_resume_data: state = h.is_seed(status) ? "checkingUP" : "checkingDL"; break; case torrent_status::downloading: case torrent_status::downloading_metadata: state = status.download_payload_rate > 0 ? "downloading" : "stalledDL"; eta = misc::userFriendlyDuration(QBtSession::instance()->getETA(h.hash(), status)); break; default: qWarning("Unrecognized torrent status, should not happen!!! status was %d", h.state()); } } } ret[KEY_TORRENT_ETA] = eta.isEmpty() ? QString::fromUtf8("∞") : eta; ret[KEY_TORRENT_STATE] = state; return ret; }
bool QTorrentHandle::operator ==(const QTorrentHandle& new_h) const { return info_hash() == new_h.info_hash(); }
void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) { try { m_samples.remove(h.hash()); } catch(invalid_handle&) {} }