Updated packaging files in debian folder.
[ptas] / zouba / src / logic / locationfinder.cpp
1 #include "locationfinder.h"
2 #include "ytv.h"
3
4 #include <QString>
5 #include <QUrl>
6 #include <QXmlStreamReader>
7 #include <QDebug>
8 #include <QNetworkRequest>
9 #include <stdexcept>
10
11 #include <QTimer>
12
13 LocationFinder::LocationFinder(QString address, QObject *parent) :
14     QObject(parent), address(address), reply(NULL),
15     places(QList<Location*>()), roadNames(QList<Location*>()),
16     stops(QList<Location*>()), invalidResponse(false)
17 {
18     QUrl fullUrl(Ytv::Url);
19
20     fullUrl.addEncodedQueryItem( "key", this->address.toAscii().toPercentEncoding() );
21     fullUrl.addQueryItem( "user", Ytv::Username );
22     fullUrl.addQueryItem( "pass", Ytv::Password );
23
24     qDebug() << "The query url: " << fullUrl.toString();
25
26     this->reply = Ytv::manager.get(QNetworkRequest(fullUrl));
27     connect(this->reply, SIGNAL(finished()), this, SLOT(processReply()));
28 }
29
30 LocationFinder::~LocationFinder()
31 {
32     if (this->reply)
33         this->reply->deleteLater();
34
35     while (!this->places.isEmpty())
36         delete this->places.takeLast();
37
38     while (!this->roadNames.isEmpty())
39         delete this->roadNames.takeLast();
40
41     while (!this->stops.isEmpty())
42         delete this->stops.takeLast();
43 }
44
45
46 void LocationFinder::processReply()
47 {
48     qDebug() << "Processing reply from Reittiopas in LocationFinder";
49     QXmlStreamReader xml(this->reply->readAll());
50
51     this->reply->disconnect(this);
52     this->reply->deleteLater();
53     this->reply = NULL;
54
55     int resultNumber = 0;
56     while (!xml.atEnd())
57     {
58         qDebug() << "Reading next element";
59         xml.readNext();
60
61         if (xml.isStartElement())
62         {
63             QString xmlName(xml.name().toString());
64
65             if (xmlName == "LOC")
66             {
67                 QXmlStreamAttributes attributes(xml.attributes());
68                 QStringRef xAttribute( attributes.value("x") );
69                 QStringRef yAttribute( attributes.value("y") );
70                 QString newX( xAttribute.toString() );
71                 QString newY( yAttribute.toString() );
72                 QString category(attributes.value("category").toString());
73                 QString address(attributes.value("name1").toString());
74                 QString number(attributes.value("number").toString());
75                 if (!number.isEmpty())
76                 {
77                     address.append(" ");
78                     address.append(number);
79                 }
80                 address.append(", ");
81                 address.append(attributes.value("city").toString());
82
83                 QString name("Result" + resultNumber++);
84                 if (category == "poi")
85                 {
86                     this->places.append(new Location(newX, newY, name, address));
87                 }
88                 else if (category == "street")
89                 {
90                     this->roadNames.append(new Location(newX, newY, name, address));
91                 }
92                 else if (category == "stop")
93                 {
94                     this->stops.append(new Location(newX, newY, name, address));
95                 }
96                 else
97                 {
98                     resultNumber--;
99                     QString errorMessage("Unknown category: ");
100                     errorMessage.append(category);
101                     qDebug() << errorMessage;
102                 }
103             }
104
105             if (xmlName == "ERROR") {
106                 this->invalidResponse = true;
107             }
108
109         }
110     }
111
112     qDebug() << xml.errorString();
113     if ( xml.hasError() ) {
114         qDebug() << "Invalid response received from Ytv";
115         this->invalidResponse = true;
116     } else {
117         int locationsFound = this->places.size() + this->roadNames.size() + this->stops.size();
118         qDebug() << "Number of locations received: " + locationsFound;
119     }
120     qDebug() << "Exiting xml parsing.";
121
122     emit(finished());
123 }
124
125 bool LocationFinder::responseWasValid() const
126 {
127     return !this->invalidResponse;
128 }
129
130 bool LocationFinder::locationsFound() const
131 {
132     return (this->numberOfLocationsFound() > 0);
133 }
134
135 int LocationFinder::numberOfLocationsFound() const
136 {
137     return this->numberOfPlaces() + this->numberOfRoadNames() + this->numberOfStops();
138 }
139
140 int LocationFinder::numberOfPlaces() const
141 {
142     return this->places.size();
143 }
144
145 int LocationFinder::numberOfRoadNames() const
146 {
147     return this->roadNames.size();
148 }
149
150 int LocationFinder::numberOfStops() const
151 {
152     return this->stops.size();
153 }
154
155 Location* LocationFinder::getPlace(int index) const
156 {
157     if (index < 0 || index >= this->places.size())
158         throw std::invalid_argument("Given index out of bounds.");
159
160     return new Location(*(this->places.at(index)));
161 }
162
163 Location* LocationFinder::getRoadName(int index) const
164 {
165     if (index < 0 || index >= this->roadNames.size())
166         throw std::invalid_argument("Given index out of bounds.");
167
168     return new Location(*(this->roadNames.at(index)));
169 }
170
171 Location* LocationFinder::getStop(int index) const
172 {
173     if (index < 0 || index >= this->stops.size())
174         throw std::invalid_argument("Given index out of bounds.");
175
176     return new Location(*(this->stops.at(index)));
177 }
178
179 const QList<Location*>& LocationFinder::getPlaces() const
180 {
181     return this->places;
182 }
183
184 const QList<Location*>& LocationFinder::getRoadNames() const
185 {
186     return this->roadNames;
187 }
188
189 const QList<Location*>& LocationFinder::getStops() const
190 {
191     return this->stops;
192 }