Falkon Develop
Cross-platform Qt-based web browser
opensearchreader.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2009 Jakub Wieczorek <faw217@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
18 */
19/* ============================================================
20* Falkon - Qt web browser
21* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
22*
23* This program is free software: you can redistribute it and/or modify
24* it under the terms of the GNU General Public License as published by
25* the Free Software Foundation, either version 3 of the License, or
26* (at your option) any later version.
27*
28* This program is distributed in the hope that it will be useful,
29* but WITHOUT ANY WARRANTY; without even the implied warranty of
30* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31* GNU General Public License for more details.
32*
33* You should have received a copy of the GNU General Public License
34* along with this program. If not, see <http://www.gnu.org/licenses/>.
35* ============================================================ */
36#include "opensearchreader.h"
37
38#include "opensearchengine.h"
39
40#include <qiodevice.h>
41
65 : QXmlStreamReader()
66{
67}
68
86{
87 clear();
88
89 if (!device->isOpen()) {
90 device->open(QIODevice::ReadOnly);
91 }
92
93 setDevice(device);
94 return read();
95}
96
97OpenSearchEngine* OpenSearchReader::read()
98{
99 auto* engine = new OpenSearchEngine();
100 m_searchXml = QString::fromLatin1(device()->peek(1024 * 5));
101
102 if (!m_searchXml.contains(QLatin1String("http://a9.com/-/spec/opensearch/1.1/")) &&
103 !m_searchXml.contains(QLatin1String("http://www.mozilla.org/2006/browser/search/"))
104 ) {
105 raiseError(QObject::tr("The file is not an OpenSearch 1.1 file."));
106 return engine;
107 }
108
109 // It just skips the XML declaration
110 // The parsing code bellow for some reason doesn't like it -,-
111
112 int index = m_searchXml.indexOf(QLatin1String("<?xml"));
113 if (index > 0) {
114 int end = m_searchXml.indexOf(QLatin1String("?>"), index);
115
116 if (end > 0) {
117 device()->read(end + 2);
118 }
119 }
120
121 while (!isStartElement() && !atEnd()) {
122 readNext();
123 }
124
125
126 while (!atEnd()) {
127 readNext();
128
129 if (!isStartElement()) {
130 continue;
131 }
132
133 if (name() == QLatin1String("ShortName") || name() == QLatin1String("os:ShortName")) {
134 engine->setName(readElementText());
135 }
136 else if (name() == QLatin1String("Description") || name() == QLatin1String("os:Description")) {
137 engine->setDescription(readElementText());
138 }
139 else if (name() == QLatin1String("Url") || name() == QLatin1String("os:Url")) {
140 QString type = attributes().value(QLatin1String("type")).toString();
141 QString url = attributes().value(QLatin1String("template")).toString();
142 QString method = attributes().value(QLatin1String("method")).toString();
143
144 if (type == QLatin1String("application/x-suggestions+json") &&
145 !engine->suggestionsUrlTemplate().isEmpty()
146 ) {
147 continue;
148 }
149
150 if ((type.isEmpty() ||
151 type == QLatin1String("text/html") ||
152 type == QLatin1String("application/xhtml+xml")) &&
153 !engine->searchUrlTemplate().isEmpty()
154 ) {
155 continue;
156 }
157
158 if (url.isEmpty()) {
159 continue;
160 }
161
162 QList<OpenSearchEngine::Parameter> parameters;
163
164 readNext();
165
166 while (!isEndElement() || (name() != QLatin1String("Url") && name() != QLatin1String("os:Url"))) {
167 if (!isStartElement() || (name() != QLatin1String("Param") && name() != QLatin1String("Parameter") &&
168 name() != QLatin1String("os:Param") && name() != QLatin1String("os:Parameter"))
169 ) {
170 readNext();
171 continue;
172 }
173
174 QString key = attributes().value(QLatin1String("name")).toString();
175 QString value = attributes().value(QLatin1String("value")).toString();
176
177 if (!key.isEmpty() && !value.isEmpty()) {
178 parameters.append(OpenSearchEngine::Parameter(key, value));
179 }
180
181 while (!isEndElement()) {
182 readNext();
183 }
184 }
185
186 if (type == QLatin1String("application/x-suggestions+json")) {
187 engine->setSuggestionsUrlTemplate(url);
188 engine->setSuggestionsParameters(parameters);
189 engine->setSuggestionsMethod(method);
190 }
191 else if (type.isEmpty() || type == QLatin1String("text/html") || type == QLatin1String("application/xhtml+xml")) {
192 engine->setSearchUrlTemplate(url);
193 engine->setSearchParameters(parameters);
194 engine->setSearchMethod(method);
195 }
196
197 }
198 else if (name() == QLatin1String("Image") || name() == QLatin1String("os:Image")) {
199 engine->setImageUrl(readElementText());
200 }
201
202 if (!engine->name().isEmpty() &&
203 !engine->description().isEmpty() &&
204 !engine->suggestionsUrlTemplate().isEmpty() &&
205 !engine->searchUrlTemplate().isEmpty() &&
206 !engine->imageUrl().isEmpty()
207 ) {
208 break;
209 }
210 }
211
212 return engine;
213}
214
A class representing a single search engine described in OpenSearch format.
QPair< QString, QString > Parameter
OpenSearchEngine * read(QIODevice *device)
int value(const QColor &c)
Definition: colors.cpp:238