diff --git a/README.md b/README.md index a2c75ef52..8c0d32e72 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ It aims to be a good alternative to all other bittorrent clients out there. qBittorrent is fast, stable and provides unicode support as well as many features. -This product includes GeoLite data created by MaxMind, available from -https://www.maxmind.com/ +The free [IP to Country Lite database](https://db-ip.com/db/download/ip-to-country-lite) by [DB-IP](https://db-ip.com/) is used for resolving the countries of peers. The database is licensed under the [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). ### Installation: For installation, follow the instructions from INSTALL file, but simple: diff --git a/src/base/net/geoipmanager.cpp b/src/base/net/geoipmanager.cpp index d5a6e8067..49f30cfb1 100644 --- a/src/base/net/geoipmanager.cpp +++ b/src/base/net/geoipmanager.cpp @@ -42,10 +42,9 @@ #include "downloadmanager.h" #include "private/geoipdatabase.h" -static const char DATABASE_URL[] = "https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"; -static const char GEOIP_FOLDER[] = "GeoIP"; -static const char GEOIP_FILENAME[] = "GeoLite2-Country.mmdb"; -static const int UPDATE_INTERVAL = 30; // Days between database updates +static const QString DATABASE_URL = QStringLiteral("https://download.db-ip.com/free/dbip-country-lite-%1.mmdb.gz"); +static const char GEODB_FOLDER[] = "GeoDB"; +static const char GEODB_FILENAME[] = "dbip-country-lite.mmdb"; using namespace Net; @@ -89,29 +88,45 @@ void GeoIPManager::loadDatabase() m_geoIPDatabase = nullptr; const QString filepath = Utils::Fs::expandPathAbs( - QString("%1%2/%3").arg(specialFolderLocation(SpecialFolder::Data), GEOIP_FOLDER, GEOIP_FILENAME)); + QString("%1%2/%3").arg(specialFolderLocation(SpecialFolder::Data), GEODB_FOLDER, GEODB_FILENAME)); QString error; m_geoIPDatabase = GeoIPDatabase::load(filepath, error); if (m_geoIPDatabase) - Logger::instance()->addMessage(tr("GeoIP database loaded. Type: %1. Build time: %2.") + Logger::instance()->addMessage(tr("IP geolocation database loaded. Type: %1. Build time: %2.") .arg(m_geoIPDatabase->type(), m_geoIPDatabase->buildEpoch().toString()), Log::INFO); else - Logger::instance()->addMessage(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING); + Logger::instance()->addMessage(tr("Couldn't load IP geolocation database. Reason: %1").arg(error), Log::WARNING); manageDatabaseUpdate(); } void GeoIPManager::manageDatabaseUpdate() { - if (!m_geoIPDatabase || (m_geoIPDatabase->buildEpoch().daysTo(QDateTime::currentDateTimeUtc()) >= UPDATE_INTERVAL)) + const auto expired = [](const QDateTime &testDateTime) + { + const QDate testDate = testDateTime.date(); + const QDate curDate = QDateTime::currentDateTimeUtc().date(); + + if ((testDate.year() < curDate.year()) && (curDate.day() > 1)) + return true; + + if ((testDate.month() < curDate.month()) && (curDate.day() > 1)) + return true; + + return false; + }; + + if (!m_geoIPDatabase || expired(m_geoIPDatabase->buildEpoch())) downloadDatabaseFile(); } void GeoIPManager::downloadDatabaseFile() { - DownloadManager::instance()->download({DATABASE_URL}, this, &GeoIPManager::downloadFinished); + const QDate curDate = QDateTime::currentDateTimeUtc().date(); + const QString curUrl = DATABASE_URL.arg(curDate.toString("yyyy-MM")); + DownloadManager::instance()->download({curUrl}, this, &GeoIPManager::downloadFinished); } QString GeoIPManager::lookup(const QHostAddress &hostAddr) const @@ -403,14 +418,14 @@ void GeoIPManager::configure() void GeoIPManager::downloadFinished(const DownloadResult &result) { if (result.status != DownloadStatus::Success) { - LogMsg(tr("Couldn't download GeoIP database file. Reason: %1").arg(result.errorString), Log::WARNING); + LogMsg(tr("Couldn't download IP geolocation database file. Reason: %1").arg(result.errorString), Log::WARNING); return; } bool ok = false; const QByteArray data = Utils::Gzip::decompress(result.data, &ok); if (!ok) { - LogMsg(tr("Could not decompress GeoIP database file."), Log::WARNING); + LogMsg(tr("Could not decompress IP geolocation database file."), Log::WARNING); return; } @@ -420,24 +435,24 @@ void GeoIPManager::downloadFinished(const DownloadResult &result) if (!m_geoIPDatabase || (geoIPDatabase->buildEpoch() > m_geoIPDatabase->buildEpoch())) { delete m_geoIPDatabase; m_geoIPDatabase = geoIPDatabase; - LogMsg(tr("GeoIP database loaded. Type: %1. Build time: %2.") + LogMsg(tr("IP geolocation database loaded. Type: %1. Build time: %2.") .arg(m_geoIPDatabase->type(), m_geoIPDatabase->buildEpoch().toString()), Log::INFO); const QString targetPath = Utils::Fs::expandPathAbs( - specialFolderLocation(SpecialFolder::Data) + GEOIP_FOLDER); + specialFolderLocation(SpecialFolder::Data) + GEODB_FOLDER); if (!QDir(targetPath).exists()) QDir().mkpath(targetPath); - QFile targetFile(QString("%1/%2").arg(targetPath, GEOIP_FILENAME)); + QFile targetFile(QString("%1/%2").arg(targetPath, GEODB_FILENAME)); if (!targetFile.open(QFile::WriteOnly) || (targetFile.write(data) == -1)) - LogMsg(tr("Couldn't save downloaded GeoIP database file."), Log::WARNING); + LogMsg(tr("Couldn't save downloaded IP geolocation database file."), Log::WARNING); else - LogMsg(tr("Successfully updated GeoIP database."), Log::INFO); + LogMsg(tr("Successfully updated IP geolocation database."), Log::INFO); } else { delete geoIPDatabase; } } else { - LogMsg(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING); + LogMsg(tr("Couldn't load IP geolocation database. Reason: %1").arg(error), Log::WARNING); } } diff --git a/src/base/net/private/geoipdatabase.cpp b/src/base/net/private/geoipdatabase.cpp index f50538684..f191e882b 100644 --- a/src/base/net/private/geoipdatabase.cpp +++ b/src/base/net/private/geoipdatabase.cpp @@ -37,7 +37,6 @@ namespace { const qint32 MAX_FILE_SIZE = 67108864; // 64MB - const char DB_TYPE[] = "GeoLite2-Country"; const quint32 MAX_METADATA_SIZE = 131072; // 128KB const char METADATA_BEGIN_MARK[] = "\xab\xcd\xefMaxMind.com"; const char DATA_SECTION_SEPARATOR[16] = {0}; @@ -143,7 +142,7 @@ GeoIPDatabase::~GeoIPDatabase() QString GeoIPDatabase::type() const { - return DB_TYPE; + return m_dbType; } quint16 GeoIPDatabase::ipVersion() const @@ -253,11 +252,7 @@ bool GeoIPDatabase::parseMetadata(const QVariantHash &metadata, QString &error) m_indexSize = m_nodeCount * m_nodeSize; CHECK_METADATA_REQ(database_type, QString); - const QString dbType = metadata.value("database_type").toString(); - if (dbType != DB_TYPE) { - error = tr("Invalid database type: %1").arg(dbType); - return false; - } + m_dbType = metadata.value("database_type").toString(); CHECK_METADATA_REQ(build_epoch, ULongLong); m_buildEpoch = QDateTime::fromSecsSinceEpoch(metadata.value("build_epoch").toULongLong()); @@ -270,7 +265,7 @@ bool GeoIPDatabase::parseMetadata(const QVariantHash &metadata, QString &error) bool GeoIPDatabase::loadDB(QString &error) const { - qDebug() << "Parsing MaxMindDB index tree..."; + qDebug() << "Parsing IP geolocation database index tree..."; const int nodeSize = m_recordSize / 4; // in bytes const int indexSize = m_nodeCount * nodeSize; diff --git a/src/base/net/private/geoipdatabase.h b/src/base/net/private/geoipdatabase.h index 5ba3d0196..313ee0346 100644 --- a/src/base/net/private/geoipdatabase.h +++ b/src/base/net/private/geoipdatabase.h @@ -93,6 +93,7 @@ private: int m_indexSize; int m_recordBytes; QDateTime m_buildEpoch; + QString m_dbType; // Search data mutable QHash m_countries; quint32 m_size; diff --git a/src/gui/aboutdialog.cpp b/src/gui/aboutdialog.cpp index d070abef2..76640cc9f 100644 --- a/src/gui/aboutdialog.cpp +++ b/src/gui/aboutdialog.cpp @@ -48,7 +48,7 @@ AboutDialog::AboutDialog(QWidget *parent) m_ui->logo->setPixmap(Utils::Gui::scaledPixmapSvg(":/icons/skin/qbittorrent-tray.svg", this, 32)); // About - QString aboutText = QString( + const QString aboutText = QString( "

