File indexing completed on 2024-04-28 16:30:15
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr 0003 * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 ***************************************************************************/ 0006 /** @file 0007 * This file defines classes SKGUnitObject. 0008 * 0009 * @author Stephane MANKOWSKI / Guillaume DE BURE 0010 */ 0011 #include "skgunitobject.h" 0012 0013 #include <qdesktopservices.h> 0014 #include <qdir.h> 0015 #include <qdiriterator.h> 0016 #include <qfile.h> 0017 #include <qfileinfo.h> 0018 #include <qglobal.h> 0019 #include <qmath.h> 0020 #include <qprocess.h> 0021 #include <qregularexpression.h> 0022 #include <qsavefile.h> 0023 #include <qstandardpaths.h> 0024 0025 #include <kconfig.h> 0026 #include <kconfiggroup.h> 0027 #include <klocalizedstring.h> 0028 #include <kservice.h> 0029 #include <kservicetypetrader.h> 0030 #include <qvariant.h> 0031 0032 #include "skgdocumentbank.h" 0033 #include "skgoperationobject.h" 0034 #include "skgtraces.h" 0035 #include "skgtransactionmng.h" 0036 #include "skgunitvalueobject.h" 0037 0038 SKGUnitObject::SKGUnitObject() : SKGUnitObject(nullptr) 0039 {} 0040 0041 SKGUnitObject::SKGUnitObject(SKGDocument* iDocument, int iID) : SKGNamedObject(iDocument, QStringLiteral("v_unit"), iID) 0042 {} 0043 0044 SKGUnitObject::~SKGUnitObject() 0045 = default; 0046 0047 SKGUnitObject::SKGUnitObject(const SKGUnitObject& iObject) = default; 0048 0049 SKGUnitObject::SKGUnitObject(const SKGNamedObject& iObject) 0050 { 0051 if (iObject.getRealTable() == QStringLiteral("unit")) { 0052 copyFrom(iObject); 0053 } else { 0054 *this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID()); 0055 } 0056 } 0057 0058 SKGUnitObject::SKGUnitObject(const SKGObjectBase& iObject) 0059 { 0060 if (iObject.getRealTable() == QStringLiteral("unit")) { 0061 copyFrom(iObject); 0062 } else { 0063 *this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID()); 0064 } 0065 } 0066 0067 SKGUnitObject& SKGUnitObject::operator= (const SKGObjectBase& iObject) 0068 { 0069 copyFrom(iObject); 0070 return *this; 0071 } 0072 0073 SKGUnitObject& SKGUnitObject::operator= (const SKGUnitObject& iObject) 0074 { 0075 copyFrom(iObject); 0076 return *this; 0077 } 0078 0079 0080 QString SKGUnitObject::getWhereclauseId() const 0081 { 0082 QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method 0083 if (output.isEmpty()) { 0084 QString name = getName(); 0085 if (!name.isEmpty()) { 0086 output = "t_name='" % SKGServices::stringToSqlString(name) % '\''; 0087 } 0088 0089 QString symbol = getSymbol(); 0090 if (!symbol.isEmpty()) { 0091 if (!output.isEmpty()) { 0092 output += QStringLiteral(" OR "); 0093 } 0094 output += "t_symbol='" % SKGServices::stringToSqlString(symbol) % '\''; 0095 } 0096 if (!output.isEmpty()) { 0097 output = '(' % output % ')'; 0098 } 0099 } 0100 0101 return output; 0102 } 0103 0104 QList<SKGServices::SKGUnitInfo> SKGUnitObject::currencies; 0105 0106 QStringList SKGUnitObject::getListofKnownCurrencies(bool iIncludingObsolete) 0107 { 0108 SKGTRACEINFUNC(10) 0109 if (currencies.isEmpty()) { 0110 // Search currencies 0111 const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/"), QStandardPaths::LocateDirectory); 0112 for (const auto& dir : dirs) { 0113 auto listDesktopFiles = QDir(dir).entryList(QStringList() << QStringLiteral("*.desktop")); 0114 for (const auto& path : qAsConst(listDesktopFiles)) { 0115 // Read the file 0116 QFileInfo file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/") + path)); 0117 KConfig cgFile(file.absoluteFilePath()); 0118 KConfigGroup cg(&cgFile, QStringLiteral("Currency Code")); 0119 0120 SKGServices::SKGUnitInfo unit; 0121 unit.Name = cg.readEntry(QStringLiteral("Name"), QString()) + QStringLiteral(" (") + cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), QString()) + QStringLiteral(")"); 0122 unit.Symbol = cg.readEntry(QStringLiteral("CurrencyUnitSymbolDefault"), QString()); 0123 if (unit.Symbol.isEmpty()) { 0124 unit.Symbol = cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), file.baseName()); 0125 } 0126 unit.Value = 1; 0127 unit.NbDecimal = cg.readEntry(QStringLiteral("CurrencyDecimalPlacesDisplay"), 2); 0128 unit.Source = QStringLiteral("GrandTrunk"); 0129 unit.Date = cg.readEntry(QStringLiteral("CurrencyIntroducedDate"), QDate::currentDate()); 0130 unit.Obsolete = (cg.readEntry(QStringLiteral("CurrencySuspendedDate"), cg.readEntry(QStringLiteral("CurrencyWithdrawnDate"), QDate())) != QDate()); 0131 currencies.push_back(unit); 0132 } 0133 } 0134 0135 // Add other units 0136 { 0137 // CAC40 0138 SKGServices::SKGUnitInfo info; 0139 info.Name = i18nc("Noun, a currency", "CAC 40"); 0140 info.Symbol = info.Name; 0141 info.Country = i18nc("Noun, a country", "France"); 0142 info.Date = QDate(1987, 1, 1); 0143 info.Internet = QStringLiteral("^FCHI"); 0144 info.Source = QStringLiteral("Yahoo"); 0145 info.NbDecimal = 2; 0146 info.Value = -1; 0147 currencies.push_back(info); 0148 } 0149 { 0150 // NASDAQ 0151 SKGServices::SKGUnitInfo info; 0152 info.Name = i18nc("Noun, a currency", "NASDAQ"); 0153 info.Symbol = info.Name; 0154 info.Country = i18nc("Noun, a country", "United States"); 0155 info.Date = QDate(1971, 2, 5); 0156 info.Internet = QStringLiteral("^IXIC"); 0157 info.Source = QStringLiteral("Yahoo"); 0158 info.NbDecimal = 2; 0159 info.Value = -1; 0160 currencies.push_back(info); 0161 } 0162 { 0163 // Dow Jones 0164 SKGServices::SKGUnitInfo info; 0165 info.Name = i18nc("Noun, a currency", "Dow Jones (DJIA)"); 0166 info.Symbol = QStringLiteral("DJIA"); 0167 info.Country = i18nc("Noun, a country", "United States"); 0168 info.Date = QDate(1884, 1, 1); 0169 info.Internet = QStringLiteral("^DJI"); 0170 info.Source = QStringLiteral("Yahoo"); 0171 info.NbDecimal = 2; 0172 info.Value = -1; 0173 currencies.push_back(info); 0174 } 0175 { 0176 // SBF 120 0177 SKGServices::SKGUnitInfo info; 0178 info.Name = i18nc("Noun, a currency", "SBF 120"); 0179 info.Symbol = info.Name; 0180 info.Country = i18nc("Noun, a country", "France"); 0181 info.Date = QDate(1990, 12, 31); 0182 info.Internet = QStringLiteral("^SBF120"); 0183 info.Source = QStringLiteral("Yahoo"); 0184 info.NbDecimal = 2; 0185 info.Value = -1; 0186 currencies.push_back(info); 0187 } 0188 { 0189 // S&P 500 0190 SKGServices::SKGUnitInfo info; 0191 info.Name = i18nc("Noun, a currency", "S&P 500"); 0192 info.Symbol = info.Name; 0193 info.Country = i18nc("Noun, a country", "United States"); 0194 info.Date = QDate(1920, 1, 1); 0195 info.Internet = QStringLiteral("^GSPC"); 0196 info.Source = QStringLiteral("Yahoo"); 0197 info.NbDecimal = 2; 0198 info.Value = -1; 0199 currencies.push_back(info); 0200 } 0201 { 0202 // FTSE 100 0203 SKGServices::SKGUnitInfo info; 0204 info.Name = i18nc("Noun, a currency", "FTSE 100"); 0205 info.Symbol = info.Name; 0206 info.Country = i18nc("Noun, a country", "England"); 0207 info.Date = QDate(1984, 1, 3); 0208 info.Internet = QStringLiteral("^FTSE"); 0209 info.Source = QStringLiteral("Yahoo"); 0210 info.NbDecimal = 2; 0211 info.Value = -1; 0212 currencies.push_back(info); 0213 } 0214 { 0215 // DAX 0216 SKGServices::SKGUnitInfo info; 0217 info.Name = i18nc("Noun, a currency", "DAX"); 0218 info.Symbol = info.Name; 0219 info.Country = i18nc("Noun, a country", "Germany"); 0220 info.Date = QDate(1920, 1, 1); 0221 info.Internet = QStringLiteral("^GDAXI"); 0222 info.Source = QStringLiteral("Yahoo"); 0223 info.NbDecimal = 2; 0224 info.Value = -1; 0225 currencies.push_back(info); 0226 } 0227 { 0228 // NIKKEI 225 0229 SKGServices::SKGUnitInfo info; 0230 info.Name = i18nc("Noun, a currency", "NIKKEI 225"); 0231 info.Symbol = info.Name; 0232 info.Country = i18nc("Noun, a country", "Japan"); 0233 info.Date = QDate(1920, 1, 1); 0234 info.Internet = QStringLiteral("^N225"); 0235 info.Source = QStringLiteral("Yahoo"); 0236 info.NbDecimal = 2; 0237 info.Value = -1; 0238 currencies.push_back(info); 0239 } 0240 { 0241 // HANG SENG 0242 SKGServices::SKGUnitInfo info; 0243 info.Name = i18nc("Noun, a currency", "HANG SENG"); 0244 info.Symbol = info.Name; 0245 info.Country = i18nc("Noun, a country", "China"); 0246 info.Date = QDate(1920, 1, 1); 0247 info.Internet = QStringLiteral("^HSI"); 0248 info.Source = QStringLiteral("Yahoo"); 0249 info.NbDecimal = 2; 0250 info.Value = -1; 0251 currencies.push_back(info); 0252 } 0253 { 0254 // STRAITS TIMES 0255 SKGServices::SKGUnitInfo info; 0256 info.Name = i18nc("Noun, a currency", "STRAITS TIMES"); 0257 info.Symbol = info.Name; 0258 info.Date = QDate(1920, 1, 1); 0259 info.Country = i18nc("Noun, a country", "Singapore"); 0260 info.Internet = QStringLiteral("^STI"); 0261 info.Source = QStringLiteral("Yahoo"); 0262 info.NbDecimal = 2; 0263 info.Value = -1; 0264 currencies.push_back(info); 0265 } 0266 { 0267 // BITCOIN 0268 SKGServices::SKGUnitInfo info; 0269 info.Name = i18nc("Noun, a currency", "Bitcoin"); 0270 info.Symbol = QStringLiteral("BTC"); 0271 info.Date = QDate(2009, 2, 4); 0272 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0273 info.Internet = QStringLiteral("BTC"); 0274 info.Source = QStringLiteral("CoinMarketCap"); 0275 info.Parent = QStringLiteral("USD"); 0276 info.NbDecimal = 4; 0277 info.Value = -1; 0278 currencies.push_back(info); 0279 } 0280 { 0281 // ETHEREUM 0282 SKGServices::SKGUnitInfo info; 0283 info.Name = i18nc("Noun, a cryptocurrency", "Ethereum"); 0284 info.Symbol = QStringLiteral("ETH"); 0285 info.Date = QDate(2009, 2, 4); 0286 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0287 info.Internet = QStringLiteral("ETH"); 0288 info.Source = QStringLiteral("CoinMarketCap"); 0289 info.Parent = QStringLiteral("USD"); 0290 info.NbDecimal = 4; 0291 info.Value = -1; 0292 currencies.push_back(info); 0293 } 0294 { 0295 // RIPPLE 0296 SKGServices::SKGUnitInfo info; 0297 info.Name = i18nc("Noun, a cryptocurrency", "Ripple"); 0298 info.Symbol = QStringLiteral("XRP"); 0299 info.Date = QDate(2009, 2, 4); 0300 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0301 info.Internet = QStringLiteral("XRP"); 0302 info.Source = QStringLiteral("CoinMarketCap"); 0303 info.Parent = QStringLiteral("USD"); 0304 info.NbDecimal = 4; 0305 info.Value = -1; 0306 currencies.push_back(info); 0307 } 0308 { 0309 // BITCOIN-CASH 0310 SKGServices::SKGUnitInfo info; 0311 info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Cash"); 0312 info.Symbol = QStringLiteral("BCH"); 0313 info.Date = QDate(2009, 2, 4); 0314 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0315 info.Internet = QStringLiteral("BCH"); 0316 info.Source = QStringLiteral("CoinMarketCap"); 0317 info.Parent = QStringLiteral("USD"); 0318 info.NbDecimal = 4; 0319 info.Value = -1; 0320 currencies.push_back(info); 0321 } 0322 { 0323 // CARDANO 0324 SKGServices::SKGUnitInfo info; 0325 info.Name = i18nc("Noun, a cryptocurrency", "Cardano"); 0326 info.Symbol = QStringLiteral("ADA"); 0327 info.Date = QDate(2009, 2, 4); 0328 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0329 info.Internet = QStringLiteral("ADA"); 0330 info.Source = QStringLiteral("CoinMarketCap"); 0331 info.Parent = QStringLiteral("USD"); 0332 info.NbDecimal = 4; 0333 info.Value = -1; 0334 currencies.push_back(info); 0335 } 0336 { 0337 // NEM 0338 SKGServices::SKGUnitInfo info; 0339 info.Name = i18nc("Noun, a cryptocurrency", "NEM"); 0340 info.Symbol = QStringLiteral("XEM"); 0341 info.Date = QDate(2009, 2, 4); 0342 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0343 info.Internet = QStringLiteral("XEM"); 0344 info.Source = QStringLiteral("CoinMarketCap"); 0345 info.Parent = QStringLiteral("USD"); 0346 info.NbDecimal = 4; 0347 info.Value = -1; 0348 currencies.push_back(info); 0349 } 0350 { 0351 // LITECOIN 0352 SKGServices::SKGUnitInfo info; 0353 info.Name = i18nc("Noun, a cryptocurrency", "Litecoin"); 0354 info.Symbol = QStringLiteral("LTC"); 0355 info.Date = QDate(2009, 2, 4); 0356 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0357 info.Internet = QStringLiteral("LTC"); 0358 info.Source = QStringLiteral("CoinMarketCap"); 0359 info.Parent = QStringLiteral("USD"); 0360 info.NbDecimal = 4; 0361 info.Value = -1; 0362 currencies.push_back(info); 0363 } 0364 { 0365 // STELLAR 0366 SKGServices::SKGUnitInfo info; 0367 info.Name = i18nc("Noun, a cryptocurrency", "Stellar"); 0368 info.Symbol = QStringLiteral("XLM"); 0369 info.Date = QDate(2009, 2, 4); 0370 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0371 info.Internet = QStringLiteral("XLM"); 0372 info.Source = QStringLiteral("CoinMarketCap"); 0373 info.Parent = QStringLiteral("USD"); 0374 info.NbDecimal = 4; 0375 info.Value = -1; 0376 currencies.push_back(info); 0377 } 0378 { 0379 // IOTA 0380 SKGServices::SKGUnitInfo info; 0381 info.Name = i18nc("Noun, a cryptocurrency", "IOTA"); 0382 info.Symbol = QStringLiteral("MIOTA"); 0383 info.Date = QDate(2009, 2, 4); 0384 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0385 info.Internet = QStringLiteral("MIOTA"); 0386 info.Source = QStringLiteral("CoinMarketCap"); 0387 info.Parent = QStringLiteral("USD"); 0388 info.NbDecimal = 4; 0389 info.Value = -1; 0390 currencies.push_back(info); 0391 } 0392 { 0393 // TRON 0394 SKGServices::SKGUnitInfo info; 0395 info.Name = i18nc("Noun, a cryptocurrency", "TRON"); 0396 info.Symbol = QStringLiteral("TRX"); 0397 info.Date = QDate(2009, 2, 4); 0398 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0399 info.Internet = QStringLiteral("TRX"); 0400 info.Source = QStringLiteral("CoinMarketCap"); 0401 info.Parent = QStringLiteral("USD"); 0402 info.NbDecimal = 4; 0403 info.Value = -1; 0404 currencies.push_back(info); 0405 } 0406 { 0407 // DASH 0408 SKGServices::SKGUnitInfo info; 0409 info.Name = i18nc("Noun, a cryptocurrency", "Dash"); 0410 info.Symbol = QStringLiteral("DASH"); 0411 info.Date = QDate(2009, 2, 4); 0412 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0413 info.Internet = QStringLiteral("DASH"); 0414 info.Source = QStringLiteral("CoinMarketCap"); 0415 info.Parent = QStringLiteral("USD"); 0416 info.NbDecimal = 4; 0417 info.Value = -1; 0418 currencies.push_back(info); 0419 } 0420 { 0421 // NEO 0422 SKGServices::SKGUnitInfo info; 0423 info.Name = i18nc("Noun, a cryptocurrency", "NEO"); 0424 info.Symbol = QStringLiteral("NEO"); 0425 info.Date = QDate(2009, 2, 4); 0426 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0427 info.Internet = QStringLiteral("NEO"); 0428 info.Source = QStringLiteral("CoinMarketCap"); 0429 info.Parent = QStringLiteral("USD"); 0430 info.NbDecimal = 4; 0431 info.Value = -1; 0432 currencies.push_back(info); 0433 } 0434 { 0435 // MONERO 0436 SKGServices::SKGUnitInfo info; 0437 info.Name = i18nc("Noun, a cryptocurrency", "Monero"); 0438 info.Symbol = QStringLiteral("XMR"); 0439 info.Date = QDate(2009, 2, 4); 0440 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0441 info.Internet = QStringLiteral("XMR"); 0442 info.Source = QStringLiteral("CoinMarketCap"); 0443 info.Parent = QStringLiteral("USD"); 0444 info.NbDecimal = 4; 0445 info.Value = -1; 0446 currencies.push_back(info); 0447 } 0448 { 0449 // EOS 0450 SKGServices::SKGUnitInfo info; 0451 info.Name = i18nc("Noun, a cryptocurrency", "EOS"); 0452 info.Symbol = QStringLiteral("EOS"); 0453 info.Date = QDate(2009, 2, 4); 0454 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0455 info.Internet = QStringLiteral("EOS"); 0456 info.Source = QStringLiteral("CoinMarketCap"); 0457 info.Parent = QStringLiteral("USD"); 0458 info.NbDecimal = 4; 0459 info.Value = -1; 0460 currencies.push_back(info); 0461 } 0462 { 0463 // QTUM 0464 SKGServices::SKGUnitInfo info; 0465 info.Name = i18nc("Noun, a cryptocurrency", "Qtum"); 0466 info.Symbol = QStringLiteral("QTUM"); 0467 info.Date = QDate(2009, 2, 4); 0468 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0469 info.Internet = QStringLiteral("QTUM"); 0470 info.Source = QStringLiteral("CoinMarketCap"); 0471 info.Parent = QStringLiteral("USD"); 0472 info.NbDecimal = 4; 0473 info.Value = -1; 0474 currencies.push_back(info); 0475 } 0476 { 0477 // ICON 0478 SKGServices::SKGUnitInfo info; 0479 info.Name = i18nc("Noun, a cryptocurrency", "ICON"); 0480 info.Symbol = QStringLiteral("ICX"); 0481 info.Date = QDate(2009, 2, 4); 0482 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0483 info.Internet = QStringLiteral("ICX"); 0484 info.Source = QStringLiteral("CoinMarketCap"); 0485 info.Parent = QStringLiteral("USD"); 0486 info.NbDecimal = 4; 0487 info.Value = -1; 0488 currencies.push_back(info); 0489 } 0490 { 0491 // BITCOIN-GOLD 0492 SKGServices::SKGUnitInfo info; 0493 info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Gold"); 0494 info.Symbol = QStringLiteral("BTG"); 0495 info.Date = QDate(2009, 2, 4); 0496 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0497 info.Internet = QStringLiteral("BTG"); 0498 info.Source = QStringLiteral("CoinMarketCap"); 0499 info.Parent = QStringLiteral("USD"); 0500 info.NbDecimal = 4; 0501 info.Value = -1; 0502 currencies.push_back(info); 0503 } 0504 { 0505 // LISK 0506 SKGServices::SKGUnitInfo info; 0507 info.Name = i18nc("Noun, a cryptocurrency", "Lisk"); 0508 info.Symbol = QStringLiteral("LSK"); 0509 info.Date = QDate(2009, 2, 4); 0510 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0511 info.Internet = QStringLiteral("LSK"); 0512 info.Source = QStringLiteral("CoinMarketCap"); 0513 info.Parent = QStringLiteral("USD"); 0514 info.NbDecimal = 4; 0515 info.Value = -1; 0516 currencies.push_back(info); 0517 } 0518 { 0519 // RAIBLOCKS 0520 SKGServices::SKGUnitInfo info; 0521 info.Name = i18nc("Noun, a cryptocurrency", "RaiBlocks"); 0522 info.Symbol = QStringLiteral("XRB"); 0523 info.Date = QDate(2009, 2, 4); 0524 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0525 info.Internet = QStringLiteral("XRB"); 0526 info.Source = QStringLiteral("CoinMarketCap"); 0527 info.Parent = QStringLiteral("USD"); 0528 info.NbDecimal = 4; 0529 info.Value = -1; 0530 currencies.push_back(info); 0531 } 0532 { 0533 // ETHEREUM-CLASSIC 0534 SKGServices::SKGUnitInfo info; 0535 info.Name = i18nc("Noun, a cryptocurrency", "Ethereum Classic"); 0536 info.Symbol = QStringLiteral("ETC"); 0537 info.Date = QDate(2009, 2, 4); 0538 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0539 info.Internet = QStringLiteral("ETC"); 0540 info.Source = QStringLiteral("CoinMarketCap"); 0541 info.Parent = QStringLiteral("USD"); 0542 info.NbDecimal = 4; 0543 info.Value = -1; 0544 currencies.push_back(info); 0545 } 0546 { 0547 // VERGE 0548 SKGServices::SKGUnitInfo info; 0549 info.Name = i18nc("Noun, a cryptocurrency", "Verge"); 0550 info.Symbol = QStringLiteral("XVG"); 0551 info.Date = QDate(2009, 2, 4); 0552 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0553 info.Internet = QStringLiteral("XVG"); 0554 info.Source = QStringLiteral("CoinMarketCap"); 0555 info.Parent = QStringLiteral("USD"); 0556 info.NbDecimal = 4; 0557 info.Value = -1; 0558 currencies.push_back(info); 0559 } 0560 { 0561 // SIACOIN 0562 SKGServices::SKGUnitInfo info; 0563 info.Name = i18nc("Noun, a cryptocurrency", "Siacoin"); 0564 info.Symbol = QStringLiteral("SC"); 0565 info.Date = QDate(2009, 2, 4); 0566 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0567 info.Internet = QStringLiteral("SC"); 0568 info.Source = QStringLiteral("CoinMarketCap"); 0569 info.Parent = QStringLiteral("USD"); 0570 info.NbDecimal = 4; 0571 info.Value = -1; 0572 currencies.push_back(info); 0573 } 0574 { 0575 // OMISEGO 0576 SKGServices::SKGUnitInfo info; 0577 info.Name = i18nc("Noun, a cryptocurrency", "OmiseGO"); 0578 info.Symbol = QStringLiteral("OMG"); 0579 info.Date = QDate(2009, 2, 4); 0580 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0581 info.Internet = QStringLiteral("OMG"); 0582 info.Source = QStringLiteral("CoinMarketCap"); 0583 info.Parent = QStringLiteral("USD"); 0584 info.NbDecimal = 4; 0585 info.Value = -1; 0586 currencies.push_back(info); 0587 } 0588 { 0589 // BYTECOIN-BCN 0590 SKGServices::SKGUnitInfo info; 0591 info.Name = i18nc("Noun, a cryptocurrency", "Bytecoin"); 0592 info.Symbol = QStringLiteral("BCN"); 0593 info.Date = QDate(2009, 2, 4); 0594 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0595 info.Internet = QStringLiteral("BCN"); 0596 info.Source = QStringLiteral("CoinMarketCap"); 0597 info.Parent = QStringLiteral("USD"); 0598 info.NbDecimal = 4; 0599 info.Value = -1; 0600 currencies.push_back(info); 0601 } 0602 { 0603 // BITCONNECT 0604 SKGServices::SKGUnitInfo info; 0605 info.Name = i18nc("Noun, a cryptocurrency", "BitConnect"); 0606 info.Symbol = QStringLiteral("BCC"); 0607 info.Date = QDate(2009, 2, 4); 0608 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0609 info.Internet = QStringLiteral("BCC"); 0610 info.Source = QStringLiteral("CoinMarketCap"); 0611 info.Parent = QStringLiteral("USD"); 0612 info.NbDecimal = 4; 0613 info.Value = -1; 0614 currencies.push_back(info); 0615 } 0616 { 0617 // POPULOUS 0618 SKGServices::SKGUnitInfo info; 0619 info.Name = i18nc("Noun, a cryptocurrency", "Populous"); 0620 info.Symbol = QStringLiteral("PPT"); 0621 info.Date = QDate(2009, 2, 4); 0622 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0623 info.Internet = QStringLiteral("PPT"); 0624 info.Source = QStringLiteral("CoinMarketCap"); 0625 info.Parent = QStringLiteral("USD"); 0626 info.NbDecimal = 4; 0627 info.Value = -1; 0628 currencies.push_back(info); 0629 } 0630 { 0631 // STRATIS 0632 SKGServices::SKGUnitInfo info; 0633 info.Name = i18nc("Noun, a cryptocurrency", "Stratis"); 0634 info.Symbol = QStringLiteral("STRAT"); 0635 info.Date = QDate(2009, 2, 4); 0636 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0637 info.Internet = QStringLiteral("STRAT"); 0638 info.Source = QStringLiteral("CoinMarketCap"); 0639 info.Parent = QStringLiteral("USD"); 0640 info.NbDecimal = 4; 0641 info.Value = -1; 0642 currencies.push_back(info); 0643 } 0644 { 0645 // ZCASH 0646 SKGServices::SKGUnitInfo info; 0647 info.Name = i18nc("Noun, a cryptocurrency", "Zcash"); 0648 info.Symbol = QStringLiteral("ZEC"); 0649 info.Date = QDate(2009, 2, 4); 0650 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0651 info.Internet = QStringLiteral("ZEC"); 0652 info.Source = QStringLiteral("CoinMarketCap"); 0653 info.Parent = QStringLiteral("USD"); 0654 info.NbDecimal = 4; 0655 info.Value = -1; 0656 currencies.push_back(info); 0657 } 0658 { 0659 // DENTACOIN 0660 SKGServices::SKGUnitInfo info; 0661 info.Name = i18nc("Noun, a cryptocurrency", "Dentacoin"); 0662 info.Symbol = QStringLiteral("DCN"); 0663 info.Date = QDate(2009, 2, 4); 0664 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0665 info.Internet = QStringLiteral("DCN"); 0666 info.Source = QStringLiteral("CoinMarketCap"); 0667 info.Parent = QStringLiteral("USD"); 0668 info.NbDecimal = 4; 0669 info.Value = -1; 0670 currencies.push_back(info); 0671 } 0672 { 0673 // BITSHARES 0674 SKGServices::SKGUnitInfo info; 0675 info.Name = i18nc("Noun, a cryptocurrency", "BitShares"); 0676 info.Symbol = QStringLiteral("BTS"); 0677 info.Date = QDate(2009, 2, 4); 0678 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0679 info.Internet = QStringLiteral("BTS"); 0680 info.Source = QStringLiteral("CoinMarketCap"); 0681 info.Parent = QStringLiteral("USD"); 0682 info.NbDecimal = 4; 0683 info.Value = -1; 0684 currencies.push_back(info); 0685 } 0686 { 0687 // BINANCE-COIN 0688 SKGServices::SKGUnitInfo info; 0689 info.Name = i18nc("Noun, a cryptocurrency", "Binance Coin"); 0690 info.Symbol = QStringLiteral("BNB"); 0691 info.Date = QDate(2009, 2, 4); 0692 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0693 info.Internet = QStringLiteral("BNB"); 0694 info.Source = QStringLiteral("CoinMarketCap"); 0695 info.Parent = QStringLiteral("USD"); 0696 info.NbDecimal = 4; 0697 info.Value = -1; 0698 currencies.push_back(info); 0699 } 0700 { 0701 // DOGECOIN 0702 SKGServices::SKGUnitInfo info; 0703 info.Name = i18nc("Noun, a cryptocurrency", "Dogecoin"); 0704 info.Symbol = QStringLiteral("DOGE"); 0705 info.Date = QDate(2009, 2, 4); 0706 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0707 info.Internet = QStringLiteral("DOGE"); 0708 info.Source = QStringLiteral("CoinMarketCap"); 0709 info.Parent = QStringLiteral("USD"); 0710 info.NbDecimal = 4; 0711 info.Value = -1; 0712 currencies.push_back(info); 0713 } 0714 { 0715 // STATUS 0716 SKGServices::SKGUnitInfo info; 0717 info.Name = i18nc("Noun, a cryptocurrency", "Status"); 0718 info.Symbol = QStringLiteral("SNT"); 0719 info.Date = QDate(2009, 2, 4); 0720 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0721 info.Internet = QStringLiteral("SNT"); 0722 info.Source = QStringLiteral("CoinMarketCap"); 0723 info.Parent = QStringLiteral("USD"); 0724 info.NbDecimal = 4; 0725 info.Value = -1; 0726 currencies.push_back(info); 0727 } 0728 { 0729 // ARDOR 0730 SKGServices::SKGUnitInfo info; 0731 info.Name = i18nc("Noun, a cryptocurrency", "Ardor"); 0732 info.Symbol = QStringLiteral("ARDR"); 0733 info.Date = QDate(2009, 2, 4); 0734 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0735 info.Internet = QStringLiteral("ARDR"); 0736 info.Source = QStringLiteral("CoinMarketCap"); 0737 info.Parent = QStringLiteral("USD"); 0738 info.NbDecimal = 4; 0739 info.Value = -1; 0740 currencies.push_back(info); 0741 } 0742 { 0743 // KUCOIN-SHARES 0744 SKGServices::SKGUnitInfo info; 0745 info.Name = i18nc("Noun, a cryptocurrency", "KuCoin Shares"); 0746 info.Symbol = QStringLiteral("KCS"); 0747 info.Date = QDate(2009, 2, 4); 0748 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0749 info.Internet = QStringLiteral("KCS"); 0750 info.Source = QStringLiteral("CoinMarketCap"); 0751 info.Parent = QStringLiteral("USD"); 0752 info.NbDecimal = 4; 0753 info.Value = -1; 0754 currencies.push_back(info); 0755 } 0756 { 0757 // TETHER 0758 SKGServices::SKGUnitInfo info; 0759 info.Name = i18nc("Noun, a cryptocurrency", "Tether"); 0760 info.Symbol = QStringLiteral("USDT"); 0761 info.Date = QDate(2009, 2, 4); 0762 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0763 info.Internet = QStringLiteral("USDT"); 0764 info.Source = QStringLiteral("CoinMarketCap"); 0765 info.Parent = QStringLiteral("USD"); 0766 info.NbDecimal = 4; 0767 info.Value = -1; 0768 currencies.push_back(info); 0769 } 0770 { 0771 // STEEM 0772 SKGServices::SKGUnitInfo info; 0773 info.Name = i18nc("Noun, a cryptocurrency", "Steem"); 0774 info.Symbol = QStringLiteral("STEEM"); 0775 info.Date = QDate(2009, 2, 4); 0776 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0777 info.Internet = QStringLiteral("STEEM"); 0778 info.Source = QStringLiteral("CoinMarketCap"); 0779 info.Parent = QStringLiteral("USD"); 0780 info.NbDecimal = 4; 0781 info.Value = -1; 0782 currencies.push_back(info); 0783 } 0784 { 0785 // WAVES 0786 SKGServices::SKGUnitInfo info; 0787 info.Name = i18nc("Noun, a cryptocurrency", "Waves"); 0788 info.Symbol = QStringLiteral("WAVES"); 0789 info.Date = QDate(2009, 2, 4); 0790 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0791 info.Internet = QStringLiteral("WAVES"); 0792 info.Source = QStringLiteral("CoinMarketCap"); 0793 info.Parent = QStringLiteral("USD"); 0794 info.NbDecimal = 4; 0795 info.Value = -1; 0796 currencies.push_back(info); 0797 } 0798 { 0799 // VECHAIN 0800 SKGServices::SKGUnitInfo info; 0801 info.Name = i18nc("Noun, a cryptocurrency", "VeChain"); 0802 info.Symbol = QStringLiteral("VEN"); 0803 info.Date = QDate(2009, 2, 4); 0804 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0805 info.Internet = QStringLiteral("VEN"); 0806 info.Source = QStringLiteral("CoinMarketCap"); 0807 info.Parent = QStringLiteral("USD"); 0808 info.NbDecimal = 4; 0809 info.Value = -1; 0810 currencies.push_back(info); 0811 } 0812 { 0813 // DIGIBYTE 0814 SKGServices::SKGUnitInfo info; 0815 info.Name = i18nc("Noun, a cryptocurrency", "DigiByte"); 0816 info.Symbol = QStringLiteral("DGB"); 0817 info.Date = QDate(2009, 2, 4); 0818 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0819 info.Internet = QStringLiteral("DGB"); 0820 info.Source = QStringLiteral("CoinMarketCap"); 0821 info.Parent = QStringLiteral("USD"); 0822 info.NbDecimal = 4; 0823 info.Value = -1; 0824 currencies.push_back(info); 0825 } 0826 { 0827 // KOMODO 0828 SKGServices::SKGUnitInfo info; 0829 info.Name = i18nc("Noun, a cryptocurrency", "Komodo"); 0830 info.Symbol = QStringLiteral("KMD"); 0831 info.Date = QDate(2009, 2, 4); 0832 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0833 info.Internet = QStringLiteral("KMD"); 0834 info.Source = QStringLiteral("CoinMarketCap"); 0835 info.Parent = QStringLiteral("USD"); 0836 info.NbDecimal = 4; 0837 info.Value = -1; 0838 currencies.push_back(info); 0839 } 0840 { 0841 // DRAGONCHAIN 0842 SKGServices::SKGUnitInfo info; 0843 info.Name = i18nc("Noun, a cryptocurrency", "Dragonchain"); 0844 info.Symbol = QStringLiteral("DRGN"); 0845 info.Date = QDate(2009, 2, 4); 0846 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0847 info.Internet = QStringLiteral("DRGN"); 0848 info.Source = QStringLiteral("CoinMarketCap"); 0849 info.Parent = QStringLiteral("USD"); 0850 info.NbDecimal = 4; 0851 info.Value = -1; 0852 currencies.push_back(info); 0853 } 0854 { 0855 // AUGUR 0856 SKGServices::SKGUnitInfo info; 0857 info.Name = i18nc("Noun, a cryptocurrency", "Augur"); 0858 info.Symbol = QStringLiteral("REP"); 0859 info.Date = QDate(2009, 2, 4); 0860 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0861 info.Internet = QStringLiteral("REP"); 0862 info.Source = QStringLiteral("CoinMarketCap"); 0863 info.Parent = QStringLiteral("USD"); 0864 info.NbDecimal = 4; 0865 info.Value = -1; 0866 currencies.push_back(info); 0867 } 0868 { 0869 // GOLEM-NETWORK-TOKENS 0870 SKGServices::SKGUnitInfo info; 0871 info.Name = i18nc("Noun, a cryptocurrency", "Golem"); 0872 info.Symbol = QStringLiteral("GNT"); 0873 info.Date = QDate(2009, 2, 4); 0874 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0875 info.Internet = QStringLiteral("GNT"); 0876 info.Source = QStringLiteral("CoinMarketCap"); 0877 info.Parent = QStringLiteral("USD"); 0878 info.NbDecimal = 4; 0879 info.Value = -1; 0880 currencies.push_back(info); 0881 } 0882 { 0883 // VERITASEUM 0884 SKGServices::SKGUnitInfo info; 0885 info.Name = i18nc("Noun, a cryptocurrency", "Veritaseum"); 0886 info.Symbol = QStringLiteral("VERI"); 0887 info.Date = QDate(2009, 2, 4); 0888 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0889 info.Internet = QStringLiteral("VERI"); 0890 info.Source = QStringLiteral("CoinMarketCap"); 0891 info.Parent = QStringLiteral("USD"); 0892 info.NbDecimal = 4; 0893 info.Value = -1; 0894 currencies.push_back(info); 0895 } 0896 { 0897 // HSHARE 0898 SKGServices::SKGUnitInfo info; 0899 info.Name = i18nc("Noun, a cryptocurrency", "Hshare"); 0900 info.Symbol = QStringLiteral("HSR"); 0901 info.Date = QDate(2009, 2, 4); 0902 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0903 info.Internet = QStringLiteral("HSR"); 0904 info.Source = QStringLiteral("CoinMarketCap"); 0905 info.Parent = QStringLiteral("USD"); 0906 info.NbDecimal = 4; 0907 info.Value = -1; 0908 currencies.push_back(info); 0909 } 0910 { 0911 // KIN 0912 SKGServices::SKGUnitInfo info; 0913 info.Name = i18nc("Noun, a cryptocurrency", "Kin"); 0914 info.Symbol = QStringLiteral("KIN"); 0915 info.Date = QDate(2009, 2, 4); 0916 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0917 info.Internet = QStringLiteral("KIN"); 0918 info.Source = QStringLiteral("CoinMarketCap"); 0919 info.Parent = QStringLiteral("USD"); 0920 info.NbDecimal = 4; 0921 info.Value = -1; 0922 currencies.push_back(info); 0923 } 0924 { 0925 // SALT 0926 SKGServices::SKGUnitInfo info; 0927 info.Name = i18nc("Noun, a cryptocurrency", "SALT"); 0928 info.Symbol = QStringLiteral("SALT"); 0929 info.Date = QDate(2009, 2, 4); 0930 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0931 info.Internet = QStringLiteral("SALT"); 0932 info.Source = QStringLiteral("CoinMarketCap"); 0933 info.Parent = QStringLiteral("USD"); 0934 info.NbDecimal = 4; 0935 info.Value = -1; 0936 currencies.push_back(info); 0937 } 0938 { 0939 // ELECTRONEUM 0940 SKGServices::SKGUnitInfo info; 0941 info.Name = i18nc("Noun, a cryptocurrency", "Electroneum"); 0942 info.Symbol = QStringLiteral("ETN"); 0943 info.Date = QDate(2009, 2, 4); 0944 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0945 info.Internet = QStringLiteral("ETN"); 0946 info.Source = QStringLiteral("CoinMarketCap"); 0947 info.Parent = QStringLiteral("USD"); 0948 info.NbDecimal = 4; 0949 info.Value = -1; 0950 currencies.push_back(info); 0951 } 0952 { 0953 // ARK 0954 SKGServices::SKGUnitInfo info; 0955 info.Name = i18nc("Noun, a cryptocurrency", "Ark"); 0956 info.Symbol = QStringLiteral("ARK"); 0957 info.Date = QDate(2009, 2, 4); 0958 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0959 info.Internet = QStringLiteral("ARK"); 0960 info.Source = QStringLiteral("CoinMarketCap"); 0961 info.Parent = QStringLiteral("USD"); 0962 info.NbDecimal = 4; 0963 info.Value = -1; 0964 currencies.push_back(info); 0965 } 0966 { 0967 // DENT 0968 SKGServices::SKGUnitInfo info; 0969 info.Name = i18nc("Noun, a cryptocurrency", "Dent"); 0970 info.Symbol = QStringLiteral("DENT"); 0971 info.Date = QDate(2009, 2, 4); 0972 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0973 info.Internet = QStringLiteral("DENT"); 0974 info.Source = QStringLiteral("CoinMarketCap"); 0975 info.Parent = QStringLiteral("USD"); 0976 info.NbDecimal = 4; 0977 info.Value = -1; 0978 currencies.push_back(info); 0979 } 0980 { 0981 // ETHOS 0982 SKGServices::SKGUnitInfo info; 0983 info.Name = i18nc("Noun, a cryptocurrency", "Ethos"); 0984 info.Symbol = QStringLiteral("ETHOS"); 0985 info.Date = QDate(2009, 2, 4); 0986 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 0987 info.Internet = QStringLiteral("ETHOS"); 0988 info.Source = QStringLiteral("CoinMarketCap"); 0989 info.Parent = QStringLiteral("USD"); 0990 info.NbDecimal = 4; 0991 info.Value = -1; 0992 currencies.push_back(info); 0993 } 0994 { 0995 // BASIC-ATTENTION-TOKEN 0996 SKGServices::SKGUnitInfo info; 0997 info.Name = i18nc("Noun, a cryptocurrency", "Basic Attention Token"); 0998 info.Symbol = QStringLiteral("BAT"); 0999 info.Date = QDate(2009, 2, 4); 1000 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1001 info.Internet = QStringLiteral("BAT"); 1002 info.Source = QStringLiteral("CoinMarketCap"); 1003 info.Parent = QStringLiteral("USD"); 1004 info.NbDecimal = 4; 1005 info.Value = -1; 1006 currencies.push_back(info); 1007 } 1008 { 1009 // REDDCOIN 1010 SKGServices::SKGUnitInfo info; 1011 info.Name = i18nc("Noun, a cryptocurrency", "ReddCoin"); 1012 info.Symbol = QStringLiteral("RDD"); 1013 info.Date = QDate(2009, 2, 4); 1014 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1015 info.Internet = QStringLiteral("RDD"); 1016 info.Source = QStringLiteral("CoinMarketCap"); 1017 info.Parent = QStringLiteral("USD"); 1018 info.NbDecimal = 4; 1019 info.Value = -1; 1020 currencies.push_back(info); 1021 } 1022 { 1023 // 0X 1024 SKGServices::SKGUnitInfo info; 1025 info.Name = i18nc("Noun, a cryptocurrency", "0x"); 1026 info.Symbol = QStringLiteral("ZRX"); 1027 info.Date = QDate(2009, 2, 4); 1028 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1029 info.Internet = QStringLiteral("ZRX"); 1030 info.Source = QStringLiteral("CoinMarketCap"); 1031 info.Parent = QStringLiteral("USD"); 1032 info.NbDecimal = 4; 1033 info.Value = -1; 1034 currencies.push_back(info); 1035 } 1036 { 1037 // DECRED 1038 SKGServices::SKGUnitInfo info; 1039 info.Name = i18nc("Noun, a cryptocurrency", "Decred"); 1040 info.Symbol = QStringLiteral("DCR"); 1041 info.Date = QDate(2009, 2, 4); 1042 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1043 info.Internet = QStringLiteral("DCR"); 1044 info.Source = QStringLiteral("CoinMarketCap"); 1045 info.Parent = QStringLiteral("USD"); 1046 info.NbDecimal = 4; 1047 info.Value = -1; 1048 currencies.push_back(info); 1049 } 1050 { 1051 // NEXUS 1052 SKGServices::SKGUnitInfo info; 1053 info.Name = i18nc("Noun, a cryptocurrency", "Nexus"); 1054 info.Symbol = QStringLiteral("NXS"); 1055 info.Date = QDate(2009, 2, 4); 1056 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1057 info.Internet = QStringLiteral("NXS"); 1058 info.Source = QStringLiteral("CoinMarketCap"); 1059 info.Parent = QStringLiteral("USD"); 1060 info.NbDecimal = 4; 1061 info.Value = -1; 1062 currencies.push_back(info); 1063 } 1064 { 1065 // EXPERIENCE-POINTS 1066 SKGServices::SKGUnitInfo info; 1067 info.Name = i18nc("Noun, a cryptocurrency", "Experience Points"); 1068 info.Symbol = QStringLiteral("XP"); 1069 info.Date = QDate(2009, 2, 4); 1070 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1071 info.Internet = QStringLiteral("XP"); 1072 info.Source = QStringLiteral("CoinMarketCap"); 1073 info.Parent = QStringLiteral("USD"); 1074 info.NbDecimal = 4; 1075 info.Value = -1; 1076 currencies.push_back(info); 1077 } 1078 { 1079 // QASH 1080 SKGServices::SKGUnitInfo info; 1081 info.Name = i18nc("Noun, a cryptocurrency", "QASH"); 1082 info.Symbol = QStringLiteral("QASH"); 1083 info.Date = QDate(2009, 2, 4); 1084 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1085 info.Internet = QStringLiteral("QASH"); 1086 info.Source = QStringLiteral("CoinMarketCap"); 1087 info.Parent = QStringLiteral("USD"); 1088 info.NbDecimal = 4; 1089 info.Value = -1; 1090 currencies.push_back(info); 1091 } 1092 { 1093 // KYBER-NETWORK 1094 SKGServices::SKGUnitInfo info; 1095 info.Name = i18nc("Noun, a cryptocurrency", "Kyber Network"); 1096 info.Symbol = QStringLiteral("KNC"); 1097 info.Date = QDate(2009, 2, 4); 1098 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1099 info.Internet = QStringLiteral("KNC"); 1100 info.Source = QStringLiteral("CoinMarketCap"); 1101 info.Parent = QStringLiteral("USD"); 1102 info.NbDecimal = 4; 1103 info.Value = -1; 1104 currencies.push_back(info); 1105 } 1106 { 1107 // PIVX 1108 SKGServices::SKGUnitInfo info; 1109 info.Name = i18nc("Noun, a cryptocurrency", "PIVX"); 1110 info.Symbol = QStringLiteral("PIVX"); 1111 info.Date = QDate(2009, 2, 4); 1112 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1113 info.Internet = QStringLiteral("PIVX"); 1114 info.Source = QStringLiteral("CoinMarketCap"); 1115 info.Parent = QStringLiteral("USD"); 1116 info.NbDecimal = 4; 1117 info.Value = -1; 1118 currencies.push_back(info); 1119 } 1120 { 1121 // FUNFAIR 1122 SKGServices::SKGUnitInfo info; 1123 info.Name = i18nc("Noun, a cryptocurrency", "FunFair"); 1124 info.Symbol = QStringLiteral("FUN"); 1125 info.Date = QDate(2009, 2, 4); 1126 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1127 info.Internet = QStringLiteral("FUN"); 1128 info.Source = QStringLiteral("CoinMarketCap"); 1129 info.Parent = QStringLiteral("USD"); 1130 info.NbDecimal = 4; 1131 info.Value = -1; 1132 currencies.push_back(info); 1133 } 1134 { 1135 // FACTOM 1136 SKGServices::SKGUnitInfo info; 1137 info.Name = i18nc("Noun, a cryptocurrency", "Factom"); 1138 info.Symbol = QStringLiteral("FCT"); 1139 info.Date = QDate(2009, 2, 4); 1140 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1141 info.Internet = QStringLiteral("FCT"); 1142 info.Source = QStringLiteral("CoinMarketCap"); 1143 info.Parent = QStringLiteral("USD"); 1144 info.NbDecimal = 4; 1145 info.Value = -1; 1146 currencies.push_back(info); 1147 } 1148 { 1149 // NEBLIO 1150 SKGServices::SKGUnitInfo info; 1151 info.Name = i18nc("Noun, a cryptocurrency", "Neblio"); 1152 info.Symbol = QStringLiteral("NEBL"); 1153 info.Date = QDate(2009, 2, 4); 1154 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1155 info.Internet = QStringLiteral("NEBL"); 1156 info.Source = QStringLiteral("CoinMarketCap"); 1157 info.Parent = QStringLiteral("USD"); 1158 info.NbDecimal = 4; 1159 info.Value = -1; 1160 currencies.push_back(info); 1161 } 1162 { 1163 // REQUEST-NETWORK 1164 SKGServices::SKGUnitInfo info; 1165 info.Name = i18nc("Noun, a cryptocurrency", "Request Network"); 1166 info.Symbol = QStringLiteral("REQ"); 1167 info.Date = QDate(2009, 2, 4); 1168 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1169 info.Internet = QStringLiteral("REQ"); 1170 info.Source = QStringLiteral("CoinMarketCap"); 1171 info.Parent = QStringLiteral("USD"); 1172 info.NbDecimal = 4; 1173 info.Value = -1; 1174 currencies.push_back(info); 1175 } 1176 { 1177 // AETERNITY 1178 SKGServices::SKGUnitInfo info; 1179 info.Name = i18nc("Noun, a cryptocurrency", "Aeternity"); 1180 info.Symbol = QStringLiteral("AE"); 1181 info.Date = QDate(2009, 2, 4); 1182 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1183 info.Internet = QStringLiteral("AE"); 1184 info.Source = QStringLiteral("CoinMarketCap"); 1185 info.Parent = QStringLiteral("USD"); 1186 info.NbDecimal = 4; 1187 info.Value = -1; 1188 currencies.push_back(info); 1189 } 1190 { 1191 // SUBSTRATUM 1192 SKGServices::SKGUnitInfo info; 1193 info.Name = i18nc("Noun, a cryptocurrency", "Substratum"); 1194 info.Symbol = QStringLiteral("SUB"); 1195 info.Date = QDate(2009, 2, 4); 1196 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1197 info.Internet = QStringLiteral("SUB"); 1198 info.Source = QStringLiteral("CoinMarketCap"); 1199 info.Parent = QStringLiteral("USD"); 1200 info.NbDecimal = 4; 1201 info.Value = -1; 1202 currencies.push_back(info); 1203 } 1204 { 1205 // POWER-LEDGER 1206 SKGServices::SKGUnitInfo info; 1207 info.Name = i18nc("Noun, a cryptocurrency", "Power Ledger"); 1208 info.Symbol = QStringLiteral("POWR"); 1209 info.Date = QDate(2009, 2, 4); 1210 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1211 info.Internet = QStringLiteral("POWR"); 1212 info.Source = QStringLiteral("CoinMarketCap"); 1213 info.Parent = QStringLiteral("USD"); 1214 info.NbDecimal = 4; 1215 info.Value = -1; 1216 currencies.push_back(info); 1217 } 1218 { 1219 // WAX 1220 SKGServices::SKGUnitInfo info; 1221 info.Name = i18nc("Noun, a cryptocurrency", "WAX"); 1222 info.Symbol = QStringLiteral("WAX"); 1223 info.Date = QDate(2009, 2, 4); 1224 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1225 info.Internet = QStringLiteral("WAX"); 1226 info.Source = QStringLiteral("CoinMarketCap"); 1227 info.Parent = QStringLiteral("USD"); 1228 info.NbDecimal = 4; 1229 info.Value = -1; 1230 currencies.push_back(info); 1231 } 1232 { 1233 // AELF 1234 SKGServices::SKGUnitInfo info; 1235 info.Name = i18nc("Noun, a cryptocurrency", "aelf"); 1236 info.Symbol = QStringLiteral("ELF"); 1237 info.Date = QDate(2009, 2, 4); 1238 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1239 info.Internet = QStringLiteral("ELF"); 1240 info.Source = QStringLiteral("CoinMarketCap"); 1241 info.Parent = QStringLiteral("USD"); 1242 info.NbDecimal = 4; 1243 info.Value = -1; 1244 currencies.push_back(info); 1245 } 1246 { 1247 // BYTOM 1248 SKGServices::SKGUnitInfo info; 1249 info.Name = i18nc("Noun, a cryptocurrency", "Bytom"); 1250 info.Symbol = QStringLiteral("BTM"); 1251 info.Date = QDate(2009, 2, 4); 1252 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1253 info.Internet = QStringLiteral("BTM"); 1254 info.Source = QStringLiteral("CoinMarketCap"); 1255 info.Parent = QStringLiteral("USD"); 1256 info.NbDecimal = 4; 1257 info.Value = -1; 1258 currencies.push_back(info); 1259 } 1260 { 1261 // AION 1262 SKGServices::SKGUnitInfo info; 1263 info.Name = i18nc("Noun, a cryptocurrency", "Aion"); 1264 info.Symbol = QStringLiteral("AION"); 1265 info.Date = QDate(2009, 2, 4); 1266 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1267 info.Internet = QStringLiteral("AION"); 1268 info.Source = QStringLiteral("CoinMarketCap"); 1269 info.Parent = QStringLiteral("USD"); 1270 info.NbDecimal = 4; 1271 info.Value = -1; 1272 currencies.push_back(info); 1273 } 1274 { 1275 // RCHAIN 1276 SKGServices::SKGUnitInfo info; 1277 info.Name = i18nc("Noun, a cryptocurrency", "RChain"); 1278 info.Symbol = QStringLiteral("RHOC"); 1279 info.Date = QDate(2009, 2, 4); 1280 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1281 info.Internet = QStringLiteral("RHOC"); 1282 info.Source = QStringLiteral("CoinMarketCap"); 1283 info.Parent = QStringLiteral("USD"); 1284 info.NbDecimal = 4; 1285 info.Value = -1; 1286 currencies.push_back(info); 1287 } 1288 { 1289 // DIGITALNOTE 1290 SKGServices::SKGUnitInfo info; 1291 info.Name = i18nc("Noun, a cryptocurrency", "DigitalNote"); 1292 info.Symbol = QStringLiteral("XDN"); 1293 info.Date = QDate(2009, 2, 4); 1294 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1295 info.Internet = QStringLiteral("XDN"); 1296 info.Source = QStringLiteral("CoinMarketCap"); 1297 info.Parent = QStringLiteral("USD"); 1298 info.NbDecimal = 4; 1299 info.Value = -1; 1300 currencies.push_back(info); 1301 } 1302 { 1303 // ENIGMA-PROJECT 1304 SKGServices::SKGUnitInfo info; 1305 info.Name = i18nc("Noun, a cryptocurrency", "Enigma"); 1306 info.Symbol = QStringLiteral("ENG"); 1307 info.Date = QDate(2009, 2, 4); 1308 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1309 info.Internet = QStringLiteral("ENG"); 1310 info.Source = QStringLiteral("CoinMarketCap"); 1311 info.Parent = QStringLiteral("USD"); 1312 info.NbDecimal = 4; 1313 info.Value = -1; 1314 currencies.push_back(info); 1315 } 1316 { 1317 // NXT 1318 SKGServices::SKGUnitInfo info; 1319 info.Name = i18nc("Noun, a cryptocurrency", "Nxt"); 1320 info.Symbol = QStringLiteral("NXT"); 1321 info.Date = QDate(2009, 2, 4); 1322 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1323 info.Internet = QStringLiteral("NXT"); 1324 info.Source = QStringLiteral("CoinMarketCap"); 1325 info.Parent = QStringLiteral("USD"); 1326 info.NbDecimal = 4; 1327 info.Value = -1; 1328 currencies.push_back(info); 1329 } 1330 { 1331 // TIME-NEW-BANK 1332 SKGServices::SKGUnitInfo info; 1333 info.Name = i18nc("Noun, a cryptocurrency", "Time New Bank"); 1334 info.Symbol = QStringLiteral("TNB"); 1335 info.Date = QDate(2009, 2, 4); 1336 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1337 info.Internet = QStringLiteral("TNB"); 1338 info.Source = QStringLiteral("CoinMarketCap"); 1339 info.Parent = QStringLiteral("USD"); 1340 info.NbDecimal = 4; 1341 info.Value = -1; 1342 currencies.push_back(info); 1343 } 1344 { 1345 // BITCOINDARK 1346 SKGServices::SKGUnitInfo info; 1347 info.Name = i18nc("Noun, a cryptocurrency", "BitcoinDark"); 1348 info.Symbol = QStringLiteral("BTCD"); 1349 info.Date = QDate(2009, 2, 4); 1350 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1351 info.Internet = QStringLiteral("BTCD"); 1352 info.Source = QStringLiteral("CoinMarketCap"); 1353 info.Parent = QStringLiteral("USD"); 1354 info.NbDecimal = 4; 1355 info.Value = -1; 1356 currencies.push_back(info); 1357 } 1358 { 1359 // MONACOIN 1360 SKGServices::SKGUnitInfo info; 1361 info.Name = i18nc("Noun, a cryptocurrency", "MonaCoin"); 1362 info.Symbol = QStringLiteral("MONA"); 1363 info.Date = QDate(2009, 2, 4); 1364 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1365 info.Internet = QStringLiteral("MONA"); 1366 info.Source = QStringLiteral("CoinMarketCap"); 1367 info.Parent = QStringLiteral("USD"); 1368 info.NbDecimal = 4; 1369 info.Value = -1; 1370 currencies.push_back(info); 1371 } 1372 { 1373 // QUANTSTAMP 1374 SKGServices::SKGUnitInfo info; 1375 info.Name = i18nc("Noun, a cryptocurrency", "Quantstamp"); 1376 info.Symbol = QStringLiteral("QSP"); 1377 info.Date = QDate(2009, 2, 4); 1378 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1379 info.Internet = QStringLiteral("QSP"); 1380 info.Source = QStringLiteral("CoinMarketCap"); 1381 info.Parent = QStringLiteral("USD"); 1382 info.NbDecimal = 4; 1383 info.Value = -1; 1384 currencies.push_back(info); 1385 } 1386 { 1387 // MAIDSAFECOIN 1388 SKGServices::SKGUnitInfo info; 1389 info.Name = i18nc("Noun, a cryptocurrency", "MaidSafeCoin"); 1390 info.Symbol = QStringLiteral("MAID"); 1391 info.Date = QDate(2009, 2, 4); 1392 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1393 info.Internet = QStringLiteral("MAID"); 1394 info.Source = QStringLiteral("CoinMarketCap"); 1395 info.Parent = QStringLiteral("USD"); 1396 info.NbDecimal = 4; 1397 info.Value = -1; 1398 currencies.push_back(info); 1399 } 1400 { 1401 // BYTEBALL 1402 SKGServices::SKGUnitInfo info; 1403 info.Name = i18nc("Noun, a cryptocurrency", "Byteball Bytes"); 1404 info.Symbol = QStringLiteral("GBYTE"); 1405 info.Date = QDate(2009, 2, 4); 1406 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1407 info.Internet = QStringLiteral("GBYTE"); 1408 info.Source = QStringLiteral("CoinMarketCap"); 1409 info.Parent = QStringLiteral("USD"); 1410 info.NbDecimal = 4; 1411 info.Value = -1; 1412 currencies.push_back(info); 1413 } 1414 { 1415 // GAS 1416 SKGServices::SKGUnitInfo info; 1417 info.Name = i18nc("Noun, a cryptocurrency", "Gas"); 1418 info.Symbol = QStringLiteral("GAS"); 1419 info.Date = QDate(2009, 2, 4); 1420 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1421 info.Internet = QStringLiteral("GAS"); 1422 info.Source = QStringLiteral("CoinMarketCap"); 1423 info.Parent = QStringLiteral("USD"); 1424 info.NbDecimal = 4; 1425 info.Value = -1; 1426 currencies.push_back(info); 1427 } 1428 { 1429 // CHAINLINK 1430 SKGServices::SKGUnitInfo info; 1431 info.Name = i18nc("Noun, a cryptocurrency", "ChainLink"); 1432 info.Symbol = QStringLiteral("LINK"); 1433 info.Date = QDate(2009, 2, 4); 1434 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1435 info.Internet = QStringLiteral("LINK"); 1436 info.Source = QStringLiteral("CoinMarketCap"); 1437 info.Parent = QStringLiteral("USD"); 1438 info.NbDecimal = 4; 1439 info.Value = -1; 1440 currencies.push_back(info); 1441 } 1442 { 1443 // SYSCOIN 1444 SKGServices::SKGUnitInfo info; 1445 info.Name = i18nc("Noun, a cryptocurrency", "Syscoin"); 1446 info.Symbol = QStringLiteral("SYS"); 1447 info.Date = QDate(2009, 2, 4); 1448 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1449 info.Internet = QStringLiteral("SYS"); 1450 info.Source = QStringLiteral("CoinMarketCap"); 1451 info.Parent = QStringLiteral("USD"); 1452 info.NbDecimal = 4; 1453 info.Value = -1; 1454 currencies.push_back(info); 1455 } 1456 { 1457 // SANTIMENT 1458 SKGServices::SKGUnitInfo info; 1459 info.Name = i18nc("Noun, a cryptocurrency", "Santiment Network Token"); 1460 info.Symbol = QStringLiteral("SAN"); 1461 info.Date = QDate(2009, 2, 4); 1462 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1463 info.Internet = QStringLiteral("SAN"); 1464 info.Source = QStringLiteral("CoinMarketCap"); 1465 info.Parent = QStringLiteral("USD"); 1466 info.NbDecimal = 4; 1467 info.Value = -1; 1468 currencies.push_back(info); 1469 } 1470 { 1471 // COBINHOOD 1472 SKGServices::SKGUnitInfo info; 1473 info.Name = i18nc("Noun, a cryptocurrency", "Cobinhood"); 1474 info.Symbol = QStringLiteral("COB"); 1475 info.Date = QDate(2009, 2, 4); 1476 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1477 info.Internet = QStringLiteral("COB"); 1478 info.Source = QStringLiteral("CoinMarketCap"); 1479 info.Parent = QStringLiteral("USD"); 1480 info.NbDecimal = 4; 1481 info.Value = -1; 1482 currencies.push_back(info); 1483 } 1484 { 1485 // RED-PULSE 1486 SKGServices::SKGUnitInfo info; 1487 info.Name = i18nc("Noun, a cryptocurrency", "Red Pulse"); 1488 info.Symbol = QStringLiteral("RPX"); 1489 info.Date = QDate(2009, 2, 4); 1490 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1491 info.Internet = QStringLiteral("RPX"); 1492 info.Source = QStringLiteral("CoinMarketCap"); 1493 info.Parent = QStringLiteral("USD"); 1494 info.NbDecimal = 4; 1495 info.Value = -1; 1496 currencies.push_back(info); 1497 } 1498 { 1499 // DIGIXDAO 1500 SKGServices::SKGUnitInfo info; 1501 info.Name = i18nc("Noun, a cryptocurrency", "DigixDAO"); 1502 info.Symbol = QStringLiteral("DGD"); 1503 info.Date = QDate(2009, 2, 4); 1504 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1505 info.Internet = QStringLiteral("DGD"); 1506 info.Source = QStringLiteral("CoinMarketCap"); 1507 info.Parent = QStringLiteral("USD"); 1508 info.NbDecimal = 4; 1509 info.Value = -1; 1510 currencies.push_back(info); 1511 } 1512 { 1513 // TENX 1514 SKGServices::SKGUnitInfo info; 1515 info.Name = i18nc("Noun, a cryptocurrency", "TenX"); 1516 info.Symbol = QStringLiteral("PAY"); 1517 info.Date = QDate(2009, 2, 4); 1518 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1519 info.Internet = QStringLiteral("PAY"); 1520 info.Source = QStringLiteral("CoinMarketCap"); 1521 info.Parent = QStringLiteral("USD"); 1522 info.NbDecimal = 4; 1523 info.Value = -1; 1524 currencies.push_back(info); 1525 } 1526 { 1527 // ICONOMI 1528 SKGServices::SKGUnitInfo info; 1529 info.Name = i18nc("Noun, a cryptocurrency", "Iconomi"); 1530 info.Symbol = QStringLiteral("ICN"); 1531 info.Date = QDate(2009, 2, 4); 1532 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1533 info.Internet = QStringLiteral("ICN"); 1534 info.Source = QStringLiteral("CoinMarketCap"); 1535 info.Parent = QStringLiteral("USD"); 1536 info.NbDecimal = 4; 1537 info.Value = -1; 1538 currencies.push_back(info); 1539 } 1540 { 1541 // POET 1542 SKGServices::SKGUnitInfo info; 1543 info.Name = i18nc("Noun, a cryptocurrency", "Po.et"); 1544 info.Symbol = QStringLiteral("POE"); 1545 info.Date = QDate(2009, 2, 4); 1546 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1547 info.Internet = QStringLiteral("POE"); 1548 info.Source = QStringLiteral("CoinMarketCap"); 1549 info.Parent = QStringLiteral("USD"); 1550 info.NbDecimal = 4; 1551 info.Value = -1; 1552 currencies.push_back(info); 1553 } 1554 { 1555 // ZCOIN 1556 SKGServices::SKGUnitInfo info; 1557 info.Name = i18nc("Noun, a cryptocurrency", "ZCoin"); 1558 info.Symbol = QStringLiteral("XZC"); 1559 info.Date = QDate(2009, 2, 4); 1560 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1561 info.Internet = QStringLiteral("XZC"); 1562 info.Source = QStringLiteral("CoinMarketCap"); 1563 info.Parent = QStringLiteral("USD"); 1564 info.NbDecimal = 4; 1565 info.Value = -1; 1566 currencies.push_back(info); 1567 } 1568 { 1569 // GNOSIS-GNO 1570 SKGServices::SKGUnitInfo info; 1571 info.Name = i18nc("Noun, a cryptocurrency", "Gnosis"); 1572 info.Symbol = QStringLiteral("GNO"); 1573 info.Date = QDate(2009, 2, 4); 1574 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1575 info.Internet = QStringLiteral("GNO"); 1576 info.Source = QStringLiteral("CoinMarketCap"); 1577 info.Parent = QStringLiteral("USD"); 1578 info.NbDecimal = 4; 1579 info.Value = -1; 1580 currencies.push_back(info); 1581 } 1582 { 1583 // BLOCKV 1584 SKGServices::SKGUnitInfo info; 1585 info.Name = i18nc("Noun, a cryptocurrency", "BLOCKv"); 1586 info.Symbol = QStringLiteral("VEE"); 1587 info.Date = QDate(2009, 2, 4); 1588 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1589 info.Internet = QStringLiteral("VEE"); 1590 info.Source = QStringLiteral("CoinMarketCap"); 1591 info.Parent = QStringLiteral("USD"); 1592 info.NbDecimal = 4; 1593 info.Value = -1; 1594 currencies.push_back(info); 1595 } 1596 { 1597 // WALTON 1598 SKGServices::SKGUnitInfo info; 1599 info.Name = i18nc("Noun, a cryptocurrency", "Walton"); 1600 info.Symbol = QStringLiteral("WTC"); 1601 info.Date = QDate(2009, 2, 4); 1602 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1603 info.Internet = QStringLiteral("WTC"); 1604 info.Source = QStringLiteral("CoinMarketCap"); 1605 info.Parent = QStringLiteral("USD"); 1606 info.NbDecimal = 4; 1607 info.Value = -1; 1608 currencies.push_back(info); 1609 } 1610 { 1611 // PACCOIN 1612 SKGServices::SKGUnitInfo info; 1613 info.Name = i18nc("Noun, a cryptocurrency", "PACcoin"); 1614 info.Symbol = QStringLiteral("PAC"); 1615 info.Date = QDate(2009, 2, 4); 1616 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1617 info.Internet = QStringLiteral("PAC"); 1618 info.Source = QStringLiteral("CoinMarketCap"); 1619 info.Parent = QStringLiteral("USD"); 1620 info.NbDecimal = 4; 1621 info.Value = -1; 1622 currencies.push_back(info); 1623 } 1624 { 1625 // DEEPBRAIN-CHAIN 1626 SKGServices::SKGUnitInfo info; 1627 info.Name = i18nc("Noun, a cryptocurrency", "DeepBrain Chain"); 1628 info.Symbol = QStringLiteral("DBC"); 1629 info.Date = QDate(2009, 2, 4); 1630 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1631 info.Internet = QStringLiteral("DBC"); 1632 info.Source = QStringLiteral("CoinMarketCap"); 1633 info.Parent = QStringLiteral("USD"); 1634 info.NbDecimal = 4; 1635 info.Value = -1; 1636 currencies.push_back(info); 1637 } 1638 { 1639 // ETHLEND 1640 SKGServices::SKGUnitInfo info; 1641 info.Name = i18nc("Noun, a cryptocurrency", "ETHLend"); 1642 info.Symbol = QStringLiteral("LEND"); 1643 info.Date = QDate(2009, 2, 4); 1644 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1645 info.Internet = QStringLiteral("LEND"); 1646 info.Source = QStringLiteral("CoinMarketCap"); 1647 info.Parent = QStringLiteral("USD"); 1648 info.NbDecimal = 4; 1649 info.Value = -1; 1650 currencies.push_back(info); 1651 } 1652 { 1653 // CIVIC 1654 SKGServices::SKGUnitInfo info; 1655 info.Name = i18nc("Noun, a cryptocurrency", "Civic"); 1656 info.Symbol = QStringLiteral("CVC"); 1657 info.Date = QDate(2009, 2, 4); 1658 info.Country = i18nc("Noun, the country of bitcoin", "Internet"); 1659 info.Internet = QStringLiteral("CVC"); 1660 info.Source = QStringLiteral("CoinMarketCap"); 1661 info.Parent = QStringLiteral("USD"); 1662 info.NbDecimal = 4; 1663 info.Value = -1; 1664 currencies.push_back(info); 1665 } 1666 } 1667 QStringList output; 1668 output.reserve(currencies.count()); 1669 for (const auto& unit : qAsConst(currencies)) { 1670 if (iIncludingObsolete || !unit.Obsolete) { 1671 output.push_back(unit.Name); 1672 } 1673 } 1674 output.sort(); 1675 return output; 1676 } 1677 1678 QString SKGUnitObject::getInternationalCode(const QString& iUnitName) 1679 { 1680 SKGTRACEINFUNC(10) 1681 QString output = iUnitName; 1682 auto match = QRegularExpression(QStringLiteral(".*\\(([^\\(\\)]+)\\)[^\\(\\)]*")).match(iUnitName); 1683 if (match.hasMatch()) { 1684 output = match.captured(1); 1685 } 1686 1687 return output; 1688 } 1689 1690 SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo() 1691 { 1692 SKGTRACEINFUNC(10) 1693 SKGServices::SKGUnitInfo info; 1694 info.Name = getName(); 1695 info.Value = getAmount(); 1696 info.NbDecimal = getNumberDecimal(); 1697 info.Symbol = getSymbol(); 1698 info.Country = getCountry(); 1699 info.Internet = getInternetCode(); 1700 info.Date = QDate::currentDate(); 1701 1702 return info; 1703 } 1704 1705 SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo(const QString& iUnitName) 1706 { 1707 SKGTRACEINFUNC(10) 1708 SKGServices::SKGUnitInfo info; 1709 if (currencies.isEmpty()) { 1710 getListofKnownCurrencies(false); 1711 } 1712 QString isoCode = getInternationalCode(iUnitName); 1713 for (const auto& unit : qAsConst(currencies)) { 1714 if (getInternationalCode(unit.Name) == isoCode) { 1715 info = unit; 1716 break; 1717 } 1718 } 1719 return info; 1720 } 1721 1722 SKGError SKGUnitObject::createCurrencyUnit(SKGDocumentBank* iDocument, const QString& iUnitName, SKGUnitObject& oUnit) 1723 { 1724 SKGError err; 1725 SKGTRACEINFUNCRC(10, err) 1726 if (iDocument != nullptr) { 1727 SKGUnitObject parentUnit; 1728 oUnit = SKGUnitObject(iDocument); 1729 1730 SKGUnitObject::UnitType type = SKGUnitObject::CURRENCY; 1731 SKGServices::SKGUnitInfo prim = iDocument->getPrimaryUnit(); 1732 SKGServices::SKGUnitInfo seco = iDocument->getSecondaryUnit(); 1733 1734 // Get information on the unit 1735 SKGServices::SKGUnitInfo info = getUnitInfo(iUnitName); 1736 if (info.Name.isEmpty()) { 1737 err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Unknown unit '%1'", iUnitName)); 1738 } 1739 if (!err && !info.Parent.isEmpty()) { 1740 err = createCurrencyUnit(iDocument, info.Parent, parentUnit); 1741 } 1742 1743 // Set the type 1744 if (info.Name == info.Symbol) { 1745 // This is an index 1746 type = SKGUnitObject::INDEX; 1747 } else if (!info.Parent.isEmpty()) { 1748 // This is a secondary unit 1749 type = (seco.Symbol.isEmpty() || seco.Symbol == info.Symbol ? SKGUnitObject::SECONDARY : SKGUnitObject::CURRENCY); 1750 } else { 1751 // As primary 1752 type = (prim.Symbol.isEmpty() || prim.Symbol == info.Symbol ? SKGUnitObject::PRIMARY : SKGUnitObject::CURRENCY); 1753 } 1754 1755 // Point on primary unit 1756 if (info.Value == 1 && !err && (type == SKGUnitObject::CURRENCY || type == SKGUnitObject::SECONDARY)) { 1757 SKGUnitObject primunit(iDocument); 1758 err = primunit.setSymbol(prim.Symbol); 1759 IFOKDO(err, primunit.load()) 1760 IFOK(err) { 1761 QString codeprimunit = getInternationalCode(primunit.getName()); 1762 QString codeunit = getInternationalCode(info.Name); 1763 if (!codeprimunit.isEmpty()) { 1764 info.Internet = codeunit % '/' % codeprimunit; 1765 info.Value = -1; 1766 1767 parentUnit = SKGUnitObject(iDocument); 1768 err = parentUnit.setSymbol(prim.Symbol); 1769 IFOKDO(err, parentUnit.load()) 1770 } 1771 } 1772 } 1773 1774 IFOKDO(err, oUnit.setName(info.Name)) 1775 if (!err && oUnit.exist()) { 1776 err = oUnit.load(); 1777 } 1778 IFOKDO(err, oUnit.setType(type)) 1779 IFOKDO(err, oUnit.setSymbol(info.Symbol)) 1780 IFOKDO(err, oUnit.setInternetCode(info.Internet)) 1781 IFOKDO(err, oUnit.setDownloadSource(info.Source)) 1782 IFOKDO(err, oUnit.setCountry(info.Country)) 1783 IFOKDO(err, oUnit.setNumberDecimal(info.NbDecimal)) 1784 if (!err && parentUnit.exist()) { 1785 err = oUnit.setUnit(parentUnit); 1786 } 1787 IFOKDO(err, oUnit.save()) 1788 1789 // Creation of the value 1790 if (info.Value > 0) { 1791 SKGUnitValueObject unitValue; 1792 IFOKDO(err, oUnit.addUnitValue(unitValue)) 1793 IFOKDO(err, unitValue.setDate(info.Date)) 1794 IFOKDO(err, unitValue.setQuantity(info.Value)) 1795 IFOKDO(err, unitValue.save()) 1796 } 1797 } 1798 return err; 1799 } 1800 1801 double SKGUnitObject::convert(double iValue, const SKGUnitObject& iUnitFrom, const SKGUnitObject& iUnitTo, QDate iDate) 1802 { 1803 double output = iValue; 1804 if (iUnitFrom != iUnitTo) { 1805 double valFrom = iUnitFrom.getAmount(iDate); 1806 double valTo = iUnitTo.getAmount(iDate); 1807 output = iValue * valFrom / valTo; 1808 } 1809 return output; 1810 } 1811 1812 SKGError SKGUnitObject::setSymbol(const QString& iSymbol) 1813 { 1814 return setAttribute(QStringLiteral("t_symbol"), iSymbol); 1815 } 1816 1817 QString SKGUnitObject::getSymbol() const 1818 { 1819 return getAttribute(QStringLiteral("t_symbol")); 1820 } 1821 1822 QString SKGUnitObject::getDownloadSource() const 1823 { 1824 return getAttribute(QStringLiteral("t_source")); 1825 } 1826 1827 SKGError SKGUnitObject::setDownloadSource(const QString& iSource) 1828 { 1829 return setAttribute(QStringLiteral("t_source"), iSource); 1830 } 1831 1832 SKGError SKGUnitObject::setNumberDecimal(int iNb) 1833 { 1834 return setAttribute(QStringLiteral("i_nbdecimal"), SKGServices::intToString(iNb)); 1835 } 1836 1837 int SKGUnitObject::getNumberDecimal() const 1838 { 1839 return SKGServices::stringToInt(getAttribute(QStringLiteral("i_nbdecimal"))); 1840 } 1841 1842 SKGError SKGUnitObject::setCountry(const QString& iCountry) 1843 { 1844 return setAttribute(QStringLiteral("t_country"), iCountry); 1845 } 1846 1847 QString SKGUnitObject::getCountry() const 1848 { 1849 return getAttribute(QStringLiteral("t_country")); 1850 } 1851 1852 SKGError SKGUnitObject::setInternetCode(const QString& iCode) 1853 { 1854 return setAttribute(QStringLiteral("t_internet_code"), iCode); 1855 } 1856 1857 QString SKGUnitObject::getInternetCode() const 1858 { 1859 return getAttribute(QStringLiteral("t_internet_code")); 1860 } 1861 1862 SKGError SKGUnitObject::setType(SKGUnitObject::UnitType iType) 1863 { 1864 SKGError err; 1865 if (getAttribute(QStringLiteral("t_type")).isEmpty() || this->getType() != iType) { 1866 // Guaranty that PRIMARY and SECONDARY is unique 1867 if (iType == PRIMARY || iType == SECONDARY) { 1868 // Set old SECONDARY as CURRENCY 1869 err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='C' WHERE t_type='2'")); 1870 1871 // Set old PRIMARY as SECONDARY 1872 if (!err && iType == PRIMARY) { 1873 err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='2' WHERE t_type='1'")); 1874 } 1875 } 1876 } 1877 IFOKDO(err, setAttribute(QStringLiteral("t_type"), (iType == CURRENCY ? QStringLiteral("C") : (iType == PRIMARY ? QStringLiteral("1") : (iType == SECONDARY ? QStringLiteral("2") : (iType == SHARE ? QStringLiteral("S") : (iType == INDEX ? QStringLiteral("I") : QStringLiteral("O")))))))) 1878 return err; 1879 } 1880 1881 SKGUnitObject::UnitType SKGUnitObject::getType() const 1882 { 1883 QString typeString = getAttribute(QStringLiteral("t_type")); 1884 return (typeString == QStringLiteral("C") ? CURRENCY : (typeString == QStringLiteral("S") ? SHARE : (typeString == QStringLiteral("1") ? PRIMARY : (typeString == QStringLiteral("2") ? SECONDARY : (typeString == QStringLiteral("I") ? INDEX : OBJECT))))); 1885 } 1886 1887 SKGError SKGUnitObject::getUnit(SKGUnitObject& oUnit) const 1888 { 1889 SKGError err; 1890 if (getDocument() != nullptr) { 1891 err = getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rd_unit_id")), oUnit); 1892 } 1893 return err; 1894 } 1895 1896 SKGError SKGUnitObject::setUnit(const SKGUnitObject& iUnit) 1897 { 1898 SKGError err; 1899 if (*this == iUnit && iUnit.getID() != 0) { 1900 err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Reference unit of a unit cannot be itself.")); 1901 } else { 1902 err = setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(iUnit.getID())); 1903 } 1904 return err; 1905 } 1906 1907 SKGError SKGUnitObject::removeUnit() 1908 { 1909 return setAttribute(QStringLiteral("rd_unit_id"), QStringLiteral("0")); 1910 } 1911 1912 SKGError SKGUnitObject::addUnitValue(SKGUnitValueObject& oUnitValue) 1913 { 1914 SKGError err; 1915 if (getID() == 0) { 1916 err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGUnitObject::addUnitValue"))); 1917 } else { 1918 oUnitValue = SKGUnitValueObject(qobject_cast<SKGDocumentBank*>(getDocument())); 1919 err = oUnitValue.setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(getID())); 1920 } 1921 return err; 1922 } 1923 1924 SKGError SKGUnitObject::simplify() 1925 { 1926 SKGListSKGObjectBase values; 1927 SKGError err = getUnitValues(values); 1928 int nb = values.count(); 1929 if (!err && (nb != 0)) { 1930 QHash<QString, SKGListSKGObjectBase> groups; 1931 1932 SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Simplify unit"), err, 2) 1933 // Build groups 1934 { 1935 SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Analyze unit"), err, nb) 1936 QDate limit1 = QDate::currentDate().addMonths(-3); 1937 QDate limit2 = QDate::currentDate().addYears(-1); 1938 QDate limit3 = QDate::currentDate().addYears(-3); 1939 for (int i = nb - 1; !err && i >= 0 ; --i) { 1940 SKGUnitValueObject v(values.at(i)); 1941 QDate date = v.getDate(); 1942 if (date >= limit1) { 1943 // No simplification ==> nothing to do 1944 } else if (date >= limit2) { 1945 // Simplification by group of 30 days 1946 QString key = limit1.addDays(30 * (limit1.daysTo(date) / 30)).toString(); 1947 SKGListSKGObjectBase group = groups[key]; 1948 group.push_back(v); 1949 groups[key] = group; 1950 1951 } else if (date >= limit3) { 1952 // Simplification by group of 2 months 1953 QString key = limit2.addDays(60 * (limit2.daysTo(date) / 60)).toString(); 1954 SKGListSKGObjectBase group = groups[key]; 1955 group.push_back(v); 1956 groups[key] = group; 1957 } else { 1958 // Simplification by group of 6 months 1959 QString key = limit3.addDays(180 * (limit2.daysTo(date) / 180)).toString(); 1960 SKGListSKGObjectBase group = groups[key]; 1961 group.push_back(v); 1962 groups[key] = group; 1963 } 1964 1965 IFOKDO(err, getDocument()->stepForward(nb - i)) 1966 } 1967 } 1968 IFOKDO(err, getDocument()->stepForward(1)) 1969 1970 // Simplify 1971 { 1972 QList<QString> keys = groups.keys(); 1973 nb = keys.count(); 1974 SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Remove useless values"), err, nb) 1975 for (int i = 0; !err && i < nb ; ++i) { 1976 const QString& k = keys.at(i); 1977 SKGListSKGObjectBase group = groups[k]; 1978 1979 // Simplify the group 1980 int nb2 = group.count(); 1981 1982 // Compute min and max 1983 double min = 10e20; 1984 double max = 0; 1985 for (int j = 0; j < nb2; ++j) { 1986 SKGUnitValueObject v1(group.at(j)); 1987 double y1 = v1.getQuantity(); 1988 min = qMin(y1, min); 1989 max = qMax(y1, max); 1990 } 1991 1992 // Simplify 1993 for (int j = 1; !err && j < nb2 - 1; ++j) { 1994 SKGUnitValueObject v1(group.at(j)); 1995 double y1 = v1.getQuantity(); 1996 if (y1 != min && y1 != max) { 1997 err = v1.remove(); 1998 } 1999 } 2000 2001 IFOKDO(err, getDocument()->stepForward(i + 1)) 2002 } 2003 } 2004 IFOKDO(err, getDocument()->stepForward(2)) 2005 } 2006 return err; 2007 } 2008 2009 SKGError SKGUnitObject::getUnitValues(SKGListSKGObjectBase& oUnitValueList) const 2010 { 2011 SKGError err = getDocument()->getObjects(QStringLiteral("v_unitvalue"), 2012 "rd_unit_id=" % SKGServices::intToString(getID()) % " ORDER BY d_date", 2013 oUnitValueList); 2014 return err; 2015 } 2016 2017 SKGError SKGUnitObject::getLastUnitValue(SKGUnitValueObject& oUnitValue) const 2018 { 2019 return SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"), 2020 "rd_unit_id=" % SKGServices::intToString(getID()) % " AND d_date=(select MAX(u2.d_date) from unitvalue u2 where u2.rd_unit_id=" % SKGServices::intToString(getID()) % ')', 2021 oUnitValue); 2022 } 2023 2024 SKGError SKGUnitObject::getUnitValue(QDate iDate, SKGUnitValueObject& oUnitValue) const 2025 { 2026 QString ids = SKGServices::intToString(getID()); 2027 QString dates = SKGServices::dateToSqlString(iDate); 2028 SKGError err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"), 2029 "rd_unit_id=" % ids % " AND d_date<='" % dates % 2030 "' AND ABS(strftime('%s','" % dates % 2031 "')-strftime('%s',d_date))=(select MIN(ABS(strftime('%s','" % dates % 2032 "')-strftime('%s',u2.d_date))) from unitvalue u2 where u2.rd_unit_id=" % ids % 2033 " AND u2.d_date<='" % dates % "')", 2034 oUnitValue); 2035 2036 // If not found then get first 2037 IFKO(err) err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"), 2038 "rd_unit_id=" % SKGServices::intToString(getID()) % " AND d_date=(select MIN(d_date) from unitvalue where rd_unit_id=" % 2039 SKGServices::intToString(getID()) % ')', 2040 oUnitValue); 2041 return err; 2042 } 2043 2044 double SKGUnitObject::getAmount(QDate iDate) const 2045 { 2046 SKGTRACEINFUNC(10) 2047 double output = 0; 2048 if (getType() == SKGUnitObject::PRIMARY) { 2049 output = 1.0; 2050 } else if (getDocument() != nullptr) { 2051 // Search result in cache 2052 QString ids = SKGServices::intToString(getID()); 2053 QString dates = SKGServices::dateToSqlString(iDate); 2054 QString key = "unitvalue-" % ids % '-' % dates; 2055 QString val = getDocument()->getCachedValue(key); 2056 if (val.isEmpty()) { 2057 // Get quantity 2058 double quantity = 1; 2059 SKGUnitValueObject uv; 2060 if (getUnitValue(iDate, uv).isSucceeded()) { 2061 quantity = uv.getQuantity(); 2062 } 2063 2064 SKGUnitObject unit; 2065 double coef = 1; 2066 if (getUnit(unit).isSucceeded()) { 2067 if (unit != *this) { 2068 coef = unit.getAmount(iDate); 2069 } 2070 } 2071 2072 output = coef * quantity; 2073 getDocument()->addValueInCache(key, SKGServices::doubleToString(output)); 2074 2075 if (getAttribute(QStringLiteral("i_NBVALUES")) == QStringLiteral("1")) { 2076 // Store value for this symbol for all date 2077 getDocument()->addValueInCache("unitvalue-" % ids, SKGServices::doubleToString(output)); 2078 } 2079 } else { 2080 output = SKGServices::stringToDouble(val); 2081 } 2082 } 2083 return output; 2084 } 2085 2086 double SKGUnitObject::getDailyChange(QDate iDate) const 2087 { 2088 double output = 0; 2089 SKGStringListList result; 2090 SKGError err = getDocument()->executeSelectSqliteOrder( 2091 "SELECT d_date, f_quantity from unitvalue where rd_unit_id=" % 2092 SKGServices::intToString(getID()) % 2093 " AND d_date<='" % SKGServices::dateToSqlString(iDate) % 2094 "' ORDER BY d_date DESC LIMIT 2", 2095 result); 2096 if (!err && result.count() == 3) { 2097 double v2 = SKGServices::stringToDouble(result.at(1).at(1)); 2098 double v1 = SKGServices::stringToDouble(result.at(2).at(1)); 2099 2100 QDate d2 = SKGServices::stringToTime(result.at(1).at(0)).date(); 2101 QDate d1 = SKGServices::stringToTime(result.at(2).at(0)).date(); 2102 2103 output = 100 * (qExp(qLn(v2 / v1) / (SKGServices::nbWorkingDays(d1, d2))) - 1); 2104 } 2105 return output; 2106 } 2107 2108 SKGError SKGUnitObject::split(double iRatio) const 2109 { 2110 SKGError err; 2111 if (iRatio > 0) { 2112 err = getDocument()->executeSqliteOrder("UPDATE unitvalue SET f_quantity=f_quantity/" % SKGServices::doubleToString(iRatio) % 2113 " WHERE rd_unit_id=" % SKGServices::intToString(getID())); 2114 IFOKDO(err, getDocument()->executeSqliteOrder("UPDATE suboperation SET f_value=f_value*" % SKGServices::doubleToString(iRatio) % 2115 " WHERE rd_operation_id IN (SELECT id FROM operation WHERE rc_unit_id=" % SKGServices::intToString(getID()) % ')')); 2116 } else { 2117 err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid ratio. Ratio must be greater than 0.")); 2118 } 2119 return err; 2120 } 2121 2122 QStringList SKGUnitObject::downloadSources() 2123 { 2124 QStringList sources; 2125 // Get sources from .txt file (old mode) TODO: Remove 2126 QString a = QStringLiteral("skrooge/quotes"); 2127 const auto list = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, a, QStandardPaths::LocateDirectory); 2128 for (const auto& dir : list) { 2129 QDirIterator it(dir, QStringList() << QStringLiteral("*.txt")); 2130 while (it.hasNext()) { 2131 QFileInfo f(it.next()); 2132 QString file2 = f.completeBaseName(); 2133 if (!sources.contains(file2)) { 2134 sources.push_back(file2); 2135 } 2136 } 2137 } 2138 2139 // Get sources from.desktop file 2140 const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source")); 2141 for (const auto& service : list2) { 2142 #ifdef SKG_KF_5102 2143 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QMetaType::QString).toString(); 2144 #else 2145 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString(); 2146 #endif 2147 if (!sources.contains(name)) { 2148 sources.push_back(name); 2149 } 2150 } 2151 sources.sort(); 2152 return sources; 2153 } 2154 2155 QString SKGUnitObject::getCommentFromSource(const QString& iSource) 2156 { 2157 QString output; 2158 const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source")); 2159 for (const auto& service : list2) { 2160 #ifdef SKG_KF_5102 2161 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QMetaType::QString).toString(); 2162 if (name == iSource) { 2163 output = service->property(QStringLiteral("Comment"), QMetaType::QString).toString(); 2164 #else 2165 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString(); 2166 if (name == iSource) { 2167 output = service->property(QStringLiteral("Comment"), QVariant::String).toString(); 2168 #endif 2169 break; 2170 } 2171 } 2172 return output; 2173 } 2174 2175 SKGError SKGUnitObject::addSource(const QString& iNewSource, bool iOpenSource) 2176 { 2177 SKGError err; 2178 2179 QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); 2180 QDir(path).mkpath(QStringLiteral("skrooge/quotes/")); 2181 2182 QString newfile = path + "/skrooge/quotes/" % iNewSource % ".txt"; 2183 2184 // Create the new file 2185 QSaveFile file(newfile); 2186 // Check if file already existing 2187 if (!QFile(newfile).exists()) { 2188 // Creation of the template 2189 if (!file.open(QIODevice::WriteOnly)) { 2190 err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", newfile)); 2191 } else { 2192 QTextStream out(&file); 2193 2194 out << "#" << i18nc("Description test for a text file used to define a source of download", 2195 "The URL or the SCRIPT of the source. %1 will be replaced by the internet code of the unit", "%1") << SKGENDL; 2196 out << "#" << i18nc("Description test for a text file used to define a source of download", 2197 "%1 will be replaced by the current day in format yyyy-MM-dd", "%2") << SKGENDL; 2198 out << "#" << i18nc("Description test for a text file used to define a source of download", 2199 "%1 will be replaced by the previous date in format yyyy-MM-dd", "%3") << SKGENDL; 2200 out << "url=https://server/?s=%1" << SKGENDL; 2201 out << "or" << SKGENDL; 2202 out << "script=mydownloadscript %1" << SKGENDL << SKGENDL; 2203 2204 2205 out << "#" << i18nc("Description test for a text file used to define a source of download", 2206 "The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode.") << SKGENDL; 2207 out << "mode=CSV, CSVR or or HTML" << SKGENDL << SKGENDL; 2208 2209 out << "#" << i18nc("Description test for a text file used to define a source of download", 2210 "The regular expression for the price (see %1)", "https://doc.qt.io/qt-5/qregularexpression.html") << SKGENDL; 2211 out << "price=" << SKGENDL << SKGENDL; 2212 2213 out << "#" << i18nc("Description test for a text file used to define a source of download", 2214 "The regular expression for the date (see %1)", "https://doc.qt.io/qt-5/qregularexpression.html") << SKGENDL; 2215 out << "date=" << SKGENDL << SKGENDL; 2216 2217 out << "#" << i18nc("Description test for a text file used to define a source of download", 2218 "The format of the date (see %1) or \"UNIX\" for unix time", "https://doc.qt.io/qt-5/qdate.html#fromString-1") << SKGENDL; 2219 out << "dateformat=yyyy-MM-dd" << SKGENDL; 2220 2221 // Close file 2222 file.commit(); 2223 } 2224 } 2225 2226 // Open the created or already existing file 2227 if (iOpenSource) { 2228 QDesktopServices::openUrl(QUrl::fromLocalFile(newfile)); 2229 } 2230 return err; 2231 } 2232 2233 SKGError SKGUnitObject::deleteSource(const QString& iSource) 2234 { 2235 SKGError err; 2236 2237 QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt"; 2238 2239 // Delete the file 2240 QFile file(fileName); 2241 if (!file.remove()) { 2242 err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Deletion of '%1' failed", fileName)); 2243 } 2244 return err; 2245 } 2246 2247 bool SKGUnitObject::isWritable(const QString& iSource) 2248 { 2249 QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt"; 2250 return QFileInfo(fileName).isWritable(); 2251 } 2252 2253 SKGError SKGUnitObject::downloadUnitValue(UnitDownloadMode iMode, int iNbMaxValues) 2254 { 2255 SKGError err; 2256 SKGTRACEINFUNCRC(10, err) 2257 2258 QString unitname = getName(); 2259 QString code = getInternetCode(); 2260 bool invert = code.contains(QStringLiteral(" /")); 2261 code.remove(QStringLiteral(" /")); 2262 QString source = getDownloadSource(); 2263 auto* doc = qobject_cast<SKGDocumentBank*>(getDocument()); 2264 if (!code.trimmed().isEmpty() && (doc != nullptr)) { 2265 // Get last date 2266 QDate firstDate; 2267 SKGStringListList result; 2268 doc->executeSelectSqliteOrder("SELECT MAX(d_date) FROM unitvalue where rd_unit_id=" % SKGServices::intToString(getID()), result); 2269 if (result.count() == 2) { 2270 firstDate = SKGServices::stringToTime(result.at(1).at(0)).date().addDays(-1); 2271 } 2272 2273 if (code.startsWith(QLatin1String("="))) { 2274 // MODE FORMULAR 2275 // Set 1st january if date is not found 2276 if (!firstDate.isValid()) { 2277 firstDate.setDate(QDate::currentDate().year(), 1, 1); 2278 } 2279 2280 // Compute yearly rate 2281 double rate = SKGServices::stringToDouble(code.right(code.length() - 1)); 2282 2283 // Compute rate for step 2284 double step = (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY ? 12.0 : (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY ? 365.0 / 7.0 : 365)); 2285 double rate2 = 100.0 * (qExp(qLn(1 + rate / 100.0) / step) - 1.0); 2286 2287 // Get last value 2288 SKGStringListList result2; 2289 double value = 100; 2290 doc->executeSelectSqliteOrder("SELECT f_quantity FROM unitvalue where rd_unit_id=(SELECT id from unit where t_name='" % SKGServices::stringToSqlString(unitname) % "') AND d_date='" % SKGServices::dateToSqlString(firstDate) % '\'', result2); 2291 if (result2.count() == 2) { 2292 value = SKGServices::stringToDouble(result2.at(1).at(0)); 2293 } 2294 2295 // Compute and add values 2296 while (!err && firstDate <= QDate::currentDate()) { 2297 // Compute next date and value 2298 if (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY) { 2299 firstDate = firstDate.addMonths(1); 2300 } else if (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY) { 2301 firstDate = firstDate.addDays(7); 2302 } else { 2303 firstDate = firstDate.addDays(1); 2304 } 2305 2306 value *= (1 + rate2 / 100.0); 2307 2308 // Create value 2309 SKGUnitValueObject val; 2310 err = addUnitValue(val); 2311 IFOKDO(err, val.setDate(firstDate)) 2312 IFOKDO(err, val.setQuantity(value)) 2313 IFOKDO(err, val.save()) 2314 } 2315 } else if (!source.trimmed().isEmpty()) { 2316 // Quote download 2317 2318 // Set 1st january 1970 if date is not found 2319 if (!firstDate.isValid()) { 2320 firstDate.setDate(1970, 1, 1); 2321 } 2322 2323 QString interval = QStringLiteral("1d"); 2324 bool last = (iMode == LAST); 2325 if (last) { 2326 interval = QStringLiteral("1d"); 2327 } else if (iMode == LAST_MONTHLY) { 2328 interval = QStringLiteral("1mo"); 2329 } else if (iMode == LAST_WEEKLY) { 2330 interval = QStringLiteral("1wk"); 2331 } else if (iMode == LAST_DAILY) { 2332 interval = QStringLiteral("1d"); 2333 } else if (iMode == ALL_MONTHLY) { 2334 firstDate = QDate(1970, 01, 01); 2335 interval = QStringLiteral("1mo"); 2336 } else if (iMode == ALL_WEEKLY) { 2337 firstDate = QDate(1970, 01, 01); 2338 interval = QStringLiteral("1wk"); 2339 } else if (iMode == ALL_DAILY) { 2340 firstDate = QDate(1970, 01, 01); 2341 interval = QStringLiteral("1d"); 2342 } 2343 2344 bool modeScript = false; 2345 QString path; 2346 QString mode; 2347 QString price; 2348 QString date; 2349 QString dateFormat; 2350 QString apiKey; 2351 QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt"); 2352 if (fileName.isEmpty()) { 2353 const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source")); 2354 for (const auto& service : list2) { 2355 #ifdef SKG_KF_5102 2356 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QMetaType::QString).toString(); 2357 if (name == source) { 2358 path = service->property(QStringLiteral("X-SKROOGE-url"), QMetaType::QString).toString(); 2359 if (path.isEmpty()) { 2360 path = service->property(QStringLiteral("X-SKROOGE-script"), QMetaType::QString).toString(); 2361 modeScript = true; 2362 } 2363 2364 mode = service->property(QStringLiteral("X-SKROOGE-mode"), QMetaType::QString).toString().toUpper(); 2365 price = service->property(QStringLiteral("X-SKROOGE-price"), QMetaType::QString).toString().replace(QStringLiteral("%1"), code); 2366 date = service->property(QStringLiteral("X-SKROOGE-date"), QMetaType::QString).toString().replace(QStringLiteral("%1"), code); 2367 dateFormat = service->property(QStringLiteral("X-SKROOGE-dateformat"), QMetaType::QString).toString(); 2368 if (service->property(QStringLiteral("X-SKROOGE-keyAPI"), QMetaType::Bool).toBool()) { 2369 apiKey = getDocument()->getParameter("KEYAPI_" + source); 2370 } 2371 break; 2372 } 2373 #else 2374 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString(); 2375 if (name == source) { 2376 path = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString(); 2377 if (path.isEmpty()) { 2378 path = service->property(QStringLiteral("X-SKROOGE-script"), QVariant::String).toString(); 2379 modeScript = true; 2380 } 2381 2382 mode = service->property(QStringLiteral("X-SKROOGE-mode"), QVariant::String).toString().toUpper(); 2383 price = service->property(QStringLiteral("X-SKROOGE-price"), QVariant::String).toString().replace(QStringLiteral("%1"), code); 2384 date = service->property(QStringLiteral("X-SKROOGE-date"), QVariant::String).toString().replace(QStringLiteral("%1"), code); 2385 dateFormat = service->property(QStringLiteral("X-SKROOGE-dateformat"), QVariant::String).toString(); 2386 if (service->property(QStringLiteral("X-SKROOGE-keyAPI"), QVariant::Bool).toBool()) { 2387 apiKey = getDocument()->getParameter("KEYAPI_" + source); 2388 } 2389 break; 2390 } 2391 #endif 2392 } 2393 if (path.isEmpty()) { 2394 err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source)); 2395 } 2396 } else { 2397 // Read source file from .txt file 2398 QHash< QString, QString > properties; 2399 err = SKGServices::readPropertyFile(fileName, properties); 2400 IFOK(err) { 2401 path = properties[QStringLiteral("url")]; 2402 if (path.isEmpty()) { 2403 path = properties[QStringLiteral("script")]; 2404 modeScript = true; 2405 } 2406 mode = properties[QStringLiteral("mode")].toUpper(); 2407 price = properties[QStringLiteral("price")].replace(QStringLiteral("%1"), code); 2408 date = properties[QStringLiteral("date")].replace(QStringLiteral("%1"), code); 2409 dateFormat = properties[QStringLiteral("dateformat")]; 2410 } else { 2411 doc->sendMessage(i18nc("An information message", "Open url '%1' failed", path), SKGDocument::Warning); 2412 } 2413 } 2414 2415 IFOK(err) { 2416 path = path.replace(QStringLiteral("%1"), code); 2417 path = path.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))); 2418 path = path.replace(QStringLiteral("%3"), firstDate.toString(QStringLiteral("yyyy-MM-dd"))); 2419 path = path.replace(QStringLiteral("%4"), interval); 2420 path = path.replace(QStringLiteral("%5"), apiKey); 2421 2422 SKGTRACEL(1) << "path=[" << path << "]" << SKGENDL; 2423 SKGTRACEL(1) << "mode=[" << mode << "]" << SKGENDL; 2424 SKGTRACEL(1) << "price=[" << price << "]" << SKGENDL; 2425 SKGTRACEL(1) << "date=[" << date << "]" << SKGENDL; 2426 SKGTRACEL(1) << "dateFormat=[" << dateFormat << "]" << SKGENDL; 2427 2428 // Download url 2429 QByteArray stream; 2430 if (modeScript) { 2431 path = SKGServices::getFullPathCommandLine(path); 2432 SKGTRACEL(1) << "full path=[" << path << "]" << SKGENDL; 2433 2434 QProcess p; 2435 p.start(QStringLiteral("/bin/bash"), QStringList() << QStringLiteral("-c") << path); 2436 if (p.waitForFinished(1000 * 60 * 2) && p.exitCode() == 0) { 2437 stream = p.readAllStandardOutput(); 2438 } else { 2439 err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", path, p.exitCode())); 2440 } 2441 } else { 2442 SKGServices::downloadToStream(QUrl::fromUserInput(path), stream); 2443 } 2444 if (!err && !stream.isEmpty()) { 2445 SKGTRACEL(1) << "stream=[" << stream << "]" << SKGENDL; 2446 2447 // Parse data 2448 QRegularExpression priceRegExp(price, QRegularExpression::CaseInsensitiveOption); 2449 QRegularExpression dateRegExp(date, QRegularExpression::CaseInsensitiveOption); 2450 2451 QStringList lines = (mode.startsWith(QLatin1String("CSV")) ? SKGServices::splitCSVLine(stream, '\n') : QStringList() << QLatin1String("") << stream); 2452 int nb = lines.count(); 2453 int nbLoaded = 0; 2454 for (int i = 1; i < nb && !err && (i < iNbMaxValues || iNbMaxValues == 0); ++i) { 2455 QString data = lines.at(mode == QStringLiteral("CSVR") ? nb - i : i).trimmed(); 2456 if (!data.isEmpty()) { 2457 SKGTRACEL(1) << "Downloaded data from [" << path << "]=[" << data << "]" << SKGENDL; 2458 2459 double val = 0.0; 2460 auto match = priceRegExp.match(data); 2461 if (match.hasMatch()) { 2462 val = SKGServices::stringToDouble(match.captured(1)); 2463 } 2464 QString date2; 2465 match = dateRegExp.match(data); 2466 if (match.hasMatch()) { 2467 date2 = match.captured(1); 2468 } 2469 SKGTRACEL(1) << "Price found=[" << val << "]" << SKGENDL; 2470 SKGTRACEL(1) << "Date found=[" << date2 << "]" << SKGENDL; 2471 2472 // Set value 2473 if (val != 0.0) { 2474 QDate ds; 2475 if (dateFormat == QStringLiteral("UNIX")) { 2476 ds = QDateTime::fromTime_t(SKGServices::stringToInt(date2)).date(); 2477 } else { 2478 ds = QDate::fromString(date2, dateFormat); 2479 // Try with an english locale 2480 if (!ds.isValid()) { 2481 QLocale en(QStringLiteral("en_EN")); 2482 ds = en.toDate(date2, dateFormat); 2483 } 2484 } 2485 2486 if (!ds.isValid()) { 2487 ds = QDate::currentDate(); 2488 SKGTRACE << "WARNING:" << date2 << " not well parsed with format " << dateFormat << SKGENDL; 2489 } 2490 if (!dateFormat.contains(QStringLiteral("yyyy")) && ds.year() < 2000) { 2491 ds = ds.addYears(100); 2492 } 2493 2494 // Creation or update of the value 2495 SKGUnitValueObject value; 2496 IFOKDO(err, addUnitValue(value)) 2497 IFOKDO(err, value.setDate(ds)) 2498 IFOKDO(err, value.setQuantity(invert && val != 0 ? 1 / val : val)) 2499 IFOKDO(err, value.save()) 2500 2501 if (last) { 2502 break; 2503 } 2504 2505 nbLoaded++; 2506 } 2507 } 2508 if (nbLoaded == 0 && !data.isEmpty()) { 2509 err = doc->sendMessage(i18nc("Information message", "Price not found for '%1' with regular expression '%2' in line '%3'", getName(), SKGServices::stringToHtml(price), data), SKGDocument::Warning); // TODO(Stephane MANKOWSKI) does not work with html 2510 } 2511 } 2512 } 2513 } 2514 } 2515 } 2516 2517 IFKO(err) { 2518 err.addError(ERR_FAIL, i18nc("Error message", "Impossible to download unit %1 with Internet code %2 on the source %3.", unitname, code, source)); 2519 } 2520 2521 return err; 2522 } 2523 2524 SKGError SKGUnitObject::getUrl(QUrl& oUrl) const 2525 { 2526 SKGError err; 2527 SKGTRACEINFUNCRC(10, err) 2528 2529 QString url; 2530 QString code = getInternetCode(); 2531 code.remove(QStringLiteral(" /")); 2532 QString source = getDownloadSource(); 2533 if (!code.isEmpty()) { 2534 if (code.startsWith(QLatin1String("="))) { 2535 // MODE FORMULAR 2536 2537 } else { 2538 // ALTERNATIVE MODE 2539 QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt"); 2540 if (fileName.isEmpty()) { 2541 const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source")); 2542 for (const auto& service : list2) { 2543 #ifdef SKG_KF_5102 2544 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QMetaType::QString).toString(); 2545 if (name == source) { 2546 url = service->property(QStringLiteral("X-SKROOGE-url"), QMetaType::QString).toString().replace(QStringLiteral("%1"), code); 2547 #else 2548 auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString(); 2549 if (name == source) { 2550 url = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString().replace(QStringLiteral("%1"), code); 2551 #endif 2552 url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))); 2553 url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd"))); 2554 break; 2555 } 2556 } 2557 if (url.isEmpty()) { 2558 err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source)); 2559 } 2560 } else { 2561 // Read source file 2562 QHash< QString, QString > properties; 2563 err = SKGServices::readPropertyFile(fileName, properties); 2564 2565 IFOK(err) { 2566 url = properties[QStringLiteral("url")].replace(QStringLiteral("%1"), code); 2567 url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))); 2568 url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd"))); 2569 } 2570 } 2571 } 2572 } 2573 2574 IFOK(err) { 2575 oUrl = QUrl(url); 2576 } 2577 2578 return err; 2579 } 2580 2581 SKGError SKGUnitObject::openURL() const 2582 { 2583 QUrl url; 2584 SKGError err = getUrl(url); 2585 2586 IFKO(err) { 2587 err.addError(ERR_FAIL, i18nc("Error message", "Impossible to open unit %1 with Internet code %2.", getName(), getInternetCode())); 2588 } else { 2589 QDesktopServices::openUrl(url); 2590 } 2591 2592 return err; 2593 } 2594 2595 SKGError SKGUnitObject::getOperations(SKGObjectBase::SKGListSKGObjectBase& oOperations) const 2596 { 2597 SKGError err = getDocument()->getObjects(QStringLiteral("v_operation"), 2598 "rc_unit_id=" % SKGServices::intToString(getID()), 2599 oOperations); 2600 return err; 2601 } 2602 2603 SKGError SKGUnitObject::merge(const SKGUnitObject& iUnit) 2604 { 2605 SKGError err; 2606 2607 SKGObjectBase::SKGListSKGObjectBase ops; 2608 IFOKDO(err, iUnit.getOperations(ops)) 2609 int nb = ops.count(); 2610 for (int i = 0; !err && i < nb; ++i) { 2611 SKGOperationObject op(ops.at(i)); 2612 err = op.setUnit(*this); 2613 IFOKDO(err, op.save(true, false)) 2614 } 2615 2616 IFOKDO(err, iUnit.remove(false)) 2617 return err; 2618 }