1 /****************************************************************************************
2  * Copyright (c) 2010 Rick W. Chen <stuffcorpse@archlinux.us>                           *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 #include "LastFmEventXmlParser.h"
18 
19 
LastFmEventXmlParser(QXmlStreamReader & reader)20 LastFmEventXmlParser::LastFmEventXmlParser( QXmlStreamReader &reader )
21     : m_xml( reader )
22 {
23 }
24 
~LastFmEventXmlParser()25 LastFmEventXmlParser::~LastFmEventXmlParser()
26 {}
27 
28 bool
read()29 LastFmEventXmlParser::read()
30 {
31     while( !m_xml.atEnd() && !m_xml.hasError() )
32     {
33         m_xml.readNext();
34         if( m_xml.isStartElement() && m_xml.name() == "event" )
35         {
36             QHash<QString, QString> artists;
37             LastFmEventPtr event( new LastFmEvent );
38             while( !m_xml.atEnd() )
39             {
40                 m_xml.readNext();
41                 const QStringRef &n = m_xml.name();
42                 if( m_xml.isEndElement() && n == "event" )
43                     break;
44 
45                 if( m_xml.isStartElement() )
46                 {
47                     const QXmlStreamAttributes &a = m_xml.attributes();
48                     if( n == "title" )
49                         event->setName( m_xml.readElementText() );
50                     else if( n == "artists" )
51                         artists = readEventArtists();
52                     else if( n == "venue" )
53                     {
54                         LastFmVenueXmlParser venueParser( m_xml );
55                         if( venueParser.read() )
56                             event->setVenue( venueParser.venue() );
57                     }
58                     else if( n == "startDate" )
59                         event->setDate( KDateTime::fromString( m_xml.readElementText(), "%a, %d %b %Y %H:%M:%S" ) );
60                     else if( n == "image" && a.hasAttribute("size") )
61                         event->setImageUrl( LastFmEvent::stringToImageSize(a.value("size").toString()), QUrl( m_xml.readElementText() ) );
62                     else if( n == "url" )
63                         event->setUrl( QUrl( m_xml.readElementText() ) );
64                     else if( n == "attendance" )
65                         event->setAttendance( m_xml.readElementText().toInt() );
66                     else if( n == "cancelled" )
67                         event->setCancelled( bool( m_xml.readElementText().toInt() ) );
68                     else if( n == "tags" )
69                         event->setTags( readEventTags() );
70                     else
71                         m_xml.skipCurrentElement();
72                 }
73             }
74             event->setHeadliner( artists.value("headliner") );
75             event->setParticipants( artists.values("artist") );
76             m_events << event;
77         }
78     }
79     return !m_xml.error();
80 }
81 
82 QStringList
readEventTags()83 LastFmEventXmlParser::readEventTags()
84 {
85     QStringList tags;
86     while( !m_xml.atEnd() )
87     {
88         m_xml.readNext();
89         if( m_xml.isEndElement() && m_xml.name() == "tags" )
90             break;
91 
92         if( m_xml.isStartElement() )
93         {
94             if( m_xml.name() == "tag" )
95                 tags << m_xml.readElementText();
96             else
97                 m_xml.skipCurrentElement();
98         }
99     }
100     return tags;
101 }
102 
103 QHash<QString, QString>
readEventArtists()104 LastFmEventXmlParser::readEventArtists()
105 {
106     QHash<QString, QString> artists;
107     while( !m_xml.atEnd() )
108     {
109         m_xml.readNext();
110         if( m_xml.isEndElement() && m_xml.name() == "artists" )
111             break;
112 
113         if( m_xml.isStartElement() )
114         {
115             if( m_xml.name() == "artist" )
116                 artists.insertMulti( "artist", m_xml.readElementText() );
117             else if( m_xml.name() == "headliner" )
118                 artists.insert( "headliner", m_xml.readElementText() );
119             else
120                 m_xml.skipCurrentElement();
121         }
122     }
123     return artists;
124 }
125 
126 
LastFmVenueXmlParser(QXmlStreamReader & reader)127 LastFmVenueXmlParser::LastFmVenueXmlParser( QXmlStreamReader &reader )
128     : m_xml( reader )
129 {}
130 
131 bool
read()132 LastFmVenueXmlParser::read()
133 {
134     m_venue = new LastFmVenue;
135     while( !m_xml.atEnd() && !m_xml.hasError() )
136     {
137         m_xml.readNext();
138         const QStringRef &n = m_xml.name();
139         if( m_xml.isEndElement() && n == "venue" )
140             break;
141 
142         if( m_xml.isStartElement() )
143         {
144             const QXmlStreamAttributes &a = m_xml.attributes();
145             if( n == "id" )
146                 m_venue->id = m_xml.readElementText().toInt();
147             else if( n == "name" )
148                 m_venue->name = m_xml.readElementText();
149             else if( n == "location" )
150             {
151                 LastFmLocationXmlParser locationParser( m_xml );
152                 if( locationParser.read() )
153                     m_venue->location = locationParser.location();
154             }
155             else if( n == "url" )
156                 m_venue->url = QUrl( m_xml.readElementText() );
157             else if( n == "website" )
158                 m_venue->website = QUrl( m_xml.readElementText() );
159             else if( n == "phonenumber" )
160                 m_venue->phoneNumber = m_xml.readElementText();
161             else if( n == "image" && a.hasAttribute("size") )
162             {
163                 LastFmEvent::ImageSize size = LastFmEvent::stringToImageSize( a.value("size").toString() );
164                 m_venue->imageUrls[ size ] = QUrl( m_xml.readElementText() );
165             }
166             else
167                 m_xml.skipCurrentElement();
168         }
169     }
170     return !m_xml.error();
171 }
172 
~LastFmVenueXmlParser()173 LastFmVenueXmlParser::~LastFmVenueXmlParser()
174 {}
175 
LastFmLocationXmlParser(QXmlStreamReader & reader)176 LastFmLocationXmlParser::LastFmLocationXmlParser( QXmlStreamReader &reader )
177     : m_xml( reader )
178 {}
179 
180 bool
read()181 LastFmLocationXmlParser::read()
182 {
183     m_location = new LastFmLocation;
184     while( !m_xml.atEnd() && !m_xml.hasError() )
185     {
186         m_xml.readNext();
187         if( m_xml.isEndElement() && m_xml.name() == "location" )
188             break;
189 
190         if( m_xml.isStartElement() )
191         {
192             if( m_xml.name() == "city" )
193                 m_location->city = m_xml.readElementText();
194             else if( m_xml.name() == "country" )
195                 m_location->country = m_xml.readElementText();
196             else if( m_xml.name() == "street" )
197                 m_location->street = m_xml.readElementText();
198             else if( m_xml.name() == "postalcode" )
199                 m_location->postalCode = m_xml.readElementText();
200             else if( m_xml.prefix() == "geo" && m_xml.name() == "point" )
201                 readGeoPoint();
202             else
203                 m_xml.skipCurrentElement();
204         }
205     }
206     return !m_xml.error();
207 }
208 
~LastFmLocationXmlParser()209 LastFmLocationXmlParser::~LastFmLocationXmlParser()
210 {}
211 
212 void
readGeoPoint()213 LastFmLocationXmlParser::readGeoPoint()
214 {
215     while( !m_xml.atEnd() && !m_xml.hasError() )
216     {
217         m_xml.readNext();
218         if( m_xml.isEndElement() && m_xml.name() == "point" )
219             break;
220 
221         if( m_xml.isStartElement() )
222         {
223             if( m_xml.name() == "lat" )
224                 m_location->latitude = m_xml.readElementText().toDouble();
225             else if( m_xml.name() == "long" )
226                 m_location->longitude = m_xml.readElementText().toDouble();
227             else
228                 m_xml.skipCurrentElement();
229         }
230     }
231 }
232