Danish Eniro search fixed.
[jenirok] / src / common / eniro.cpp
index 9a9f1a2..718064d 100644 (file)
@@ -25,7 +25,7 @@ namespace
     {
             "http://wap.eniro.fi/",
             "http://wap.eniro.se/",
-            "http://wap.eniro.dk/"
+            "http://m.krak.dk/"
     };
 
     static const QString SITE_NAMES[Eniro::SITE_COUNT] =
@@ -45,8 +45,8 @@ namespace
     static const QString INVALID_LOGIN_STRING = "Invalid login details";
     static const QString TIMEOUT_STRING = "Request timed out";
     static const QString PERSON_REGEXP = "<td class=\"hTd2\">(.*)<b>(.*)</td>";
-    static const QString YELLOW_REGEXP = "<td class=\"hTd2\">(.*)<span class=\"gray\">(.*)</td>";
-    static const QString SINGLE_REGEXP = "<div class=\"header\">(.*)</div>(.*)<div class=\"callRow\">(.*)</div>";
+    static const QString YELLOW_REGEXP = "<td class=\"hTd2\">(.*)<span class=\"gray\">(.*)</td>|<td class=\"hTd2\">(.*)<span class=\"bold\"\\}>(.*)</td>";
+    static const QString SINGLE_REGEXP = "<div class=\"header\">(.*)</div>(.*)<div class=\"callRow\">(.*)(<div class=\"block\">|</p>(.*)<br/>|</p>(.*)<br />)";
     static const QString NUMBER_REGEXP = "<div class=\"callRow\">(.*)</div>";
     static const QString LOGIN_CHECK = "<input class=\"inpTxt\" id=\"loginformUsername\"";
 }
@@ -142,7 +142,7 @@ void Eniro::search(SearchDetails const& details)
     SearchType type = details.type;
 
     // Only logged in users can use other than person search
-    if(!loggedIn_)
+    if(!loggedIn_ && site_ == FI)
     {
         type = PERSONS;
     }
@@ -150,7 +150,13 @@ void Eniro::search(SearchDetails const& details)
     QUrl url = createUrl(details.query, details.location);
     QString what;
 
-    if(loggedIn_)
+    // We must use full search instead of wap page because wap search is currently not
+    // working for persons
+    if(loggedIn_ && type == PERSONS && site_ == FI && getMaxResults() > 1)
+    {
+        what = "wp";
+    }
+    else if(loggedIn_ || site_ != FI)
     {
         switch(type)
         {
@@ -178,6 +184,8 @@ void Eniro::search(SearchDetails const& details)
     http_.setHost(url.host(), url.port(80));
     int id = http_.get(url.encodedPath() + '?' + url.encodedQuery());
 
+    //qDebug() << "Url: " << url.host() << url.encodedPath() << "?" << url.encodedQuery();
+
     QVector <Source::Result> results;
 
     // Store search data for later identification
@@ -201,6 +209,13 @@ void Eniro::handleHttpData(int id, QByteArray const& data)
     if((searchIt = pendingSearches_.find(id)) !=
         pendingSearches_.end())
     {
+        if(data.isEmpty())
+        {
+            setError(CONNECTION_FAILURE, "Server returned empty data");
+            emitRequestFinished(id, searchIt.value(), true);
+            return;
+        }
+
         // Load results from html data
         loadResults(id, data);
     }
@@ -209,6 +224,13 @@ void Eniro::handleHttpData(int id, QByteArray const& data)
     else if((numberIt = pendingNumberRequests_.find(id)) !=
         pendingNumberRequests_.end())
     {
+        if(data.isEmpty())
+        {
+            setError(CONNECTION_FAILURE, "Server returned empty data");
+            emitRequestFinished(id, searchIt.value(), true);
+            return;
+        }
+
         // Load number from html data
         loadNumber(id, data);
     }
@@ -257,7 +279,6 @@ void Eniro::handleHttpError(int id)
         pendingLoginRequests_.end())
     {
         emit loginStatus(false);
-
     }
 }
 
@@ -266,6 +287,13 @@ void Eniro::loadResults(int id, QString const& httpData)
 {
     searchMap::iterator it = pendingSearches_.find(id);
 
+    // Finnish person search is not working in wap mode so we have to use different type of loading
+    if(getMaxResults() > 1 && loggedIn_ && site_ == FI && it.value()->details.type == PERSONS)
+    {
+        loadFinnishPersonResults(id, httpData);
+        return;
+    }
+
     QRegExp rx("((" + YELLOW_REGEXP + ")|(" + PERSON_REGEXP + ")|(" + SINGLE_REGEXP + "))");
     rx.setMinimal(true);
 
@@ -281,6 +309,7 @@ void Eniro::loadResults(int id, QString const& httpData)
         data = rx.cap(1);
 
         data = stripTags(data);
+
         QStringList rows = data.split('\n');
 
         for(int i = 0; i < rows.size(); i++)
@@ -303,6 +332,19 @@ void Eniro::loadResults(int id, QString const& httpData)
 
         Result result;
 
+        switch(site_)
+        {
+        case FI:
+            result.country = "Finland";
+            break;
+        case SE:
+            result.country = "Sweden";
+            break;
+        case DK:
+            result.country = "Denmark";
+            break;
+        }
+
         int size = rows.size();
 
         switch(size)
@@ -340,6 +382,35 @@ void Eniro::loadResults(int id, QString const& httpData)
             break;
 
         default:
+            bool ok = false;
+
+            for(int a = 0; a < size && a < 8; a++)
+            {
+                if(isPhoneNumber(rows[a]))
+                {
+                    result.name = rows[0];
+                    result.number = cleanUpNumber(rows[a]);
+
+                    for(int i = a + 1; i < size && i < 8; i++)
+                    {
+                        if(!isPhoneNumber(rows[i]) && size > i + 1 && isStreet(rows[i]))
+                        {
+                            result.street = rows[i];
+                            result.city = rows[i+1];
+                            ok = true;
+                            break;
+                        }
+                    }
+
+                }
+
+            }
+
+            if(ok)
+            {
+                break;
+            }
+
             continue;
 
         }
