From 55644fae34ab49834dd52c834c211e765d41f8ab Mon Sep 17 00:00:00 2001
From: Raphael Geissert <atomo64@gmail.com>
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<QString, IonInterface::ConditionIcons> 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<QString, IonInterface::ConditionIcons> 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;
- // "<p><a id="result_40" href ="/weather/forecast/4160?count=200">Vitoria, Brazil</a></p>"
- 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("<p class=\"response\">") > 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("<div class=\"line\">") > 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