alkimia  8.0.2
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("appdata",
145  QString("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  source.setName(source.name() + ".webkit");
207  result[source.name()] = source;
208  break;
209  }
210  default:
211  break;
212  }
213  return result;
214  }
215 
220  QString dataRootPath()
221  {
222  return QLibraryInfo::location(QLibraryInfo::PrefixPath) + "/share";
223  }
224 
229  QString homeRootPath()
230  {
232  return QDir::homePath();
234 #ifdef Q_OS_WIN
235  return qgetenv("APPDATA");
236 #else
237  return QDir::homePath();
238 #endif
239  } else {
240  return QString();
241  }
242  }
243 
244  QString configPath()
245  {
247  return QString("%1/.config").arg(homeRootPath());
249  return QString("%1/.kde4/share/config").arg(homeRootPath());
250  return
251  QString();
252  }
253 
254  QString dataReadPath()
255  {
257  return dataRootPath();
259  return QString("%1/kde4/apps").arg(dataRootPath());
260  return
261  QString();
262  }
263 
264  QString dataWritePath()
265  {
267  return QString("%1/.local/share").arg(homeRootPath());
269  return QString("%1/.kde4/share/apps").arg(homeRootPath());
270  return
271  QString();
272  }
273 };
274 
275 // define static members
278 
279 
281  const QString &ghnsConfigFile)
282  : d(new Private(this))
283 {
284  d->m_name = name;
285  d->m_GHNSFile = ghnsConfigFile;
286  d->m_type = type;
287  if (type == Type::KMyMoney5)
288  d->m_kconfigFile = QString("%1/kmymoney/kmymoneyrc").arg(d->configPath());
289  else if (type == Type::KMyMoney4)
290  d->m_kconfigFile = QString("%1/kmymoneyrc").arg(d->configPath());
291  else if (type == Type::Alkimia5 || type == Type::Alkimia4)
292  d->m_kconfigFile = QString("%1/alkimiarc").arg(d->configPath());
293  else
294  d->m_kconfigFile = "";
295  if (!d->m_kconfigFile.isEmpty())
296  d->m_config = new KConfig(d->m_kconfigFile);
297  if (!d->m_GHNSFile.isEmpty()) {
298  KConfig ghnsFile(hotNewStuffConfigFile());
299  KConfigGroup group = ghnsFile.group("KNewStuff3");
300  d->m_GHNSFilePath = group.readEntry("TargetDir");
301  d->checkUpdates();
302  }
303 }
304 
306 {
307  delete d;
308 }
309 
311 {
312  return d->m_name;
313 }
314 
316 {
317  QString configFile = KStandardDirs::locate("config", d->m_GHNSFile);
318  if (configFile.isEmpty()) {
319  configFile = QString("%1/%2").arg(KNSRC_DIR, d->m_GHNSFile);
320  }
321 
322  return configFile;
323 }
324 
325 QString AlkOnlineQuotesProfile::hotNewStuffReadFilePath(const QString &fileName) const
326 {
327  foreach(const QString &path, hotNewStuffReadPath()) {
328  QFileInfo f(path + fileName);
329  if (f.exists())
330  return f.absoluteFilePath();
331  }
332  return QString();
333 }
334 
335 QString AlkOnlineQuotesProfile::hotNewStuffWriteFilePath(const QString &fileName) const
336 {
337  return QString("%1%2").arg(hotNewStuffWriteDir(), fileName);
338 }
339 
341 {
342  return QStringList()
343  << QString("%1/%2/").arg(d->dataReadPath(), d->m_GHNSFilePath)
344  << hotNewStuffWriteDir();
345 }
346 
348 {
349  return QString("%1/%2/").arg(d->dataWritePath(), d->m_GHNSFilePath);
350 }
351 
353 {
354  return d->m_GHNSFilePath;
355 }
356 
358 {
359  return d->m_kconfigFile;
360 }
361 
363 {
364  return d->m_config;
365 }
366 
368 {
369  return d->m_type;
370 }
371 
373 {
374  return !d->m_GHNSFile.isEmpty();
375 }
376 
378 {
379  return d->defaultQuoteSources();
380 }
381 
383 {
384  QStringList result;
385  switch(d->m_type) {
390  result << d->quoteSourcesNative();
391  break;
393  result << d->quoteSourcesFinanceQuote();
394  break;
396  result << d->defaultQuoteSources().keys();
397  break;
398  default:
399  break;
400  }
401  if (hasGHNSSupport())
402  result << d->quoteSourcesGHNS();
403  return result;
404 }
405 
407 {
409 }
410 
412 {
413  return d->m_profileManager;
414 }
415 
416 #include "alkonlinequotesprofile.moc"
QString hotNewStuffWriteFilePath(const QString &fileName) const
void launch(const QString &scriptPath)
void entryStatusChanged(const KNS3::Entry &entry)
void setManager(AlkOnlineQuotesProfileManager *manager)
void slotUpdatesFound(const KNS3::Entry::List &updates)
void setName(const QString &name)
QString hotNewStuffReadFilePath(const QString &fileName) const
AlkOnlineQuotesProfileManager * m_profileManager
QString dataRootPath()
return data root path
QString homeRootPath()
return home root path
Private(AlkOnlineQuotesProfile *p)
AlkOnlineQuotesProfileManager * manager()
AlkOnlineQuotesProfile(const QString &name="alkimia", Type type=Type::None, const QString &ghnsConfigFile=QString())
const AlkOnlineQuotesProfile::Map defaultQuoteSources()
QStringList hotNewStuffReadPath() const
QMap< QString, AlkOnlineQuoteSource > Map
const QStringList getSourceList() const
void setProfile(AlkOnlineQuotesProfile *profile)
const QStringList quoteSources()