alkimia  8.0.3
alkonlinequotesprofile.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2018 Ralf Habacker <ralf.habacker@freenet.de> *
3  * *
4  * This file is part of libalkimia. *
5  * *
6  * libalkimia is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public License *
8  * as published by the Free Software Foundation; either version 2.1 of *
9  * the License or (at your option) version 3 or any later version. *
10  * *
11  * libalkimia is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program. If not, see <http://www.gnu.org/licenses/> *
18  ***************************************************************************/
19 
20 #include "alkonlinequotesprofile.h"
22 
23 #include "alkonlinequotesource.h"
24 #include "alkfinancequoteprocess.h"
25 
26 #include <QApplication>
27 #include <QDir>
28 #include <QLibraryInfo>
29 #include <QString>
30 #include <QtDebug>
31 #include <QFileInfo>
32 
33 #include <KConfig>
34 #include <KConfigGroup>
35 #include <KGlobal>
36 #include <KStandardDirs>
37 #include <knewstuff3/downloadmanager.h>
38 
39 class AlkOnlineQuotesProfile::Private : public QObject
40 {
41  Q_OBJECT
42 public:
44  QString m_name;
45  QString m_GHNSFile;
46  QString m_GHNSFilePath;
47  QString m_kconfigFile;
49  KNS3::DownloadManager *m_manager;
50  KConfig *m_config;
52  static QString m_financeQuoteScriptPath;
53  static QStringList m_financeQuoteSources;
54 
56  : m_p(p)
57  , m_profileManager(0)
58  , m_manager(0)
59  , m_config(0)
60  , m_type(Type::Undefined)
61  {
62 
63  if (m_financeQuoteScriptPath.isEmpty()) {
64  m_financeQuoteScriptPath = KGlobal::dirs()->findResource("appdata",
65  QString("misc/financequote.pl"));
66  }
67  }
68 
70  {
71  delete m_manager;
72  delete m_config;
73  }
74 
75  void checkUpdates()
76  {
77  m_manager = new KNS3::DownloadManager(m_p->hotNewStuffConfigFile(), this);
78  // to know when checking for updates is done
79  connect(m_manager, SIGNAL(searchResult(KNS3::Entry::List)), this,
80  SLOT(slotUpdatesFound(KNS3::Entry::List)));
81  // to know about finished installations
82  connect(m_manager, SIGNAL(entryStatusChanged(KNS3::Entry)), this,
83  SLOT(entryStatusChanged(KNS3::Entry)));
84  // start checking for updates
85  m_manager->checkForUpdates();
86  }
87 
88 public Q_SLOTS:
89  void slotUpdatesFound(const KNS3::Entry::List &updates)
90  {
91  foreach (const KNS3::Entry &entry, updates) {
92  qDebug() << entry.name();
93  }
94  }
95 
96  // to know about finished installations
97  void entryStatusChanged(const KNS3::Entry &entry)
98  {
99  qDebug() << entry.summary();
100  }
101 
102  const QStringList quoteSourcesNative()
103  {
104  //KSharedConfigPtr kconfig = KGlobal::config();
105  KConfig config(m_kconfigFile);
106  KConfig *kconfig = &config;
107  QStringList groups = kconfig->groupList();
108 
109  QStringList::Iterator it;
110  QRegExp onlineQuoteSource(QString("^Online-Quote-Source-(.*)$"));
111 
112  // get rid of all 'non online quote source' entries
113  for (it = groups.begin(); it != groups.end(); it = groups.erase(it)) {
114  if (onlineQuoteSource.indexIn(*it) >= 0) {
115  // Insert the name part
116  it = groups.insert(it, onlineQuoteSource.cap(1));
117  ++it;
118  }
119  }
120 
121  // Set up each of the default sources. These are done piecemeal so that
122  // when we add a new source, it's automatically picked up. And any changes
123  // are also picked up.
124  QMap<QString, AlkOnlineQuoteSource> defaults = defaultQuoteSources();
125  QMap<QString, AlkOnlineQuoteSource>::iterator it_source = defaults.begin();
126  while (it_source != defaults.end()) {
127  if (!groups.contains((*it_source).name())) {
128  groups += (*it_source).name();
129  (*it_source).write();
130  kconfig->sync();
131  }
132  ++it_source;
133  }
134 
135  return groups;
136  }
137 
138  const QStringList quoteSourcesFinanceQuote()
139  {
140  if (m_financeQuoteSources.empty()) { // run the process one time only
141  // since this is a static function it can be called without constructing an object
142  // so we need to make sure that m_financeQuoteScriptPath is properly initialized
143  if (m_financeQuoteScriptPath.isEmpty()) {
144  m_financeQuoteScriptPath = KGlobal::dirs()->findResource("data",
145  QString("alkimia/misc/financequote.pl"));
146  }
147  AlkFinanceQuoteProcess getList;
149  while (!getList.isFinished()) {
150  qApp->processEvents();
151  }
153  }
154  return m_financeQuoteSources;
155  }
156 
157  const QStringList quoteSourcesSkrooge()
158  {
159  return quoteSourcesGHNS();
160  }
161 
162  const QStringList quoteSourcesGHNS()
163  {
164  QStringList sources;
165  QString relPath = m_GHNSFilePath;
166 
167  foreach (const QString &file,
168  KStandardDirs().findAllResources("data", relPath + QString::fromLatin1("/*.txt"))) {
169  QFileInfo f(file);
170  QString file2 = f.completeBaseName();
171  AlkOnlineQuoteSource source(file2, m_p);
172  if (source.isEmpty()) {
173  qDebug() << "skipping" << file2;
174  continue;
175  }
176  if (!sources.contains(file2)) {
177  sources.push_back(file2);
178  }
179  }
180 
181  return sources;
182  }
183 
185  {
186  QMap<QString, AlkOnlineQuoteSource> result;
187 
188  // Use fx-rate.net as the standard currency exchange rate source until
189  // we have the capability to use more than one source. Use a neutral
190  // name for the source.
191 
192  switch (m_p->type()) {
196  AlkOnlineQuoteSource source("Alkimia Currency",
197  "https://fx-rate.net/%1/%2",
198  QString(), // symbolregexp
199  "1[ a-zA-Z]+=</span><br */?> *(\\d+\\.\\d+)",
200  "updated\\s\\d+:\\d+:\\d+\\(\\w+\\)\\s+(\\d{1,2}/\\d{2}/\\d{4})",
201  "%d/%m/%y",
202  true // skip HTML stripping
203  );
204  source.setProfile(m_p);
205  result[source.name()] = source;
206 #if defined(BUILD_WITH_WEBKIT)
207  source.setName(source.name() + ".webkit");
208  result[source.name()] = source;
209 #endif
210  break;
211  }
212  default:
213  break;
214  }
215  return result;
216  }
217 
222  QString dataRootPath()
223  {
224  return QLibraryInfo::location(QLibraryInfo::PrefixPath) + "/share";
225  }
226 
231  QString homeRootPath()
232  {
234  return QDir::homePath();
236 #ifdef Q_OS_WIN
237  return qgetenv("APPDATA");
238 #else
239  return QDir::homePath();
240 #endif
241  } else {
242  return QString();
243  }
244  }
245 
246  QString configPath()
247  {
249  return QString("%1/.config").arg(homeRootPath());
251  return QString("%1/.kde4/share/config").arg(homeRootPath());
252  return
253  QString();
254  }
255 
256  QString dataReadPath()
257  {
259  return dataRootPath();
261  return QString("%1/kde4/apps").arg(dataRootPath());
262  return
263  QString();
264  }
265 
266  QString dataWritePath()
267  {
269  return QString("%1/.local/share").arg(homeRootPath());
271  return QString("%1/.kde4/share/apps").arg(homeRootPath());
272  return
273  QString();
274  }
275 };
276 
277 // define static members
280 
281 
283  const QString &ghnsConfigFile)
284  : d(new Private(this))
285 {
286  d->m_name = name;
287  d->m_GHNSFile = ghnsConfigFile;
288  d->m_type = type;
289  if (type == Type::KMyMoney5)
290  d->m_kconfigFile = QString("%1/kmymoney/kmymoneyrc").arg(d->configPath());
291  else if (type == Type::KMyMoney4)
292  d->m_kconfigFile = QString("%1/kmymoneyrc").arg(d->configPath());
293  else if (type == Type::Alkimia5 || type == Type::Alkimia4)
294  d->m_kconfigFile = QString("%1/alkimiarc").arg(d->configPath());
295  else
296  d->m_kconfigFile = "";
297  if (!d->m_kconfigFile.isEmpty())
298  d->m_config = new KConfig(d->m_kconfigFile);
299  if (!d->m_GHNSFile.isEmpty()) {
300  KConfig ghnsFile(hotNewStuffConfigFile());
301  KConfigGroup group = ghnsFile.group("KNewStuff3");
302  d->m_GHNSFilePath = group.readEntry("TargetDir");
303  d->checkUpdates();
304  }
305 }
306 
308 {
309  delete d;
310 }
311 
313 {
314  return d->m_name;
315 }
316 
318 {
319  QString configFile = KStandardDirs::locate("config", d->m_GHNSFile);
320  if (configFile.isEmpty()) {
321  configFile = QString("%1/%2").arg(KNSRC_DIR, d->m_GHNSFile);
322  }
323 
324  return configFile;
325 }
326 
327 QString AlkOnlineQuotesProfile::hotNewStuffReadFilePath(const QString &fileName) const
328 {
329  foreach(const QString &path, hotNewStuffReadPath()) {
330  QFileInfo f(path + fileName);
331  if (f.exists())
332  return f.absoluteFilePath();
333  }
334  return QString();
335 }
336 
337 QString AlkOnlineQuotesProfile::hotNewStuffWriteFilePath(const QString &fileName) const
338 {
339  return QString("%1%2").arg(hotNewStuffWriteDir(), fileName);
340 }
341 
343 {
344  return QStringList()
345  << QString("%1/%2/").arg(d->dataReadPath(), d->m_GHNSFilePath)
346  << hotNewStuffWriteDir();
347 }
348 
350 {
351  return QString("%1/%2/").arg(d->dataWritePath(), d->m_GHNSFilePath);
352 }
353 
355 {
356  return d->m_GHNSFilePath;
357 }
358 
360 {
361  return d->m_kconfigFile;
362 }
363 
365 {
366  return d->m_config;
367 }
368 
370 {
371  return d->m_type;
372 }
373 
375 {
376  return !d->m_GHNSFile.isEmpty();
377 }
378 
380 {
381  return d->defaultQuoteSources();
382 }
383 
385 {
386  QStringList result;
387  switch(d->m_type) {
392  result << d->quoteSourcesNative();
393  break;
395  result << d->quoteSourcesFinanceQuote();
396  break;
398  result << d->defaultQuoteSources().keys();
399  break;
400  default:
401  break;
402  }
403  if (hasGHNSSupport())
404  result << d->quoteSourcesGHNS();
405  return result;
406 }
407 
409 {
411 }
412 
414 {
415  return d->m_profileManager;
416 }
417 
419 {
420  return d->m_financeQuoteScriptPath;
421 }
422 
423 #include "alkonlinequotesprofile.moc"
const QStringList getSourceList() const
void launch(const QString &scriptPath)
void setProfile(AlkOnlineQuotesProfile *profile)
void setName(const QString &name)
const AlkOnlineQuotesProfile::Map defaultQuoteSources()
QString homeRootPath()
return home root path
void slotUpdatesFound(const KNS3::Entry::List &updates)
QString dataRootPath()
return data root path
Private(AlkOnlineQuotesProfile *p)
void entryStatusChanged(const KNS3::Entry &entry)
AlkOnlineQuotesProfileManager * m_profileManager
AlkOnlineQuotesProfileManager * manager()
QString hotNewStuffWriteFilePath(const QString &fileName) const
QMap< QString, AlkOnlineQuoteSource > Map
void setManager(AlkOnlineQuotesProfileManager *manager)
AlkOnlineQuotesProfile(const QString &name="alkimia", Type type=Type::None, const QString &ghnsConfigFile=QString())
QStringList hotNewStuffReadPath() const
QString hotNewStuffReadFilePath(const QString &fileName) const
const QStringList quoteSources()