X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=traffic.cpp;h=05d5adfbf3f2a7eed1b5e1523cc93974f0e18ea7;hb=HEAD;hp=2abfeedf97bd93ec68116cd7ceb7f1d40b8c533c;hpb=d78260124b2bded856e35f1e9196debb9dd8d237;p=yandex-traffic diff --git a/traffic.cpp b/traffic.cpp index 2abfeed..05d5adf 100644 --- a/traffic.cpp +++ b/traffic.cpp @@ -1,17 +1,240 @@ #include +#include + #include "traffic.hpp" +#include "log.hpp" + + +// -------------------------------------------------- +// TrafficInfo +// -------------------------------------------------- +TrafficInfo::TrafficInfo (const QDomElement& elem) throw (const QString&) +{ + _valid = false; + _len1 = getFloatNode (elem, "length_1", 0); + _len2 = getFloatNode (elem, "length_2", 0); + _len = getFloatNode (elem, "length", 0); + _ts = getTSNode (elem, "timestamp"); + _isotime = getStringNode (elem, "isotime"); + _localtime = getStringNode (elem, "localtime"); + _valid = true; +} + + +float TrafficInfo::getFloatNode (const QDomElement& elem, const char* node, float def) +{ + QDomElement e; + bool ok; + float val; + e = elem.firstChildElement (node); + if (e.isNull ()) + return def; + val = e.text ().toFloat (&ok); + if (!ok) + return def; + return val; +} + + +int TrafficInfo::getIntNode (const QDomElement& elem, const char* node, int def) +{ + QDomElement e; + bool ok; + int val; -TrafficInfo::TrafficInfo () + e = elem.firstChildElement (node); + if (e.isNull ()) + return def; + val = e.text ().toInt (&ok); + if (!ok) + return def; + return val; +} + + +QString TrafficInfo::getStringNode (const QDomElement& elem, const char* node) throw (const QString&) { + QDomElement e; + QString val; + + e = elem.firstChildElement (node); + if (e.isNull ()) + throw QString (QString::fromAscii (node) + " not found"); + return e.text (); +} + + +QDateTime TrafficInfo::getTSNode (const QDomElement& elem, const char* node) throw (const QString&) +{ + QDomElement e; + bool ok; + uint val; + QDateTime ts; + + e = elem.firstChildElement (node); + if (e.isNull ()) + throw QString (QString::fromAscii (node) + " not found"); + val = e.text ().toUInt (&ok); + if (!ok) + throw QString (QString::fromAscii (node) + " is not a timestamp"); + ts.setTime_t (val); + return ts; +} + + +void TrafficInfo::dump () +{ + Log::instance ()->add (QString ("TrafficInfo (%1): time = %2").arg (_valid ? "valid" : "not valid").arg (_localtime)); +} + + +// -------------------------------------------------- +// ExtendedTrafficInfo +// -------------------------------------------------- +ExtendedTrafficInfo::ExtendedTrafficInfo (const QDomElement& elem) throw (const QString&) + : TrafficInfo (elem) +{ + QString color; + + setValid (false); + _level_raw = getFloatNode (elem, "level_raw", 0); + _level = getIntNode (elem, "level", 1); + _tend = getIntNode (elem, "tend", 0); + _hint = getStringNode (elem, "hint"); + + color = getStringNode (elem, "icon"); + if (color == "green") + _color = Green; + else if (color == "yellow") + _color = Yellow; + else if (color == "red") + _color = Red; + else + throw "Color is unknown"; + + setValid (true); } -ExtendedTrafficInfo::ExtendedTrafficInfo () +void ExtendedTrafficInfo::dump () { + TrafficInfo::dump (); + Log::instance ()->add (QString ("ExtTrafficInfo: level = %1, hint = %2").arg (_level).arg (_hint)); } +// -------------------------------------------------- +// Traffic +// -------------------------------------------------- Traffic::Traffic () + : QObject () +{ + connect (&_fetcher, SIGNAL (done (const QByteArray&)), + SLOT (fetchDone (const QByteArray&))); +} + + +// Perform asyncronous refresh of traffic information. If another update +// request is in progress, new is discarded. If update request finished +// successfully, updated() signal called. +void Traffic::update () +{ + Log::instance ()->add ("Traffic::update: Request status download"); + _fetcher.fetch ("http://trf.maps.yandex.net/trf/stat.xml"); +} + + +void Traffic::fetchDone (const QByteArray& data) { + // parse data got + if (parse_traffic_data (QString::fromUtf8 (data.data ()))) { + Log::instance ()->add ("Traffic::fetchDone: data parsed successfully"); + updated (); + } + else + Log::instance ()->add ("Traffic::fetchDone: data parse error"); } + + +bool Traffic::parse_traffic_data (const QString& xml) +{ + QDomDocument doc; + QDateTime new_ts; + QDomElement e; + QDomNode n; + bool ok; + QString s; + QMap new_info; + QMap new_ext_info; + + if (!doc.setContent (xml)) + return false; + + // get timestamp + e = doc.documentElement (); + if (e.isNull () || e.tagName () != "jams_stat") + return false; + + s = e.attribute ("timestamp"); + if (s.isNull ()) + return false; + + new_ts.setTime_t (s.toUInt (&ok)); + if (!ok) + return false; + + // parse all regions + n = e.firstChild (); + while (!n.isNull ()) { + e = n.toElement (); + if (!e.isNull () && e.tagName () == "region") { + s = e.attribute ("id"); + try { + // Check that it is an extended traffic info + if (!e.firstChildElement ("level").isNull ()) { + ExtendedTrafficInfo info (e); + if (info.valid ()) + new_ext_info[s] = info; + } + else { + TrafficInfo info (e); + if (info.valid ()) + new_info[s] = info; + } + } + catch (const QString& msg) { + } + } + n = n.nextSibling (); + } + + _ts = new_ts; + _info = new_info; + _ext_info = new_ext_info; + + return true; +} + + +TrafficInfo Traffic::lookup (const QString &id) const +{ + QMap::const_iterator it = _info.find (id); + + if (it == _info.end ()) + return TrafficInfo (); + else + return it.value (); +} + + +ExtendedTrafficInfo Traffic::lookup_ext (const QString &id) const +{ + QMap::const_iterator it = _ext_info.find (id); + + if (it == _ext_info.end ()) + return ExtendedTrafficInfo (); + else + return it.value (); +} +