- added settingsdialog
[buliscores] / src / backendkicker.cpp
1 #include <QtNetwork/QNetworkAccessManager>
2 #include <QtNetwork/QNetworkRequest>
3 #include <QUrl>
4 #include <QRegExp>
5 #include <QDebug>
6 #include <QStringList>
7 #include <QDateTime>
8 #include <QSettings>
9
10 #include "backendkicker.h"
11
12 BackendKicker::BackendKicker(QObject *parent) :
13     QObject(parent)
14 {
15     QSettings settings("David Solbach", "BuliScores");
16     this->setLeague(settings.value("League", "1. Bundesliga").toString());
17
18     this->update();
19 }
20
21 Match* BackendKicker::getMatch(QString hometeam, QString awayteam, QDateTime date)
22 {
23     QListIterator<Match*> iter(m_matchlist);
24     Match*        match;
25
26     while (iter.hasNext()) {
27         match = iter.next();
28         if (match->awayTeam() == awayteam &&
29             match->homeTeam() == hometeam) {
30             return match;
31         }
32     }
33
34     match = new Match(hometeam, awayteam, date, this);
35     m_matchlist.append(match);
36
37     emit matchListChanged();
38
39     return match;
40 }
41
42 QList<Match*> BackendKicker::matchList()
43 {
44     return m_matchlist;
45 }
46
47 static QDateTime parseDate(QString datehtml)
48 {
49     static QDateTime    lastParsedDate;
50     QStringList         tokens;
51     QDate               date;
52
53     int month, day, hour, minute;
54
55     //qDebug() << "parseDate in: " << datehtml;
56
57     tokens = datehtml.split(QRegExp("[>.&;:<\"]"), QString::SkipEmptyParts);
58     date = QDate::currentDate();
59
60     qDebug() << tokens;
61     if (tokens.count() < 6) {
62         return lastParsedDate;
63     }
64
65     month  = (tokens.at(2)).toInt();
66     day    = (tokens.at(1)).toInt();
67     hour   = (tokens.at(4)).toInt();
68     minute = (tokens.at(5)).toInt();
69
70     lastParsedDate =  QDateTime(QDate(date.year(), month, day),
71                                 QTime(hour, minute));
72
73     return lastParsedDate;
74 }
75
76 static QString parseTeam(QString teamhtml)
77 {
78     QString team;
79
80     //qDebug() << "parseTeam in: " << teamhtml;
81
82     teamhtml.truncate(teamhtml.indexOf("</a>"));
83     team = teamhtml.mid(teamhtml.lastIndexOf(">") + 1);
84
85     qDebug() << "parseTeam out: " << team;
86     return team;
87 }
88
89 static int parseScore(Match* match, QString scorehtml)
90 {
91     int         score = -1;
92     QStringList tokens;
93
94     qDebug() << "parseScore in: " << scorehtml;
95     tokens = scorehtml.split(QRegExp("[>&();:<]"), QString::SkipEmptyParts);
96     qDebug() << tokens;
97
98     if (tokens.count() == 7) {
99         // no extra color tag -> either not started, halftime or finished
100         if (tokens.at(4) == "-") {
101             // no first half results -> match not started yet
102             match->setState(Match::NotStarted);
103         } else if (tokens.at(1) == "-") {
104             // second half has not been started but there are first
105             // half results -> currently half time
106             match->setScore(tokens.at(4).toInt(), tokens.at(5).toInt());
107             match->setState(Match::HalfTime);
108         } else {
109             // no color tag and no "-" -> game is finished
110             match->setScore(tokens.at(1).toInt(), tokens.at(3).toInt());
111             match->setState(Match::Finished);
112         }
113     } else {
114         // there is a color tag which means that either first
115         // half or second half are currently running
116         if (tokens.at(4).contains("color")) {
117             // first half score marked red -> first half running
118             match->setScore(tokens.at(5).toInt(), tokens.at(6).toInt());
119             match->setState(Match::FirstHalf);
120         } else if (tokens.at(1).contains("color")) {
121             // second half score marked res -> second half running
122             match->setState(Match::SecondHalf);
123             match->setScore(tokens.at(2).toInt(), tokens.at(3).toInt());
124         }
125
126     }
127     qDebug() << "match out: " << match;
128
129     return score;
130 }
131
132 void BackendKicker::parsePage (QString htmlstr)
133 {
134     QStringList     rawmatches;
135     QString         hometeam, awayteam, tmp;
136     QRegExp         rx;
137     QDateTime       date;
138     Match*          match;
139
140     int             pos     = 0;
141     int             count   = 0;
142
143     //qDebug() << "parsePage in: " << htmlstr;
144
145     rx.setPattern("<td class=\"first\">(.*)<td class=\"aligncenter last\">");
146     rx.setMinimal(true);
147     while ((pos = rx.indexIn(htmlstr, pos)) != -1) {
148          ++count;
149          rawmatches.append(htmlstr.mid(pos, rx.matchedLength()));
150          qDebug() << "MATCH " << count << ":" << htmlstr.mid(pos, rx.matchedLength()) << "\n\n";
151          pos += rx.matchedLength();
152      }
153
154     rx.setPattern("<td.*>(.*)</td>");
155
156     QStringList::iterator i;
157     for (i = rawmatches.begin(); i != rawmatches.end(); ++i) {
158         pos = 0;
159         count = 0;
160         while ((pos = rx.indexIn(*i, pos)) != -1) {
161              ++count;
162              tmp = (*i).mid(pos, rx.matchedLength());
163              pos += rx.matchedLength();
164              switch (count) {
165              case 2: // date
166                  date = parseDate(tmp);
167                  break;
168              case 3: // hometeam
169                  hometeam = parseTeam(tmp);
170                  break;
171              case 5: // awayteam
172                  awayteam = parseTeam(tmp);
173                  match = getMatch(hometeam, awayteam, date);
174                  break;
175              case 6: // scores
176                  parseScore(match, tmp);
177                  break;
178              default:
179                 ;;
180              }
181         }
182     }
183
184
185 }
186
187 void BackendKicker::setLeague(QString league)
188 {
189     if (league == "1. Bundesliga") {
190         m_URL = "http://www.kicker.de/news/fussball/bundesliga/spieltag/1-bundesliga/2010-11/spieltag.html";
191     } else if (league == "2. Bundesliga") {
192         m_URL = "http://www.kicker.de/news/fussball/bundesliga/spieltag/2-bundesliga/2010-11/spieltag.html";
193     } else if (league == "tipp3 Bundesliga") {
194         m_URL = "http://www.kicker.de/news/fussball/intligen/oesterreich/tipp3-bundesliga/2010-11/spieltag.html";
195     }
196 }
197
198 void BackendKicker::update()
199 {
200     QNetworkAccessManager *manager = new QNetworkAccessManager(this);
201     connect(manager, SIGNAL(finished(QNetworkReply*)),
202             this, SLOT(dlndFinished(QNetworkReply*)));
203
204     qDebug() << "URL: " << m_URL;
205     manager->get(QNetworkRequest(QUrl(m_URL)));
206 }
207
208 void BackendKicker::dlndFinished(QNetworkReply *reply)
209 {
210     QString         rawdata;
211
212     if (reply->error() != QNetworkReply::NoError) {
213         // TODO proper user friendly error handling here!
214         qDebug() << "dlnd failed: error: " << reply->error();
215     }
216
217     rawdata = reply->readAll();
218     parsePage(rawdata);
219 }