From 55644fae34ab49834dd52c834c211e765d41f8ab Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Sat, 15 Feb 2014 15:20:26 +0100 Subject: [PATCH 1/3] Update to BBC's new json-based search and modified xml BUG:330773 --- .../weather/ions/bbcukmet/ion_bbcukmet.cpp | 93 ++++++++++++-------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp index 746a734..c656e40 100644 --- a/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp +++ b/plasma/generic/dataengines/weather/ions/bbcukmet/ion_bbcukmet.cpp @@ -80,6 +80,7 @@ QMap UKMETIon::setupDayIconMappings(void) //dayList["sunny intervals night"] = ClearNight; dayList["partly cloudy"] = PartlyCloudyDay; dayList["cloudy"] = Overcast; + dayList["light cloud"] = Overcast; dayList["white cloud"] = Overcast; dayList["grey cloud"] = Overcast; //dayList["low level cloud"] = NotAvailable; @@ -131,6 +132,7 @@ QMap UKMETIon::setupNightIconMappings(voi nightList["sunny intervals"] = PartlyCloudyDay; // it's not really sunny nightList["sunny"] = ClearDay; nightList["cloudy"] = Overcast; + nightList["light cloud"] = Overcast; nightList["white cloud"] = Overcast; nightList["grey cloud"] = Overcast; nightList["partly cloudy"] = PartlyCloudyNight; @@ -252,7 +254,8 @@ void UKMETIon::getXMLData(const QString& source) void UKMETIon::findPlace(const QString& place, const QString& source) { KUrl url; - url = "http://news.bbc.co.uk/weather/util/search/SearchResultsNode.xhtml?&search=" + place + "®ion=world&startIndex=0&count=500"; + /* There's a page= parameter, results are limited to 10 by page */ + url = "http://www.bbc.com/locator/default/en-GB/search.json?search="+place+"&filter=international&postcode_unit=false&postcode_district=true"; m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); m_job->addMetaData("cookies", "none"); // Disable displaying cookies @@ -281,7 +284,7 @@ void UKMETIon::getFiveDayForecast(const QString& source) int splitIDPos = xmlPath.lastIndexOf('/'); QString stationID = xmlPath.midRef(splitIDPos + 1).toString(); - m_place[source].XMLforecastURL = "http://newsrss.bbc.co.uk/weather/forecast/" + stationID + "/Next3DaysRSS.xml" + xmlMap.query(); + m_place[source].XMLforecastURL = "http://open.live.bbc.co.uk/weather/feeds/en/" + stationID + "/3dayforecast.rss" + xmlMap.query(); KUrl url(m_place[source].XMLforecastURL); m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo); @@ -303,47 +306,43 @@ void UKMETIon::readSearchHTMLData(const QString& source, const QByteArray& html) QStringList tokens; QString url; QString tmp; - int flag = 0; int counter = 2; - // "

Vitoria, Brazil

