+/*
+ * This file is part of Jenirok.
+ *
+ * Jenirok is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Jenirok is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jenirok. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtCore/QDebug>
+#include "mobil1881.h"
+
+
+Mobil1881::Mobil1881(QObject* parent): Source(parent)
+{
+}
+
+Mobil1881::~Mobil1881()
+{
+ abort();
+}
+
+void Mobil1881::abort()
+{
+ Source::abort();
+
+ for(int i = 0; i < pendingSearches_.size(); i++)
+ {
+ delete pendingSearches_[i];
+ pendingSearches_[i] = 0;
+ }
+
+ pendingSearches_.clear();
+
+}
+
+void Mobil1881::search(Source::SearchDetails const& details)
+{
+ resetTimeout();
+
+ int id = sendQuery(details, 1);
+
+ SearchData* newData = new SearchData;
+ newData->details = details;
+ newData->searchIds.insert(id);
+ newData->currentPage = 1;
+
+ pendingSearches_.push_back(newData);
+}
+
+void Mobil1881::handleHttpData(int id, QString const& data)
+{
+ for(int i = 0; i < pendingSearches_.size(); i++)
+ {
+ if(pendingSearches_.at(i) && pendingSearches_.at(i)->searchIds.find(id) !=
+ pendingSearches_.at(i)->searchIds.end())
+ {
+
+ addNumbers(pendingSearches_.at(i), data, i);
+ break;
+ }
+ }
+}
+
+void Mobil1881::handleHttpError(int id)
+{
+ for(int i = 0; i < pendingSearches_.size(); i++)
+ {
+ if(pendingSearches_.at(i) && pendingSearches_.at(i)->searchIds.find(id) !=
+ pendingSearches_.at(i)->searchIds.end())
+ {
+
+ setError(Source::CONNECTION_FAILURE, http_.errorString());
+ emitRequestFinished(pendingSearches_.at(i), true, i);
+ break;
+ }
+ }
+}
+
+void Mobil1881::addNumbers(SearchData* searchData,
+ QString const& data,
+ int index)
+{
+ if(data.indexOf("<b>Last ned vCard</b>") > 0)
+ {
+ addOnlyNumber(searchData, data, index);
+ return;
+ }
+
+ int pos = 0;
+ QRegExp rx("<td valign=\"top\" width=\"99%\">(.*)</td>");
+ QRegExp name("<div class=\"srln\">(.*)</div>");
+ QRegExp address("<div class=\"srla\">(.*),<br/>(.*)</div>");
+ QRegExp number("<div class=\"srlp\">(.*)</div>");
+ rx.setMinimal(true);
+ name.setMinimal(true);
+ address.setMinimal(true);
+ number.setMinimal(true);
+
+ int maxResults = getMaxResults();
+
+ while((pos = rx.indexIn(data, pos)) != -1)
+ {
+ pos += rx.matchedLength();
+
+ if(searchData->results.size() >= maxResults)
+ {
+ break;
+ }
+
+ QString part = rx.cap(1);
+ Source::Result result;
+ QString nameStr;
+ QString numberStr;
+ QString streetStr;
+ QString cityStr;
+
+ if(name.indexIn(part) != -1)
+ {
+ nameStr = name.cap(1);
+ }
+
+ if(address.indexIn(part) != -1)
+ {
+ streetStr = address.cap(1);
+ cityStr = address.cap(2);
+ }
+
+ if(number.indexIn(part) != -1)
+ {
+ numberStr = number.cap(1);
+ }
+
+ if(formatResult(nameStr, numberStr, streetStr,
+ cityStr, result))
+ {
+ emit resultAvailable(result, searchData->details);
+ searchData->results.push_back(result);
+ }
+
+ }
+
+ if(searchData->results.size() >= maxResults)
+ {
+ emitRequestFinished(searchData, false, index);
+ }
+ else
+ {
+
+ if(data.indexOf("Neste") > 0)
+ {
+ searchData->currentPage++;
+ int id = sendQuery(searchData->details, searchData->currentPage);
+ searchData->searchIds.insert(id);
+ }
+ else
+ {
+ emitRequestFinished(searchData, false, index);
+ }
+ }
+
+}
+
+void Mobil1881::addOnlyNumber(SearchData* searchData,
+ QString const& data,
+ int index)
+{
+ QRegExp name("<div class=\"srsln\">(.*)</div>");
+ QRegExp number("class=\"srlttxt\"><b>(.*)</b>");
+ QRegExp address("class=\"srlttxt\"><span>(.*),<br/>(.*)</span>");
+ name.setMinimal(true);
+ number.setMinimal(true);
+ address.setMinimal(true);
+
+ Source::Result result;
+
+ QString nameStr;
+ QString numberStr;
+ QString streetStr;
+ QString cityStr;
+
+ if(name.indexIn(data) != -1)
+ {
+ nameStr = name.cap(1);
+ }
+
+ if(number.indexIn(data) != -1)
+ {
+ numberStr = number.cap(1);
+ }
+
+ if(address.indexIn(data) != -1)
+ {
+ streetStr = address.cap(1);
+ cityStr = address.cap(2);
+ }
+
+ if(formatResult(nameStr, numberStr, streetStr,
+ cityStr, result))
+ {
+ searchData->results.push_back(result);
+ emit resultAvailable(result, searchData->details);
+ }
+
+ emitRequestFinished(searchData, false, index);
+}
+
+bool Mobil1881::formatResult(QString& name, QString& number,
+ QString& street, QString& city,
+ Source::Result& result)
+{
+ name = stripTags(name);
+ result.name = name.trimmed();
+ number = stripTags(number);
+ number = cleanUpNumber(number);
+ result.number = number.trimmed();
+ street = stripTags(street);
+ city = stripTags(city);
+ result.street = street.trimmed();
+ result.city = city.trimmed();
+
+ if(!result.name.isEmpty() && !result.number.isEmpty())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void Mobil1881::emitRequestFinished(SearchData* data,
+ bool error, int index)
+{
+ QVector<Source::Result> results = data->results;
+ Source::SearchDetails details = data->details;
+
+ emit requestFinished(results, details, error);
+ delete pendingSearches_[index];
+ pendingSearches_[index] = 0;
+ pendingSearches_.removeAt(index);
+}
+
+int Mobil1881::sendQuery(Source::SearchDetails const& details,
+ int page)
+{
+ QUrl url("http://wap.1881.no/");
+ url.addQueryItem("i", "4854");
+ url.addQueryItem("showonly", "1");
+ QString query = details.query;
+
+ if(!details.location.isEmpty())
+ {
+ query += details.location;
+ }
+
+ url.addQueryItem("s", query);
+ if(details.type == Source::YELLOW_PAGES)
+ {
+ url.addQueryItem("t", "c");
+ }
+ else
+ {
+ url.addQueryItem("t", "p");
+ }
+
+ if(page > 1)
+ {
+ url.addQueryItem("p", QString::number(page));
+ }
+
+ fixUrl(url);
+
+ http_.setHost(url.host(), url.port(80));
+ return http_.get(url.encodedPath() + '?' + url.encodedQuery());
+}