1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
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. *
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. *
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 ***************************************************************************/
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>
31 #include <KGenericFactory>
34 #include <QDomDocument>
35 #include <QDomElement>
36 #include <QDomNodeList>
38 KW_REGISTER_BIBLE_MANAGER(KwBibleManagerBibleGateway
)
40 K_EXPORT_COMPONENT_FACTORY( kworship_bible_biblegateway
, KGenericFactory
<KwBibleManagerBibleGateway
>("kworship_bible_biblegateway") )
43 * Constructors + destructor
46 /// Default constructor.
47 KwBibleManagerBibleGateway::KwBibleManagerBibleGateway(QObject
* parent
, const QStringList
& params
)
48 : KwBibleManager(parent
, params
)
53 , m_versionsByLanguage()
59 KwBibleManagerBibleGateway::~KwBibleManagerBibleGateway()
61 foreach (Version
* version
, m_versions
)
63 delete version
->module
;
72 QString
KwBibleManagerBibleGateway::name() const
74 return "BibleGateway.com";
77 bool KwBibleManagerBibleGateway::isRemote() const
82 KwBibleModule
* KwBibleManagerBibleGateway::module(const QString
& name
)
84 QHash
<QString
, Version
*>::iterator it
= m_versionsByName
.find(name
);
86 // Does the module with this name exist?
87 if (it
!= m_versionsByName
.end())
91 // Otherwise perhaps its a language
94 int langId
= m_languages
.indexOf(name
);
97 // Just get the first module of this language
98 const QList
<int>& moduleIds
= m_versionsByLanguage
[langId
];
99 if (!moduleIds
.isEmpty())
101 int id
= moduleIds
.first();
102 version
= m_versions
[id
];
108 if (0 == version
->module
)
110 version
->module
= new KwBibleModuleBibleGateway(version
->url
);
112 return version
->module
;
120 QStringList
KwBibleManagerBibleGateway::moduleNames()
123 return m_versionsByName
.keys();
126 QStringList
KwBibleManagerBibleGateway::moduleNamesInLanguage(const QString
& lang
)
129 int languageId
= m_languages
.indexOf(lang
);
133 const QList
<int>& moduleIds
= m_versionsByLanguage
[languageId
];
134 foreach (int id
, moduleIds
)
136 names
<< m_versions
[id
]->name
;
142 QStringList
KwBibleManagerBibleGateway::languages()
152 /// Ensure the version information is cached.
153 void KwBibleManagerBibleGateway::ensureCached()
158 // First get list from drop down menu on main page
160 if (KIO::NetAccess::download(KUrl("http://mobile.biblegateway.com/"), tmpFile
, 0))
163 if (file
.open(QFile::ReadOnly
| QFile::Text
))
165 QByteArray rawPage
= file
.readAll();
167 QString page
= QString::fromUtf8(rawPage
);
168 QRegExp
rx("<select\\s+name=\"qs_version\">.*</select>");
169 if (-1 != rx
.indexIn(page
))
172 if (dom
.setContent(rx
.cap(), false))
174 // Go through all the options (languages and versions)
176 QList
<int>* langMods
= 0;
177 QDomNodeList options
= dom
.elementsByTagName("option");
178 for (int i
= 0; i
< options
.count(); ++i
)
180 QDomElement el
= options
.at(i
).toElement();
183 // Its either a language (with class="lang") or a version
184 QString className
= el
.attribute("class");
185 QString text
= el
.text();
186 if (className
== "lang")
190 langMods
= &m_versionsByLanguage
[langId
];
192 else if (langId
>= 0)
194 QString versionId
= el
.attribute("value");
195 // Ensure there is none with this shortname already
196 QHash
<QString
, Version
*>::const_iterator it
= m_versionsByShortName
.constFind(versionId
);
197 if (it
== m_versionsByShortName
.constEnd())
199 Version
* version
= new Version
;
200 version
->name
= text
;
201 version
->shortname
= versionId
;
202 version
->id
= m_versionsById
.size();
204 m_versionsById
[version
->id
] = version
;
205 m_versionsByName
[text
] = version
;
206 m_versionsByShortName
[versionId
] = version
;
207 *langMods
<< version
->id
;
217 if (KIO::NetAccess::download(KUrl("http://mobile.biblegateway.com/versions"), tmpFile
, 0))
220 if (file
.open(QFile::ReadOnly
| QFile::Text
))
222 QByteArray rawPage
= file
.readAll();
224 QString page
= QString::fromUtf8(rawPage
);
225 QRegExp
rx("<table[^>]*class=\"infotable\">.*</table>");
226 if (-1 != rx
.indexIn(page
))
229 if (dom
.setContent(rx
.cap(), false))
231 // Go through all the options (languages and versions)
234 QList
<int>* langMods
= 0;
235 QDomNodeList rows
= dom
.elementsByTagName("tr");
236 for (int i
= 0; i
< rows
.count(); ++i
)
238 QDomElement row
= rows
.at(i
).toElement();
241 QDomNodeList cols
= row
.elementsByTagName("td");
242 for (int j
= 0; j
< cols
.count(); ++j
)
244 QDomElement cell
= cols
.at(j
).toElement();
247 // if first columnn and rowspan, its a language
248 QString rowSpanStr
= cell
.attribute("rowspan");
250 int newRowSpan
= rowSpanStr
.toInt(&ok
);
251 if (!j
&& ok
&& newRowSpan
)
253 QString text
= cell
.text();
256 langMods
= &m_versionsByLanguage
[langId
];
257 rowSpan
= newRowSpan
;
259 else if (langId
>= 0)
261 QDomNodeList as
= cell
.elementsByTagName("a");
264 QDomElement ael
= as
.at(0).toElement();
267 QString href
= ael
.attribute("href");
268 QString text
= ael
.text();
269 QHash
<QString
, Version
*>::const_iterator it
= m_versionsByName
.constFind(text
);
270 if (it
== m_versionsByName
.constEnd())
272 Version
* version
= new Version
;
273 version
->name
= text
;
274 version
->id
= m_versions
.size();
277 m_versions
.push_back(version
);
278 m_versionsByName
[text
] = version
;
279 *langMods
<< version
->id
;
283 // jump out of column loop
297 KIO::NetAccess::removeTempFile(tmpFile
);
301 KMessageBox::error(0, KIO::NetAccess::lastErrorString());
306 /// Clear all modules.
307 void KwBibleManagerBibleGateway::clear()
311 foreach (Version
* version
, m_versions
)
313 delete version
->module
;
319 m_versionsByName
.clear();
320 m_versionsByLanguage
.clear();