Indicate loading state, fix cache time parsing
[evehomescreen] / src / eveskilltraining.cpp
1 // Copyright (C) 2010 Jaakko Kyro <jkyro@korjaussarja.net>
2 // This file is licenced under GPL, see COPYING
3 // for full licence information
4 #include "eveskilltraining.h"
5 #include "evemodel.h"
6 #include "eveaccount.h"
7
8 #include <QXmlStreamReader>
9 #include <QNetworkAccessManager>
10 #include <QNetworkRequest>
11 #include <QNetworkReply>
12 #include <QtDebug>
13 EveSkillTraining::EveSkillTraining(QObject *parent) :
14     QObject(parent),
15     training(false),
16     m_character(NULL),
17     m_account(NULL),
18     m_reply(NULL),
19     m_loading(false)
20 {
21 }
22
23 bool EveSkillTraining::fromXml(QXmlStreamReader &xml)
24 {
25     xml.readNextStartElement();
26     if (xml.name() != "eveapi")
27         return false;
28     xml.readNextStartElement();
29     if (xml.name() != "currentTime") {
30         return false;
31     }
32
33     currentTime = QDateTime::fromString(xml.readElementText(),"yyyy-MM-dd hh:mm:ss");
34     currentTime.setTimeSpec(Qt::UTC);
35     //xml.readNextStartElement(); // end currentTime element
36     bool inResult = xml.readNextStartElement(); // start result element
37     if (xml.name() != "result") {
38         qDebug() << "Wrong element:" << xml.name();
39         return false;
40     }
41     inResult = xml.readNextStartElement();
42     if (!inResult || xml.name() != "rowset" ) {
43         qDebug() << "No rowset element";
44         return false;
45     }
46     inResult = xml.readNextStartElement();
47     if (xml.name() == "row") {
48         training = true;
49         m_trainingQueue.clear();
50     }
51     while (xml.name() == "row") {
52
53         TrainingEntry entry;
54         entry.typeId = xml.attributes().value("","typeID").toString().toInt();
55         entry.destSkillpoints = xml.attributes().value("","endSP").toString().toInt();
56         entry.startSkillpoints = xml.attributes().value("","startSP").toString().toInt();
57         entry.level = xml.attributes().value("","level").toString().toInt();
58         if (xml.attributes().hasAttribute("","startTime")) {
59             entry.startTime = QDateTime::fromString(xml.attributes().value("","startTime").toString(),
60                                                     "yyyy-MM-dd hh:mm:ss");
61             entry.startTime.setTimeSpec(Qt::UTC);
62         }
63         if (xml.attributes().hasAttribute("","endTime")) {
64             entry.endTime = QDateTime::fromString(xml.attributes().value("","endTime").toString(),
65                                                   "yyyy-MM-dd hh:mm:ss");
66             entry.endTime.setTimeSpec(Qt::UTC);
67         }
68         qDebug() << entry;
69         m_trainingQueue.append(entry);
70         if (!xml.readNextStartElement() ) // end row element
71             xml.readNextStartElement(); // start next row element
72     }
73     xml.readNextStartElement(); // end rowset
74     xml.readNextStartElement(); // end result
75
76     if (xml.name() == "cachedUntil" ) {
77         QString cacheDate = xml.readElementText();
78         qDebug() << "Cache date: " << cacheDate;
79         cachedUntil = QDateTime::fromString(cacheDate,"yyyy-MM-dd hh:mm:ss");
80
81         cachedUntil.setTimeSpec(Qt::UTC);
82         qDebug() << "Cached until " << cachedUntil.toString(Qt::SystemLocaleShortDate);
83     }
84     qDebug() << "Parsing finished";
85     qDebug() << firstTraining();
86     return true;
87 }
88
89 void EveSkillTraining::fetchInfo()
90 {
91     if (m_character == NULL || m_account == NULL)
92         return;
93     if (cachedUntil.isValid()) {
94         if (cachedUntil > QDateTime::currentDateTime().toUTC() ) {
95             qDebug() << "Cached until " << cachedUntil.toString(Qt::SystemLocaleShortDate);
96             return;
97         }
98     }
99     m_loading = true;
100     QNetworkRequest req(QUrl(QString("http://api.eveonline.com/char/SkillQueue.xml.aspx?apiKey=%1&userID=%2&characterID=%3")
101                              .arg(m_account->apiKey())
102                              .arg(m_account->userId())
103                              .arg(m_character->characterId)));
104     m_reply = m_mgr.get(req);
105     connect(m_reply,SIGNAL(finished()),this,SLOT(infoReady()));
106 }
107
108 void EveSkillTraining::infoReady()
109 {
110     if (m_reply->error()) {
111         qDebug() << "Failed! " << m_reply->errorString();
112         return;
113     }
114     qDebug() << "Skill reply";
115     QByteArray reply = m_reply->readAll();
116     qDebug() << "Reply ready";
117     qDebug() << reply;
118     QXmlStreamReader reader(reply);
119     fromXml(reader);
120     m_reply->deleteLater();
121     m_loading = false;
122     emit finished();
123 }
124
125 QDebug operator<<(QDebug dbg, const TrainingEntry &e)
126 {
127     dbg.nospace() << e.typeId << " to "
128                 << e.level << " "
129                 << e.startTime.toString(Qt::SystemLocaleShortDate) << " -> "
130                 << e.endTime.toString(Qt::SystemLocaleShortDate);
131     return dbg.space();
132 };