" - QRegExp grabURL("/[a-z]+/[a-z]+/([0-9]+)(\\?[^\"]+)?"); - QRegExp grabPlace(">([^<]*[a-z()])"); // FIXME: It would be better to strip away the extra '>' +#ifdef __GNUC__ +#warning FIXME: use a json parser instead of regexes +#endif + + QRegExp grabURL("\"id\":\\s*\"([0-9]+)\""); + QRegExp grabPlace("\"fullName\":\\s*\"([^\"]+)\""); while (!stream.atEnd()) { line = stream.readLine(); - if (line.contains("

") > 0) { - flag = 1; - } - if (line.contains("There are no forecasts matching") > 0) { + if (line.contains("Sorry, no results found for") > 0) { break; } - if (flag) { + if (line.contains("\"results\"") > 0) { if (grabURL.indexIn(line.trimmed()) > 0) { - url = "http://newsrss.bbc.co.uk/weather/forecast/" + grabURL.cap(1) + "/ObservationsRSS.xml"; - if (grabURL.captureCount() > 1) { - url += grabURL.cap(2); - } - grabPlace.indexIn(line.trimmed()); - tmp = QString("bbcukmet|").append(grabPlace.cap(1)); - // Duplicate places can exist - if (m_locations.contains(tmp)) { - tmp = QString("bbcukmet|").append(QString("%1 (#%2)").arg(grabPlace.cap(1)).arg(counter)); - counter++; - } + for (int captureIndex = 1; captureIndex <= grabURL.captureCount(); captureIndex++) { - m_place[tmp].XMLurl = url; - m_place[tmp].place = grabPlace.cap(1); - m_locations.append(tmp); - } - } + url = "http://open.live.bbc.co.uk/weather/feeds/en/" + grabURL.cap(captureIndex) + "/observations.rss"; + grabPlace.indexIn(line.trimmed()); + tmp = QString("bbcukmet|").append(grabPlace.cap(captureIndex)); + + // Duplicate places can exist + if (m_locations.contains(tmp)) { + tmp = QString("bbcukmet|").append(QString("%1 (#%2)").arg(grabPlace.cap(captureIndex)).arg(counter)); + counter++; + } - if (line.contains("

") > 0) { - flag = 0; + m_place[tmp].XMLurl = url; + m_place[tmp].place = grabPlace.cap(captureIndex); + m_locations.append(tmp); + } + } } } @@ -557,12 +556,13 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, QStringRef conditionData = conditionString.midRef(splitIndex + 1); // Include ':' data.obsTime = conditionString.midRef(0, splitIndex).toString(); - // Friday at 0200 GMT - m_dateFormat = QDateTime::fromString(data.obsTime.split("at")[1].trimmed(), "hhmm 'GMT'"); + // Saturday - 13:00 CET + // Saturday - 12:00 GMT + m_dateFormat = QDateTime::fromString(data.obsTime.split("-")[1].trimmed(), "hh:mm 'GMT'"); data.iconPeriodHour = m_dateFormat.toString("hh").toInt(); data.iconPeriodMinute = m_dateFormat.toString("mm").toInt(); - data.condition = conditionData.toString().split('.')[0].trimmed(); + data.condition = conditionData.toString().split(',')[0].trimmed(); } else if (xml.name() == "link") { m_place[source].forecastHTMLUrl = xml.readElementText(); @@ -575,21 +575,32 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, #endif data.temperature_C = observeData[1].split(QChar(176))[0].trimmed(); - - // Temperature might be not available - if (data.temperature_C.contains("N/A")) { + if (data.temperature_C.contains("N/A") || data.temperature_C.contains("null")) { data.temperature_C = i18n("N/A"); } data.windDirection = observeData[2].split(',')[0].trimmed(); + if (data.windDirection.contains("null")) { + data.windDirection = ""; + } + data.windSpeed_miles = observeData[3].split(',')[0].split(' ')[1].remove("mph"); + if (data.windSpeed_miles.contains("null")) { + data.windSpeed_miles = "N/A"; + } data.humidity = observeData[4].split(',')[0].split(' ')[1]; if (data.humidity.endsWith('%')) { data.humidity.chop(1); } + if (data.humidity.contains("null")) { + data.humidity = "N/A"; + } data.pressure = observeData[5].split(',')[0].split(' ')[1].split("mb")[0]; + if (data.pressure.contains("null")) { + data.pressure = "N/A"; + } data.pressureTendency = observeData[5].split(',')[1].trimmed(); data.visibilityStr = observeData[6].trimmed(); @@ -600,6 +611,10 @@ void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, } else if (xml.name() == "long") { const QString ordinate = xml.readElementText(); data.longitude = ordinate.toDouble(); + } else if (xml.name() == "georss:point") { + const QString ordinates = xml.readElementText(); + data.latitude = ordinates.split(' ')[0].toDouble(); + data.longitude = ordinates.split(' ')[1].toDouble(); } else { parseUnknownElement(xml); } @@ -675,8 +690,8 @@ void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml QString line; QString period; QString summary; - QRegExp high("-?\\d+"); - QRegExp low("-?\\d+"); + QRegExp high("-?\\d+.C"); + QRegExp low("-?\\d+.C"); while (!xml.atEnd()) { xml.readNext(); if (xml.name() == "title") { @@ -687,8 +702,8 @@ void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml period = line.split(',')[0].split(':')[0]; summary = line.split(',')[0].split(':')[1].trimmed(); - high.indexIn(line.split(',')[1]); - low.indexIn(line.split(',')[2]); + high.indexIn(line.split(',')[1].split(':')[1]); + low.indexIn(line.split(',')[1].split(':')[2]); forecast->period = period; forecast->iconName = getWeatherIcon(dayIcons(), summary.toLower()); -- 1.7.10