1 #include <QtNetwork/QNetworkAccessManager>
2 #include <QtNetwork/QNetworkRequest>
9 #include <QApplication>
11 #include "backendkicker.h"
13 const int BackendKicker::INTERVAL_FAST = 100 * 1000;
14 const int BackendKicker::INTERVAL_SLOW = 3600 * 1000;
16 BackendKicker::BackendKicker(QObject *parent) :
17 MatchDayBackend(parent),
19 m_netaccmgr(new QNetworkAccessManager(this))
21 QSettings settings(qApp->organizationName(), qApp->applicationName());
23 this->selectLeague(settings.value("League", "1. Bundesliga").toString());
25 connect(m_netaccmgr, SIGNAL(finished(QNetworkReply*)),
26 this, SLOT(dlndFinished(QNetworkReply*)));
28 connect(&m_updateTimer, SIGNAL(timeout()),
29 this, SLOT(update()));
34 Match* BackendKicker::getMatch(QString hometeam, QString awayteam, QDateTime date)
36 QListIterator<Match*> iter(m_matchlist);
39 while (iter.hasNext()) {
41 if (match->awayTeam() == awayteam &&
42 match->homeTeam() == hometeam) {
47 match = new Match(hometeam, awayteam, date, this);
48 m_matchlist.append(match);
53 QList<Match*> BackendKicker::matchList()
58 static QDateTime parseDate(QString datehtml)
60 static QDateTime lastParsedDate;
64 int month, day, hour, minute;
66 //qDebug() << "parseDate in: " << datehtml;
68 tokens = datehtml.split(QRegExp("[>.&;:<\"]"), QString::SkipEmptyParts);
69 date = QDate::currentDate();
72 if (tokens.count() < 6) {
73 return lastParsedDate;
76 month = (tokens.at(2)).toInt();
77 day = (tokens.at(1)).toInt();
78 hour = (tokens.at(4)).toInt();
79 minute = (tokens.at(5)).toInt();
81 lastParsedDate = QDateTime(QDate(date.year(), month, day),
84 return lastParsedDate;
87 static QString parseTeam(QString teamhtml)
91 //qDebug() << "parseTeam in: " << teamhtml;
93 teamhtml.truncate(teamhtml.indexOf("</a>"));
94 team = teamhtml.mid(teamhtml.lastIndexOf(">") + 1);
96 //qDebug() << "parseTeam out: " << team;
100 static void parseScore(Match* match, QString scorehtml)
104 //qDebug() << "parseScore in: " << scorehtml;
105 tokens = scorehtml.split(QRegExp("[>&();:<]"), QString::SkipEmptyParts);
106 //qDebug() << tokens;
108 if (tokens.count() == 7) {
109 // no extra color tag -> either not started, halftime or finished
110 if (tokens.at(4) == "-") {
111 // no first half results -> match not started yet
112 match->setState(Match::NotStarted);
113 } else if (tokens.at(1) == "-") {
114 // second half has not been started but there are first
115 // half results -> currently half time
116 match->setScore(tokens.at(4).toInt(), tokens.at(5).toInt());
117 match->setState(Match::HalfTime);
119 // no color tag and no "-" -> game is finished
120 match->setScore(tokens.at(1).toInt(), tokens.at(2).toInt());
121 match->setState(Match::Finished);
124 // there is a color tag which means that either first
125 // half or second half are currently running
126 if (tokens.at(4).contains("color")) {
127 // first half score marked red -> first half running
128 match->setScore(tokens.at(5).toInt(), tokens.at(6).toInt());
129 match->setState(Match::FirstHalf);
130 } else if (tokens.at(1).contains("color")) {
131 // second half score marked res -> second half running
132 match->setState(Match::SecondHalf);
133 match->setScore(tokens.at(2).toInt(), tokens.at(3).toInt());
137 // qDebug() << "match state: " << match->state();
138 // qDebug() << "match home: " << match->homeScore();
139 // qDebug() << "match away: " << match->awayScore();
142 void BackendKicker::parsePage (QString htmlstr)
144 QStringList rawmatches;
145 QString hometeam, awayteam, tmp;
153 //qDebug() << "parsePage in: " << htmlstr;
155 rx.setPattern("<td class=\"first\">(.*)<td class=\"aligncenter last\">");
157 while ((pos = rx.indexIn(htmlstr, pos)) != -1) {
159 rawmatches.append(htmlstr.mid(pos, rx.matchedLength()));
160 //qDebug() << "MATCH " << count << ":" << htmlstr.mid(pos, rx.matchedLength()) << "\n\n";
161 pos += rx.matchedLength();
164 rx.setPattern("<td.*>(.*)</td>");
166 QStringList::iterator i;
167 for (i = rawmatches.begin(); i != rawmatches.end(); ++i) {
170 while ((pos = rx.indexIn(*i, pos)) != -1) {
172 tmp = (*i).mid(pos, rx.matchedLength());
173 pos += rx.matchedLength();
176 date = parseDate(tmp);
179 hometeam = parseTeam(tmp);
182 awayteam = parseTeam(tmp);
183 match = getMatch(hometeam, awayteam, date);
186 parseScore(match, tmp);
195 bool BackendKicker::selectLeague(QString league)
197 bool leagueIsSupported = true;
199 if (league == "1. Bundesliga") {
200 m_URL = "http://www.kicker.de/news/fussball/bundesliga/spieltag/1-bundesliga/2010-11/spieltag.html";
201 } else if (league == "2. Bundesliga") {
202 m_URL = "http://www.kicker.de/news/fussball/bundesliga/spieltag/2-bundesliga/2010-11/spieltag.html";
203 } else if (league == "tipp3 Bundesliga") {
204 m_URL = "http://www.kicker.de/news/fussball/intligen/oesterreich/tipp3-bundesliga/2010-11/spieltag.html";
206 leagueIsSupported = false;
210 return leagueIsSupported;
213 void BackendKicker::update()
215 if (matchRunning()) {
216 m_updateTimer.start(INTERVAL_FAST);
218 m_updateTimer.start(INTERVAL_SLOW);
221 emit updateStarted();
223 //qDebug() << "URL: " << m_URL;
224 m_netaccmgr->get(QNetworkRequest(QUrl(m_URL)));
227 void BackendKicker::dlndFinished(QNetworkReply *reply)
231 if (reply->error() != QNetworkReply::NoError) {
232 // TODO proper user friendly error handling here!
233 qDebug() << "dlnd failed: error: " << reply->error();
236 this->m_matchlist.clear();
238 rawdata = reply->readAll();
241 emit matchListChanged();
244 bool BackendKicker::matchRunning()
246 QListIterator<Match*> iter(m_matchlist);
248 bool matchrunning = false;
251 while (iter.hasNext()) {
253 if (match->state() == Match::FirstHalf ||
254 match->state() == Match::SecondHalf) {
259 secstogame = QDateTime::currentDateTime().secsTo(match->date());
260 if (secstogame >= 0 && secstogame < INTERVAL_SLOW) {