Extended BibleGateway integration, now loads chapters
[kworship.git] / kworship / bible / KwBibleManagerBibleGateway.cpp
blob4d779f4d1aa545bd9d647a76e44809e75b303201
1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 /**
21 * @file KwBibleManagerBibleGateway.cpp
22 * @brief A bible manager for BibleGateway.com.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwBibleManagerBibleGateway.h"
27 #include "KwBibleModuleBibleGateway.h"
29 #include <KIO/NetAccess>
30 #include <KMessageBox>
32 #include <QFile>
33 #include <QDomDocument>
34 #include <QDomElement>
35 #include <QDomNodeList>
38 * Constructors + destructor
41 /// Default constructor.
42 KwBibleManagerBibleGateway::KwBibleManagerBibleGateway()
43 : KwBibleManager()
44 , m_cached(false)
45 , m_languages()
46 , m_versionsById()
47 , m_versionsByName()
48 , m_versionsByLanguage()
52 /// Destructor.
53 KwBibleManagerBibleGateway::~KwBibleManagerBibleGateway()
55 foreach (Version* version, m_versionsById)
57 delete version->module;
58 delete version;
63 * Main interface
66 QString KwBibleManagerBibleGateway::name() const
68 return "BibleGateway.com";
71 bool KwBibleManagerBibleGateway::isRemote() const
73 return true;
76 KwBibleModule* KwBibleManagerBibleGateway::module(const QString& name)
78 QHash<QString, Version*>::iterator it = m_versionsByName.find(name);
79 Version* version = 0;
80 // Does the module with this name exist?
81 if (it != m_versionsByName.end())
83 version = *it;
85 // Otherwise perhaps its a language
86 else
88 int langId = m_languages.indexOf(name);
89 if (-1 != langId)
91 // Just get the first module of this language
92 const QList<int>& moduleIds = m_versionsByLanguage[langId];
93 if (!moduleIds.isEmpty())
95 int id = moduleIds.first();
96 version = m_versionsById[id];
100 if (0 != version)
102 if (0 == version->module)
104 version->module = new KwBibleModuleBibleGateway(version->id);
106 return version->module;
108 else
110 return 0;
114 QStringList KwBibleManagerBibleGateway::moduleNames()
116 ensureCached();
117 return m_versionsByName.keys();
120 QStringList KwBibleManagerBibleGateway::moduleNamesInLanguage(const QString& lang)
122 ensureCached();
123 int languageId = m_languages.indexOf(lang);
124 QStringList names;
125 if (languageId >= 0)
127 const QList<int>& moduleIds = m_versionsByLanguage[languageId];
128 foreach (int id, moduleIds)
130 names << m_versionsById[id]->name;
133 return names;
136 QStringList KwBibleManagerBibleGateway::languages()
138 ensureCached();
139 return m_languages;
143 * Private functions
146 /// Ensure the version information is cached.
147 void KwBibleManagerBibleGateway::ensureCached()
149 if (!m_cached)
151 QString tmpFile;
152 if (KIO::NetAccess::download(KUrl("http://www.biblegateway.com/"), tmpFile, 0))
154 QFile file(tmpFile);
155 if (file.open(QFile::ReadOnly | QFile::Text))
157 QByteArray rawPage = file.readAll();
158 file.close();
159 /// @todo Convert to use KDE DOM as its a bit more flexible of invalid XML
160 QString page = QString::fromUtf8(rawPage);
161 QRegExp rx("<select\\s+name=\"qs_version\">.*</select>");
162 if (-1 != rx.indexIn(page))
164 QDomDocument dom;
165 if (dom.setContent(rx.cap(), false))
167 // Go through all the options (languages and versions)
168 int langId = -1;
169 QList<int>* langMods = 0;
170 QDomNodeList options = dom.elementsByTagName("option");
171 for (int i = 0; i < options.count(); ++i)
173 QDomElement el = options.at(i).toElement();
174 if (!el.isNull())
176 // Its either a language (with class="lang") or a version
177 QString className = el.attribute("class");
178 QString text = el.text();
179 if (className == "lang")
181 m_languages << text;
182 ++langId;
183 langMods = &m_versionsByLanguage[langId];
185 else if (langId >= 0)
187 bool ok;
188 int versionId = el.attribute("value").toInt(&ok);
189 if (ok)
191 // Ensure there is none with this id already
192 QHash<int, Version*>::const_iterator it = m_versionsById.constFind(versionId);
193 if (it == m_versionsById.constEnd())
195 Version* version = new Version;
196 version->name = text;
197 version->id = versionId;
198 version->module = 0;
199 m_versionsById[versionId] = version;
200 m_versionsByName[text] = version;
201 *langMods << versionId;
207 m_cached = true;
212 KIO::NetAccess::removeTempFile(tmpFile);
214 else
216 KMessageBox::error(0, KIO::NetAccess::lastErrorString());
221 /// Clear all modules.
222 void KwBibleManagerBibleGateway::clear()
224 if (m_cached)
226 foreach (Version* version, m_versionsById)
228 delete version->module;
229 delete version;
231 m_cached = false;
232 m_languages.clear();
233 m_versionsById.clear();
234 m_versionsByName.clear();
235 m_versionsByLanguage.clear();