ip2cloader.cpp
1 #include "ip2cloader.h"
2 
3 #include "configuration/doomseekerconfig.h"
4 #include "doomseekerfilepaths.h"
5 #include "ip2c/ip2c.h"
6 #include "ip2c/ip2cparser.h"
7 #include "ip2c/ip2cupdater.h"
8 #include "log.h"
9 #include <QFile>
10 
11 DClass<IP2CLoader>
12 {
13  public:
14  IP2CParser* ip2cParser;
15  IP2CUpdater* ip2cUpdater;
16 };
17 
18 DPointered(IP2CLoader)
19 
22 {
23  d->ip2cParser = new IP2CParser(IP2C::instance());
24  this->connect(d->ip2cParser, SIGNAL( parsingFinished(bool) ),
25  SLOT( ip2cFinishedParsing(bool) ) );
26 
27  d->ip2cUpdater = new IP2CUpdater();
28  d->ip2cUpdater->setFilePath(DoomseekerFilePaths::ip2cDatabase());
29  this->connect(d->ip2cUpdater, SIGNAL( databaseDownloadFinished(const QByteArray&) ),
30  SLOT( ip2cFinishUpdate(const QByteArray&) ) );
31  this->connect(d->ip2cUpdater, SIGNAL( downloadProgress(qint64, qint64) ),
32  SIGNAL( downloadProgress(qint64, qint64) ) );
33 }
34 
35 IP2CLoader::~IP2CLoader()
36 {
37  if (d->ip2cParser->isParsing())
38  {
39  gLog << tr("IP2C parser is still working. Program will close once this job is done.");
40  while (d->ip2cParser->isParsing());
41  }
42 
43  delete d->ip2cParser;
44  delete d->ip2cUpdater;
45 }
46 
47 void IP2CLoader::load()
48 {
49  bool bParseIP2CDatabase = true;
50  bool bPerformAutomaticIP2CUpdates = gConfig.doomseeker.bIP2CountryAutoUpdate;
51 
52  if (bPerformAutomaticIP2CUpdates)
53  {
54  int maxAge = gConfig.doomseeker.ip2CountryDatabaseMaximumAge;
55 
56  QString databasePath = DoomseekerFilePaths::ip2cDatabase();
57  if (IP2CUpdater::needsUpdate(databasePath, maxAge))
58  {
59  ip2cStartUpdate();
60  bParseIP2CDatabase = false;
61  }
62  }
63 
64  if (bParseIP2CDatabase)
65  {
66  ip2cParseDatabase();
67  }
68 }
69 
70 void IP2CLoader::update()
71 {
72  ip2cStartUpdate();
73 }
74 
75 void IP2CLoader::ip2cFinishUpdate(const QByteArray& downloadedData)
76 {
77  if (!downloadedData.isEmpty())
78  {
79  gLog << tr("IP2C database finished downloading.");
80  QString filePath = DoomseekerFilePaths::ip2cDatabase();
81  d->ip2cUpdater->getRollbackData();
82  if (!d->ip2cUpdater->saveDownloadedData())
83  {
84  gLog << tr("Unable to save IP2C database at path: %1").arg(filePath);
85  }
86  ip2cParseDatabase();
87  }
88  else
89  {
90  gLog << tr("IP2C download has failed.");
91  ip2cJobsFinished();
92  }
93 }
94 
95 void IP2CLoader::ip2cFinishedParsing(bool bSuccess)
96 {
97  QString filePath = DoomseekerFilePaths::ip2cDatabase();
98 
99  if (!bSuccess)
100  {
101  gLog << tr("Failed to read IP2C database. Reverting...");
102 
103  if (d->ip2cUpdater == NULL || !d->ip2cUpdater->hasRollbackData())
104  {
105  gLog << tr("IP2C revert attempt failed. Nothing to go back to.");
106 
107  // Delete file in this case.
108  QFile file(filePath);
109  file.remove();
110 
111  gLog << tr("Using precompiled IP2C database.");
112  d->ip2cParser->readDatabaseThreaded(DoomseekerFilePaths::IP2C_QT_SEARCH_PATH);
113  }
114  else
115  {
116  // Revert to old content.
117  d->ip2cUpdater->rollback();
118 
119  // Must succeed now.
120  d->ip2cParser->readDatabaseThreaded(filePath);
121  }
122  }
123  else
124  {
125  if (d->ip2cUpdater != NULL)
126  {
127  gLog << tr("IP2C database updated successfully.");
128  }
129 
130  ip2cJobsFinished();
131  }
132 }
133 
134 void IP2CLoader::ip2cJobsFinished()
135 {
136  IP2C::instance()->setDataAccessLockEnabled(false);
137 
138  if (d->ip2cParser != NULL)
139  {
140  gLog << tr("IP2C parsing finished.");
141  }
142 
143  if (d->ip2cUpdater != NULL)
144  {
145  gLog << tr("IP2C update finished.");
146  }
147  emit finished();
148 }
149 
150 void IP2CLoader::ip2cParseDatabase()
151 {
152  QString filePath = DoomseekerFilePaths::IP2C_QT_SEARCH_PATH;
153 
154  gLog << tr("Please wait. IP2C database is being read and converted if necessary. This may take some time.");
155  // Attempt to read IP2C database.
156 
157  IP2C::instance()->setDataAccessLockEnabled(true);
158  d->ip2cParser->readDatabaseThreaded(filePath);
159 }
160 
161 void IP2CLoader::ip2cStartUpdate()
162 {
163  gLog << tr("Starting IP2C update.");
164  IP2C::instance()->setDataAccessLockEnabled(true);
165  QString downloadUrl = gConfig.doomseeker.ip2CountryUrl;
166  d->ip2cUpdater->downloadDatabase(downloadUrl);
167 }
static bool needsUpdate(const QString &filePath, unsigned minimumUpdateAge)
Checks if IP2C file must be updated.
IP2CUpdater is responsible for downloading a new version of database from the site.
Definition: ip2cupdater.h:42