" "%1\n\n" "%2\n\n" @@ -88,13 +88,21 @@ AboutDialog::AboutDialog(QWidget *parent) licensefile.close(); } - // Libraries + // Software Used m_ui->labelQtVer->setText(QT_VERSION_STR); m_ui->labelLibtVer->setText(Utils::Misc::libtorrentVersionString()); m_ui->labelBoostVer->setText(Utils::Misc::boostVersionString()); m_ui->labelOpensslVer->setText(Utils::Misc::opensslVersionString()); m_ui->labelZlibVer->setText(Utils::Misc::zlibVersionString()); + const QString DBIPText = QString( + "

" + "%1" + " (https://db-ip.com/)

") + .arg(tr("The free IP to Country Lite database by DB-IP is used for resolving the countries of peers. " + "The database is licensed under the Creative Commons Attribution 4.0 International License")); + m_ui->labelDBIP->setText(DBIPText); + Utils::Gui::resize(this); show(); } diff --git a/src/gui/aboutdialog.ui b/src/gui/aboutdialog.ui index fa27a9818..13ac0eb7b 100644 --- a/src/gui/aboutdialog.ui +++ b/src/gui/aboutdialog.ui @@ -314,11 +314,11 @@ - + - Libraries + Software Used - + @@ -470,6 +470,22 @@ + + + + DB-IP license text + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse + + + diff --git a/src/gui/advancedsettings.cpp b/src/gui/advancedsettings.cpp index 04cadf491..a6e91fa9f 100644 --- a/src/gui/advancedsettings.cpp +++ b/src/gui/advancedsettings.cpp @@ -496,7 +496,7 @@ void AdvancedSettings::loadAdvancedSettings() addRow(LIST_REFRESH, tr("Transfer list refresh interval"), &m_spinBoxListRefresh); // Resolve Peer countries m_checkBoxResolveCountries.setChecked(pref->resolvePeerCountries()); - addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries (GeoIP)"), &m_checkBoxResolveCountries); + addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries"), &m_checkBoxResolveCountries); // Resolve peer hosts m_checkBoxResolveHosts.setChecked(pref->resolvePeerHostNames()); addRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &m_checkBoxResolveHosts); diff --git a/src/webui/www/private/views/about.html b/src/webui/www/private/views/about.html index b7455b6b7..55483857f 100644 --- a/src/webui/www/private/views/about.html +++ b/src/webui/www/private/views/about.html @@ -652,7 +652,7 @@

-