mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-01-09 00:27:28 +03:00
459 lines
18 KiB
C++
459 lines
18 KiB
C++
/*
|
|
* Bittorrent Client using Qt and libtorrent.
|
|
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
|
* Copyright (C) 2010 Christophe Dumez <chris@qbittorrent.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* In addition, as a special exception, the copyright holders give permission to
|
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
|
* and distribute the linked executables. You must obey the GNU General Public
|
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
|
* modify file(s), you may extend this exception to your version of the file(s),
|
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
|
* exception statement from your version.
|
|
*/
|
|
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
#include <QDir>
|
|
#include <QHostAddress>
|
|
#include <QDateTime>
|
|
|
|
#include "base/logger.h"
|
|
#include "base/preferences.h"
|
|
#include "base/utils/fs.h"
|
|
#include "base/utils/gzip.h"
|
|
#include "downloadmanager.h"
|
|
#include "downloadhandler.h"
|
|
#include "private/geoipdatabase.h"
|
|
#include "geoipmanager.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
|
|
|
|
using namespace Net;
|
|
|
|
// GeoIPManager
|
|
|
|
GeoIPManager *GeoIPManager::m_instance = 0;
|
|
|
|
GeoIPManager::GeoIPManager()
|
|
: m_enabled(false)
|
|
, m_geoIPDatabase(0)
|
|
{
|
|
configure();
|
|
connect(Preferences::instance(), SIGNAL(changed()), SLOT(configure()));
|
|
}
|
|
|
|
GeoIPManager::~GeoIPManager()
|
|
{
|
|
if (m_geoIPDatabase)
|
|
delete m_geoIPDatabase;
|
|
}
|
|
|
|
void GeoIPManager::initInstance()
|
|
{
|
|
if (!m_instance)
|
|
m_instance = new GeoIPManager;
|
|
}
|
|
|
|
void GeoIPManager::freeInstance()
|
|
{
|
|
if (m_instance) {
|
|
delete m_instance;
|
|
m_instance = 0;
|
|
}
|
|
}
|
|
|
|
GeoIPManager *GeoIPManager::instance()
|
|
{
|
|
return m_instance;
|
|
}
|
|
|
|
void GeoIPManager::loadDatabase()
|
|
{
|
|
if (m_geoIPDatabase) {
|
|
delete m_geoIPDatabase;
|
|
m_geoIPDatabase = 0;
|
|
}
|
|
|
|
QString filepath = Utils::Fs::expandPathAbs(
|
|
QString("%1%2/%3").arg(Utils::Fs::QDesktopServicesDataLocation())
|
|
.arg(GEOIP_FOLDER).arg(GEOIP_FILENAME));
|
|
|
|
QString error;
|
|
m_geoIPDatabase = GeoIPDatabase::load(filepath, error);
|
|
if (m_geoIPDatabase)
|
|
Logger::instance()->addMessage(tr("GeoIP database loaded. Type: %1. Build time: %2.")
|
|
.arg(m_geoIPDatabase->type()).arg(m_geoIPDatabase->buildEpoch().toString()),
|
|
Log::INFO);
|
|
else
|
|
Logger::instance()->addMessage(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING);
|
|
|
|
manageDatabaseUpdate();
|
|
}
|
|
|
|
void GeoIPManager::manageDatabaseUpdate()
|
|
{
|
|
if (!m_geoIPDatabase || (m_geoIPDatabase->buildEpoch().daysTo(QDateTime::currentDateTimeUtc()) >= UPDATE_INTERVAL))
|
|
downloadDatabaseFile();
|
|
}
|
|
|
|
void GeoIPManager::downloadDatabaseFile()
|
|
{
|
|
DownloadHandler *handler = DownloadManager::instance()->downloadUrl(DATABASE_URL);
|
|
connect(handler, SIGNAL(downloadFinished(QString, QByteArray)), SLOT(downloadFinished(QString, QByteArray)));
|
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), SLOT(downloadFailed(QString, QString)));
|
|
}
|
|
|
|
QString GeoIPManager::lookup(const QHostAddress &hostAddr) const
|
|
{
|
|
if (m_enabled && m_geoIPDatabase)
|
|
return m_geoIPDatabase->lookup(hostAddr);
|
|
|
|
return QString();
|
|
}
|
|
|
|
QString GeoIPManager::CountryName(const QString &countryISOCode)
|
|
{
|
|
static QHash<QString, QString> countries;
|
|
static bool initialized = false;
|
|
|
|
// ISO 3166-1 alpha-2 codes
|
|
// http://www.iso.org/iso/home/standards/country_codes/country_names_and_code_elements_txt-temp.htm
|
|
if (!initialized) {
|
|
// Officially assigned
|
|
countries["AD"] = tr("Andorra");
|
|
countries["AE"] = tr("United Arab Emirates");
|
|
countries["AF"] = tr("Afghanistan");
|
|
countries["AG"] = tr("Antigua and Barbuda");
|
|
countries["AI"] = tr("Anguilla");
|
|
countries["AL"] = tr("Albania");
|
|
countries["AM"] = tr("Armenia");
|
|
countries["AO"] = tr("Angola");
|
|
countries["AQ"] = tr("Antarctica");
|
|
countries["AR"] = tr("Argentina");
|
|
countries["AS"] = tr("American Samoa");
|
|
countries["AT"] = tr("Austria");
|
|
countries["AU"] = tr("Australia");
|
|
countries["AW"] = tr("Aruba");
|
|
countries["AX"] = tr("Aland Islands");
|
|
countries["AZ"] = tr("Azerbaijan");
|
|
countries["BA"] = tr("Bosnia and Herzegovina");
|
|
countries["BB"] = tr("Barbados");
|
|
countries["BD"] = tr("Bangladesh");
|
|
countries["BE"] = tr("Belgium");
|
|
countries["BF"] = tr("Burkina Faso");
|
|
countries["BG"] = tr("Bulgaria");
|
|
countries["BH"] = tr("Bahrain");
|
|
countries["BI"] = tr("Burundi");
|
|
countries["BJ"] = tr("Benin");
|
|
countries["BL"] = tr("Saint Barthelemy");
|
|
countries["BM"] = tr("Bermuda");
|
|
countries["BN"] = tr("Brunei Darussalam");
|
|
countries["BO"] = tr("Bolivia, Plurinational State of");
|
|
countries["BQ"] = tr("Bonaire, Sint Eustatius and Saba");
|
|
countries["BR"] = tr("Brazil");
|
|
countries["BS"] = tr("Bahamas");
|
|
countries["BT"] = tr("Bhutan");
|
|
countries["BV"] = tr("Bouvet Island");
|
|
countries["BW"] = tr("Botswana");
|
|
countries["BY"] = tr("Belarus");
|
|
countries["BZ"] = tr("Belize");
|
|
countries["CA"] = tr("Canada");
|
|
countries["CC"] = tr("Cocos (Keeling) Islands");
|
|
countries["CD"] = tr("Congo, The Democratic Republic of the");
|
|
countries["CF"] = tr("Central African Republic");
|
|
countries["CG"] = tr("Congo");
|
|
countries["CH"] = tr("Switzerland");
|
|
countries["CI"] = tr("Cote d'Ivoire");
|
|
countries["CK"] = tr("Cook Islands");
|
|
countries["CL"] = tr("Chile");
|
|
countries["CM"] = tr("Cameroon");
|
|
countries["CN"] = tr("China");
|
|
countries["CO"] = tr("Colombia");
|
|
countries["CR"] = tr("Costa Rica");
|
|
countries["CU"] = tr("Cuba");
|
|
countries["CV"] = tr("Cape Verde");
|
|
countries["CW"] = tr("Curacao");
|
|
countries["CX"] = tr("Christmas Island");
|
|
countries["CY"] = tr("Cyprus");
|
|
countries["CZ"] = tr("Czech Republic");
|
|
countries["DE"] = tr("Germany");
|
|
countries["DJ"] = tr("Djibouti");
|
|
countries["DK"] = tr("Denmark");
|
|
countries["DM"] = tr("Dominica");
|
|
countries["DO"] = tr("Dominican Republic");
|
|
countries["DZ"] = tr("Algeria");
|
|
countries["EC"] = tr("Ecuador");
|
|
countries["EE"] = tr("Estonia");
|
|
countries["EG"] = tr("Egypt");
|
|
countries["EH"] = tr("Western Sahara");
|
|
countries["ER"] = tr("Eritrea");
|
|
countries["ES"] = tr("Spain");
|
|
countries["ET"] = tr("Ethiopia");
|
|
countries["FI"] = tr("Finland");
|
|
countries["FJ"] = tr("Fiji");
|
|
countries["FK"] = tr("Falkland Islands (Malvinas)");
|
|
countries["FM"] = tr("Micronesia, Federated States of");
|
|
countries["FO"] = tr("Faroe Islands");
|
|
countries["FR"] = tr("France");
|
|
countries["GA"] = tr("Gabon");
|
|
countries["GB"] = tr("United Kingdom");
|
|
countries["GD"] = tr("Grenada");
|
|
countries["GE"] = tr("Georgia");
|
|
countries["GF"] = tr("French Guiana");
|
|
countries["GG"] = tr("Guernsey");
|
|
countries["GH"] = tr("Ghana");
|
|
countries["GI"] = tr("Gibraltar");
|
|
countries["GL"] = tr("Greenland");
|
|
countries["GM"] = tr("Gambia");
|
|
countries["GN"] = tr("Guinea");
|
|
countries["GP"] = tr("Guadeloupe");
|
|
countries["GQ"] = tr("Equatorial Guinea");
|
|
countries["GR"] = tr("Greece");
|
|
countries["GS"] = tr("South Georgia and the South Sandwich Islands");
|
|
countries["GT"] = tr("Guatemala");
|
|
countries["GU"] = tr("Guam");
|
|
countries["GW"] = tr("Guinea-Bissau");
|
|
countries["GY"] = tr("Guyana");
|
|
countries["HK"] = tr("Hong Kong");
|
|
countries["HM"] = tr("Heard Island and McDonald Islands");
|
|
countries["HN"] = tr("Honduras");
|
|
countries["HR"] = tr("Croatia");
|
|
countries["HT"] = tr("Haiti");
|
|
countries["HU"] = tr("Hungary");
|
|
countries["ID"] = tr("Indonesia");
|
|
countries["IE"] = tr("Ireland");
|
|
countries["IL"] = tr("Israel");
|
|
countries["IM"] = tr("Isle of Man");
|
|
countries["IN"] = tr("India");
|
|
countries["IO"] = tr("British Indian Ocean Territory");
|
|
countries["IQ"] = tr("Iraq");
|
|
countries["IR"] = tr("Iran, Islamic Republic of");
|
|
countries["IS"] = tr("Iceland");
|
|
countries["IT"] = tr("Italy");
|
|
countries["JE"] = tr("Jersey");
|
|
countries["JM"] = tr("Jamaica");
|
|
countries["JO"] = tr("Jordan");
|
|
countries["JP"] = tr("Japan");
|
|
countries["KE"] = tr("Kenya");
|
|
countries["KG"] = tr("Kyrgyzstan");
|
|
countries["KH"] = tr("Cambodia");
|
|
countries["KI"] = tr("Kiribati");
|
|
countries["KM"] = tr("Comoros");
|
|
countries["KN"] = tr("Saint Kitts and Nevis");
|
|
countries["KP"] = tr("Korea, Democratic People's Republic of");
|
|
countries["KR"] = tr("Korea, Republic of");
|
|
countries["KW"] = tr("Kuwait");
|
|
countries["KY"] = tr("Cayman Islands");
|
|
countries["KZ"] = tr("Kazakhstan");
|
|
countries["LA"] = tr("Lao People's Democratic Republic");
|
|
countries["LB"] = tr("Lebanon");
|
|
countries["LC"] = tr("Saint Lucia");
|
|
countries["LI"] = tr("Liechtenstein");
|
|
countries["LK"] = tr("Sri Lanka");
|
|
countries["LR"] = tr("Liberia");
|
|
countries["LS"] = tr("Lesotho");
|
|
countries["LT"] = tr("Lithuania");
|
|
countries["LU"] = tr("Luxembourg");
|
|
countries["LV"] = tr("Latvia");
|
|
countries["LY"] = tr("Libya");
|
|
countries["MA"] = tr("Morocco");
|
|
countries["MC"] = tr("Monaco");
|
|
countries["MD"] = tr("Moldova, Republic of");
|
|
countries["ME"] = tr("Montenegro");
|
|
countries["MF"] = tr("Saint Martin (French part)");
|
|
countries["MG"] = tr("Madagascar");
|
|
countries["MH"] = tr("Marshall Islands");
|
|
countries["MK"] = tr("Macedonia, The Former Yugoslav Republic of");
|
|
countries["ML"] = tr("Mali");
|
|
countries["MM"] = tr("Myanmar");
|
|
countries["MN"] = tr("Mongolia");
|
|
countries["MO"] = tr("Macao");
|
|
countries["MP"] = tr("Northern Mariana Islands");
|
|
countries["MQ"] = tr("Martinique");
|
|
countries["MR"] = tr("Mauritania");
|
|
countries["MS"] = tr("Montserrat");
|
|
countries["MT"] = tr("Malta");
|
|
countries["MU"] = tr("Mauritius");
|
|
countries["MV"] = tr("Maldives");
|
|
countries["MW"] = tr("Malawi");
|
|
countries["MX"] = tr("Mexico");
|
|
countries["MY"] = tr("Malaysia");
|
|
countries["MZ"] = tr("Mozambique");
|
|
countries["NA"] = tr("Namibia");
|
|
countries["NC"] = tr("New Caledonia");
|
|
countries["NE"] = tr("Niger");
|
|
countries["NF"] = tr("Norfolk Island");
|
|
countries["NG"] = tr("Nigeria");
|
|
countries["NI"] = tr("Nicaragua");
|
|
countries["NL"] = tr("Netherlands");
|
|
countries["NO"] = tr("Norway");
|
|
countries["NP"] = tr("Nepal");
|
|
countries["NR"] = tr("Nauru");
|
|
countries["NU"] = tr("Niue");
|
|
countries["NZ"] = tr("New Zealand");
|
|
countries["OM"] = tr("Oman");
|
|
countries["PA"] = tr("Panama");
|
|
countries["PE"] = tr("Peru");
|
|
countries["PF"] = tr("French Polynesia");
|
|
countries["PG"] = tr("Papua New Guinea");
|
|
countries["PH"] = tr("Philippines");
|
|
countries["PK"] = tr("Pakistan");
|
|
countries["PL"] = tr("Poland");
|
|
countries["PM"] = tr("Saint Pierre and Miquelon");
|
|
countries["PN"] = tr("Pitcairn");
|
|
countries["PR"] = tr("Puerto Rico");
|
|
countries["PS"] = tr("Palestine, State of");
|
|
countries["PT"] = tr("Portugal");
|
|
countries["PW"] = tr("Palau");
|
|
countries["PY"] = tr("Paraguay");
|
|
countries["QA"] = tr("Qatar");
|
|
countries["RE"] = tr("Reunion");
|
|
countries["RO"] = tr("Romania");
|
|
countries["RS"] = tr("Serbia");
|
|
countries["RU"] = tr("Russian Federation");
|
|
countries["RW"] = tr("Rwanda");
|
|
countries["SA"] = tr("Saudi Arabia");
|
|
countries["SB"] = tr("Solomon Islands");
|
|
countries["SC"] = tr("Seychelles");
|
|
countries["SD"] = tr("Sudan");
|
|
countries["SE"] = tr("Sweden");
|
|
countries["SG"] = tr("Singapore");
|
|
countries["SH"] = tr("Saint Helena, Ascension and Tristan da Cunha");
|
|
countries["SI"] = tr("Slovenia");
|
|
countries["SJ"] = tr("Svalbard and Jan Mayen");
|
|
countries["SK"] = tr("Slovakia");
|
|
countries["SL"] = tr("Sierra Leone");
|
|
countries["SM"] = tr("San Marino");
|
|
countries["SN"] = tr("Senegal");
|
|
countries["SO"] = tr("Somalia");
|
|
countries["SR"] = tr("Suriname");
|
|
countries["SS"] = tr("South Sudan");
|
|
countries["ST"] = tr("Sao Tome and Principe");
|
|
countries["SV"] = tr("El Salvador");
|
|
countries["SX"] = tr("Sint Maarten (Dutch part)");
|
|
countries["SY"] = tr("Syrian Arab Republic");
|
|
countries["SZ"] = tr("Swaziland");
|
|
countries["TC"] = tr("Turks and Caicos Islands");
|
|
countries["TD"] = tr("Chad");
|
|
countries["TF"] = tr("French Southern Territories");
|
|
countries["TG"] = tr("Togo");
|
|
countries["TH"] = tr("Thailand");
|
|
countries["TJ"] = tr("Tajikistan");
|
|
countries["TK"] = tr("Tokelau");
|
|
countries["TL"] = tr("Timor-Leste");
|
|
countries["TM"] = tr("Turkmenistan");
|
|
countries["TN"] = tr("Tunisia");
|
|
countries["TO"] = tr("Tonga");
|
|
countries["TR"] = tr("Turkey");
|
|
countries["TT"] = tr("Trinidad and Tobago");
|
|
countries["TV"] = tr("Tuvalu");
|
|
countries["TW"] = tr("Taiwan");
|
|
countries["TZ"] = tr("Tanzania, United Republic of");
|
|
countries["UA"] = tr("Ukraine");
|
|
countries["UG"] = tr("Uganda");
|
|
countries["UM"] = tr("United States Minor Outlying Islands");
|
|
countries["US"] = tr("United States");
|
|
countries["UY"] = tr("Uruguay");
|
|
countries["UZ"] = tr("Uzbekistan");
|
|
countries["VA"] = tr("Holy See (Vatican City State)");
|
|
countries["VC"] = tr("Saint Vincent and the Grenadines");
|
|
countries["VE"] = tr("Venezuela, Bolivarian Republic of");
|
|
countries["VG"] = tr("Virgin Islands, British");
|
|
countries["VI"] = tr("Virgin Islands, U.S.");
|
|
countries["VN"] = tr("Viet Nam");
|
|
countries["VU"] = tr("Vanuatu");
|
|
countries["WF"] = tr("Wallis and Futuna");
|
|
countries["WS"] = tr("Samoa");
|
|
countries["YE"] = tr("Yemen");
|
|
countries["YT"] = tr("Mayotte");
|
|
countries["ZA"] = tr("South Africa");
|
|
countries["ZM"] = tr("Zambia");
|
|
countries["ZW"] = tr("Zimbabwe");
|
|
|
|
countries[QString()] = tr("N/A");
|
|
initialized = true;
|
|
}
|
|
|
|
return countries.value(countryISOCode, tr("N/A"));
|
|
}
|
|
|
|
void GeoIPManager::configure()
|
|
{
|
|
const bool enabled = Preferences::instance()->resolvePeerCountries();
|
|
if (m_enabled != enabled) {
|
|
m_enabled = enabled;
|
|
if (m_enabled && !m_geoIPDatabase) {
|
|
loadDatabase();
|
|
}
|
|
else if (!m_enabled && m_geoIPDatabase) {
|
|
delete m_geoIPDatabase;
|
|
m_geoIPDatabase = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GeoIPManager::downloadFinished(const QString &url, QByteArray data)
|
|
{
|
|
Q_UNUSED(url);
|
|
|
|
if (!Utils::Gzip::uncompress(data, data)) {
|
|
Logger::instance()->addMessage(tr("Could not uncompress GeoIP database file."), Log::WARNING);
|
|
return;
|
|
}
|
|
|
|
QString error;
|
|
GeoIPDatabase *geoIPDatabase = GeoIPDatabase::load(data, error);
|
|
if (geoIPDatabase) {
|
|
if (!m_geoIPDatabase || (geoIPDatabase->buildEpoch() > m_geoIPDatabase->buildEpoch())) {
|
|
if (m_geoIPDatabase)
|
|
delete m_geoIPDatabase;
|
|
m_geoIPDatabase = geoIPDatabase;
|
|
Logger::instance()->addMessage(tr("GeoIP database loaded. Type: %1. Build time: %2.")
|
|
.arg(m_geoIPDatabase->type()).arg(m_geoIPDatabase->buildEpoch().toString()),
|
|
Log::INFO);
|
|
QString targetPath = Utils::Fs::expandPathAbs(
|
|
Utils::Fs::QDesktopServicesDataLocation() + GEOIP_FOLDER);
|
|
if (!QDir(targetPath).exists())
|
|
QDir().mkpath(targetPath);
|
|
QFile targetFile(QString("%1/%2").arg(targetPath).arg(GEOIP_FILENAME));
|
|
if (!targetFile.open(QFile::WriteOnly) || (targetFile.write(data) == -1)) {
|
|
Logger::instance()->addMessage(
|
|
tr("Couldn't save downloaded GeoIP database file."), Log::WARNING);
|
|
}
|
|
else {
|
|
Logger::instance()->addMessage(tr("Successfully updated GeoIP database."), Log::INFO);
|
|
}
|
|
}
|
|
else {
|
|
delete geoIPDatabase;
|
|
}
|
|
}
|
|
else {
|
|
Logger::instance()->addMessage(tr("Couldn't load GeoIP database. Reason: %1").arg(error), Log::WARNING);
|
|
}
|
|
}
|
|
|
|
void GeoIPManager::downloadFailed(const QString &url, const QString &reason)
|
|
{
|
|
Q_UNUSED(url);
|
|
Logger::instance()->addMessage(tr("Couldn't download GeoIP database file. Reason: %1").arg(reason), Log::WARNING);
|
|
}
|