Fix forward navigation control on Linux.
[dorian] / search.cpp
index 27e4ed2..df928c7 100644 (file)
@@ -1,10 +1,11 @@
-#include <QNetworkAccessManager>
-#include <QNetworkReply>
 #include <QNetworkRequest>
-#include <QWebFrame>
+#include <QNetworkReply>
+#include <QtGui>
+#include <QFile>
+#include <QNetworkAccessManager>
 #include <QWebPage>
 #include <QWebElementCollection>
-#include <QWebElement>
+#include <QWebFrame>
 
 #include "search.h"
 #include "platform.h"
@@ -26,14 +27,15 @@ void Search::close()
     inst = 0;
 }
 
-Search::Search(): QObject(0), reply(0)
+Search::Search(): QObject(0), reply(0), downloadReply(0)
 {
     manager = new QNetworkAccessManager(this);
+    downloadManager = new QNetworkAccessManager(this);
 }
 
 void Search::start(const Query &query)
 {
-    Trace t("Search::start");
+    TRACE;
 
     emit beginSearch();
 
@@ -58,30 +60,45 @@ QList<Search::Result> Search::results()
     return searchResults;
 }
 
-bool Search::download(const Search::Result &result, const QString &fileName)
+void Search::download(const Search::Result &result, const QString &fileName)
 {
-    Q_UNUSED(result);
+    TRACE;
+    downloadResult = result;
+    downloadFileName = fileName;
+    qDebug() << "UID" << result.id;
     Q_UNUSED(fileName);
     emit beginDownload(0);
-    emit endDownload();
-    return false;
+    QUrl url("http://www.gutenberg.org/ebooks/" + result.id + ".epub");
+    qDebug() << "Requesting" << url;
+    QNetworkRequest request;
+    request.setUrl(url);
+    downloadReply = downloadManager->get(request);
+    connect(downloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
 }
 
 void Search::finished()
 {
-    Trace t("Search::finished");
+    TRACE;
+
+    if (!reply) {
+        return;
+    }
+
     QByteArray data = reply->readAll();
-    qDebug() << data;
+
+    // Parse search results
 
     QWebPage page(this);
     QWebFrame *frame = page.mainFrame();
     frame->setHtml(QString(data));
     QWebElementCollection tables = frame->findAllElements("table");
     if (tables.count() == 1) {
-        qDebug() << "Found table";
         QWebElement table = tables[0];
         foreach (QWebElement row, table.findAll("tr")) {
             QWebElementCollection cols = row.findAll("td");
+            if (cols.count() < 5) {
+                continue;
+            }
             QString id = cols[0].toPlainText().trimmed();
             if (id.isEmpty()) {
                 continue;
@@ -96,6 +113,7 @@ void Search::finished()
                 r.title = titles[0];
             }
             r.language = cols[4].toPlainText().trimmed();
+            r.source = "Project Gutenberg";
             searchResults.append(r);
             qDebug() << id;
             qDebug() << " Authors:" << r.authors;
@@ -105,5 +123,61 @@ void Search::finished()
     }
 
     reply->deleteLater();
+    reply = 0;
     emit endSearch();
 }
+
+void Search::downloadFinished()
+{
+    TRACE;
+
+    if (!downloadReply) {
+        return;
+    }
+
+    // Handle download errors
+    if (QNetworkReply::NoError != downloadReply->error()) {
+        qCritical() << "Search::downloadFinished: Network error"
+                << downloadReply->error();
+        downloadReply->deleteLater();
+        downloadReply = 0;
+        emit endDownload(Search::DownloadError, downloadResult, downloadFileName);
+        return;
+    }
+
+    // Handle redirection
+    QVariant header = downloadReply->header(QNetworkRequest::LocationHeader);
+    if (header.isValid()) {
+        // Handle redirection: Download again with the new URL
+        qDebug() << "Redirected to" << header;
+        QNetworkRequest request;
+        request.setUrl(header.toUrl());
+        downloadReply->deleteLater();
+        downloadReply = downloadManager->get(request);
+        connect(downloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+        return;
+    }
+
+    // Handle download success
+    QByteArray data = downloadReply->readAll();
+    qint64 size = (qint64)data.size();
+    qDebug() << "Got" << size << "bytes";
+    downloadReply->deleteLater();
+    downloadReply = 0;
+    QFile out(downloadFileName);
+    int status = Search::FileError;
+    if (out.open(QIODevice::WriteOnly)) {
+        if (size == out.write(data, size)) {
+            qDebug() << "Book saved to" << downloadFileName;
+            status = Search::Ok;
+        } else {
+            qCritical() << "Search::downloadFinished: Failed to write" << size
+                    << "bytes to" << downloadFileName;
+        }
+        out.close();
+    } else {
+        qCritical() << "Search::downloadFinished: Could not open"
+                << downloadFileName;
+    }
+    emit endDownload(status, downloadResult, downloadFileName);
+}