Process and show search results.
[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     QByteArray data = reply->readAll();
74     qDebug() << data;
75
76     QWebPage page(this);
77     QWebFrame *frame = page.mainFrame();
78     frame->setHtml(QString(data));
79     QWebElementCollection tables = frame->findAllElements("table");
80     if (tables.count() == 1) {
81         qDebug() << "Found table";
82         QWebElement table = tables[0];
83         foreach (QWebElement row, table.findAll("tr")) {
84             QWebElementCollection cols = row.findAll("td");
85             QString id = cols[0].toPlainText().trimmed();
86             if (id.isEmpty()) {
87                 continue;
88             }
89             QString author = cols[2].toPlainText().trimmed();
90             QStringList titles = cols[3].toPlainText().trimmed().
91                                  split("\n", QString::SkipEmptyParts);
92             Result r;
93             r.authors = author.split("\n", QString::SkipEmptyParts);
94             r.id = id;
95             if (titles.count()) {
96                 r.title = titles[0];
97             }
98             r.language = cols[4].toPlainText().trimmed();
99             searchResults.append(r);
100             qDebug() << id;
101             qDebug() << " Authors:" << r.authors;
102             qDebug() << " Title:" << r.title;
103             qDebug() << " Language:" << r.language;
104         }
105     }
106
107     reply->deleteLater();
108     emit endSearch();
109 }