Download search results: initial steps.
[dorian] / search.cpp
1 #include <QNetworkAccessManager>
2 #include <QNetworkReply>
3 #include <QNetworkRequest>
4 #include <QWebFrame>
5 #include <QWebPage>
6 #include <QWebElementCollection>
7 #include <QWebElement>
8
9 #include "search.h"
10 #include "platform.h"
11 #include "trace.h"
12
13 Search *inst = 0;
14
15 Search *Search::instance()
16 {
17     if (!inst) {
18         inst = new Search();
19     }
20     return inst;
21 }
22
23 void Search::close()
24 {
25     delete inst;
26     inst = 0;
27 }
28
29 Search::Search(): QObject(0), reply(0)
30 {
31     manager = new QNetworkAccessManager(this);
32 }
33
34 void Search::start(const Query &query)
35 {
36     Trace t("Search::start");
37
38     emit beginSearch();
39
40     searchResults.clear();
41     QNetworkRequest request;
42     request.setUrl(QUrl("http://www.gutenberg.org/catalog/world/results"));
43     // request.setRawHeader("User-Agent", "Dorian " + Platform::version());
44     QString title = query.title;
45     if (title.isEmpty()) {
46         title = ".";
47     }
48     QByteArray data;
49     data = "title=" + QUrl::toPercentEncoding(title) + "&author=" +
50            QUrl::toPercentEncoding(query.author);
51     qDebug() << "Request:" << (request.url().toString() + "?" + data);
52     reply = manager->post(request, data);
53     connect(reply, SIGNAL(finished()), this, SLOT(finished()));
54 }
55
56 QList<Search::Result> Search::results()
57 {
58     return searchResults;
59 }
60
61 bool Search::download(const Search::Result &result, const QString &fileName)
62 {
63     Q_UNUSED(result);
64     Q_UNUSED(fileName);
65     emit beginDownload(0);
66     emit endDownload();
67     return false;
68 }
69
70 void Search::finished()
71 {
72     Trace t("Search::finished");
73
74     if (!reply) {
75         return;
76     }
77
78     QByteArray data = reply->readAll();
79     qDebug() << data;
80
81     // Parse search results
82
83     QWebPage page(this);
84     QWebFrame *frame = page.mainFrame();
85     frame->setHtml(QString(data));
86     QWebElementCollection tables = frame->findAllElements("table");
87     if (tables.count() == 1) {
88         QWebElement table = tables[0];
89         foreach (QWebElement row, table.findAll("tr")) {
90             QWebElementCollection cols = row.findAll("td");
91             if (cols.count() < 5) {
92                 continue;
93             }
94             QString id = cols[0].toPlainText().trimmed();
95             if (id.isEmpty()) {
96                 continue;
97             }
98             QString author = cols[2].toPlainText().trimmed();
99             QStringList titles = cols[3].toPlainText().trimmed().
100                                  split("\n", QString::SkipEmptyParts);
101             Result r;
102             r.authors = author.split("\n", QString::SkipEmptyParts);
103             r.id = id;
104             if (titles.count()) {
105                 r.title = titles[0];
106             }
107             r.language = cols[4].toPlainText().trimmed();
108             r.source = "Project Gutenberg";
109             searchResults.append(r);
110             qDebug() << id;
111             qDebug() << " Authors:" << r.authors;
112             qDebug() << " Title:" << r.title;
113             qDebug() << " Language:" << r.language;
114         }
115     }
116
117     reply->deleteLater();
118     reply = 0;
119     emit endSearch();
120 }