();
+ for (auto i = 0; i < nb; ++i) {
+ // Get Current value
+ auto ln = new QLineEdit(w);
+ ln->setText(m_currentBankDocument->getParameter("KEYAPI_" + sources[i]));
+ lwidgets->insert(sources.value(i), ln);
+
+ ui.kAPIKeyLayout->addWidget(new QLabel(sources[i] + ':', w), i, 0);
+ ui.kAPIKeyLayout->addWidget(ln, i, 1);
+ }
+
connect(ui.kcfg_download_on_open, &QCheckBox::toggled, ui.kcfg_download_frequency, &KComboBox::setEnabled);
+ connect(ui.kSave, &QPushButton::clicked, this, [ = ]() {
+ SKGError err;
+ {
+ SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Save API keys"), err)
+ foreach (auto k, lwidgets->keys()) {
+ m_currentBankDocument->setParameter("KEYAPI_" + k, lwidgets->value(k)->text());
+ }
+ }
+ // Display error
+ SKGMainPanel::displayErrorMessage(err);
+ });
return w;
}
KConfigSkeleton* SKGUnitPlugin::getPreferenceSkeleton()
{
return skgunit_settings::self();
}
QString SKGUnitPlugin::title() const
{
return i18nc("Noun, units for operations, usually currencies or a shares", "Units");
}
QString SKGUnitPlugin::icon() const
{
return QStringLiteral("taxes-finances");
}
QString SKGUnitPlugin::toolTip() const
{
return i18nc("A tool tip", "Unit management");
}
QStringList SKGUnitPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "... you can download units.
"));
output.push_back(i18nc("Description of a tips", "... units can be downloaded automatically when a document is opened.
"));
output.push_back(i18nc("Description of a tips", "... you can split a share.
"));
output.push_back(i18nc("Description of a tips", "... units can be merged by drag & drop.
"));
output.push_back(i18nc("Description of a tips", "... you can download more sources of quote.
"));
output.push_back(i18nc("Description of a tips", "... you can create and share your own source of quote.
"));
return output;
}
int SKGUnitPlugin::getOrder() const
{
return 60;
}
bool SKGUnitPlugin::isInPagesChooser() const
{
return true;
}
void SKGUnitPlugin::onSplitShare()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb == 1) {
bool ok = false;
double ratio = QInputDialog::getDouble(SKGMainPanel::getMainPanel(), i18nc("Question", "Split share"),
i18nc("Question", "Ratio (2 means 2-for-1, 0.5 means 1-for-2):"), 2.0,
0, std::numeric_limits::max(), 8, &ok);
if (ok) {
SKGUnitObject unit(selection.at(0));
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Split stock '%1' by '%2'", unit.getName(), ratio), err)
IFOKDO(err, unit.split(ratio))
}
}
// status
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Stock split.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Splitting stock failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
SKGAdviceList SKGUnitPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
output.reserve(20);
// Get all currencies
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT (SELECT count(1) FROM operation WHERE operation.rc_unit_id=unit.id), unit.t_name FROM unit WHERE t_type='C' GROUP BY t_name ORDER BY count(1) DESC"), result);
int nb = result.count();
// Check primary unit
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_primaryunit"))) {
if (m_currentBankDocument->getPrimaryUnit().Name.isEmpty() && nb > 1) {
// Get unit
QString unit = result.at(1).at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_primaryunit|" % unit);
ad.setPriority(8);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a primary currency"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "To avoid misunderstanding and conflicts between units at conversion time, you should define a primary currency. It is the currency against which all other will be converted"));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Set '%1' as primary currency", unit);
a.IconName = icon();
a.IsRecommended = true;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
--nb;
}
}
// Check secondary unit
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_secondaryunit"))) {
if (m_currentBankDocument->getSecondaryUnit().Name.isEmpty() && nb > 1) {
// Get unit
QString unit = result.at(1).at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_secondaryunit|" % unit);
ad.setPriority(2);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a secondary currency"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "When a secondary unit is defined, Skrooge will display it as an additional amount information."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Set '%1' as secondary currency", unit);
a.IconName = icon();
a.IsRecommended = true;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Shares not downloaded
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_notdownloaded"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name, t_internet_code from unit WHERE t_internet_code<>'' AND (julianday('now')-(SELECT MAX(julianday(d_date)) FROM unitvalue WHERE rd_unit_id=unit.id ))>30 OR NOT EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
const QString& internet_code = line.at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_notdownloaded|" % unit);
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has not been downloaded for more than a month", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget download units to have a better view of your accounts"));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
if (!internet_code.isEmpty()) {
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Download '%1'", unit);
a.IconName = QStringLiteral("download");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unused units
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_unused"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_unused"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused units"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing units for which no operation is registered."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://clean_delete_unused_units"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unit too complex
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_amountnotdefined"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_unit WHERE t_type IN ('2','C') AND f_CURRENTAMOUNT=1"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID("skgunitplugin_amountnotdefined|" % unit);
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "The amount of the unit '%1' is not defined", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' has an amount defined at 1. Most of the time this is not normal and causes wrong computation. Check if this is normal.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unit too complex
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_toocomplex"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT A.t_name FROM unit A, unit B, unit C, unit D WHERE A.rd_unit_id=B.id AND B.rd_unit_id=C.id AND C.rd_unit_id=D.id"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_toocomplex"));
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "The definition of the unit '%1' is too complex", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' is defined relatively to another unit defined relatively to a third one. This is too complex and not supported by Skrooge.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Unit with very old values
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_veryold"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name from unit WHERE (SELECT COUNT(*) FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)>1 AND EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id AND unitvalue.d_date<=(SELECT date('now', '-50 year')))"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID("skgunitplugin_veryold|" % unit);
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has very old values", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Unit '%1' has very old values. Check if this is normal.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// No decimal settings
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_decimalsymbol")) && QLocale().decimalPoint().isNull()) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_decimalsymbol"));
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "No decimal symbol defined"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "In KDE localization settings, there is no decimal symbol defined for currencies. This could be confusing."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit KDE settings");
a.IconName = QStringLiteral("configure");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
return output;
}
SKGError SKGUnitPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_primaryunit|"))) {
if (iSolution == 1) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 26);
SKGError err;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define primary currency"), err)
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, unitObj.setType(SKGUnitObject::PRIMARY))
IFOKDO(err, unitObj.save())
// Send message
IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the primary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Primary currency defined.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Primary currency definition failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_secondaryunit|"))) {
if (iSolution == 1) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);
SKGError err;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define secondary currency"), err)
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, unitObj.setType(SKGUnitObject::SECONDARY))
IFOKDO(err, unitObj.save())
// Send message
IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the secondary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Secondary currency defined.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Secondary currency definition failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_notdownloaded|"))) {
if (iSolution == 0) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);
SKGError err;
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, SKGUnitPluginWidget::downloadUnitValue(unitObj, SKGUnitPluginWidget::getDownloadModeFromSettings()))
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && (iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_veryold|")) ||
iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_toocomplex")) ||
iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_amountnotdefined|")))
) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_decimalsymbol"))) {
QProcess::execute(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("formats"));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGUnitPlugin::deleteUnusedUnits() const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused units"), err)
// Modification of payee object
QString sql = QStringLiteral("DELETE FROM unit WHERE t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)");
err = m_currentBankDocument->executeSqliteOrder(sql);
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused units deleted")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Unused units deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
#include
diff --git a/plugins/skrooge/skrooge_unit/skgunitpluginwidget_pref.ui b/plugins/skrooge/skrooge_unit/skgunitpluginwidget_pref.ui
index 8ee9c3990..47ce22990 100644
--- a/plugins/skrooge/skrooge_unit/skgunitpluginwidget_pref.ui
+++ b/plugins/skrooge/skrooge_unit/skgunitpluginwidget_pref.ui
@@ -1,197 +1,236 @@
skgunitplugin_pref
0
0
- 328
- 334
+ 596
+ 542
-
2
-
Download on open
-
false
-
Once a day
-
Once a week
-
Once a month
-
Qt::Horizontal
40
20
-
Download mode
2
-
Last &value found only
-
&Monthly values since last download
-
Wee&kly values since last download
-
Dail&y values since last download
-
Monthly values for all dates
-
Weekly values for all dates
-
Daily values for all dates
-
2
-
Maximum num&ber of imported values:
kcfg_nb_loaded_values
-
50
-
Qt::Horizontal
40
20
+ -
+
+
+ API Keys
+
+
+
-
+
+
+ <html><head/><body><p>Some download sources (e.g. coinmarketcap, cryptocompare) may require an API key. So you need to request one from the source site and enter it here:</p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+ 2
+
+
+
+ -
+
+
+ For security reasons, these keys are not save in setting file but in your document.
+
+
+ Save in document
+
+
+ true
+
+
+
+
+
+
-
Qt::Vertical
20
44
KComboBox
QComboBox
kcfg_download_on_open
kcfg_download_frequency
kcfg_last
kcfg_last_monthly
kcfg_last_weekly
kcfg_last_daily
kcfg_all_monthly
kcfg_all_weekly
kcfg_all_daily
kcfg_nb_loaded_values
diff --git a/skgbankmodeler/CMakeLists.txt b/skgbankmodeler/CMakeLists.txt
index 2200064f5..1adb57f01 100644
--- a/skgbankmodeler/CMakeLists.txt
+++ b/skgbankmodeler/CMakeLists.txt
@@ -1,62 +1,63 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU General Public License as published by *
#* the Free Software Foundation; either version 2 of the License, or *
#* (at your option) any later version. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU General Public License for more details. *
#* *
#* You should have received a copy of the GNU General Public License *
#* along with this program. If not, see *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKMODELER ::..")
PROJECT(SKGBANKMODELER)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skgbankmodeler_SRCS
skgbankobject.cpp
skgbudgetobject.cpp
skgbudgetruleobject.cpp
skgaccountobject.cpp
skgoperationobject.cpp
skgrecurrentoperationobject.cpp
skgtrackerobject.cpp
skgpayeeobject.cpp
skgsuboperationobject.cpp
skgcategoryobject.cpp
skgunitobject.cpp
skgunitvalueobject.cpp
skgruleobject.cpp
skginterestobject.cpp
skgdocumentbank.cpp
skgimportexportmanager.cpp
skgimportplugin.cpp
skgreportbank.cpp
)
#build a shared library
ADD_LIBRARY(skgbankmodeler SHARED ${skgbankmodeler_SRCS})
#need to link to some other libraries ? just add them here
TARGET_LINK_LIBRARIES(skgbankmodeler LINK_PUBLIC KF5::Parts Qt5::Xml skgbasemodeler)
SET_TARGET_PROPERTIES( skgbankmodeler PROPERTIES VERSION ${SKG_VERSION} SOVERSION ${SOVERSION} )
GENERATE_EXPORT_HEADER(skgbankmodeler BASE_NAME skgbankmodeler)
ADD_SUBDIRECTORY(currency)
########### install files ###############
INSTALL(TARGETS skgbankmodeler ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP)
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-source-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(DIRECTORY sources DESTINATION ${KDE_INSTALL_KSERVICES5DIR} FILES_MATCHING PATTERN "*.desktop")
INSTALL(PROGRAMS skrooge-yahoodl.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
INSTALL(PROGRAMS skrooge-ratesapi.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
INSTALL(PROGRAMS skrooge-cryptocompare.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
+INSTALL(PROGRAMS skrooge-coinmarketcap.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
diff --git a/skgbankmodeler/skgunitobject.cpp b/skgbankmodeler/skgunitobject.cpp
index 1298584a5..20d5b2444 100644
--- a/skgbankmodeler/skgunitobject.cpp
+++ b/skgbankmodeler/skgunitobject.cpp
@@ -1,2578 +1,2582 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see *
***************************************************************************/
/** @file
* This file defines classes SKGUnitObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitobject.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitvalueobject.h"
SKGUnitObject::SKGUnitObject() : SKGUnitObject(nullptr)
{}
SKGUnitObject::SKGUnitObject(SKGDocument* iDocument, int iID) : SKGNamedObject(iDocument, QStringLiteral("v_unit"), iID)
{}
SKGUnitObject::~SKGUnitObject()
= default;
SKGUnitObject::SKGUnitObject(const SKGUnitObject& iObject) = default;
SKGUnitObject::SKGUnitObject(const SKGNamedObject& iObject)
{
if (iObject.getRealTable() == QStringLiteral("unit")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID());
}
}
SKGUnitObject::SKGUnitObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("unit")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID());
}
}
SKGUnitObject& SKGUnitObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
QString SKGUnitObject::getWhereclauseId() const
{
QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method
if (output.isEmpty()) {
QString name = getName();
if (!name.isEmpty()) {
output = "t_name='" % SKGServices::stringToSqlString(name) % '\'';
}
QString symbol = getSymbol();
if (!symbol.isEmpty()) {
if (!output.isEmpty()) {
output += QStringLiteral(" OR ");
}
output += "t_symbol='" % SKGServices::stringToSqlString(symbol) % '\'';
}
if (!output.isEmpty()) {
output = '(' % output % ')';
}
}
return output;
}
QList SKGUnitObject::currencies;
QStringList SKGUnitObject::getListofKnownCurrencies(bool iIncludingObsolete)
{
SKGTRACEINFUNC(10)
if (currencies.isEmpty()) {
// Search currencies
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/"), QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
auto listDesktopFiles = QDir(dir).entryList(QStringList() << QStringLiteral("*.desktop"));
for (const auto& path : qAsConst(listDesktopFiles)) {
// Read the file
QFileInfo file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/") + path));
KConfig cgFile(file.absoluteFilePath());
KConfigGroup cg(&cgFile, QStringLiteral("Currency Code"));
SKGServices::SKGUnitInfo unit;
unit.Name = cg.readEntry(QStringLiteral("Name"), QString()) + QStringLiteral(" (") + cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), QString()) + QStringLiteral(")");
unit.Symbol = cg.readEntry(QStringLiteral("CurrencyUnitSymbolDefault"), QString());
if (unit.Symbol.isEmpty()) {
unit.Symbol = cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), file.baseName());
}
unit.Value = 1;
unit.NbDecimal = cg.readEntry(QStringLiteral("CurrencyDecimalPlacesDisplay"), 2);
unit.Source = QStringLiteral("GrandTrunk");
unit.Date = cg.readEntry(QStringLiteral("CurrencyIntroducedDate"), QDate::currentDate());
unit.Obsolete = (cg.readEntry(QStringLiteral("CurrencySuspendedDate"), cg.readEntry(QStringLiteral("CurrencyWithdrawnDate"), QDate())) != QDate());
currencies.push_back(unit);
}
}
// Add other units
{
// CAC40
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "CAC 40");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "France");
info.Date = QDate(1987, 1, 1);
info.Internet = QStringLiteral("^FCHI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// NASDAQ
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "NASDAQ");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1971, 2, 5);
info.Internet = QStringLiteral("^IXIC");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// Dow Jones
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "Dow Jones (DJIA)");
info.Symbol = QStringLiteral("DJIA");
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1884, 1, 1);
info.Internet = QStringLiteral("^DJI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// SBF 120
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "SBF 120");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "France");
info.Date = QDate(1990, 12, 31);
info.Internet = QStringLiteral("^SBF120");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// S&P 500
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "S&P 500");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^GSPC");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// FTSE 100
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "FTSE 100");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "England");
info.Date = QDate(1984, 1, 3);
info.Internet = QStringLiteral("^FTSE");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// DAX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "DAX");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "Germany");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^GDAXI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// NIKKEI 225
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "NIKKEI 225");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "Japan");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^N225");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// HANG SENG
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "HANG SENG");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "China");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^HSI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// STRAITS TIMES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "STRAITS TIMES");
info.Symbol = info.Name;
info.Date = QDate(1920, 1, 1);
info.Country = i18nc("Noun, a country", "Singapore");
info.Internet = QStringLiteral("^STI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "Bitcoin");
info.Symbol = QStringLiteral("BTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHEREUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethereum");
info.Symbol = QStringLiteral("ETH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RIPPLE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ripple");
info.Symbol = QStringLiteral("XRP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XRP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN-CASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Cash");
info.Symbol = QStringLiteral("BCH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CARDANO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Cardano");
info.Symbol = QStringLiteral("ADA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ADA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "NEM");
info.Symbol = QStringLiteral("XEM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XEM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// LITECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Litecoin");
info.Symbol = QStringLiteral("LTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STELLAR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Stellar");
info.Symbol = QStringLiteral("XLM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XLM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// IOTA
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "IOTA");
info.Symbol = QStringLiteral("MIOTA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MIOTA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TRON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "TRON");
info.Symbol = QStringLiteral("TRX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("TRX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dash");
info.Symbol = QStringLiteral("DASH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DASH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "NEO");
info.Symbol = QStringLiteral("NEO");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NEO");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MONERO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Monero");
info.Symbol = QStringLiteral("XMR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XMR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// EOS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "EOS");
info.Symbol = QStringLiteral("EOS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("EOS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QTUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Qtum");
info.Symbol = QStringLiteral("QTUM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QTUM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ICON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ICON");
info.Symbol = QStringLiteral("ICX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ICX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN-GOLD
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Gold");
info.Symbol = QStringLiteral("BTG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// LISK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Lisk");
info.Symbol = QStringLiteral("LSK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LSK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RAIBLOCKS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "RaiBlocks");
info.Symbol = QStringLiteral("XRB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XRB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHEREUM-CLASSIC
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethereum Classic");
info.Symbol = QStringLiteral("ETC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VERGE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Verge");
info.Symbol = QStringLiteral("XVG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XVG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SIACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Siacoin");
info.Symbol = QStringLiteral("SC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// OMISEGO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "OmiseGO");
info.Symbol = QStringLiteral("OMG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("OMG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTECOIN-BCN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bytecoin");
info.Symbol = QStringLiteral("BCN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCONNECT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitConnect");
info.Symbol = QStringLiteral("BCC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POPULOUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Populous");
info.Symbol = QStringLiteral("PPT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PPT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STRATIS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Stratis");
info.Symbol = QStringLiteral("STRAT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("STRAT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ZCASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Zcash");
info.Symbol = QStringLiteral("ZEC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ZEC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DENTACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dentacoin");
info.Symbol = QStringLiteral("DCN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DCN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITSHARES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitShares");
info.Symbol = QStringLiteral("BTS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BINANCE-COIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Binance Coin");
info.Symbol = QStringLiteral("BNB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BNB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DOGECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dogecoin");
info.Symbol = QStringLiteral("DOGE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DOGE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STATUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Status");
info.Symbol = QStringLiteral("SNT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SNT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ARDOR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ardor");
info.Symbol = QStringLiteral("ARDR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ARDR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KUCOIN-SHARES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "KuCoin Shares");
info.Symbol = QStringLiteral("KCS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KCS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TETHER
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Tether");
info.Symbol = QStringLiteral("USDT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("USDT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STEEM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Steem");
info.Symbol = QStringLiteral("STEEM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("STEEM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WAVES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Waves");
info.Symbol = QStringLiteral("WAVES");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WAVES");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VECHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "VeChain");
info.Symbol = QStringLiteral("VEN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VEN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGIBYTE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigiByte");
info.Symbol = QStringLiteral("DGB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DGB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KOMODO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Komodo");
info.Symbol = QStringLiteral("KMD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KMD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DRAGONCHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dragonchain");
info.Symbol = QStringLiteral("DRGN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DRGN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AUGUR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Augur");
info.Symbol = QStringLiteral("REP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("REP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GOLEM-NETWORK-TOKENS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Golem");
info.Symbol = QStringLiteral("GNT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GNT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VERITASEUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Veritaseum");
info.Symbol = QStringLiteral("VERI");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VERI");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// HSHARE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Hshare");
info.Symbol = QStringLiteral("HSR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("HSR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Kin");
info.Symbol = QStringLiteral("KIN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KIN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SALT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "SALT");
info.Symbol = QStringLiteral("SALT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SALT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ELECTRONEUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Electroneum");
info.Symbol = QStringLiteral("ETN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ARK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ark");
info.Symbol = QStringLiteral("ARK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ARK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DENT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dent");
info.Symbol = QStringLiteral("DENT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DENT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHOS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethos");
info.Symbol = QStringLiteral("ETHOS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETHOS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BASIC-ATTENTION-TOKEN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Basic Attention Token");
info.Symbol = QStringLiteral("BAT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BAT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// REDDCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ReddCoin");
info.Symbol = QStringLiteral("RDD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RDD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// 0X
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "0x");
info.Symbol = QStringLiteral("ZRX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ZRX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DECRED
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Decred");
info.Symbol = QStringLiteral("DCR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DCR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEXUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Nexus");
info.Symbol = QStringLiteral("NXS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NXS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// EXPERIENCE-POINTS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Experience Points");
info.Symbol = QStringLiteral("XP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "QASH");
info.Symbol = QStringLiteral("QASH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QASH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KYBER-NETWORK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Kyber Network");
info.Symbol = QStringLiteral("KNC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KNC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// PIVX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "PIVX");
info.Symbol = QStringLiteral("PIVX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PIVX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// FUNFAIR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "FunFair");
info.Symbol = QStringLiteral("FUN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("FUN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// FACTOM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Factom");
info.Symbol = QStringLiteral("FCT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("FCT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEBLIO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Neblio");
info.Symbol = QStringLiteral("NEBL");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NEBL");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// REQUEST-NETWORK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Request Network");
info.Symbol = QStringLiteral("REQ");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("REQ");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AETERNITY
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Aeternity");
info.Symbol = QStringLiteral("AE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("AE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SUBSTRATUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Substratum");
info.Symbol = QStringLiteral("SUB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SUB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POWER-LEDGER
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Power Ledger");
info.Symbol = QStringLiteral("POWR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("POWR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WAX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "WAX");
info.Symbol = QStringLiteral("WAX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WAX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AELF
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "aelf");
info.Symbol = QStringLiteral("ELF");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ELF");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTOM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bytom");
info.Symbol = QStringLiteral("BTM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AION
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Aion");
info.Symbol = QStringLiteral("AION");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("AION");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RCHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "RChain");
info.Symbol = QStringLiteral("RHOC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RHOC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGITALNOTE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigitalNote");
info.Symbol = QStringLiteral("XDN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XDN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ENIGMA-PROJECT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Enigma");
info.Symbol = QStringLiteral("ENG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ENG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NXT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Nxt");
info.Symbol = QStringLiteral("NXT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NXT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TIME-NEW-BANK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Time New Bank");
info.Symbol = QStringLiteral("TNB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("TNB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOINDARK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitcoinDark");
info.Symbol = QStringLiteral("BTCD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTCD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MONACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "MonaCoin");
info.Symbol = QStringLiteral("MONA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MONA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QUANTSTAMP
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Quantstamp");
info.Symbol = QStringLiteral("QSP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QSP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MAIDSAFECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "MaidSafeCoin");
info.Symbol = QStringLiteral("MAID");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MAID");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTEBALL
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Byteball Bytes");
info.Symbol = QStringLiteral("GBYTE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GBYTE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GAS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Gas");
info.Symbol = QStringLiteral("GAS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GAS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CHAINLINK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ChainLink");
info.Symbol = QStringLiteral("LINK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LINK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SYSCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Syscoin");
info.Symbol = QStringLiteral("SYS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SYS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SANTIMENT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Santiment Network Token");
info.Symbol = QStringLiteral("SAN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SAN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// COBINHOOD
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Cobinhood");
info.Symbol = QStringLiteral("COB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("COB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RED-PULSE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Red Pulse");
info.Symbol = QStringLiteral("RPX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RPX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGIXDAO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigixDAO");
info.Symbol = QStringLiteral("DGD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DGD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TENX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "TenX");
info.Symbol = QStringLiteral("PAY");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PAY");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ICONOMI
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Iconomi");
info.Symbol = QStringLiteral("ICN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ICN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POET
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Po.et");
info.Symbol = QStringLiteral("POE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("POE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ZCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ZCoin");
info.Symbol = QStringLiteral("XZC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XZC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GNOSIS-GNO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Gnosis");
info.Symbol = QStringLiteral("GNO");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GNO");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BLOCKV
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BLOCKv");
info.Symbol = QStringLiteral("VEE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VEE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WALTON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Walton");
info.Symbol = QStringLiteral("WTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// PACCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "PACcoin");
info.Symbol = QStringLiteral("PAC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PAC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DEEPBRAIN-CHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DeepBrain Chain");
info.Symbol = QStringLiteral("DBC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DBC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHLEND
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ETHLend");
info.Symbol = QStringLiteral("LEND");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LEND");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CIVIC
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Civic");
info.Symbol = QStringLiteral("CVC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("CVC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
}
QStringList output;
output.reserve(currencies.count());
for (const auto& unit : qAsConst(currencies)) {
if (iIncludingObsolete || !unit.Obsolete) {
output.push_back(unit.Name);
}
}
output.sort();
return output;
}
QString SKGUnitObject::getInternationalCode(const QString& iUnitName)
{
SKGTRACEINFUNC(10)
QString output = iUnitName;
QRegExp rx(QStringLiteral(".*\\(([^\\(\\)]+)\\)[^\\(\\)]*"));
if (rx.indexIn(iUnitName) != -1) {
output = rx.cap(1);
}
return output;
}
SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo()
{
SKGTRACEINFUNC(10)
SKGServices::SKGUnitInfo info;
info.Name = getName();
info.Value = getAmount();
info.NbDecimal = getNumberDecimal();
info.Symbol = getSymbol();
info.Country = getCountry();
info.Internet = getInternetCode();
info.Date = QDate::currentDate();
return info;
}
SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo(const QString& iUnitName)
{
SKGTRACEINFUNC(10)
SKGServices::SKGUnitInfo info;
if (currencies.isEmpty()) {
getListofKnownCurrencies(false);
}
QString isoCode = getInternationalCode(iUnitName);
for (const auto& unit : qAsConst(currencies)) {
if (getInternationalCode(unit.Name) == isoCode) {
info = unit;
break;
}
}
return info;
}
SKGError SKGUnitObject::createCurrencyUnit(SKGDocumentBank* iDocument, const QString& iUnitName, SKGUnitObject& oUnit)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iDocument != nullptr) {
SKGUnitObject parentUnit;
oUnit = SKGUnitObject(iDocument);
SKGUnitObject::UnitType type = SKGUnitObject::CURRENCY;
SKGServices::SKGUnitInfo prim = iDocument->getPrimaryUnit();
SKGServices::SKGUnitInfo seco = iDocument->getSecondaryUnit();
// Get information on the unit
SKGServices::SKGUnitInfo info = getUnitInfo(iUnitName);
if (info.Name.isEmpty()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Unknown unit '%1'", iUnitName));
}
if (!err && !info.Parent.isEmpty()) {
err = createCurrencyUnit(iDocument, info.Parent, parentUnit);
}
// Set the type
if (info.Name == info.Symbol) {
// This is an index
type = SKGUnitObject::INDEX;
} else if (!info.Parent.isEmpty()) {
// This is a secondary unit
type = (seco.Symbol.isEmpty() || seco.Symbol == info.Symbol ? SKGUnitObject::SECONDARY : SKGUnitObject::CURRENCY);
} else {
// As primary
type = (prim.Symbol.isEmpty() || prim.Symbol == info.Symbol ? SKGUnitObject::PRIMARY : SKGUnitObject::CURRENCY);
}
// Point on primary unit
if (info.Value == 1 && !err && (type == SKGUnitObject::CURRENCY || type == SKGUnitObject::SECONDARY)) {
SKGUnitObject primunit(iDocument);
err = primunit.setSymbol(prim.Symbol);
IFOKDO(err, primunit.load())
IFOK(err) {
QString codeprimunit = getInternationalCode(primunit.getName());
QString codeunit = getInternationalCode(info.Name);
if (!codeprimunit.isEmpty()) {
info.Internet = codeunit % '/' % codeprimunit;
info.Value = -1;
parentUnit = SKGUnitObject(iDocument);
err = parentUnit.setSymbol(prim.Symbol);
IFOKDO(err, parentUnit.load())
}
}
}
IFOKDO(err, oUnit.setName(info.Name))
if (!err && oUnit.exist()) {
err = oUnit.load();
}
IFOKDO(err, oUnit.setType(type))
IFOKDO(err, oUnit.setSymbol(info.Symbol))
IFOKDO(err, oUnit.setInternetCode(info.Internet))
IFOKDO(err, oUnit.setDownloadSource(info.Source))
IFOKDO(err, oUnit.setCountry(info.Country))
IFOKDO(err, oUnit.setNumberDecimal(info.NbDecimal))
if (!err && parentUnit.exist()) {
err = oUnit.setUnit(parentUnit);
}
IFOKDO(err, oUnit.save())
// Creation of the value
if (info.Value > 0) {
SKGUnitValueObject unitValue;
IFOKDO(err, oUnit.addUnitValue(unitValue))
IFOKDO(err, unitValue.setDate(info.Date))
IFOKDO(err, unitValue.setQuantity(info.Value))
IFOKDO(err, unitValue.save())
}
}
return err;
}
double SKGUnitObject::convert(double iValue, const SKGUnitObject& iUnitFrom, const SKGUnitObject& iUnitTo, QDate iDate)
{
double output = iValue;
if (iUnitFrom != iUnitTo) {
double valFrom = iUnitFrom.getAmount(iDate);
double valTo = iUnitTo.getAmount(iDate);
output = iValue * valFrom / valTo;
}
return output;
}
SKGError SKGUnitObject::setSymbol(const QString& iSymbol)
{
return setAttribute(QStringLiteral("t_symbol"), iSymbol);
}
QString SKGUnitObject::getSymbol() const
{
return getAttribute(QStringLiteral("t_symbol"));
}
QString SKGUnitObject::getDownloadSource() const
{
return getAttribute(QStringLiteral("t_source"));
}
SKGError SKGUnitObject::setDownloadSource(const QString& iSource)
{
return setAttribute(QStringLiteral("t_source"), iSource);
}
SKGError SKGUnitObject::setNumberDecimal(int iNb)
{
return setAttribute(QStringLiteral("i_nbdecimal"), SKGServices::intToString(iNb));
}
int SKGUnitObject::getNumberDecimal() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_nbdecimal")));
}
SKGError SKGUnitObject::setCountry(const QString& iCountry)
{
return setAttribute(QStringLiteral("t_country"), iCountry);
}
QString SKGUnitObject::getCountry() const
{
return getAttribute(QStringLiteral("t_country"));
}
SKGError SKGUnitObject::setInternetCode(const QString& iCode)
{
return setAttribute(QStringLiteral("t_internet_code"), iCode);
}
QString SKGUnitObject::getInternetCode() const
{
return getAttribute(QStringLiteral("t_internet_code"));
}
SKGError SKGUnitObject::setType(SKGUnitObject::UnitType iType)
{
SKGError err;
if (getAttribute(QStringLiteral("t_type")).isEmpty() || this->getType() != iType) {
// Guaranty that PRIMARY and SECONDARY is unique
if (iType == PRIMARY || iType == SECONDARY) {
// Set old SECONDARY as CURRENCY
err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='C' WHERE t_type='2'"));
// Set old PRIMARY as SECONDARY
if (!err && iType == PRIMARY) {
err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='2' WHERE t_type='1'"));
}
}
}
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"))))))))
return err;
}
SKGUnitObject::UnitType SKGUnitObject::getType() const
{
QString typeString = getAttribute(QStringLiteral("t_type"));
return (typeString == QStringLiteral("C") ? CURRENCY : (typeString == QStringLiteral("S") ? SHARE : (typeString == QStringLiteral("1") ? PRIMARY : (typeString == QStringLiteral("2") ? SECONDARY : (typeString == QStringLiteral("I") ? INDEX : OBJECT)))));
}
SKGError SKGUnitObject::getUnit(SKGUnitObject& oUnit) const
{
SKGError err;
if (getDocument() != nullptr) {
err = getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rd_unit_id")), oUnit);
}
return err;
}
SKGError SKGUnitObject::setUnit(const SKGUnitObject& iUnit)
{
SKGError err;
if (*this == iUnit && iUnit.getID() != 0) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Reference unit of a unit cannot be itself."));
} else {
err = setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(iUnit.getID()));
}
return err;
}
SKGError SKGUnitObject::removeUnit()
{
return setAttribute(QStringLiteral("rd_unit_id"), QStringLiteral("0"));
}
SKGError SKGUnitObject::addUnitValue(SKGUnitValueObject& oUnitValue)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGUnitObject::addUnitValue")));
} else {
oUnitValue = SKGUnitValueObject(qobject_cast(getDocument()));
err = oUnitValue.setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(getID()));
}
return err;
}
SKGError SKGUnitObject::simplify()
{
SKGListSKGObjectBase values;
SKGError err = getUnitValues(values);
int nb = values.count();
if (!err && (nb != 0)) {
QHash groups;
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Simplify unit"), err, 2)
// Build groups
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Analyze unit"), err, nb)
QDate limit1 = QDate::currentDate().addMonths(-3);
QDate limit2 = QDate::currentDate().addYears(-1);
QDate limit3 = QDate::currentDate().addYears(-3);
for (int i = nb - 1; !err && i >= 0 ; --i) {
SKGUnitValueObject v(values.at(i));
QDate date = v.getDate();
if (date >= limit1) {
// No simplification ==> nothing to do
} else if (date >= limit2) {
// Simplification by group of 30 days
QString key = limit1.addDays(30 * (limit1.daysTo(date) / 30)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
} else if (date >= limit3) {
// Simplification by group of 2 months
QString key = limit2.addDays(60 * (limit2.daysTo(date) / 60)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
} else {
// Simplification by group of 6 months
QString key = limit3.addDays(180 * (limit2.daysTo(date) / 180)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
}
IFOKDO(err, getDocument()->stepForward(nb - i))
}
}
IFOKDO(err, getDocument()->stepForward(1))
// Simplify
{
QList keys = groups.keys();
nb = keys.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Remove useless values"), err, nb)
for (int i = 0; !err && i < nb ; ++i) {
const QString& k = keys.at(i);
SKGListSKGObjectBase group = groups[k];
// Simplify the group
int nb2 = group.count();
// Compute min and max
double min = 10e20;
double max = 0;
for (int j = 0; j < nb2; ++j) {
SKGUnitValueObject v1(group.at(j));
double y1 = v1.getQuantity();
min = qMin(y1, min);
max = qMax(y1, max);
}
// Simplify
for (int j = 1; !err && j < nb2 - 1; ++j) {
SKGUnitValueObject v1(group.at(j));
double y1 = v1.getQuantity();
if (y1 != min && y1 != max) {
err = v1.remove();
}
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
IFOKDO(err, getDocument()->stepForward(2))
}
return err;
}
SKGError SKGUnitObject::getUnitValues(SKGListSKGObjectBase& oUnitValueList) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % SKGServices::intToString(getID()) % " ORDER BY d_date",
oUnitValueList);
return err;
}
SKGError SKGUnitObject::getLastUnitValue(SKGUnitValueObject& oUnitValue) const
{
return SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"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()) % ')',
oUnitValue);
}
SKGError SKGUnitObject::getUnitValue(QDate iDate, SKGUnitValueObject& oUnitValue) const
{
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
SKGError err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % ids % " AND d_date<='" % dates %
"' AND ABS(strftime('%s','" % dates %
"')-strftime('%s',d_date))=(select MIN(ABS(strftime('%s','" % dates %
"')-strftime('%s',u2.d_date))) from unitvalue u2 where u2.rd_unit_id=" % ids %
" AND u2.d_date<='" % dates % "')",
oUnitValue);
// If not found then get first
IFKO(err) err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % SKGServices::intToString(getID()) % " AND d_date=(select MIN(d_date) from unitvalue where rd_unit_id=" %
SKGServices::intToString(getID()) % ')',
oUnitValue);
return err;
}
double SKGUnitObject::getAmount(QDate iDate) const
{
SKGTRACEINFUNC(10)
double output = 0;
if (getType() == SKGUnitObject::PRIMARY) {
output = 1.0;
} else if (getDocument() != nullptr) {
// Search result in cache
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
QString key = "unitvalue-" % ids % '-' % dates;
QString val = getDocument()->getCachedValue(key);
if (val.isEmpty()) {
// Get quantity
double quantity = 1;
SKGUnitValueObject uv;
if (getUnitValue(iDate, uv).isSucceeded()) {
quantity = uv.getQuantity();
}
SKGUnitObject unit;
double coef = 1;
if (getUnit(unit).isSucceeded()) {
if (unit != *this) {
coef = unit.getAmount(iDate);
}
}
output = coef * quantity;
getDocument()->addValueInCache(key, SKGServices::doubleToString(output));
if (getAttribute(QStringLiteral("i_NBVALUES")) == QStringLiteral("1")) {
// Store value for this symbol for all date
getDocument()->addValueInCache("unitvalue-" % ids, SKGServices::doubleToString(output));
}
} else {
output = SKGServices::stringToDouble(val);
}
}
return output;
}
double SKGUnitObject::getDailyChange(QDate iDate) const
{
double output = 0;
SKGStringListList result;
SKGError err = getDocument()->executeSelectSqliteOrder(
"SELECT d_date, f_quantity from unitvalue where rd_unit_id=" %
SKGServices::intToString(getID()) %
" AND d_date<='" % SKGServices::dateToSqlString(QDateTime(iDate)) %
"' ORDER BY d_date DESC LIMIT 2",
result);
if (!err && result.count() == 3) {
double v2 = SKGServices::stringToDouble(result.at(1).at(1));
double v1 = SKGServices::stringToDouble(result.at(2).at(1));
QDate d2 = SKGServices::stringToTime(result.at(1).at(0)).date();
QDate d1 = SKGServices::stringToTime(result.at(2).at(0)).date();
output = 100 * (qExp(qLn(v2 / v1) / (SKGServices::nbWorkingDays(d1, d2))) - 1);
}
return output;
}
SKGError SKGUnitObject::split(double iRatio) const
{
SKGError err;
if (iRatio > 0) {
err = getDocument()->executeSqliteOrder("UPDATE unitvalue SET f_quantity=f_quantity/" % SKGServices::doubleToString(iRatio) %
" WHERE rd_unit_id=" % SKGServices::intToString(getID()));
IFOKDO(err, getDocument()->executeSqliteOrder("UPDATE suboperation SET f_value=f_value*" % SKGServices::doubleToString(iRatio) %
" WHERE rd_operation_id IN (SELECT id FROM operation WHERE rc_unit_id=" % SKGServices::intToString(getID()) % ')'));
} else {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid ratio. Ratio must be greater than 0."));
}
return err;
}
QStringList SKGUnitObject::downloadSources()
{
QStringList sources;
// Get sources from .txt file (old mode) TODO: Remove
QString a = QStringLiteral("skrooge/quotes");
const auto list = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, a, QStandardPaths::LocateDirectory);
for (const auto& dir : list) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.txt"));
while (it.hasNext()) {
QFileInfo f(it.next());
QString file2 = f.completeBaseName();
if (!sources.contains(file2)) {
sources.push_back(file2);
}
}
}
// Get sources from.desktop file
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (!sources.contains(name)) {
sources.push_back(name);
}
}
sources.sort();
return sources;
}
QString SKGUnitObject::getCommentFromSource(const QString& iSource)
{
QString output;
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == iSource) {
output = service->property(QStringLiteral("Comment"), QVariant::String).toString();
break;
}
}
return output;
}
SKGError SKGUnitObject::addSource(const QString& iNewSource, bool iOpenSource)
{
SKGError err;
QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
QDir(path).mkpath(QStringLiteral("skrooge/quotes/"));
QString newfile = path + "/skrooge/quotes/" % iNewSource % ".txt";
// Create the new file
QSaveFile file(newfile);
// Check if file already existing
if (!QFile(newfile).exists()) {
// Creation of the template
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", newfile));
} else {
QTextStream out(&file);
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The URL or the SCRIPT of the source. %1 will be replaced by the internet code of the unit", "%1") << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"%1 will be replaced by the current day in format yyyy-MM-dd", "%2") << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"%1 will be replaced by the previous date in format yyyy-MM-dd", "%3") << endl;
out << "url=https://server/?s=%1" << endl;
out << "or" << endl;
out << "script=mydownloadscript %1" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"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.") << endl;
out << "mode=CSV, CSVR or or HTML" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The regular expression for the price (see %1)", "https://doc.qt.io/qt-5/qregexp.html") << endl;
out << "price=" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The regular expression for the date (see %1)", "https://doc.qt.io/qt-5/qregexp.html") << endl;
out << "date=" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The format of the date (see %1) or \"UNIX\" for unix time", "https://doc.qt.io/qt-5/qdate.html#fromString-1") << endl;
out << "dateformat=yyyy-MM-dd" << endl;
// Close file
file.commit();
}
}
// Open the created or already existing file
if (iOpenSource) {
QDesktopServices::openUrl(QUrl::fromLocalFile(newfile));
}
return err;
}
SKGError SKGUnitObject::deleteSource(const QString& iSource)
{
SKGError err;
QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt";
// Delete the file
QFile file(fileName);
if (!file.remove()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Deletion of '%1' failed", fileName));
}
return err;
}
bool SKGUnitObject::isWritable(const QString& iSource)
{
QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt";
return QFileInfo(fileName).isWritable();
}
SKGError SKGUnitObject::downloadUnitValue(UnitDownloadMode iMode, int iNbMaxValues)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString unitname = getName();
QString code = getInternetCode();
bool invert = code.contains(QStringLiteral(" /"));
code.remove(QStringLiteral(" /"));
QString source = getDownloadSource();
auto* doc = qobject_cast(getDocument());
if (!code.trimmed().isEmpty() && !source.trimmed().isEmpty() && (doc != nullptr)) {
// Get last date
QDate firstDate;
SKGStringListList result;
doc->executeSelectSqliteOrder("SELECT MAX(d_date) FROM unitvalue where rd_unit_id=" % SKGServices::intToString(getID()), result);
if (result.count() == 2) {
firstDate = SKGServices::stringToTime(result.at(1).at(0)).date().addDays(-1);
}
if (code.startsWith(QLatin1String("="))) {
// MODE FORMULAR
// Set 1st january if date is not found
if (!firstDate.isValid()) {
firstDate.setDate(QDate::currentDate().year(), 1, 1);
}
// Compute yearly rate
double rate = SKGServices::stringToDouble(code.right(code.length() - 1));
// Compute rate for step
double step = (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY ? 12.0 : (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY ? 365.0 / 7.0 : 365));
double rate2 = 100.0 * (qExp(qLn(1 + rate / 100.0) / step) - 1.0);
// Get last value
SKGStringListList result2;
double value = 100;
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(QDateTime(firstDate)) % '\'', result2);
if (result2.count() == 2) {
value = SKGServices::stringToDouble(result2.at(1).at(0));
}
// Compute and add values
while (!err && firstDate <= QDate::currentDate()) {
// Compute next date and value
if (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY) {
firstDate = firstDate.addMonths(1);
} else if (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY) {
firstDate = firstDate.addDays(7);
} else {
firstDate = firstDate.addDays(1);
}
value *= (1 + rate2 / 100.0);
// Create value
SKGUnitValueObject val;
err = addUnitValue(val);
IFOKDO(err, val.setDate(firstDate))
IFOKDO(err, val.setQuantity(value))
IFOKDO(err, val.save())
}
} else {
// Quote download
// Set 1st january 1970 if date is not found
if (!firstDate.isValid()) {
firstDate.setDate(1970, 1, 1);
}
QString interval = QStringLiteral("1d");
bool last = (iMode == LAST);
if (last) {
interval = QStringLiteral("1d");
} else if (iMode == LAST_MONTHLY) {
interval = QStringLiteral("1mo");
} else if (iMode == LAST_WEEKLY) {
interval = QStringLiteral("1wk");
} else if (iMode == LAST_DAILY) {
interval = QStringLiteral("1d");
} else if (iMode == ALL_MONTHLY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1mo");
} else if (iMode == ALL_WEEKLY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1wk");
} else if (iMode == ALL_DAILY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1d");
}
bool modeScript = false;
QString path;
QString mode;
QString price;
QString date;
QString dateFormat;
+ QString apiKey;
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt");
if (fileName.isEmpty()) {
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == source) {
path = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString();
if (path.isEmpty()) {
path = service->property(QStringLiteral("X-SKROOGE-script"), QVariant::String).toString();
modeScript = true;
}
mode = service->property(QStringLiteral("X-SKROOGE-mode"), QVariant::String).toString().toUpper();
price = service->property(QStringLiteral("X-SKROOGE-price"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
date = service->property(QStringLiteral("X-SKROOGE-date"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
dateFormat = service->property(QStringLiteral("X-SKROOGE-dateformat"), QVariant::String).toString();
+ if (service->property(QStringLiteral("X-SKROOGE-keyAPI"), QVariant::Bool).toBool()) {
+ apiKey = getDocument()->getParameter("KEYAPI_" + source);
+ }
break;
}
}
if (path.isEmpty()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source));
}
} else {
// Read source file from .txt file
QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(fileName, properties);
IFOK(err) {
path = properties[QStringLiteral("url")];
if (path.isEmpty()) {
path = properties[QStringLiteral("script")];
modeScript = true;
}
mode = properties[QStringLiteral("mode")].toUpper();
price = properties[QStringLiteral("price")].replace(QStringLiteral("%1"), code);
date = properties[QStringLiteral("date")].replace(QStringLiteral("%1"), code);
dateFormat = properties[QStringLiteral("dateformat")];
} else {
doc->sendMessage(i18nc("An information message", "Open url '%1' failed", path), SKGDocument::Warning);
}
}
IFOK(err) {
path = path.replace(QStringLiteral("%1"), code);
path = path.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
path = path.replace(QStringLiteral("%3"), firstDate.toString(QStringLiteral("yyyy-MM-dd")));
path = path.replace(QStringLiteral("%4"), interval);
-
+ path = path.replace(QStringLiteral("%5"), apiKey);
SKGTRACEL(1) << "path=[" << path << "]" << endl;
SKGTRACEL(1) << "mode=[" << mode << "]" << endl;
SKGTRACEL(1) << "price=[" << price << "]" << endl;
SKGTRACEL(1) << "date=[" << date << "]" << endl;
SKGTRACEL(1) << "dateFormat=[" << dateFormat << "]" << endl;
// Download url
QByteArray stream;
if (modeScript) {
path = SKGServices::getFullPathCommandLine(path);
SKGTRACEL(1) << "full path=[" << path << "]" << endl;
QProcess p;
p.start(path);
if (p.waitForFinished(1000 * 60 * 2) && p.exitCode() == 0) {
stream = p.readAllStandardOutput();
} else {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", path, p.exitCode()));
}
} else {
SKGServices::downloadToStream(QUrl::fromUserInput(path), stream);
}
if (!err && !stream.isEmpty()) {
SKGTRACEL(1) << "stream=[" << stream << "]" << endl;
// Parse data
QRegExp priceRegExp(price, Qt::CaseInsensitive);
QRegExp dateRegExp(date, Qt::CaseInsensitive);
QStringList lines = (mode.startsWith(QLatin1String("CSV")) ? SKGServices::splitCSVLine(stream, '\n') : QStringList() << QLatin1String("") << stream);
int nb = lines.count();
int nbLoaded = 0;
for (int i = 1; i < nb && !err && (i < iNbMaxValues || iNbMaxValues == 0); ++i) {
QString data = lines.at(mode == QStringLiteral("CSVR") ? nb - i : i).trimmed();
if (!data.isEmpty()) {
SKGTRACEL(1) << "Downloaded data from [" << path << "]=[" << data << "]" << endl;
double val = 0.0;
if (priceRegExp.indexIn(data) > -1) {
val = SKGServices::stringToDouble(priceRegExp.cap(1));
}
QString date2;
if (dateRegExp.indexIn(data) > -1) {
date2 = dateRegExp.cap(1);
}
SKGTRACEL(1) << "Price found=[" << val << "]" << endl;
SKGTRACEL(1) << "Date found=[" << date2 << "]" << endl;
// Set value
if (val != 0.0) {
QDate ds;
if (dateFormat == QStringLiteral("UNIX")) {
ds = QDateTime::fromTime_t(SKGServices::stringToInt(date2)).date();
} else {
ds = QDate::fromString(date2, dateFormat);
// Try with an english locale
if (!ds.isValid()) {
QLocale en(QStringLiteral("en_EN"));
ds = en.toDate(date2, dateFormat);
}
}
if (!ds.isValid()) {
ds = QDate::currentDate();
SKGTRACE << "WARNING:" << date2 << " not well parsed with format " << dateFormat << endl;
}
if (!dateFormat.contains(QStringLiteral("yyyy")) && ds.year() < 2000) {
ds = ds.addYears(100);
}
// Creation or update of the value
SKGUnitValueObject value;
IFOKDO(err, addUnitValue(value))
IFOKDO(err, value.setDate(ds))
IFOKDO(err, value.setQuantity(invert && val != 0 ? 1 / val : val))
IFOKDO(err, value.save())
if (last) {
break;
}
nbLoaded++;
}
}
if (nbLoaded == 0 && !data.isEmpty()) {
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
}
}
}
}
}
}
IFKO(err) {
err.addError(ERR_FAIL, i18nc("Error message", "Impossible to download unit %1 with Internet code %2 on the source %3.", unitname, code, source));
}
return err;
}
SKGError SKGUnitObject::getUrl(QUrl& oUrl) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString url;
QString code = getInternetCode();
code.remove(QStringLiteral(" /"));
QString source = getDownloadSource();
if (!code.isEmpty()) {
if (code.startsWith(QLatin1String("="))) {
// MODE FORMULAR
} else {
// ALTERNATIVE MODE
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt");
if (fileName.isEmpty()) {
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == source) {
url = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd")));
break;
}
}
if (url.isEmpty()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source));
}
} else {
// Read source file
QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(fileName, properties);
IFOK(err) {
url = properties[QStringLiteral("url")].replace(QStringLiteral("%1"), code);
url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd")));
}
}
}
}
IFOK(err) {
oUrl = QUrl(url);
}
return err;
}
SKGError SKGUnitObject::openURL() const
{
QUrl url;
SKGError err = getUrl(url);
IFKO(err) {
err.addError(ERR_FAIL, i18nc("Error message", "Impossible to open unit %1 with Internet code %2.", getName(), getInternetCode()));
} else {
QDesktopServices::openUrl(url);
}
return err;
}
SKGError SKGUnitObject::getOperations(SKGObjectBase::SKGListSKGObjectBase& oOperations) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_operation"),
"rc_unit_id=" % SKGServices::intToString(getID()),
oOperations);
return err;
}
SKGError SKGUnitObject::merge(const SKGUnitObject& iUnit)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iUnit.getOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(ops.at(i));
err = op.setUnit(*this);
IFOKDO(err, op.save(true, false))
}
IFOKDO(err, iUnit.remove(false))
return err;
}
diff --git a/skgbankmodeler/skrooge-coinmarketcap.py b/skgbankmodeler/skrooge-coinmarketcap.py
index 46bee3709..156a2d40d 100755
--- a/skgbankmodeler/skrooge-coinmarketcap.py
+++ b/skgbankmodeler/skrooge-coinmarketcap.py
@@ -1,38 +1,38 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#**************************************************************************
#* Copyright (C) 2017 by S. MANKOWSKI / G. DE BURE support@mankowski.fr
#* Redistribution and use in source and binary forms, with or without
#* modification, are permitted provided that the following conditions
#* are met:
#*
#* 1. Redistributions of source code must retain the above copyright
#* notice, this list of conditions and the following disclaimer.
#* 2. Redistributions in binary form must reproduce the above copyright
#* notice, this list of conditions and the following disclaimer in the
#* documentation and/or other materials provided with the distribution.
#*
#* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
#* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
#* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
#* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#**************************************************************************
from urllib.request import Request, urlopen
import json
import sys
units=sys.argv[1].split('-')
req = Request('https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol='+units[0]+'&convert='+units[1])
-req.add_header("X-CMC_PRO_API_KEY", '-'.join(units[2:]))
+req.add_header("X-CMC_PRO_API_KEY", sys.argv[5])
f = urlopen(req)
print("Date,Price")
item=json.loads(f.read().decode('utf-8'))['data'][units[0]]['quote'][units[1]]
print(item["last_updated"][0:10]+','+str(item["price"]))
diff --git a/skgbankmodeler/skrooge-cryptocompare.py b/skgbankmodeler/skrooge-cryptocompare.py
index 9f1fc998b..5c5b9ea79 100755
--- a/skgbankmodeler/skrooge-cryptocompare.py
+++ b/skgbankmodeler/skrooge-cryptocompare.py
@@ -1,37 +1,37 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#**************************************************************************
#* Copyright (C) 2017 by S. MANKOWSKI / G. DE BURE support@mankowski.fr
#* Redistribution and use in source and binary forms, with or without
#* modification, are permitted provided that the following conditions
#* are met:
#*
#* 1. Redistributions of source code must retain the above copyright
#* notice, this list of conditions and the following disclaimer.
#* 2. Redistributions in binary form must reproduce the above copyright
#* notice, this list of conditions and the following disclaimer in the
#* documentation and/or other materials provided with the distribution.
#*
#* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
#* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
#* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
#* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#**************************************************************************
import urllib.request
import json
import sys
import time
units=sys.argv[1].split('-')
-f = urllib.request.urlopen('https://min-api.cryptocompare.com/data/v2/histoday?fsym='+units[0]+'&tsym='+units[1]+'&limit=1000&api_key='+units[2])
+f = urllib.request.urlopen('https://min-api.cryptocompare.com/data/v2/histoday?fsym='+units[0]+'&tsym='+units[1]+'&limit=1000&api_key='+sys.argv[5])
print("Date,Price")
for item in json.loads(f.read().decode('utf-8'))['Data']['Data']:
print(time.strftime('%Y-%m-%d', time.gmtime(int(item["time"])))+','+str(item['close']))
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
index ecb5919bb..b737bc61a 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
@@ -1,67 +1,72 @@
[Desktop Entry]
Name=CoinMarketCap
Name[ca]=CoinMarketCap
Name[ca@valencia]=CoinMarketCap
Name[en_GB]=CoinMarketCap
Name[es]=CoinMarketCap
Name[et]=CoinMarketCap
Name[fr]=CoinMarketCap
Name[gl]=CoinMarketCap
Name[it]=CoinMarketCap
Name[nl]=CoinMarketCap
Name[pl]=CoinMarketCap
Name[pt]=CoinMarketCap
Name[pt_BR]=CoinMarketCap
Name[sv]=CoinMarketCap
Name[uk]=CoinMarketCap
Name[x-test]=xxCoinMarketCapxx
-Comment=You can get the list of available quotes from CoinMarketCap.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
+Comment=You can get the list of available quotes from CoinMarketCap.
Then, you must create an account to get an API key and set it in setting.
Then, enter the -. Example: if you want BTC in USD, you must enter BTC-USD.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a CoinMarketCap.
Després, cal crear un compte per aconseguir una clau d'API.
Després, introduïu la --. Exemple: si voleu BTC en USD, cal introduir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a CoinMarketCap.
Després, cal crear un compte per aconseguir una clau d'API.
Després, introduïu la --. Exemple: si voleu BTC en USD, cal introduir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[en_GB]=You can get the list of available quotes from CoinMarketCap.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[es]=Puede obtener la lista de cotizaciones disponibles en CoinMarketCap.
Tras ello, debe crear una cuenta para obtener una clave API.
Luego, introduzca la --. Por ejemplo: si quiere BTC en USD, debe introducir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt CoinMarketCap.
Seejärel tuleb API võtme saamiseks luua konto.
Seejärel sisesta .-. Kui näiteks soovid BTC-d USA dollarites, tuleb sisestada BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[nl]=U kunt de lijst met beschikbare koersen ophalen van CoinMarketCap.
Daarna, moet u een account aanmaken om een API-sleutel te krijgen.
Voer daarna de -- in. Voorbeeld: als u BTC in USD wilt, moet u invoeren BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[pt]=Poderá obter a lista de cotações disponíveis no CoinMarketCap.
Depois será necessário criar uma conta para obter uma chave da API.
Finalmente, indique a --. Por exemplo, se quiser a BTC em USD, tem de indicar BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[sv]=Du kan hämta listan över tillgängliga kurser från CoinMarketCap.
Därefter måste du skapa ett konto för att få en programmeringsgränssnittsnyckel.
Ange därefter --. Om du exempelvis ha BTC i USD måste du skriva in BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[uk]=Ви можете отримувати список доступних курсів з CoinMarketCap.
Для цього вам слід створити обліковий запис та отримати ключ до програмного інтерфейсу.
Далі, введіть комбінацію <потрібний курс>-<бажана валюта>-<ключ до програмного інтерфейсу>. Приклад: якщо потрібен курс BTC у доларах США, вам слід вказати BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[x-test]=xxYou can get the list of available quotes from CoinMarketCap.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=coinmarketcap
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=CoinMarketCap
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=true
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
-X-SKROOGE-script=skrooge-coinmarketcap.py %1
+X-SKROOGE-script=skrooge-coinmarketcap.py "%1" "%2" "%3" "%4" "%5"
#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
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-cryptocompare.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-cryptocompare.desktop
index 107a90b65..a8b07b9dd 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-cryptocompare.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-cryptocompare.desktop
@@ -1,62 +1,67 @@
[Desktop Entry]
Name=Cryptocompare
Name[ca]=Cryptocompare
Name[ca@valencia]=Cryptocompare
Name[en_GB]=Cryptocompare
Name[es]=Cryptocompare
Name[et]=Cryptocompare
Name[nl]=Cryptocompare
Name[pt]=Cryptocompare
Name[sv]=Cryptocompare
Name[uk]=Cryptocompare
Name[x-test]=xxCryptocomparexx
-Comment=You can get the list of available quotes from CryptoCompare.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
+Comment=You can get the list of available quotes from CryptoCompare.
Then, you must create an account to get an API key and set it in setting.
Then, enter the -. Example: if you want BTC in USD, you must enter BTC-USD.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a CryptoCompare.
Després, cal crear un compte per aconseguir una clau d'API.
Després, introduïu la --. Exemple: si voleu BTC en USD, cal introduir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a CryptoCompare.
Després, cal crear un compte per aconseguir una clau d'API.
Després, introduïu la --. Exemple: si voleu BTC en USD, cal introduir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[en_GB]=You can get the list of available quotes from CryptoCompare.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[es]=Puede obtener la lista de cotizaciones disponibles en CryptoCompare
.Tras ello, debe crear una cuenta para obtener una clave API.
Luego, introduzca la --. Por ejemplo: si quiere BTC en USD, debe introducir BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt CryptoCompare.
Seejärel tuleb API võtme saamiseks luua konto.
Seejärel sisesta .-. Kui näiteks soovid BTC-d USA dollarites, tuleb sisestada BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[nl]=U kunt de lijst met beschikbare koersen ophalen van CryptoCompare.
Daarna, moet u een account aanmaken om een API-sleutel te krijgen.
Voer daarna de -- in. Voorbeeld: als u BTC in USD wilt, moet u invoeren BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[pt]=Poderá obter a lista de cotações disponíveis no CryptoCompare.
Depois será necessário criar uma conta para obter uma chave da API.
Finalmente, indique a --. Por exemplo, se quiser a BTC em USD, tem de indicar BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[sv]=Du kan hämta listan över tillgängliga kurser från CryptoCompare.
Därefter måste du skapa ett konto för att få en programmeringsgränssnittsnyckel.
Ange därefter --. Om du exempelvis ha BTC i USD måste du skriva in BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[uk]=Ви можете отримувати список доступних курсів з CryptoCompare.
Для цього вам слід створити обліковий запис та отримати ключ до програмного інтерфейсу.
Далі, введіть комбінацію <потрібний курс>-<бажана валюта>-<ключ до програмного інтерфейсу>. Приклад: якщо потрібен курс BTC у доларах США, вам слід вказати BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.
Comment[x-test]=xxYou can get the list of available quotes from CryptoCompare.
Then, you must create an account to get an API key.
Then, enter the --. Example: if you want BTC in USD, you must enter BTC-USD-3b415edbc7d42bd9e367dc43b415edbc7d42bd9e367dc3b415edbc7d42bd9e36.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=cryptocompare
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Cryptocompare
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=true
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
-X-SKROOGE-script=skrooge-cryptocompare.py %1
+X-SKROOGE-script=skrooge-cryptocompare.py "%1" "%2" "%3" "%4" "%5"
#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
X-SKROOGE-mode=CSVR
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
index 63f7894f1..1b31060c7 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
@@ -1,70 +1,75 @@
[Desktop Entry]
Name=Grand Trunk
Name[ca]=Grand Trunk
Name[ca@valencia]=Grand Trunk
Name[en_GB]=Grand Trunk
Name[es]=Grand Trunk
Name[et]=Grand Trunk
Name[fr]=Grand Trunk
Name[gl]=Grand Trunk
Name[it]=Grand Trunk
Name[nl]=Grand Trunk
Name[pl]=Grand Trunk
Name[pt]=Grand Trunk
Name[pt_BR]=Grand Trunk
Name[sv]=Grand Trunk
Name[uk]=Grand Trunk
Name[x-test]=xxGrand Trunkxx
Comment=You can get the list of supported currencies from here.
Then, enter the expected currency.
Comment[ca]=Podeu obtenir la llista de les divises admeses aquí.
Després introduïu la divisa esperada.
Comment[ca@valencia]=Podeu obtindre la llista de les divises admeses ací.
Després introduïu la divisa esperada.
Comment[en_GB]=You can get the list of supported currencies from here.
Then, enter the expected currency.
Comment[es]=Puede obtener la lista de las monedas permitidas de aquí.
A continuación, introduzca la moneda esperada.
Comment[et]=Toetatud vääringute loendi võib hankida siit.
Seejärel sisesta oodatav vääring.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis ici.
Ensuite, saisissez la devise souhaitée.
Comment[gl]=Pode obter a lista de divisas compatíbeis de aquí.
A continuación escriba a divisa esperada.
Comment[it]=Puoi ottenere un elenco delle valute supportate qui.
Digita, quindi, la valuta desiderata.
Comment[nl]=U kunt de lijst met ondersteunde valuta ophalen vanaf hier.
Voer dan de naam van de gewenste valuta in.
Comment[pt]=Poderá obter a lista de moedas suportadas a partir de aqui.
Depois, introduza a moeda esperada.
Comment[sv]=Lista över valutor som stöds kan hämtas här. Skriv därefter in förväntad valuta.
Comment[uk]=Ознайомитися зі списком підтримуваних валют можна тут.
Далі, введіть потрібну валюту.
Comment[x-test]=xxYou can get the list of supported currencies from here.
Then, enter the expected currency.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=grandtrunk
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=GrandTrunk
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=https://currencies.apps.grandtrunk.net/getrange/%3/%2/%1
#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
X-SKROOGE-mode=CSVR
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=^[^ ]* (.*)$
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=^(.*) [^ ]*$
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
index 79414a2e7..d62dc5b54 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
@@ -1,74 +1,79 @@
[Desktop Entry]
Name=MSN
Name[ca]=MSN
Name[ca@valencia]=MSN
Name[cs]=MSN
Name[de]=MSN
Name[en_GB]=MSN
Name[es]=MSN
Name[et]=MSN
Name[fr]=MSN
Name[gl]=MSN
Name[it]=MSN
Name[nl]=MSN
Name[pl]=MSN
Name[pt]=MSN
Name[pt_BR]=MSN
Name[sv]=MSN
Name[uk]=MSN
Name[x-test]=xxMSNxx
Comment=You can get the list of available quotes from MSN.
Then, enter the code of the expected quote (the xxx in the url like https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a MSN.
Després introduïu el codi de la cotització esperada (les «xxx» a l'URL com aquest https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a MSN.
Després introduïu el codi de la cotització esperada (les «xxx» a l'URL com aquest https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[en_GB]=You can get the list of available quotes from MSN.
Then, enter the code of the expected quote (the xxx in the URL like https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de MSN.
A continuación, introduzca el símbolo de la cotización esperada (el xxx del url, como en https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt MSN.
Seejärel sisesta oodatava kursi kood (xxx URL-is, näiteks https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis MSN.
Ensuite, saisissez la cotation souhaitée (le xxx dans l'adresse comme celle-ci https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de MSN.
A continuación escriba a cotización esperada (o xxx dos URL coa forma https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[it]=Puoi ottenere un elenco delle quotazioni disponibili da MSN.
Digita, quindi, il codice della quotazione desiderata (la xxx nell'URL, tipo https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit MSN.
Voer dan de naam van de gevraagde koers in (de xxx in de url zoals deze https://www.msn.com/en-us/money/stockdetails/xxx/).
Comment[pl]=Wykaz dostępnych wycen można pobrać z MSN.
Następnie podaj żądaną wycenę(trzy iksy xxx w adresie url tak jak w https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do MSN.
Depois, indique a cotação esperada (o 'xxx' num URL como o seguinte: https://msn.com/en-us/money/stockdetails/xxx/).
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från MSN.
Skriv därefter in förväntad kurs (xxx i webbadressen https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[uk]=Список доступних курсів можна отримати з MSN.
Далі, введіть потрібний курс (xxx у адресі, наприклад https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[x-test]=xxYou can get the list of available quotes from MSN.
Then, enter the code of the expected quote (the xxx in the url like https://www.msn.com/en-us/money/stockdetails/xxx).xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=msn
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=MSN
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=https://www.msn.com/en-us/money/stockdetails/%1
#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
X-SKROOGE-mode=HTML
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price="currentvalue">([^<]*)<
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
#X-SKROOGE-date=%1,([^,]*),.*
#The date format
#X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
index eea5571a3..59689f787 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
@@ -1,72 +1,77 @@
[Desktop Entry]
Name=RatesAPI
Name[ca]=RatesAPI
Name[ca@valencia]=RatesAPI
Name[cs]=RatesAPI
Name[en_GB]=RatesAPI
Name[es]=RatesAPI
Name[et]=RatesAPI
Name[fr]=RatesAPI
Name[gl]=RatesAPI
Name[it]=RatesAPI
Name[nl]=RatesAPI
Name[pl]=RatesAPI
Name[pt]=RatesAPI
Name[pt_BR]=RatesAPI
Name[sv]=RatesAPI
Name[uk]=RatesAPI
Name[x-test]=xxRatesAPIxx
Comment=You can get the list of available quotes from RatesAPI.
Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a RatesAPI.
Després introduïu la cotització desitjada en format DIVISA/BASE (p. ex. USD/EUR).
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a RatesAPI.
Després introduïu la cotització desitjada en format DIVISA/BASE (p. ex. USD/EUR).
Comment[en_GB]=You can get the list of available quotes from RatesAPI.
Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de RatesAPI.
A continuación, introduzca la cotización esperada con el formato DIVISA/BASE (por ejemplo, USD/EUR).
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt RatesAPI.
Seejärel sisesta oodatav kurss kujul VÄÄRING/BAAS (nt USD/EUR).
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis RatesAPI.
Ensuite, saisissez le symbole de la cotation souhaitée au format DEVISE/BASE (par ex. USD/EUR).
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de RatesAPI.
A continuación escriba a cotización esperada no formato DIVISA/BASE (p. ex. USD/EUR).
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da RatesAPI.
Digita, quindi, la quotazione attesa nel formato VALUTA/BASE (es. USD/EUR).
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit RatesAPI.
Voer dan de gewenste koers in in het formaat VALUTA/BASIS (bijv. USD/EUR).
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do RatesAPI.
Depois, indique o símbolo das cotações esperadas no formato MOEDA/BASE (p.ex., USD/EUR).
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från RatesAPI.
Skriv därefter in förväntad kursnotering på formatet VALUTA/BAS (t.ex. USD/EUR).
Comment[uk]=Ви можете отримати список доступних курсів з сайта RatesAPI.
Далі, введіть потрібний вам курс у форматі ВАЛЮТА/ЕТАЛОН (наприклад USD/EUR).
Comment[x-test]=xxYou can get the list of available quotes from RatesAPI.
Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=ratesapi
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=RatesAPI
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-script=skrooge-ratesapi.py %1
#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
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
index 43e082ef8..15b1787f1 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
@@ -1,87 +1,92 @@
[Desktop Entry]
Name=Skrooge
Name[bs]=Skrooge
Name[ca]=Skrooge
Name[ca@valencia]=Skrooge
Name[cs]=Skrooge
Name[da]=Skrooge
Name[de]=Skrooge
Name[el]=Skrooge
Name[en_GB]=Skrooge
Name[eo]=Skrooge
Name[es]=Skrooge
Name[et]=Skrooge
Name[fi]=Skrooge
Name[fr]=Skrooge
Name[gl]=Skrooge
Name[hu]=Skrooge
Name[it]=Skrooge
Name[lt]=Skrooge
Name[nb]=Skrooge
Name[nl]=Skrooge
Name[pl]=Skrooge
Name[pt]=Skrooge
Name[pt_BR]=Skrooge
Name[ru]=Skrooge
Name[sk]=Skrooge
Name[sv]=Skrooge
Name[tr]=Skrooge
Name[uk]=Skrooge
Name[x-test]=xxSkroogexx
Name[zh_CN]=Skrooge
Name[zh_TW]=Skrooge
Comment=Here is the list of available quotes: fr_inflation.
Comment[ca]=Aquí hi ha la llista de cotitzacions disponibles: fr_inflation.
Comment[ca@valencia]=Ací hi ha la llista de cotitzacions disponibles: fr_inflation.
Comment[en_GB]=Here is the list of available quotes: fr_inflation.
Comment[es]=Esta es la lista de las cotizaciones disponibles: fr_inflation.
Comment[et]=Saadaolevate kursside loend: fr_inflation.
Comment[fr]=Voici la liste des cotations disponibles: fr_inflation.
Comment[gl]=Esta é a lista de cotizacións dispoñíbeis: fr_inflation.
Comment[it]=Ecco l'elenco delle quotazioni disponibili: fr_inflation.
Comment[nl]=Hier is de lijst met beschikbare quotes: fr_inflation.
Comment[pl]=Oto lista dostępnych wycen: fr_inflation.
Comment[pt]=Aqui está a lista de cotações disponíveis: fr_inflation.
Comment[sv]=Här är listan över tillgängliga kursnoteringar: fr_inflation
Comment[uk]=Ось список доступних курсів: fr_inflation.
Comment[x-test]=xxHere is the list of available quotes: fr_inflation.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=skrooge
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Skrooge
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=https://filedn.com/lfh5wtnkbtUFtBhIeKEriJz/skrooge/%1.csv
#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
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
index a09adb471..40a0565b1 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
@@ -1,73 +1,78 @@
[Desktop Entry]
Name=Stooq
Name[ca]=Stooq
Name[ca@valencia]=Stooq
Name[de]=Stooq
Name[en_GB]=Stooq
Name[es]=Stooq
Name[et]=Stooq
Name[fr]=Stooq
Name[gl]=Stooq
Name[it]=Stooq
Name[nl]=Stooq
Name[pl]=Stooq
Name[pt]=Stooq
Name[pt_BR]=Stooq
Name[sv]=Stooq
Name[uk]=Stooq
Name[x-test]=xxStooqxx
Comment=You can get the list of available quotes from Stooq.
Then, enter the symbol of the expected quotes.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a Stooq.
Després introduïu el símbol de les cotitzacions esperades.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a Stooq.
Després introduïu el símbol de les cotitzacions esperades.
Comment[en_GB]=You can get the list of available quotes from Stooq.
Then, enter the symbol of the expected quotes.
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de Stooq.
A continuación, introduzca el símbolo de las cotizaciones esperadas.
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt Stooq.Seejärel sisesta oodatava kursi sümbol.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis Stooq.
Ensuite, saisissez le symbole de la cotation souhaitée.
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de Stooq.
A continuación escriba o símbolo das cotizacións esperadas.
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da Stooq.
Digita, quindi, il simbolo delle quotazioni desiderate.
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit Stooq.
Voer dan het symbool van de gewenste koers in.
Comment[pl]=Możesz pobrać wykaz dostępnych wycen z Stooq.
Następnie podaj symbol żądanej wyceny.
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do Stooq.
Depois, indique o símbolo das cotações esperadas.
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från Stooq.
Skriv därefter in symbolen för de förväntade kurserna.
Comment[uk]=Список доступних курсів можна отримати з Stooq
Далі, введіть позначення потрібного курсу.
Comment[x-test]=xxYou can get the list of available quotes from Stooq.
Then, enter the symbol of the expected quotes.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=stooq
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Stooq
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=https://stooq.pl/q/l/?s=%1&f=sd2t2ohlcv&h&e=csv
#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
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=%1,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),.*
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=%1,([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
index 72d0eb833..9437a586a 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
@@ -1,76 +1,81 @@
[Desktop Entry]
Name=Yahoo
Name[ca]=Yahoo
Name[ca@valencia]=Yahoo
Name[cs]=Yahoo
Name[de]=Yahoo
Name[en_GB]=Yahoo
Name[es]=Yahoo
Name[et]=Yahoo
Name[fr]=Yahoo
Name[gl]=Yahoo
Name[ia]=Yahoo
Name[it]=Yahoo
Name[nl]=Yahoo
Name[pl]=Yahoo
Name[pt]=Yahoo
Name[pt_BR]=Yahoo
Name[sv]=Yahoo
Name[uk]=Yahoo
Name[x-test]=xxYahooxx
Name[zh_CN]=Yahoo
Comment=You can get the list of available quotes from Yahoo Finance.
Then, enter the symbol of the expected quotes.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a Yahoo Finance.
Després introduïu el símbol de les cotitzacions esperades.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a Yahoo Finance.
Després introduïu el símbol de les cotitzacions esperades.
Comment[en_GB]=You can get the list of available quotes from Yahoo Finance.
Then, enter the symbol of the expected quotes.
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de Yahoo Finance.
A continuación, introduzca el símbolo de las cotizaciones esperadas.
Comment[et]=Saadaolevate kursside loendi võib hankida saidilt Yahoo Finance.
Seejärel sisesta oodatava kursi sümbol.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis Yahoo Finance.
Ensuite, saisissez le symbole de la cotation souhaitée.
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de Yahoo Finance.A continuación escriba o símbolo das cotizacións esperadas.
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da Yahoo Finanza.
Digita, quindi, il simbolo delle quotazioni desiderate.
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit Yahoo Finance.
Voer dan de naam van de gewenste koers in.
Comment[pl]=Możesz pobrać wykaz dostępnych wycen z Yahoo Finance.
Następnie podaj symbol żądanej wyceny.
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do Yahoo Finance. Depois, indique o símbolo das cotações esperadas.
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från Yahoo Finance.
Skriv därefter in symbolen för de förväntade kurserna.
Comment[uk]=Список доступних курсів можна отримати з Yahoo Finance.
Далі, введіть позначення потрібних курсів.
Comment[x-test]=xxYou can get the list of available quotes from Yahoo Finance.
Then, enter the symbol of the expected quotes.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=yahoo
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Yahoo
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
+#To know if this plugin needs a key API
+X-SKROOGE-keyAPI=false
+
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
+#%4 will be replaced by the interval
+#%5 will be replaced by the key API
#Example:
# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-script=skrooge-yahoodl.py %1 %3 %2 %4
#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
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,[^,]*,[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd