2 * This file is part of Jenirok.
4 * Jenirok 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 3 of the License, or
7 * (at your option) any later version.
9 * Jenirok 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.
14 * You should have received a copy of the GNU General Public License
15 * along with Jenirok. If not, see <http://www.gnu.org/licenses/>.
19 #include <QtCore/QDebug>
20 #include "dastelefonbuch.h"
23 DasTelefonbuch::DasTelefonbuch(QObject* parent): Source(parent)
27 DasTelefonbuch::~DasTelefonbuch()
32 void DasTelefonbuch::abort()
36 for(int i = 0; i < pendingSearches_.size(); i++)
38 delete pendingSearches_[i];
39 pendingSearches_[i] = 0;
42 pendingSearches_.clear();
45 void DasTelefonbuch::search(Source::SearchDetails const& details)
49 SearchData* newData = new SearchData;
50 newData->details = details;
51 newData->currentPage = 1;
52 newData->finishedSearches = 0;
54 if(details.type == Source::BOTH)
56 newData->totalSearches = 2;
57 Source::SearchDetails tmpDetails = details;
58 tmpDetails.type = Source::PERSONS;
59 int id1 = sendQuery(tmpDetails, 1);
60 tmpDetails.type = Source::YELLOW_PAGES;
61 int id2 = sendQuery(tmpDetails, 1);
62 newData->searchIds.insert(id1);
63 newData->searchIds.insert(id2);
67 newData->totalSearches = 1;
68 int id = sendQuery(details, 1);
69 newData->searchIds.insert(id);
72 pendingSearches_.push_back(newData);
75 void DasTelefonbuch::handleHttpData(int id, QByteArray const& data)
77 QString strData(data);
79 for(int i = 0; i < pendingSearches_.size(); i++)
81 if(pendingSearches_.at(i) && pendingSearches_.at(i)->searchIds.find(id) !=
82 pendingSearches_.at(i)->searchIds.end())
84 addNumbers(pendingSearches_.at(i), strData, i);
90 void DasTelefonbuch::handleHttpError(int id)
92 for(int i = 0; i < pendingSearches_.size(); i++)
94 if(pendingSearches_.at(i) && pendingSearches_.at(i)->searchIds.find(id) !=
95 pendingSearches_.at(i)->searchIds.end())
98 setError(Source::CONNECTION_FAILURE, http_.errorString());
99 emitRequestFinished(pendingSearches_.at(i), true, i);
105 void DasTelefonbuch::addNumbers(SearchData* searchData,
111 qDebug() << "Server returned no data";
112 setError(CONNECTION_FAILURE, "Server returned no data");
113 emitRequestFinished(searchData, true, index);
117 if(data.indexOf("<span>1 Gesamttreffer</span>") > 0)
119 addOnlyNumber(searchData, data, index);
124 static QRegExp rx("<table.*class=\"bg-01 entry(.*)</table>");
125 static QRegExp name("<div class=\"long hide\">(.*)</a>");
126 static QRegExp number("<td class=\"col4\">(.*)</td>");
127 static QRegExp address("<td class=\"col2\">(.*)</td>.*<td class=\"col3\">(.*)</td>");
130 name.setMinimal(true);
131 address.setMinimal(true);
132 number.setMinimal(true);
134 int maxResults = getMaxResults();
136 while((pos = rx.indexIn(data, pos)) != -1)
138 pos += rx.matchedLength();
140 if(searchData->results.size() >= maxResults)
145 QString part = rx.cap(1);
146 Source::Result result;
152 if(name.indexIn(part) != -1)
154 nameStr = name.cap(1);
157 if(address.indexIn(part) != -1)
159 streetStr = address.cap(1);
160 cityStr = address.cap(2);
163 if(number.indexIn(part) != -1)
165 numberStr = number.cap(1);
168 if(formatResult(nameStr, numberStr, streetStr,
171 emit resultAvailable(result, searchData->details);
172 searchData->results.push_back(result);
177 searchData->finishedSearches++;
179 if(searchData->results.size() >= maxResults)
181 emitRequestFinished(searchData, false, index);
185 /* TODO: Paging not implemented yet
186 if(data.indexOf("Neste") > 0)
188 searchData->currentPage++;
189 int id = sendQuery(searchData->details, searchData->currentPage);
190 searchData->searchIds.insert(id);
196 else if(searchData->finishedSearches >= searchData->totalSearches)
198 emitRequestFinished(searchData, false, index);
204 void DasTelefonbuch::addOnlyNumber(SearchData* searchData,
208 static QRegExp name("<div class=\"long hide\">(.*) (.*)</a>");
209 static QRegExp number("<td class=\"col4\">(.*)</td>");
210 static QRegExp address("<td class=\"col2\">(.*)</td>.*<td class=\"col3\">(.*)</td>");
211 name.setMinimal(true);
212 number.setMinimal(true);
213 address.setMinimal(true);
215 Source::Result result;
222 if(name.indexIn(data) != -1)
224 nameStr = name.cap(2).simplified() + name.cap(1).simplified();
225 nameStr.replace("\n","");
228 if(number.indexIn(data) != -1)
230 numberStr = number.cap(1);
233 if(address.indexIn(data) != -1)
235 streetStr = address.cap(1);
236 cityStr = address.cap(2);
239 if(formatResult(nameStr, numberStr, streetStr,
242 searchData->results.push_back(result);
243 emit resultAvailable(result, searchData->details);
246 emitRequestFinished(searchData, false, index);
249 bool DasTelefonbuch::formatResult(QString& name, QString& number,
250 QString& street, QString& city,
251 Source::Result& result)
253 name = stripTags(name);
254 name = htmlEntityDecode(name);
255 result.name = name.trimmed();
256 number = stripTags(number);
257 number = cleanUpNumber(number);
258 result.number = number.trimmed();
259 street = stripTags(street);
260 street = htmlEntityDecode(street);
261 city = stripTags(city);
262 city = htmlEntityDecode(city);
263 result.street = street.trimmed();
264 result.city = city.trimmed();
265 result.country = "Germany";
267 if(!result.name.isEmpty() && (!getFindNumber() || !result.number.isEmpty()))
274 void DasTelefonbuch::emitRequestFinished(SearchData* data,
275 bool error, int index)
277 QVector<Source::Result> results = data->results;
278 Source::SearchDetails details = data->details;
280 emit requestFinished(results, details, error);
281 delete pendingSearches_[index];
282 pendingSearches_[index] = 0;
283 pendingSearches_.removeAt(index);
286 int DasTelefonbuch::sendQuery(Source::SearchDetails const& details,
291 QUrl url("http://www.dastelefonbuch.de/");
293 //Pretending we are a Firefox-Plugin allows a simpler query-String
294 url.addQueryItem("sourceid","Mozilla-search");
295 //But we will need to give a proper User-Agent-String...see below
297 url.addQueryItem("cmd","search");
299 QString query = details.query;
301 if(!details.location.isEmpty())
303 query += "+" + details.location;
306 //Query is added as "kw"
307 url.addQueryItem("kw", query);
309 /* TODO No differentiation between personal and professional entries yet
310 if(details.type == Source::YELLOW_PAGES)
312 url.addQueryItem("t", "c");
316 url.addQueryItem("t", "p");
320 /* TODO No multi-page results yet.
323 url.addQueryItem("p", QString::number(page));
329 //Remember, we are firefox, therefore setting User-Agent here...
330 QHttpRequestHeader header("GET", url.encodedPath()+ '?' + url.encodedQuery());
332 header.setValue("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10");
333 header.setValue("Host", url.encodedHost());
335 http_.setHost(url.host(), url.port(80));
337 return http_.request(header);
340 void DasTelefonbuch::getSearchTypes(QList<SearchType>& types) const
343 types.push_back(BOTH);