Ticket #8356: new-grabber-if.patch
File new-grabber-if.patch, 11.1 KB (added by , 14 years ago) |
---|
-
mythweather/weatherScreen.cpp
Simplify the interface between the grabber and the plugin. From: Alec Leamas <leamas.alec%AT%gmail.com> This patch maks the -u <ENG|SI> parameter obsolete. The basic approach is that the grabber provides the values it actually gets from the data source without making any conversions. If need be, these are done by the plugin. The purpose is to make a clean division between the grabber which provides the data and the plugin which handles the presentation. Eventually, all conversions SI<-> ENG now being done in the grabbers can be removed together with the handling of the -u parameter. Furhermore. it creates a simpler base e. g., when presenting wind speed in either knots, m/s, km/h or mph. Since the data is parsed, all formatting is now done by the plugin which should make theming and translations easier and more consistent. Patch is compatible with current grabber interface. It always gives the '-u SI' option to the grabber. A possible downside is loss of precision in some conversions . Worst case is temperatures, where rounding errors possibly gives values 1 degree off. This is, BTW, an error present in current grabber code. To handle this for those grabbers which can get a correct ENG or SI value, the patch decodes both values in grabber output: high-0: 12; 35 should be read as 12 degrees Celsius / 35 degrees Fahrenheit. Any part can be omitted: high-0: ;35 high-0: 12; in which case plugin makes conversions as necessary. The current 'high-0: 12' is handled as today. With proper changes in the grabbers, the patch removes multiple rounding errors in current code and overall reduces the complexity of the interface and the grabber. --- mythweather/weatherScreen.cpp | 261 ++++++++++++++++++++++++++++++++++++++--- mythweather/weatherScreen.h | 1 mythweather/weatherSource.cpp | 2 3 files changed, 244 insertions(+), 20 deletions(-) diff --git a/mythweather/weatherScreen.cpp b/mythweather/weatherScreen.cpp index a4e7e42..9080e8c 100644
a b using namespace std; 9 9 #include "weather.h" 10 10 #include "weatherScreen.h" 11 11 12 static const QString kDegrees = QString::fromUtf8("°"); 13 static const float MILES_PER_KM = 0.62137; 14 static const float IN_HG_PER_MBAR = 0.02953; 15 12 16 /** Parse and format time according to current locale. */ 13 17 static QString formatTime(const QString& value) 14 18 { … … static QString formatTime(const QString& value) 42 46 return QString(buff); 43 47 } 44 48 49 50 /** Private class converting grabber values to UI format. */ 51 class Converter 52 { 53 public: 54 Converter(float factor, 55 const QString& metricUnit, 56 const QString& engUnit); 57 virtual QString convert(const QString& value, units_t units); 58 59 protected: 60 virtual float engValue(float value) 61 { return m_factor * value; }; 62 virtual float siValue(float value) 63 { return value / m_factor; }; 64 virtual QString format(float f) 65 { return QString().setNum(f, 'f', 1); }; 66 int round(float f) 67 { return static_cast<int>(f + (f > 0.0 ? +0.5 : -0.5)); }; 68 virtual QString parseValues( const QString& input, units_t unit); 69 QString m_metricUnit; 70 QString m_engUnit; 71 float m_factor; 72 QString m_value; 73 QString m_otherValue; 74 75 }; 76 77 78 Converter::Converter(float factor, 79 const QString& metricUnit, 80 const QString& engUnit) 81 { 82 m_metricUnit = metricUnit; 83 m_factor = factor; 84 m_engUnit = engUnit; 85 } 86 87 88 class DistanceConverter: public Converter 89 { 90 public: 91 DistanceConverter(): Converter( MILES_PER_KM, " km", " mi") {}; 92 }; 93 94 95 class PressureConverter: public Converter 96 { 97 public: 98 PressureConverter(): Converter( IN_HG_PER_MBAR, " mb", " in") {}; 99 }; 100 101 102 class VisibilityConverter: public Converter 103 { 104 public: 105 VisibilityConverter():Converter( MILES_PER_KM, " km", " mi") {}; 106 QString convert(const QString& value, units_t units); 107 }; 108 109 110 class TempConverter: public Converter 111 { 112 public: 113 TempConverter(): 114 Converter( 0, kDegrees + "C" , kDegrees + "F") {}; 115 float engValue(float f) { return f * 9.0/5.0 + 32; }; 116 float siValue(float f) { return (f - 32) * 5.0/9.0; }; 117 QString format(float f) {return QString().setNum(f, 'f', 0); }; 118 }; 119 120 121 class PrecipConverter: public Converter 122 { 123 public: 124 PrecipConverter(): Converter( 1, " mm" , " mm") {}; 125 QString format( float f) {return QString().setNum(f, 'f', 0); }; 126 }; 127 128 129 class WindConverter: public Converter 130 { 131 public: 132 WindConverter(): Converter( MILES_PER_KM, " km/h", " mph") {}; 133 }; 134 135 QString Converter::parseValues( const QString& input, units_t units) 136 { 137 QString siValue = ""; 138 QString engValue = ""; 139 140 QStringList parts = input.split(";"); 141 if (parts.size() > 2) 142 { 143 return QString("NA ( ") + input + ")"; 144 } 145 else if (parts.size() == 2) 146 { 147 siValue = parts[0]; 148 engValue = parts[1]; 149 } 150 else if (input.startsWith(";")) 151 { 152 engValue = input; 153 engValue.replace(";", ""); 154 } 155 else 156 { 157 // Trailing ';' or old style without ';' 158 siValue = input; 159 siValue.replace(";", ""); 160 } 161 m_value = (units == ENG_UNITS ? engValue : siValue); 162 m_otherValue = (units == ENG_UNITS ? siValue : engValue); 163 164 if (m_value == "NA" || m_value == "N/A") 165 { 166 return "NA"; 167 } 168 if( m_value == "" && (m_otherValue == "NA" || m_otherValue == "N/A")) 169 { 170 return "NA"; 171 } 172 173 return 0; 174 } 175 176 177 QString Converter::convert(const QString& input, units_t units) 178 { 179 180 VERBOSE(VB_MOST, QString( "Converting: ") + input); 181 QString na = parseValues( input, units); 182 if ( na != 0) 183 { 184 return( na ); 185 } 186 187 bool otherHasNumber; 188 QRegExp number("([-+]?[0-9][0-9.]*)"); 189 190 if (m_value.contains( number)) 191 { 192 otherHasNumber = false; 193 } 194 else if (m_otherValue.contains( number)) 195 { 196 otherHasNumber = true; 197 } 198 else 199 { 200 return QString("NA (") + input + ")"; 201 } 202 203 bool ok; 204 float f = number.cap().toFloat(&ok); 205 if (!ok) 206 { 207 return QString("NA (") + input + ")"; 208 } 209 210 if (units == ENG_UNITS && otherHasNumber) 211 { 212 f = engValue(f); 213 } 214 else if ( units == SI_UNITS && otherHasNumber) 215 { 216 f = siValue(f); 217 } 218 219 QString unit = (units == ENG_UNITS ? m_engUnit: m_metricUnit); 220 VERBOSE(VB_MOST, QString( "Returning: ") + format(round(f)) + unit); 221 return format( round(f)) + unit; 222 }; 223 224 225 QString 226 VisibilityConverter::convert(const QString& input, units_t units) 227 { 228 229 QString na = parseValues( input, units); 230 if (na != 0) 231 { 232 return( na); 233 } 234 235 QRegExp range = QRegExp( "([0-9]+)[ -]+([0-9]+)"); 236 bool otherHasRange; 237 if (m_value.contains(range)) 238 { 239 otherHasRange = false; 240 } 241 else if (m_otherValue.contains(range)) 242 { 243 otherHasRange = true; 244 } 245 else 246 { 247 return DistanceConverter().convert( input, units); 248 } 249 250 bool ok; 251 int from, to; 252 from = range.cap(1).toInt( &ok); 253 if (ok) 254 { 255 to = range.cap(2).toInt( &ok); 256 } 257 if (!ok) 258 { 259 return QString("NA (") + m_value + ")"; 260 } 261 262 if (units == ENG_UNITS && otherHasRange) 263 { 264 from *= m_factor; 265 to *= m_factor; 266 } 267 else if (units == SI_UNITS && otherHasRange) 268 { 269 from /= m_factor; 270 to /= m_factor; 271 } 272 273 QString unit = (units == ENG_UNITS ? m_engUnit: m_metricUnit); 274 return QString( "%1 - %2 %3").arg( from).arg( to).arg( unit); 275 }; 276 277 45 278 WeatherScreen *WeatherScreen::loadScreen(MythScreenStack *parent, 46 279 ScreenListInfo *screenDefn, int id) 47 280 { … … void WeatherScreen::newData(QString loc, units_t units, DataMap data) 139 372 emit screenReady(this); 140 373 } 141 374 142 QString WeatherScreen::getTemperatureUnit()143 {144 if (m_units == ENG_UNITS)145 return QString::fromUtf8("°") + "F";146 else147 return QString::fromUtf8("°") + "C";148 }149 150 375 void WeatherScreen::prepareScreen() 151 376 { 152 377 QMap<QString, QString>::iterator itr = m_dataValueMap.begin(); … … QString WeatherScreen::formatDataItem(const QString &key, 202 427 return value + " %"; 203 428 204 429 if (key == "pressure") 205 return value + (m_units == ENG_UNITS ? " in" : " mb");430 return PressureConverter().convert( value, m_units); 206 431 207 432 if (key == "visibility") 208 return value + (m_units == ENG_UNITS ? " mi" : " km");433 return VisibilityConverter().convert( value, m_units); 209 434 210 if (key == "temp" || key == "appt" || key.contains("low",Qt::CaseInsensitive) || 211 key.contains("high",Qt::CaseInsensitive)) 435 if (key.contains("temp",Qt::CaseInsensitive) || 436 key.contains("low",Qt::CaseInsensitive) || 437 key.contains("high",Qt::CaseInsensitive) || 438 key == "appt") 212 439 { 213 if ( (value == "NA") || (value == "N/A") ) 214 return value; 215 else 216 return value + getTemperatureUnit(); 440 return TempConverter().convert( value, m_units); 217 441 } 218 442 219 443 if (key == "wind_gust" || key == "wind_spdgst" || key == "wind_speed") 220 return value + (m_units == ENG_UNITS ? " mph" : " kph");444 return WindConverter().convert( value, m_units); 221 445 222 446 /*The days of the week will be translated if the script sends elements from 223 447 the enum DaysOfWeek.*/ … … QString WeatherScreen::formatDataItem(const QString &key, 260 484 if (key.startsWith("pop-")) 261 485 { 262 486 if (formatHint == "precipitation") 263 return value + " mm";487 return PrecipConverter().convert( value, m_units); 264 488 else 265 489 return value + " %"; 266 490 } … … void AnimatedImageScreen::prepareWidget(MythUIType *widget) 383 607 } 384 608 return; 385 609 } 610 -
mythweather/weatherScreen.h
diff --git a/mythweather/weatherScreen.h b/mythweather/weatherScreen.h index 4aeb2a1..17d42f0 100644
a b class WeatherScreen : public MythScreenType 67 67 const QString &formatHint = 0); 68 68 virtual void prepareWidget(MythUIType *widget); 69 69 virtual void prepareScreen(); 70 virtual QString getTemperatureUnit();71 70 QString formatDataItem(const QString &key, 72 71 const QString &value, 73 72 const QString &formatHint = 0); -
mythweather/weatherSource.cpp
diff --git a/mythweather/weatherSource.cpp b/mythweather/weatherSource.cpp index 57376d4..c0e7f9a 100644
a b void WeatherSource::startUpdate(bool forceUpdate) 535 535 QStringList args; 536 536 args.push_back(m_info->fileInfo.absoluteFilePath()); 537 537 args.push_back("-u"); 538 args.push_back( m_units == SI_UNITS ? "SI" : "ENG");538 args.push_back("SI"); 539 539 540 540 if (!m_dir.isEmpty()) 541 541 {