@@ -348,9 +419,9 @@ void Eniro::loadResults(int id, QString const& httpData)
 
         unsigned int foundResults = ++(it.value()->numbersTotal);
 
-        // If phone number searh is enabled, we have to make another
+        // If phone number search is enabled, we have to make another
         // request to find it out
-        if(getFindNumber() && size < 4 && loggedIn_ &&
+        if(getFindNumber() && size < 4 && (loggedIn_ || site_ != FI) &&
                 it.value()->details.type != YELLOW_PAGES)
         {
             requestsPending = true;
@@ -359,6 +430,7 @@ void Eniro::loadResults(int id, QString const& httpData)
         // Otherwise result is ready
         else
         {
+            it.value()->foundNumbers++;
             emit resultAvailable(result, it.value()->details);
         }
 
@@ -387,6 +459,102 @@ void Eniro::loadResults(int id, QString const& httpData)
     }
 }
 
+void Eniro::loadFinnishPersonResults(int id, QString const& httpData)
+{
+    searchMap::iterator it = pendingSearches_.find(id);
+
+    static QRegExp rx("<div id=\"hit_(.*)<p class=\"adLinks\">");
+    static QRegExp name("<a class=\"fn expand\" href=\"#\">(.*)</a>");
+    static QRegExp number("<!-- sphoneid(.*)-->(.*)<!--");
+    static QRegExp street("<span class=\"street-address\">(.*)</span>");
+    static QRegExp zipCode("<span class=\"postal-code\">(.*)</span>");
+    static QRegExp city("<span class=\"locality\">(.*)</span>");
+    rx.setMinimal(true);
+    name.setMinimal(true);
+    number.setMinimal(true);
+    street.setMinimal(true);
+    zipCode.setMinimal(true);
+    city.setMinimal(true);
+
+    int pos = 0;
+
+    unsigned int maxResults = getMaxResults();
+    unsigned int foundResults = 0;
+
+    while((pos = rx.indexIn(httpData, pos)) != -1)
+    {
+        pos += rx.matchedLength();
+
+        QString data = rx.cap(0);
+
+        Result result;
+
+        if(name.indexIn(data) != -1)
+        {
+            result.name = name.cap(1);
+        }
+        else
+        {
+            continue;
+        }
+
+        if(number.indexIn(data) != -1)
+        {
+            result.number = number.cap(2);
+        }
+
+        if(street.indexIn(data) != -1)
+        {
+            result.street = street.cap(1);
+        }
+
+        QString cityStr;
+
+        if(zipCode.indexIn(data) != -1)
+        {
+            cityStr = zipCode.cap(1) + " ";
+        }
+
+        if(city.indexIn(data) != -1)
+        {
+            cityStr += city.cap(1);
+        }
+
+        result.city = cityStr;
+
+        result.name = cleanUpString(result.name);
+        result.street = cleanUpString(result.street);
+        result.number = cleanUpNumber(result.number);
+        result.city = cleanUpString(result.city);
+        result.country = "Finland";
+
+        it.value()->results.push_back(result);
+        emit resultAvailable(result, it.value()->details);
+
+        foundResults++;
+
+        if(foundResults >= maxResults)
+        {
+            break;
+        }
+
+    }
+
+    emitRequestFinished(it.key(), it.value(), false);
+
+}
+
+QString& Eniro::cleanUpString(QString& str)
+{
+    str = htmlEntityDecode(str);
+    str = str.toLower();
+    str = str.trimmed();
+    static QRegExp cleaner("(\r\n|\n|\t| )+");
+    str = str.replace(cleaner, " ");
+    str = ucFirst(str);
+    return str;
+}
+
 // Loads phone number from html source
 void Eniro::loadNumber(int id, QString const& result)
 {
@@ -473,7 +641,7 @@ QUrl Eniro::createUrl(QString const& query, QString const& location)
     {
         url.addQueryItem("hpp", QString::number(maxResults));
     }
-    if(loggedIn_)
+    if(loggedIn_ && site_ == FI)
     {
         url.addQueryItem("login_name", username_);
         url.addQueryItem("login_password", password_);
@@ -512,7 +680,6 @@ void Eniro::emitRequestFinished(int key, SearchData* data, bool error)
 QMap <Eniro::Site, Eniro::SiteDetails> Eniro::getSites()
 {
     QMap <Site, SiteDetails> sites;
-    SiteDetails details;
 
     for(int i = 0; i < SITE_COUNT; i++)
     {
@@ -541,3 +708,17 @@ Eniro::Site Eniro::stringToSite(QString const& str)
 
     return site;
 }
+
+bool Eniro::isStreet(QString const& str)
+{
+    static QRegExp number("([0-9]+)");
+    int a = number.indexIn(str);
+    int b = str.indexOf(" ");
+
+    if((a == -1 && b == -1) || (a != -1 && b != -1))
+    {
+        return true;
+    }
+
+    return false;
+}