23 #include "ip2cloader.h"
25 #include "configuration/doomseekerconfig.h"
26 #include "doomseekerfilepaths.h"
28 #include "ip2c/ip2c.h"
29 #include "ip2c/ip2cparser.h"
30 #include "ip2c/ip2cupdater.h"
32 #include <QElapsedTimer>
39 class IP2CParserThread :
public QThread
48 IP2CParserThread(QString filePath)
52 virtual void run()
override
55 if (file.open(QIODevice::ReadOnly))
59 this->success = parser.parse(file);
63 gLog << tr(
"IP2C database read in %1 ms; IP ranges: %2").arg(time.elapsed()).arg(parser.ranges().size());
68 gLog << tr(
"Unable to open IP2C file: %1").arg(filePath);
69 this->success =
false;
79 IP2CParserThread *parserThread;
80 QScopedPointer<IP2CUpdater> ip2cUpdater;
81 bool updateInProgress;
84 bool isParsing()
const
86 return parserThread !=
nullptr && parserThread->isRunning();
97 d->parserThread =
nullptr;
98 d->updateInProgress =
false;
99 d->inFallbackMode =
false;
103 this, &IP2CLoader::onUpdateFinished);
104 connect(d->ip2cUpdater.data(), &IP2CUpdater::downloadProgress,
105 this, &IP2CLoader::downloadProgress);
107 this, &IP2CLoader::onUpdateNeeded);
110 void IP2CLoader::load()
112 if (gConfig.doomseeker.bIP2CountryAutoUpdate)
119 if (!filePath.isEmpty())
121 d->inFallbackMode =
false;
122 d->ip2c->setDataAccessLockEnabled(
true);
123 ip2cReadDatabase(filePath);
127 if (!gConfig.doomseeker.bIP2CountryAutoUpdate)
129 gLog << tr(
"Did not find any IP2C database. IP2C functionality will be disabled.");
130 gLog << tr(
"You may install an IP2C database from the \"File\" menu.");
136 void IP2CLoader::onUpdateNeeded(
int status)
138 if (status == IP2CUpdater::UpdateNeeded)
146 case IP2CUpdater::UpToDate:
147 gLog << tr(
"IP2C update not needed.");
149 case IP2CUpdater::UpdateCheckError:
150 gLog << tr(
"IP2C update errored. See log for details.");
153 gLog << tr(
"IP2C update bugged out.");
160 void IP2CLoader::update()
162 d->updateInProgress =
true;
165 gLog << tr(
"Starting IP2C update.");
166 IP2C::instance()->setDataAccessLockEnabled(
true);
171 void IP2CLoader::onUpdateFinished(
const QByteArray &downloadedData)
173 d->updateInProgress =
false;
174 if (!downloadedData.isEmpty())
176 gLog << tr(
"IP2C database finished downloading.");
178 d->ip2cUpdater->getRollbackData(filePath);
179 if (!d->ip2cUpdater->saveDownloadedData(filePath))
180 gLog << tr(
"Unable to save IP2C database at path: %1").arg(filePath);
181 ip2cReadDatabase(filePath);
185 gLog << tr(
"IP2C download has failed.");
190 void IP2CLoader::onParsingFinished()
192 auto finally = [
this]() {
193 if (d->updateInProgress) {
195 QTimer::singleShot(0,
this, &IP2CLoader::update);
197 this->ip2cJobsFinished();
200 IP2CParserThread *parserThread = d->parserThread;
201 if (parserThread ==
nullptr) {
202 gLog << tr(
"IP2C unable to retrieve the parsing result.");
206 d->parserThread =
nullptr;
208 if (!parserThread->success)
210 if (d->inFallbackMode)
212 gLog << tr(
"Failed to read the IP2C fallback. Stopping.");
216 gLog << tr(
"Failed to read the IP2C database. Reverting...");
218 d->inFallbackMode =
true;
219 if (d->ip2cUpdater ==
nullptr || !d->ip2cUpdater->hasRollbackData())
221 gLog << tr(
"IP2C revert attempt failed. Nothing to go back to.");
224 QFile file(filePath);
228 if (!preinstalledDbPath.isEmpty())
230 gLog << tr(
"Trying to use the preinstalled IP2C database.");
231 ip2cReadDatabase(preinstalledDbPath);
241 d->ip2cUpdater->rollback(filePath);
244 ip2cReadDatabase(filePath);
249 const IP2CParser &parser = parserThread->parser;
250 gLog << tr(
"IP2C parsing finished.");
251 d->ip2c->setRangesDatabase(parser.ranges());
252 d->ip2c->setLicence(parser.licences());
253 d->ip2c->setUrl(parser.url());
258 void IP2CLoader::ip2cJobsFinished()
260 if (!d->ip2cUpdater->isWorking() && !d->isParsing() && !d->updateInProgress)
262 d->ip2c->setDataAccessLockEnabled(
false);
267 void IP2CLoader::ip2cReadDatabase(
const QString &filePath)
269 gLog << tr(
"IP2C database is being read. This may take some time.");
271 if (d->parserThread !=
nullptr) {
272 d->parserThread->disconnect(
this);
275 d->parserThread =
new IP2CParserThread(filePath);
276 connect(d->parserThread, &IP2CParserThread::finished,
277 this, &IP2CLoader::onParsingFinished);
278 connect(d->parserThread, &IP2CParserThread::finished,
279 d->parserThread, &QObject::deleteLater);
280 d->parserThread->start();
283 #include "ip2cloader.moc"