23 #include "ip2cupdater.h" 25 #include <QCryptographicHash> 27 #include <QTemporaryFile> 30 #include <wadseeker/protocols/fixednetworkaccessmanager.h> 35 IP2CUpdater::IP2CUpdater(QObject *parent)
38 pCurrentNetworkReply = NULL;
39 pNetworkAccessManager =
new FixedNetworkAccessManager();
42 IP2CUpdater::~IP2CUpdater()
46 if (pNetworkAccessManager != NULL)
48 pNetworkAccessManager->deleteLater();
52 void IP2CUpdater::abort()
54 if (pCurrentNetworkReply != NULL)
56 pCurrentNetworkReply->disconnect();
57 pCurrentNetworkReply->abort();
58 pCurrentNetworkReply->deleteLater();
60 pCurrentNetworkReply = NULL;
63 void IP2CUpdater::checksumDownloadFinished()
65 if (handleRedirect(*pCurrentNetworkReply, SLOT(checksumDownloadFinished())))
70 if (pCurrentNetworkReply->error() != QNetworkReply::NoError)
72 gLog << tr(
"IP2C checksum check network error: %1").arg(pCurrentNetworkReply->errorString());
74 emit updateNeeded(UpdateCheckError);
78 QByteArray remoteMd5 = pCurrentNetworkReply->readAll();
79 remoteMd5 = remoteMd5.trimmed();
81 pCurrentNetworkReply->deleteLater();
82 pCurrentNetworkReply = NULL;
84 QFile file(this->pathToFile);
85 file.open(QIODevice::ReadOnly);
86 QByteArray localMd5 = QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5);
87 localMd5 = localMd5.toHex().toLower();
89 gLog << tr(
"Comparing IP2C hashes: local = %1, remote = %2").arg(
90 QString(localMd5)).arg(QString(remoteMd5));
91 bool needed = localMd5 != remoteMd5;
94 gLog << tr(
"IP2C update needed.");
96 emit updateNeeded(needed ? UpdateNeeded : UpToDate);
99 const QUrl IP2CUpdater::dbChecksumUrl()
101 return QUrl(
"http://doomseeker.drdteam.org/ip2c/md5");
104 const QUrl IP2CUpdater::dbDownloadUrl()
106 return QUrl(
"http://doomseeker.drdteam.org/ip2c/geolite2.gz");
109 void IP2CUpdater::downloadDatabase()
111 get(dbDownloadUrl(), SLOT(downloadFinished()));
114 void IP2CUpdater::downloadFinished()
116 if (handleRedirect(*pCurrentNetworkReply, SLOT(downloadFinished())))
121 QByteArray data = pCurrentNetworkReply->readAll();
123 pCurrentNetworkReply->deleteLater();
124 pCurrentNetworkReply = NULL;
127 QTemporaryFile tmpFile;
132 QString tmpFilePath = tmpFile.fileName();
134 QByteArray uncompressedData;
135 gzFile gz = gzopen(tmpFilePath.toUtf8().constData(),
"rb");
140 while((bytesRead = gzread(gz, chunk, 131072)) != 0)
142 uncompressedData.append(QByteArray(chunk, bytesRead));
146 retrievedData = uncompressedData;
150 emit databaseDownloadFinished(retrievedData);
153 bool IP2CUpdater::handleRedirect(QNetworkReply &reply,
const char *finishedSlot)
155 QUrl possibleRedirectUrl = reply.attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
156 QUrl url = reply.request().url();
157 if (!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != url)
160 if (possibleRedirectUrl.isRelative())
162 possibleRedirectUrl = url.resolved(possibleRedirectUrl);
164 get(possibleRedirectUrl, finishedSlot);
170 void IP2CUpdater::get(
const QUrl &url,
const char *finishedSlot)
173 retrievedData.clear();
175 QNetworkRequest request;
179 pCurrentNetworkReply = pNetworkAccessManager->get(request);
180 this->connect(pCurrentNetworkReply, SIGNAL(downloadProgress(qint64, qint64)),
181 SIGNAL(downloadProgress(qint64, qint64)));
182 this->connect(pCurrentNetworkReply, SIGNAL(finished()), finishedSlot);
187 rollbackData.clear();
189 QFile file(pathToFile);
195 if (!file.open(QIODevice::ReadOnly))
200 rollbackData = file.readAll();
206 bool IP2CUpdater::isWorking()
const 208 return pCurrentNetworkReply != NULL;
213 QFile file(filePath);
216 emit updateNeeded(UpdateNeeded);
220 this->pathToFile = filePath;
221 gLog << tr(
"Checking if IP2C database at '%1' needs updating.").arg(filePath);
222 get(dbChecksumUrl(), SLOT(checksumDownloadFinished()));
227 bool bSuccess = save(rollbackData);
228 rollbackData.clear();
233 bool IP2CUpdater::save(
const QByteArray& saveWhat)
235 if (saveWhat.isEmpty())
240 QFile file(pathToFile);
241 if (!file.open(QIODevice::WriteOnly))
246 file.write(saveWhat);
254 return save(retrievedData);
bool getRollbackData()
Obtains rollback data from pathToFile file.
static QString userAgent()
WWW User Agent used for HTTP communications.
bool rollback()
Saves data to the pathToFile file. This data must be first obtained through the rollback method...
void needsUpdate(const QString &filePath)
Checks if IP2C file must be updated.
bool saveDownloadedData()
Saves recently downloaded data to the pathToFile file.