void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; JourneyResultList *journeyResultList = new JourneyResultList(); for (QHash<QString, JourneyDetailResultList *>::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { JourneyDetailResultList *jdrl = it.value(); it = cachedJourneyDetails.erase(it); delete jdrl; } /// Use fallback values for empty results (i.e. no connections found) journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); m_earliestArrival = m_latestResultDeparture = QDateTime(); QTextStream ts(networkReply->readAll()); ts.setCodec("UTF-8"); const QString xmlRawtext = ts.readAll(); QDomDocument doc("result"); if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { JourneyResultItem *jritem = new JourneyResultItem(); JourneyDetailResultList *detailsList = new JourneyDetailResultList(); /// Set default values for journey's start and end time QDateTime journeyStart = QDateTime::currentDateTime(); QDateTime journeyEnd = QDateTime::currentDateTime(); QDomNodeList legNodeList = tripNodeList.item(i).childNodes(); int numStops = 0; QStringList trainTypes; int tripRtStatus = TRIP_RTDATA_NONE; for (unsigned int j = 0; j < legNodeList.length(); ++j) { QDomNode legNode = legNodeList.item(j); QDomNode originNode = legNode.namedItem("Origin"); QDomNode destinationNode = legNode.namedItem("Destination"); if (j == 0) { journeyStart.setDate(QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd"))); journeyEnd.setDate(journeyStart.date()); const QTime time = QTime::fromString(getAttribute(originNode, "time"), "hh:mm"); journeyStart.setTime(time); if (i == 0) { const QDate date = QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd")); journeyResultList->setDepartureStation(getAttribute(originNode, "name")); journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); } } if (j == legNodeList.length() - 1) { journeyEnd.setTime(QTime::fromString(getAttribute(destinationNode, "time"), "hh:mm")); if (i == 0) journeyResultList->setArrivalStation(getAttribute(destinationNode, "name")); } if (getAttribute(legNode, "type") != QLatin1String("WALK") || getAttribute(originNode, "name") != getAttribute(destinationNode, "name")) { ++numStops; trainTypes.append(i18nConnectionType(getAttribute(legNode, "name"))); } JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); jdrItem->setDepartureStation(getAttribute(originNode, "name")); const QString depTrack = getAttribute(originNode, "track"); jdrItem->setDepartureInfo(depTrack.isEmpty() ? QChar(0x2014) : tr("Track %1").arg(depTrack)); const QDateTime scheduledDepartureTime = QDateTime::fromString(getAttribute(originNode, "date") + getAttribute(originNode, "time"), "yyyy-MM-ddhh:mm"); jdrItem->setDepartureDateTime(scheduledDepartureTime); jdrItem->setArrivalStation(getAttribute(destinationNode, "name")); const QString arrTrack = getAttribute(destinationNode, "track"); jdrItem->setArrivalInfo(arrTrack.isEmpty() ? QChar(0x2014) : tr("Track %1").arg(arrTrack)); const QDateTime scheduledArrivalTime = QDateTime::fromString(getAttribute(destinationNode, "date") + getAttribute(destinationNode, "time"), "yyyy-MM-ddhh:mm"); jdrItem->setArrivalDateTime(scheduledArrivalTime); const QString direction = getAttribute(legNode, "direction"); if (!direction.isEmpty()) jdrItem->setInfo(tr("to %1").arg(direction)); if (getAttribute(legNode, "type") == QLatin1String("WALK")) jdrItem->setTrain(tr("Walk")); else { const QString connectionName = i18nConnectionType(getAttribute(legNode, "name")); const QString fgColor = getAttribute(legNode, "fgColor"); const QString bgColor = getAttribute(legNode, "bgColor"); if (!fgColor.isEmpty() && !bgColor.isEmpty()) jdrItem->setTrain(QString(QLatin1String("<span style=\"color:%2; background-color: %3;\">%1</span>")).arg(connectionName).arg(fgColor).arg(bgColor)); else jdrItem->setTrain(connectionName); } jdrItem->setInternalData1("NO setInternalData1"); jdrItem->setInternalData2("NO setInternalData2"); const QString realTimeDeparture = getAttribute(originNode, "rtTime"); if (!realTimeDeparture.isEmpty()) { const QTime realTimeTime = QTime::fromString(realTimeDeparture, QLatin1String("hh:mm")); const int minutesTo = scheduledDepartureTime.time().msecsTo(realTimeTime) / 60000; if (minutesTo > 3) { jdrItem->setDepartureInfo(jdrItem->departureInfo() + tr("<br/><span style=\"color:#b30;\">%1 min late</span>").arg(minutesTo)); tripRtStatus = TRIP_RTDATA_WARNING; } else { if (tripRtStatus == TRIP_RTDATA_NONE) { tripRtStatus = TRIP_RTDATA_ONTIME; } jdrItem->setDepartureInfo(jdrItem->departureInfo() + tr("<br/><span style=\"color:#093; font-weight: normal;\">on time</span>")); } } const QString realTimeArrival = getAttribute(destinationNode, "rtTime"); if (!realTimeArrival.isEmpty()) { const QTime realTimeTime = QTime::fromString(realTimeArrival, QLatin1String("hh:mm")); const int minutesTo = scheduledArrivalTime.time().msecsTo(realTimeTime) / 60000; if (minutesTo > 3) jdrItem->setArrivalInfo(jdrItem->arrivalInfo() + tr("<br/><span style=\"color:#b30;\">%1 min late</span>").arg(minutesTo)); else jdrItem->setArrivalInfo(jdrItem->arrivalInfo() + tr("<br/><span style=\"color:#093; font-weight: normal;\">on time</span>")); } detailsList->appendItem(jdrItem); } if (journeyStart.time() > journeyEnd.time()) journeyEnd = journeyEnd.addDays(1); jritem->setDate(journeyStart.date()); jritem->setDepartureTime(journeyStart.time().toString(tr("hh:mm"))); jritem->setArrivalTime(journeyEnd.time().toString(tr("hh:mm"))); int diffTime = journeyStart.secsTo(journeyEnd); if (diffTime < 0) diffTime += 86400; jritem->setDuration(tr("%1:%2").arg(diffTime / 3600).arg(QString::number(diffTime / 60 % 60), 2, '0')); jritem->setTransfers(QString::number(legNodeList.length() - 1)); trainTypes.removeDuplicates(); jritem->setTrainType(trainTypes.join(", ")); if (tripRtStatus == TRIP_RTDATA_WARNING) jritem->setMiscInfo(tr("<span style=\"color:#b30;\">traffic warning</span>")); else if (tripRtStatus == TRIP_RTDATA_ONTIME) jritem->setMiscInfo(tr("<span style=\"color:#093; font-weight: normal;\">on time</span>")); journeyResultList->appendItem(jritem); const QString id = QString::number(i); jritem->setId(id); detailsList->setId(id); detailsList->setDepartureStation(journeyResultList->departureStation()); detailsList->setViaStation(journeyResultList->viaStation()); detailsList->setArrivalStation(journeyResultList->arrivalStation()); detailsList->setDuration(jritem->duration()); detailsList->setArrivalDateTime(journeyEnd); detailsList->setDepartureDateTime(journeyStart); cachedJourneyDetails[id] = detailsList; if (!m_earliestArrival.isValid() || journeyEnd < m_earliestArrival) m_earliestArrival = journeyEnd.addSecs(-60); if (!m_latestResultDeparture.isValid() || journeyStart > m_latestResultDeparture) m_latestResultDeparture = journeyStart.addSecs(60); } } emit journeyResult(journeyResultList); }
JourneyDetailResultList * Parser131500ComAu::parseDetails(JourneyResultItem *journeyitem) { QString element = journeyitem->internalData1(); element.replace("am+", "am"); element.replace("pm+", "pm"); QStringList detailResults = element.split("<linesep>"); JourneyDetailResultList *results = new JourneyDetailResultList(); QDate journeydate = journeyitem->date(); for (int i = 0; i < detailResults.count(); i++) { JourneyDetailResultItem *item = new JourneyDetailResultItem(); QRegExp regexp = QRegExp("(Take the |Walk to )(.*)$"); regexp.setMinimal(true); regexp.indexIn(detailResults[i].trimmed()); if (regexp.cap(1) == "Take the ") { //qDebug()<<"Regular: "<<regexp.cap(2).trimmed(); QRegExp regexp2 = QRegExp("(.*)Dep: (\\d:\\d\\d|\\d\\d:\\d\\d)(am|pm)(.*)Arr: (\\d:\\d\\d|\\d\\d:\\d\\d)(am|pm)(.*)(\\t+.*)$"); regexp2.setMinimal(true); regexp2.indexIn(regexp.cap(2).trimmed()); //qDebug()<<"***"; if (regexp2.matchedLength() == -1) { regexp2 = QRegExp("(.*)Dep: (\\d:\\d\\d|\\d\\d:\\d\\d)(am|pm)(.*)Arr: (\\d:\\d\\d|\\d\\d:\\d\\d)(am|pm)(.*)$"); regexp2.setMinimal(true); regexp2.indexIn(regexp.cap(2).trimmed()); } /* qDebug()<<"Train:"<<regexp2.cap(1).trimmed(); qDebug()<<"Time1:"<<regexp2.cap(2).trimmed(); qDebug()<<"Time1b:"<<regexp2.cap(3).trimmed(); qDebug()<<"Station1:"<<regexp2.cap(4).trimmed(); qDebug()<<"Time2:"<<regexp2.cap(5).trimmed(); qDebug()<<"Time2b:"<<regexp2.cap(6).trimmed(); qDebug()<<"Station2:"<<regexp2.cap(7).trimmed(); qDebug()<<"Alt:"<<regexp2.cap(8).trimmed(); */ QDateTime fromDateTime; QDateTime toDateTime; QTime fromTime = QTime::fromString(regexp2.cap(2).trimmed() + regexp2.cap(3).trimmed(), "h:map"); QTime toTime = QTime::fromString(regexp2.cap(5).trimmed() + regexp2.cap(6).trimmed(), "h:map"); fromDateTime.setDate(journeydate); fromDateTime.setTime(fromTime); toDateTime.setDate(journeydate); toDateTime.setTime(toTime); if (toDateTime.toTime_t() < fromDateTime.toTime_t()) { toDateTime.addDays(1); journeydate.addDays(1); } item->setDepartureStation(regexp2.cap(4).trimmed()); item->setArrivalStation(regexp2.cap(7).trimmed()); item->setTrain(regexp2.cap(1).trimmed()); item->setInfo(regexp2.cap(8).trimmed()); item->setDepartureDateTime(fromDateTime); item->setArrivalDateTime(toDateTime); results->appendItem(item); } if (regexp.cap(1) == "Walk to ") { //qDebug()<<"Walking: "<<regexp.cap(2).trimmed(); QRegExp regexp2 = QRegExp("(.*) - (.+) (.*)$"); regexp2.setMinimal(true); regexp2.indexIn(regexp.cap(2).trimmed()); /* qDebug()<<"***"; qDebug()<<"Station1:"<<regexp2.cap(1).trimmed(); qDebug()<<"WalkDist1:"<<regexp2.cap(2).trimmed(); qDebug()<<"WalkDist2:"<<regexp2.cap(3).trimmed(); */ item->setDepartureStation(""); if (results->itemcount() > 0) { JourneyDetailResultItem *lastitem = results->getItem(results->itemcount() - 1); item->setDepartureStation(lastitem->arrivalStation()); item->setDepartureDateTime(lastitem->arrivalDateTime()); item->setArrivalDateTime(lastitem->arrivalDateTime()); } item->setArrivalStation(regexp2.cap(1).trimmed()); // TODO: Might need translation item->setInfo("Walking " + regexp2.cap(2).trimmed() + " " + regexp2.cap(3).trimmed()); //Don't add WalkTo infos as first item if (results->itemcount() > 0) { results->appendItem(item); } } } results->setDuration(journeyitem->duration()); if (results->itemcount() > 0) { JourneyDetailResultItem *lastitem = results->getItem(results->itemcount() - 1); JourneyDetailResultItem *firstitem = results->getItem(0); results->setDepartureStation(firstitem->departureStation()); results->setArrivalStation(lastitem->arrivalStation()); for (int i=0; i < results->itemcount(); i++) { if (!results->getItem(i)->departureDateTime().isNull()) { results->setDepartureDateTime(results->getItem(i)->departureDateTime()); break; } } for (int i=results->itemcount() -1; i >= 0; i--) { if (!results->getItem(i)->arrivalDateTime().isNull()) { results->setArrivalDateTime(results->getItem(i)->arrivalDateTime()); break; } } } return results; }
JourneyDetailResultList* ParserHafasXml::internalParseJourneyDetails(QByteArray data) { qDebug() << ";;;;;;;;;;;;;;;" << data; JourneyDetailResultList *results = new JourneyDetailResultList(); QBuffer readBuffer; readBuffer.setData(data); readBuffer.open(QIODevice::ReadOnly); QXmlQuery query; query.bindVariable("path", &readBuffer); query.setQuery("doc($path)/ResC/Err//@text/string()"); QStringList errorResult; if (!query.evaluateTo(&errorResult)) { qDebug() << "parserHafasXml::ErrorTest - Query Failed"; return results; } if (errorResult.count() > 0 ) { emit errorOccured(errorResult.join("").trimmed()); qWarning()<<"ParserHafasXml::internalParseJourneyDetails:"<<errorResult.join(""); return results; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Departure/BasicStop/Station/@name/string()"); QStringList departureResults; if (!query.evaluateTo(&departureResults)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 1 Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Arrival/BasicStop/Station/@name/string()"); QStringList arrivalResults; if (!query.evaluateTo(&arrivalResults)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 2 Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Departure/BasicStop/Location/Station/HafasName/Text/string()"); QStringList departure2Results; if (!query.evaluateTo(&departure2Results)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 1b Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Arrival/BasicStop/Location/Station/HafasName/Text/string()"); QStringList arrival2Results; if (!query.evaluateTo(&arrival2Results)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 2b Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Departure/BasicStop/Dep/Time/string()"); QStringList depTimeResult; if (!query.evaluateTo(&depTimeResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 3 Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Departure/BasicStop/Dep/Platform/Text/string()"); QStringList depPlatResult; if (!query.evaluateTo(&depPlatResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 4 Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Arrival/BasicStop/Arr/Time/string()"); QStringList arrTimeResult; if (!query.evaluateTo(&arrTimeResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 5 Failed"; } query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection/Arrival/BasicStop/Arr/Platform/Text/string()"); QStringList arrPlatResult; if (!query.evaluateTo(&arrPlatResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 6 Failed"; } //It is possible, that the stationname is in two seperate fields if (departureResults.count() == 0 && departure2Results.count() > 0) { departureResults = departure2Results; arrivalResults = arrival2Results; } if (departureResults.count() == arrivalResults.count()) { for(int i = 0; i < departureResults.count(); i++) { JourneyDetailResultItem *item = new JourneyDetailResultItem(); /* qDebug()<<" "<<"Journey "<<i; qDebug()<<" DepartureSt:"<<departureResults[i].trimmed(); qDebug()<<" DepartureTime:"<<depTimeResult[i].trimmed(); qDebug()<<" DeparturePlatform:"<<depPlatResult[i].trimmed(); qDebug()<<" ArrivalSt:"<<arrivalResults[i].trimmed(); qDebug()<<" ArrivalTime:"<<arrTimeResult[i].trimmed(); qDebug()<<" ArrivalPlatform:"<<arrPlatResult[i].trimmed(); */ item->setDepartureDateTime(cleanHafasDateTime(depTimeResult[i].trimmed(), journeyDetailRequestData.date)); item->setArrivalDateTime(cleanHafasDateTime(arrTimeResult[i].trimmed(), journeyDetailRequestData.date)); item->setDepartureStation(departureResults[i].trimmed()); item->setArrivalStation(arrivalResults[i].trimmed()); if (depPlatResult[i].trimmed() != "") { item->setDepartureInfo(tr("Pl.") + " " + depPlatResult[i].trimmed()); } if (arrPlatResult[i].trimmed() != "") { item->setArrivalInfo(tr("Pl.") + " " + arrPlatResult[i].trimmed()); } //Check for train or if walking query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection[" + QString::number(i + 1) + "]/Journey/JourneyAttributeList/JourneyAttribute/Attribute[@type='NAME']/AttributeVariant/Text/string()"); QStringList trainResult; if (!query.evaluateTo(&trainResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 7 Failed"; } if (trainResult.count() > 0) { //qDebug()<<" Train:"<<trainResult.join("").trimmed(); item->setTrain(trainResult.join("").trimmed()); } else { query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection[" + QString::number(i + 1) + "]/Walk/Duration/Time/string()"); QStringList walkResult; if (!query.evaluateTo(&walkResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 8 Failed"; } //Maybe its a transfer? QStringList transferResult; if (walkResult.count() == 0) { query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection[" + QString::number(i + 1) + "]/Transfer/Duration/Time/string()"); if (!query.evaluateTo(&transferResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 8b Failed"; } } //Maybe its gisroute? if (walkResult.count() == 0 && transferResult.count() == 0) { query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection[" + QString::number(i + 1) + "]/GisRoute/Duration/Time/string()"); QStringList gisrouteResult; if (!query.evaluateTo(&gisrouteResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 9 Failed"; } //Ok its a gisroute if (gisrouteResult.count() > 0) { query.setQuery("doc($path)/ResC/ConRes//Connection[@id='" + journeyDetailRequestData.id + "']/ConSectionList/ConSection[" + QString::number(i + 1) + "]/GisRoute/@type/string()"); QStringList gisroutetypeResult; if (!query.evaluateTo(&gisroutetypeResult)) { qDebug() << "parserHafasXml::parseJourneyDataDetails - Query 10 Failed"; } QString gisrouteType = gisroutetypeResult.join("").trimmed(); int minutes = cleanHafasDate(gisrouteResult.join("").trimmed()).toInt(); if (gisrouteType == "FOOT") { item->setInfo(tr("Walk for %n min", "", minutes)); } else if (gisrouteType == "BIKE") { item->setInfo(tr("Use a Bike for %n min", "", minutes)); } else if (gisrouteType == "CAR") { item->setInfo(tr("Use a car for %n min", "", minutes)); } else if (gisrouteType == "TAXI") { item->setInfo(tr("Take a taxi for %n min", "", minutes)); } } } else { if (transferResult.count() > 0) { item->setInfo(tr("Transfer for %n min", "", cleanHafasDate(transferResult.join("").trimmed()).toInt())); } if (walkResult.count() > 0) { item->setInfo(tr("Walk for %n min", "", cleanHafasDate(walkResult.join("").trimmed()).toInt())); } } } results->appendItem(item); } if (results->itemcount() > 0) { results->setDepartureStation(results->getItem(0)->departureStation()); results->setArrivalStation(results->getItem(results->itemcount() - 1)->arrivalStation()); for (int i=0; i < results->itemcount(); i++) { if (!results->getItem(i)->departureDateTime().isNull()) { results->setDepartureDateTime(results->getItem(i)->departureDateTime()); break; } } for (int i=results->itemcount() -1; i >= 0; i--) { if (!results->getItem(i)->arrivalDateTime().isNull()) { results->setArrivalDateTime(results->getItem(i)->arrivalDateTime()); break; } } results->setDuration(journeyDetailRequestData.duration); results->setId(journeyDetailRequestData.id); } return results; } emit errorOccured(tr("Internal error occured, Error parsing details data")); return results; }