Increased the maximum number of search results.
[jenirok] / src / common / eniro.cpp
index 56f27fe..b28760c 100644 (file)
 
 namespace
 {
-    static const QString SITE_URLS[] =
+    static const QString SITE_URLS[Eniro::SITE_COUNT] =
     {
-        "http://wap.eniro.fi/",
-        "http://wap.eniro.se/",
-        "http://wap.eniro.dk/"
+            "http://wap.eniro.fi/",
+            "http://wap.eniro.se/",
+            "http://wap.eniro.dk/"
     };
 
-    const QString INVALID_LOGIN_STRING = "Invalid login details";
-    const QString PERSON_REGEXP = "<td class=\"hTd2\">(.*)<b>(.*)</td>";
-    const QString YELLOW_REGEXP = "<td class=\"hTd2\">(.*)<span class=\"gray\"\\}>(.*)</td>";
-    const QString NUMBER_REGEXP = "<div class=\"callRow\">(.*)</div>";
-    const QString LOGIN_CHECK = "<input class=\"inpTxt\" id=\"loginformUsername\"";
+    static const QString SITE_NAMES[Eniro::SITE_COUNT] =
+    {
+         "finnish",
+         "swedish",
+         "danish"
+    };
+
+    static const QString SITE_IDS[Eniro::SITE_COUNT] =
+    {
+         "fi",
+         "se",
+         "dk"
+    };
+
+    static const QString INVALID_LOGIN_STRING = QObject::tr("Invalid login details");
+    static const QString TIMEOUT_STRING = QObject::tr("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 NUMBER_REGEXP = "<div class=\"callRow\">(.*)</div>";
+    static const QString LOGIN_CHECK = "<input class=\"inpTxt\" id=\"loginformUsername\"";
 }
 
 // Regexp used to remove numbers from string
@@ -43,8 +58,8 @@ QRegExp Eniro::tagStripper_ = QRegExp("<([^>]+)>");
 
 Eniro::Eniro(Site site, QObject *parent): QObject(parent), site_(site),
 username_(""), password_(""), loggedIn_(false), error_(NO_ERROR),
-errorString_(""), maxResults_(10), findNumber_(true),
-pendingSearches_(), pendingNumberRequests_()
+errorString_(""), maxResults_(DEFAULT_MAX_RESULTS), timeout_(0), timerId_(0),
+findNumber_(true), pendingSearches_(), pendingNumberRequests_()
 {
     connect(&http_, SIGNAL(requestFinished(int, bool)), this, SLOT(httpReady(int, bool)));
 }
@@ -59,7 +74,7 @@ void Eniro::abort()
     http_.abort();
 
     for(searchMap::iterator sit = pendingSearches_.begin();
-        sit != pendingSearches_.end(); sit++)
+    sit != pendingSearches_.end(); sit++)
     {
         if(sit.value() != 0)
         {
@@ -71,7 +86,7 @@ void Eniro::abort()
     pendingSearches_.clear();
 
     for(numberMap::iterator nit = pendingNumberRequests_.begin();
-        nit != pendingNumberRequests_.end(); nit++)
+    nit != pendingNumberRequests_.end(); nit++)
     {
         if(nit.value() != 0)
         {
@@ -91,7 +106,7 @@ void Eniro::setMaxResults(unsigned int value)
 
 void Eniro::setFindNumber(bool value)
 {
-       findNumber_ = value;
+    findNumber_ = value;
 }
 
 void Eniro::setSite(Eniro::Site site)
@@ -99,6 +114,51 @@ void Eniro::setSite(Eniro::Site site)
     site_ = site;
 }
 
+void Eniro::setTimeout(unsigned int ms)
+{
+    timeout_ = ms;
+    resetTimeout();
+}
+
+void Eniro::resetTimeout()
+{
+    if(timerId_)
+    {
+        killTimer(timerId_);
+    }
+    if(timeout_)
+    {
+        timerId_ = startTimer(timeout_);
+    }
+}
+
+void Eniro::timerEvent(QTimerEvent* t)
+{
+    if(t->timerId() == timerId_)
+    {
+        int currentId = http_.currentId();
+
+        if(currentId)
+        {
+            searchMap::const_iterator it = pendingSearches_.find(currentId);
+
+            if(it != pendingSearches_.end())
+            {
+                QVector <Eniro::Result> results = it.value()->results;
+                SearchDetails details = it.value()->details;
+
+                abort();
+
+                error_ = TIMEOUT;
+                errorString_ = TIMEOUT_STRING;
+
+                emit requestFinished(results, details, true);
+            }
+        }
+
+    }
+}
+
 void Eniro::login(QString const& username,
                   QString const& password)
 {
@@ -127,6 +187,8 @@ void Eniro::testLogin()
 
 bool Eniro::search(SearchDetails const& details)
 {
+    resetTimeout();
+
     SearchType type = details.type;
 
     // Only logged in users can use other than person search
@@ -202,7 +264,7 @@ void Eniro::httpReady(int id, bool error)
 
     // Check if request is pending search request
     if((searchIt = pendingSearches_.find(id)) !=
-       pendingSearches_.end())
+        pendingSearches_.end())
     {
         if(error)
         {
@@ -220,7 +282,7 @@ void Eniro::httpReady(int id, bool error)
 
     // Check if request is pending number requests
     else if((numberIt = pendingNumberRequests_.find(id)) !=
-            pendingNumberRequests_.end())
+        pendingNumberRequests_.end())
     {
         if(error)
         {
@@ -239,24 +301,24 @@ void Eniro::httpReady(int id, bool error)
 
     // Check for login request
     else if(pendingLoginRequests_.find(id) !=
-            pendingLoginRequests_.end())
+        pendingLoginRequests_.end())
     {
-       bool success = true;
-
-       if(!error)
-       {
-               QString result(http_.readAll());
-
-               // If html source contains LOGIN_CHECK, login failed
-               if(result.indexOf(LOGIN_CHECK) != -1)
-               {
-                       success = false;
-               }
-       }
-       else
-       {
-               success = false;
-       }
+        bool success = true;
+
+        if(!error)
+        {
+            QString result(http_.readAll());
+
+            // If html source contains LOGIN_CHECK, login failed
+            if(result.indexOf(LOGIN_CHECK) != -1)
+            {
+                success = false;
+            }
+        }
+        else
+        {
+            success = false;
+        }
 
         emit loginStatus(success);
     }
@@ -271,13 +333,13 @@ void Eniro::loadResults(int id, QString const& httpData)
 
     switch(it.value()->details.type)
     {
-      case YELLOW_PAGES:
+    case YELLOW_PAGES:
         expr = YELLOW_REGEXP;
         break;
-      case PERSONS:
+    case PERSONS:
         expr = PERSON_REGEXP;
         break;
-      default:
+    default:
         return;
     }
 
@@ -291,15 +353,15 @@ void Eniro::loadResults(int id, QString const& httpData)
     // Find all matches
     while((pos = rx.indexIn(httpData, pos)) != -1)
     {
-       pos += rx.matchedLength();
+        pos += rx.matchedLength();
 
-       data = rx.cap(2);
-       data = stripTags(data);
-       QStringList rows = data.split('\n');
+        data = rx.cap(2);
+        data = stripTags(data);
+        QStringList rows = data.split('\n');
 
-       for(int i = 0; i < rows.size(); i++)
-       {
-           // Remove white spaces
+        for(int i = 0; i < rows.size(); i++)
+        {
+            // Remove white spaces
             QString trimmed = rows.at(i).trimmed().toLower();
 
             // Remove empty strings
@@ -310,71 +372,71 @@ void Eniro::loadResults(int id, QString const& httpData)
             }
             else
             {
-               // Convert words to uppercase
+                // Convert words to uppercase
                 rows[i] = ucFirst(trimmed);
             }
-       }
+        }
 
-       Result result;
+        Result result;
 
-       int size = rows.size();
+        int size = rows.size();
 
-       switch(size)
-       {
-         case 1:
-           result.name = rows[0];
-           break;
+        switch(size)
+        {
+        case 1:
+            result.name = rows[0];
+            break;
 
-         case 2:
-           result.name = rows[0];
-           result.city = rows[1];
-           break;
+        case 2:
+            result.name = rows[0];
+            result.city = rows[1];
+            break;
 
-         case 3:
-           result.name = rows[0];
-           result.street = rows[1];
-           result.city = rows[2];
-           break;
+        case 3:
+            result.name = rows[0];
+            result.street = rows[1];
+            result.city = rows[2];
+            break;
 
-         case 4:
-           result.name = rows[0];
-           // Remove slashes and spaces from number
-           result.number = cleanUpNumber(rows[1]);
-           result.street = rows[2];
-           result.city = rows[3];
-           break;
+        case 4:
+            result.name = rows[0];
+            // Remove slashes and spaces from number
+            result.number = cleanUpNumber(rows[1]);
+            result.street = rows[2];
+            result.city = rows[3];
+            break;
 
-         default:
-           continue;
+        default:
+            continue;
 
-       }
+        }
 
-       it.value()->results.push_back(result);
+        it.value()->results.push_back(result);
 
-       unsigned int foundResults = ++(it.value()->numbersTotal);
+        unsigned int foundResults = ++(it.value()->numbersTotal);
 
-       // If phone number searh is enabled, we have to make another
-       // request to find it out
-       if(findNumber_ && size < 4 && loggedIn_ &&
-          it.value()->details.type != YELLOW_PAGES)
-       {
+        // If phone number searh is enabled, we have to make another
+        // request to find it out
+        if(findNumber_ && size < 4 && loggedIn_ &&
+                it.value()->details.type != YELLOW_PAGES)
+        {
             requestsPending = true;
             getNumberForResult(id, it.value()->results.size() - 1, it.value()->details);
-       }
-       // Otherwise result is ready
-       else
-       {
+        }
+        // Otherwise result is ready
+        else
+        {
             emit resultAvailable(result, it.value()->details);
-       }
+        }
 
-       // Stop searching if max results is reached
-       if(maxResults_ && (foundResults >= maxResults_))
-       {
-           break;
-       }
+        // Stop searching if max results is reached
+        if(maxResults_ && (foundResults >= maxResults_))
+        {
+            break;
+        }
     }
 
-    // If number there were no results or no phone numbers needed to
+    // If there were no results or no phone numbers needed to
     // be fetched, the whole request is ready
     if(it.value()->numbersTotal == 0 || !requestsPending)
     {
@@ -424,7 +486,7 @@ void Eniro::loadNumber(int id, QString const& result)
 
         if(!trimmed.isEmpty())
         {
-               // Remove whitespaces from number
+            // Remove whitespaces from number
             searchIt.value()->results[numberIt.value()->index].number = cleanUpNumber(trimmed);
 
             emit resultAvailable(searchIt.value()->results[numberIt.value()->index], searchIt.value()->details);
@@ -434,7 +496,7 @@ void Eniro::loadNumber(int id, QString const& result)
             // Check if all numbers have been found
             if(found >= searchIt.value()->numbersTotal)
             {
-               emitRequestFinished(searchIt.key(), searchIt.value(), false);
+                emitRequestFinished(searchIt.key(), searchIt.value(), false);
             }
 
             // If number was found, there was no error
@@ -507,11 +569,11 @@ void Eniro::getNumberForResult(int id, int index, SearchDetails const& details)
 void Eniro::emitRequestFinished(int key, SearchData* data, bool error)
 {
 
-       // Do not emit "Request aborted" error
-       if(!(error && (http_.error() == QHttp::Aborted)))
-       {
-               emit requestFinished(data->results, data->details, error);
-       }
+    // Do not emit "Request aborted" error
+    if(!(error && (http_.error() == QHttp::Aborted)))
+    {
+        emit requestFinished(data->results, data->details, error);
+    }
 
     delete pendingSearches_[key];
     pendingSearches_[key] = 0;
@@ -520,19 +582,19 @@ void Eniro::emitRequestFinished(int key, SearchData* data, bool error)
 
 QString Eniro::ucFirst(QString& str)
 {
-       if (str.size() < 1) {
-               return "";
-       }
+    if (str.size() < 1) {
+        return "";
+    }
 
-       QStringList tokens = str.split(" ");
-       QList<QString>::iterator tokItr;
+    QStringList tokens = str.split(" ");
+    QList<QString>::iterator tokItr;
 
-       for (tokItr = tokens.begin(); tokItr != tokens.end(); ++tokItr)
-       {
-               (*tokItr) = (*tokItr).at(0).toUpper() + (*tokItr).mid(1);
-       }
+    for (tokItr = tokens.begin(); tokItr != tokens.end(); ++tokItr)
+    {
+        (*tokItr) = (*tokItr).at(0).toUpper() + (*tokItr).mid(1);
+    }
 
-       return tokens.join(" ");
+    return tokens.join(" ");
 }
 
 QString& Eniro::cleanUpNumber(QString& number)
@@ -547,39 +609,34 @@ QString& Eniro::stripTags(QString& string)
 
 QMap <Eniro::Site, Eniro::SiteDetails> Eniro::getSites()
 {
-       QMap <Site, SiteDetails> sites;
-       SiteDetails details;
-       details.name = tr("Finnish");
-       details.id = "fi";
-       sites[FI] = details;
+    QMap <Site, SiteDetails> sites;
+    SiteDetails details;
 
-       details.name = tr("Swedish");
-       details.id = "se";
-       sites[SE] = details;
-
-       details.name = tr("Danish");
-       details.id = "dk";
-       sites[DK] = details;
+    for(int i = 0; i < SITE_COUNT; i++)
+    {
+        SiteDetails details;
+        details.name = SITE_NAMES[i];
+        details.id = SITE_IDS[i];
+        sites[static_cast<Site>(i)] = details;
+    }
 
-       return sites;
+    return sites;
 }
 
 Eniro::Site Eniro::stringToSite(QString const& str)
 {
-       Site site = FI;
-
-       QString lower = str.toLower();
+    Site site = FI;
+    QString lower = str.toLower();
 
-       if(lower == "se" || lower == "swedish")
-       {
-               site = SE;
-       }
-       else if(lower == "dk" || lower == "danish")
-       {
-               site = DK;
-       }
+    for(int i = 0; i < SITE_COUNT; i++)
+    {
+        if(lower == SITE_NAMES[i] || lower == SITE_IDS[i])
+        {
+            site = static_cast <Site> (i);
+        }
+    }
 
-       return site;
+    return site;
 }
 
 Eniro::SearchDetails::SearchDetails(QString const& q,