diff options
23 files changed, 805 insertions, 41 deletions
@@ -4,6 +4,7 @@ VDR Plugin 'skinflatplus' Revision History 2014-MM-DD: Version 0.5.0 - [add] main menu widgets - there are several widgets that can be displayed in the main menu + - Widget weather - Widget dvb devices - Widget active timer - Widget timer conflicts @@ -20,6 +21,8 @@ VDR Plugin 'skinflatplus' Revision History - add more default themes: DeepOrange, DeepPurple, Indigo, Red, Teal - [update] icons - update many icons with android material design icons +- [update] MV-Themes + - see MV_Themes.HISTORY 2014-10-29: Version 0.4.3 - [add] option to draw the menu background over the entire height @@ -79,33 +79,38 @@ cFlatConfig::cFlatConfig(void) { MainMenuItemScale = 0.5; MainMenuWidgetDVBDevicesShow = true; - MainMenuWidgetDVBDevicesPosition = 1; + MainMenuWidgetDVBDevicesPosition = 2; MainMenuWidgetActiveTimerShow = true; - MainMenuWidgetActiveTimerPosition = 2; + MainMenuWidgetActiveTimerPosition = 3; MainMenuWidgetActiveTimerMaxCount = 2; MainMenuWidgetActiveTimerHideEmpty = false; MainMenuWidgetLastRecShow = false; - MainMenuWidgetLastRecPosition = 3; + MainMenuWidgetLastRecPosition = 4; MainMenuWidgetLastRecMaxCount = 3; MainMenuWidgetTimerConflictsShow = false; - MainMenuWidgetTimerConflictsPosition = 4; + MainMenuWidgetTimerConflictsPosition = 5; MainMenuWidgetTimerConflictsHideEmpty = false; MainMenuWidgetSystemInfoShow = true; - MainMenuWidgetSystemInfoPosition = 5; + MainMenuWidgetSystemInfoPosition = 6; MainMenuWidgetSystemUpdatesShow = true; - MainMenuWidgetSystemUpdatesPosition = 6; + MainMenuWidgetSystemUpdatesPosition = 7; MainMenuWidgetSystemUpdatesHideIfZero = 0; MainMenuWidgetTemperaturesShow = true; - MainMenuWidgetTemperaturesPosition = 7; + MainMenuWidgetTemperaturesPosition = 8; MainMenuWidgetCommandShow = true; - MainMenuWidgetCommandPosition = 8; + MainMenuWidgetCommandPosition = 9; + + MainMenuWidgetWeatherShow = true; + MainMenuWidgetWeatherPosition = 1; + MainMenuWidgetWeatherDays = 5; + MainMenuWidgetWeatherType = 0; TopBarFontClockScale = 0.01; TopBarHideClockText = 0; @@ -327,6 +332,10 @@ bool cFlatConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "MainMenuWidgetTemperaturesPosition") == 0) MainMenuWidgetTemperaturesPosition = atoi(Value); else if (strcmp(Name, "MainMenuWidgetCommandShow") == 0) MainMenuWidgetCommandShow = atoi(Value); else if (strcmp(Name, "MainMenuWidgetCommandPosition") == 0) MainMenuWidgetCommandPosition = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherShow") == 0) MainMenuWidgetWeatherShow = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherPosition") == 0) MainMenuWidgetWeatherPosition = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherDays") == 0) MainMenuWidgetWeatherDays = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherType") == 0) MainMenuWidgetWeatherType = atoi(Value); else return false; @@ -607,6 +616,16 @@ bool pairCompareIntString(const std::pair<int, std::string>&i, const std::pair<i return i.first > j.first; } +int roundUp(int numToRound, int multiple) +{ + if(multiple == 0) + return numToRound; + int remainder = numToRound % multiple; + if (remainder == 0) + return numToRound; + return numToRound + multiple - remainder; +} + void cFlatConfig::DecorDescriptions(cStringList &Decors) { cString decorPath = cString::sprintf("%s/decors", PLUGINRESOURCEPATH); std::vector<std::string> files; @@ -12,6 +12,7 @@ bool stringCompare( const std::string &left, const std::string &right ); bool pairCompareTimeStringDesc(const std::pair<time_t, std::string>&i, const std::pair<time_t, std::string>&j); bool pairCompareIntString(const std::pair<int, std::string>&i, const std::pair<int, std::string>&j); +int roundUp(int numToRound, int multiple); class cFlatConfig { @@ -279,6 +280,11 @@ class cFlatConfig int MainMenuWidgetCommandShow; int MainMenuWidgetCommandPosition; + int MainMenuWidgetWeatherShow; + int MainMenuWidgetWeatherPosition; + int MainMenuWidgetWeatherType; + int MainMenuWidgetWeatherDays; + // TVScraper int TVScraperChanInfoShowPoster; double TVScraperChanInfoPosterSize; diff --git a/displaymenu.c b/displaymenu.c index 83b7174a..a0cdb4b6 100644 --- a/displaymenu.c +++ b/displaymenu.c @@ -3907,6 +3907,8 @@ void cFlatDisplayMenu::DrawMainMenuWidgets(void) { widgets.push_back(std::make_pair(Config.MainMenuWidgetTimerConflictsPosition, "timer_conflicts")); if( Config.MainMenuWidgetCommandShow ) widgets.push_back(std::make_pair(Config.MainMenuWidgetCommandPosition, "custom_command")); + if( Config.MainMenuWidgetWeatherShow ) + widgets.push_back(std::make_pair(Config.MainMenuWidgetWeatherPosition, "weather")); std::sort(widgets.begin(), widgets.end(), pairCompareIntString); @@ -3947,6 +3949,10 @@ void cFlatDisplayMenu::DrawMainMenuWidgets(void) { int addHeight = DrawMainMenuWidgetCommand(wLeft, wWidth, ContentTop); if( addHeight > 0 ) ContentTop = addHeight + marginItem; + } else if( widget.compare("weather") == 0 ) { + int addHeight = DrawMainMenuWidgetWeather(wLeft, wWidth, ContentTop); + if( addHeight > 0 ) + ContentTop = addHeight + marginItem; } } @@ -4610,6 +4616,165 @@ int cFlatDisplayMenu::DrawMainMenuWidgetCommand(int wLeft, int wWidth, int Conte return contentWidget.ContentHeight(false); } +int cFlatDisplayMenu::DrawMainMenuWidgetWeather(int wLeft, int wWidth, int ContentTop) { + if( ContentTop + fontHeight + 6 + fontSmlHeight > menuPixmap->ViewPort().Height() ) + return -1; + + cFont *fontTempSml = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize/2.0 ); + + std::string Location; + cString locationFilename = cString::sprintf("%s/widgets/weather/weather.location", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N) ); + std::ifstream file(*locationFilename, std::ifstream::in); + if( file.is_open() ) { + std::getline(file, Location); + file.close(); + } else { + Location = tr("Unknown"); + } + cString Title = cString::sprintf("%s - %s", tr("Weather"), Location.c_str()); + + cImage *img = imgLoader.LoadIcon("widgets/weather", fontHeight, fontHeight - marginItem*2); + if( img ) { + contentWidget.AddImage(img, cRect(marginItem, ContentTop + marginItem, fontHeight, fontHeight)); + } + contentWidget.AddText(*Title, false, cRect(marginItem*2 + fontHeight, ContentTop, 0, 0), Theme.Color(clrMenuEventFontTitle), Theme.Color(clrMenuEventBg), font); + ContentTop += fontHeight; + contentWidget.AddRect(cRect(0, ContentTop, wWidth, 3), Theme.Color(clrMenuEventTitleLine)); + ContentTop += 6; + + int left = marginItem; + for( int index = 0; index < Config.MainMenuWidgetWeatherDays; index++ ) { + std::string icon; + cString iconFilename = cString::sprintf("%s/widgets/weather/weather.%d.icon", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file(*iconFilename, std::ifstream::in); + if( file.is_open() ) { + std::getline(file, icon); + file.close(); + } else + continue; + + std::string summary; + cString summaryFilename = cString::sprintf("%s/widgets/weather/weather.%d.summary", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file2(*summaryFilename, std::ifstream::in); + if( file2.is_open() ) { + std::getline(file2, summary); + file2.close(); + } else + continue; + + std::string tempMax; + cString tempMaxFilename = cString::sprintf("%s/widgets/weather/weather.%d.tempMax", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file3(*tempMaxFilename, std::ifstream::in); + if( file3.is_open() ) { + std::getline(file3, tempMax); + file3.close(); + } else + continue; + + std::string tempMin; + cString tempMinFilename = cString::sprintf("%s/widgets/weather/weather.%d.tempMin", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file4(*tempMinFilename, std::ifstream::in); + if( file4.is_open() ) { + std::getline(file4, tempMin); + file4.close(); + } else + continue; + + std::string prec; + double p = 0.0; + cString precString = "0%"; + cString precFilename = cString::sprintf("%s/widgets/weather/weather.%d.precipitation", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file5(*precFilename, std::ifstream::in); + if( file5.is_open() ) { + std::getline(file5, prec); + std::replace( prec.begin(), prec.end(), '.', ','); + file5.close(); + p = atof(prec.c_str()) * 100.0; + p = roundUp(p, 10); + precString = cString::sprintf("%.0f%%", p); + dsyslog("WEATHER: %s %f %s", prec.c_str(), p, *precString); + } else + continue; + + std::string precType; + cString precTypeFilename = cString::sprintf("%s/widgets/weather/weather.%d.precipitationType", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), index ); + std::ifstream file6(*precTypeFilename, std::ifstream::in); + if( file6.is_open() ) { + std::getline(file6, precType); + file6.close(); + } else + continue; + + cString weekDayName = ""; + time_t t; + time(&t); + struct tm* tm = localtime(&t); + tm->tm_mday += index; + time_t t2 = mktime(tm); + weekDayName = WeekDayName(t2); + + if( Config.MainMenuWidgetWeatherType == 0 ) { // short + if( left + fontHeight*2 + font->Width("XXX") + font->Width("XXXX") + marginItem*6 > wWidth ) + break; + if( index > 0 ) { + contentWidget.AddText("|", false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font); + left += font->Width("|") + marginItem*2; + } + + cString weatherIcon = cString::sprintf("widgets/%s", icon.c_str()); + cImage *img = imgLoader.LoadIcon(*weatherIcon, fontHeight, fontHeight - marginItem*2); + if( img ) { + contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight)); + left += fontHeight + marginItem; + } + contentWidget.AddText(tempMax.c_str(), false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml); + contentWidget.AddText(tempMin.c_str(), false, cRect(left, ContentTop + fontTempSml->Height(), 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml); + left += font->Width("XXX") + marginItem; + + img = imgLoader.LoadIcon("widgets/umbrella", fontHeight, fontHeight - marginItem*2); + if( img ) { + contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight)); + left += fontHeight - marginItem; + } + contentWidget.AddText(*precString, false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font); + left += font->Width(*precString) + marginItem*2; + } else { // long + if( ContentTop + marginItem > menuPixmap->ViewPort().Height() ) + break; + + left = marginItem; + + cString dayname = cString::sprintf("%s ", *weekDayName); + contentWidget.AddText(*dayname, false, cRect(left, ContentTop, wWidth - marginItem*2, fontHeight), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font, wWidth - marginItem*2); + left += font->Width("XXXX") + marginItem; + + cString weatherIcon = cString::sprintf("widgets/%s", icon.c_str()); + cImage *img = imgLoader.LoadIcon(*weatherIcon, fontHeight, fontHeight - marginItem*2); + if( img ) { + contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight)); + left += fontHeight + marginItem; + } + contentWidget.AddText(tempMax.c_str(), false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml); + contentWidget.AddText(tempMin.c_str(), false, cRect(left, ContentTop + fontTempSml->Height(), 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml); + left += font->Width("XXX") + marginItem; + + img = imgLoader.LoadIcon("widgets/umbrella", fontHeight, fontHeight - marginItem*2); + if( img ) { + contentWidget.AddImage(img, cRect(left, ContentTop + marginItem, fontHeight, fontHeight)); + left += fontHeight - marginItem; + } + contentWidget.AddText(*precString, false, cRect(left, ContentTop, 0, 0), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), font); + left += font->Width("XXXX") + marginItem; + + contentWidget.AddText(summary.c_str(), true, cRect(left, ContentTop, wWidth - left, fontHeight), Theme.Color(clrMenuEventFontInfo), Theme.Color(clrMenuEventBg), fontTempSml, wWidth - left, fontHeight); + + ContentTop += fontHeight; + } + + } + return contentWidget.ContentHeight(false); +} + /* int cFlatDisplayMenu::DrawMainMenuWidgetTimerConflicts(int wLeft, int wTop, int wWidth) { int wHeight = fontHeight + 6 + (Config.MainMenuWidgetLastRecMaxCount * fontSmlHeight) + Config.decorBorderMenuContentSize*2; diff --git a/displaymenu.h b/displaymenu.h index 3d803820..adca16c6 100644 --- a/displaymenu.h +++ b/displaymenu.h @@ -99,6 +99,7 @@ class cFlatDisplayMenu : public cFlatBaseRender, public cSkinDisplayMenu { int DrawMainMenuWidgetSystemUpdates(int wLeft, int wWidth, int ContentTop); int DrawMainMenuWidgetTemperaturs(int wLeft, int wWidth, int ContentTop); int DrawMainMenuWidgetCommand(int wLeft, int wWidth, int ContentTop); + int DrawMainMenuWidgetWeather(int wLeft, int wWidth, int ContentTop); public: cFlatDisplayMenu(void); diff --git a/icons/default/widgets/clear-day.png b/icons/default/widgets/clear-day.png Binary files differnew file mode 100644 index 00000000..2b06a14e --- /dev/null +++ b/icons/default/widgets/clear-day.png diff --git a/icons/default/widgets/clear-night.png b/icons/default/widgets/clear-night.png Binary files differnew file mode 100644 index 00000000..9bbe49f6 --- /dev/null +++ b/icons/default/widgets/clear-night.png diff --git a/icons/default/widgets/cloudy.png b/icons/default/widgets/cloudy.png Binary files differnew file mode 100644 index 00000000..9870c7f4 --- /dev/null +++ b/icons/default/widgets/cloudy.png diff --git a/icons/default/widgets/fog.png b/icons/default/widgets/fog.png Binary files differnew file mode 100644 index 00000000..9bc88d2a --- /dev/null +++ b/icons/default/widgets/fog.png diff --git a/icons/default/widgets/partly-cloudy-day.png b/icons/default/widgets/partly-cloudy-day.png Binary files differnew file mode 100644 index 00000000..b6df1798 --- /dev/null +++ b/icons/default/widgets/partly-cloudy-day.png diff --git a/icons/default/widgets/partly-cloudy-night.png b/icons/default/widgets/partly-cloudy-night.png Binary files differnew file mode 100644 index 00000000..aa358fb7 --- /dev/null +++ b/icons/default/widgets/partly-cloudy-night.png diff --git a/icons/default/widgets/rain.png b/icons/default/widgets/rain.png Binary files differnew file mode 100644 index 00000000..1d99ae00 --- /dev/null +++ b/icons/default/widgets/rain.png diff --git a/icons/default/widgets/sleet.png b/icons/default/widgets/sleet.png Binary files differnew file mode 100644 index 00000000..de3761bc --- /dev/null +++ b/icons/default/widgets/sleet.png diff --git a/icons/default/widgets/snow.png b/icons/default/widgets/snow.png Binary files differnew file mode 100644 index 00000000..939e22f3 --- /dev/null +++ b/icons/default/widgets/snow.png diff --git a/icons/default/widgets/thunderstorm.png b/icons/default/widgets/thunderstorm.png Binary files differnew file mode 100644 index 00000000..4abf3717 --- /dev/null +++ b/icons/default/widgets/thunderstorm.png diff --git a/icons/default/widgets/umbrella.png b/icons/default/widgets/umbrella.png Binary files differnew file mode 100644 index 00000000..18deac14 --- /dev/null +++ b/icons/default/widgets/umbrella.png diff --git a/icons/default/widgets/weather.png b/icons/default/widgets/weather.png Binary files differnew file mode 100644 index 00000000..18deac14 --- /dev/null +++ b/icons/default/widgets/weather.png diff --git a/icons/default/widgets/wind.png b/icons/default/widgets/wind.png Binary files differnew file mode 100644 index 00000000..d92ec154 --- /dev/null +++ b/icons/default/widgets/wind.png diff --git a/po/de_DE.po b/po/de_DE.po index 2e136543..18483ec4 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-skinflat 0.4.3\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2014-11-09 14:53+0100\n" +"POT-Creation-Date: 2014-11-15 15:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -246,6 +246,9 @@ msgstr "" msgid "no output available" msgstr "" +msgid "Weather" +msgstr "" + msgid "Audio Tracks" msgstr "Audio Spuren" @@ -378,6 +381,12 @@ msgstr "vergangen" msgid "remaining" msgstr "verbleibend" +msgid "short" +msgstr "" + +msgid "long" +msgstr "" + msgid "General settings" msgstr "Allgemeine Einstellungen" @@ -738,6 +747,18 @@ msgstr "" msgid "Main menu item scale" msgstr "" +msgid "Widget DVB weather: enable" +msgstr "" + +msgid "Widget DVB weather: position" +msgstr "" + +msgid "Widget DVB weather: show days" +msgstr "" + +msgid "Widget DVB weather: type" +msgstr "" + msgid "Widget DVB devices: enable" msgstr "" @@ -800,27 +821,3 @@ msgstr "" msgid "Widget custom commands: position" msgstr "" - -msgid "Enable widget: DVB devices" -msgstr "" - -msgid "Enable widget: active timer" -msgstr "" - -msgid "Enable widget: last recordings" -msgstr "" - -msgid "Enable widget: timer conflicts" -msgstr "" - -msgid "Enable widget: system information" -msgstr "" - -msgid "Enable widget: system updates" -msgstr "" - -msgid "Enable widget: temperatures" -msgstr "" - -msgid "Enable widget: custom commands" -msgstr "" diff --git a/preview/Zitrone.png b/preview/Zitrone.png Binary files differnew file mode 100644 index 00000000..8788e59f --- /dev/null +++ b/preview/Zitrone.png @@ -14,6 +14,7 @@ cStringList ScrollerTypes; cStringList ScrollBarTypes; cStringList DiskUsageFree; cStringList ChannelTimeLefts; +cStringList WeatherTypes; int ConfigFileSelection; @@ -111,6 +112,9 @@ void cFlatSetup::Setup(void) { ChannelTimeLefts.Append( strdup( tr("past")) ); ChannelTimeLefts.Append( strdup( tr("remaining")) ); + WeatherTypes.Clear(); + WeatherTypes.Append( strdup( tr("short")) ); + WeatherTypes.Append( strdup( tr("long")) ); Add(new cOsdItem(tr("General settings"), osUnknown, true)); Add(new cOsdItem(tr("Channelinfo settings"), osUnknown, true)); @@ -300,6 +304,10 @@ void cFlatSetup::Store(void) { SetupStore("MainMenuWidgetTemperaturesPosition", Config.MainMenuWidgetTemperaturesPosition); SetupStore("MainMenuWidgetCommandShow", Config.MainMenuWidgetCommandShow); SetupStore("MainMenuWidgetCommandPosition", Config.MainMenuWidgetCommandPosition); + SetupStore("MainMenuWidgetWeatherShow", Config.MainMenuWidgetWeatherShow); + SetupStore("MainMenuWidgetWeatherPosition", Config.MainMenuWidgetWeatherPosition); + SetupStore("MainMenuWidgetWeatherDays", Config.MainMenuWidgetWeatherDays); + SetupStore("MainMenuWidgetWeatherType", Config.MainMenuWidgetWeatherType); Config.Init(); } @@ -469,6 +477,10 @@ bool cFlatSetupGeneral::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "MainMenuWidgetTemperaturesPosition") == 0) SetupConfig->MainMenuWidgetTemperaturesPosition = atoi(Value); else if (strcmp(Name, "MainMenuWidgetCommandShow") == 0) SetupConfig->MainMenuWidgetCommandShow = atoi(Value); else if (strcmp(Name, "MainMenuWidgetCommandPosition") == 0) SetupConfig->MainMenuWidgetCommandPosition = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherShow") == 0) SetupConfig->MainMenuWidgetWeatherShow = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherPosition") == 0) SetupConfig->MainMenuWidgetWeatherPosition = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherDays") == 0) SetupConfig->MainMenuWidgetWeatherDays = atoi(Value); + else if (strcmp(Name, "MainMenuWidgetWeatherType") == 0) SetupConfig->MainMenuWidgetWeatherType = atoi(Value); else return false; return true; @@ -620,6 +632,10 @@ void cFlatSetupGeneral::SaveCurrentSettings(void) { Config.Store("MainMenuWidgetTemperaturesPosition", SetupConfig->MainMenuWidgetTemperaturesPosition, *Filename); Config.Store("MainMenuWidgetCommandShow", SetupConfig->MainMenuWidgetCommandShow, *Filename); Config.Store("MainMenuWidgetCommandPosition", SetupConfig->MainMenuWidgetCommandPosition, *Filename); + Config.Store("MainMenuWidgetWeatherShow", SetupConfig->MainMenuWidgetWeatherShow, *Filename); + Config.Store("MainMenuWidgetWeatherPosition", SetupConfig->MainMenuWidgetWeatherPosition, *Filename); + Config.Store("MainMenuWidgetWeatherDays", SetupConfig->MainMenuWidgetWeatherDays, *Filename); + Config.Store("MainMenuWidgetWeatherType", SetupConfig->MainMenuWidgetWeatherType, *Filename); cString msg = cString::sprintf("%s %s", tr("saved settings in file:"), *File); Skins.Message(mtInfo, msg); @@ -1205,6 +1221,14 @@ void cFlatSetupMMWidget::Setup(void) { if( SetupConfig->MainMenuWidgetsEnable ) { Add(new cMenuEditPrcItem(tr("Main menu item scale"), &SetupConfig->MainMenuItemScale, 0.3, 0.7, 0)); + Add(new cOsdItem("Widget DVB weather", osUnknown, false)); + Add(new cMenuEditBoolItem(tr("Widget DVB weather: enable"), &SetupConfig->MainMenuWidgetWeatherShow)); + if( SetupConfig->MainMenuWidgetWeatherShow ) { + Add(new cMenuEditIntItem(tr("Widget DVB weather: position"), &SetupConfig->MainMenuWidgetWeatherPosition)); + Add(new cMenuEditIntItem(tr("Widget DVB weather: show days"), &SetupConfig->MainMenuWidgetWeatherDays)); + Add(new cMenuEditStraItem(tr("Widget DVB weather: type"), &SetupConfig->MainMenuWidgetWeatherType, WeatherTypes.Size(), &WeatherTypes[0])); + } + Add(new cOsdItem("Widget DVB devices", osUnknown, false)); Add(new cMenuEditBoolItem(tr("Widget DVB devices: enable"), &SetupConfig->MainMenuWidgetDVBDevicesShow)); if( SetupConfig->MainMenuWidgetDVBDevicesShow ) { @@ -1280,14 +1304,15 @@ eOSState cFlatSetupMMWidget::ProcessKey(eKeys Key) { if( Key == kLeft || Key == kRight ) { const char* ItemText = Get(Current())->Text(); if( strstr(ItemText, tr("Enable main menu widgets")) != NULL || - strstr(ItemText, tr("Enable widget: DVB devices")) != NULL || - strstr(ItemText, tr("Enable widget: active timer")) != NULL || - strstr(ItemText, tr("Enable widget: last recordings")) != NULL || - strstr(ItemText, tr("Enable widget: timer conflicts")) != NULL || - strstr(ItemText, tr("Enable widget: system information")) != NULL || - strstr(ItemText, tr("Enable widget: system updates")) != NULL || - strstr(ItemText, tr("Enable widget: temperatures")) != NULL || - strstr(ItemText, tr("Enable widget: custom commands")) != NULL + strstr(ItemText, tr("Widget DVB weather: enable")) != NULL || + strstr(ItemText, tr("Widget DVB devices: enable")) != NULL || + strstr(ItemText, tr("Widget active timer: enable")) != NULL || + strstr(ItemText, tr("Widget last recordings: enable")) != NULL || + strstr(ItemText, tr("Widget timer conflicts: enable")) != NULL || + strstr(ItemText, tr("Widget system information: enable")) != NULL || + strstr(ItemText, tr("Widget system updates: enable")) != NULL || + strstr(ItemText, tr("Widget temperatures: enable")) != NULL || + strstr(ItemText, tr("Widget custom commands: enable")) != NULL ) { ItemLastSel = Current(); Setup(); diff --git a/widgets/weather/lib/forecast.io.php b/widgets/weather/lib/forecast.io.php new file mode 100644 index 00000000..a3fdd0b2 --- /dev/null +++ b/widgets/weather/lib/forecast.io.php @@ -0,0 +1,431 @@ +<?php +/** + * Helper Class for forecast.io webservice + */ + +class ForecastIO{ + + private $api_key; + const API_ENDPOINT = 'https://api.forecast.io/forecast/'; + + /** + * Create a new instance + * + * @param String $api_key + */ + function __construct($api_key) { + + $this->api_key = $api_key; + + } + + + private function requestData($latitude, $longitude, $units, $language = 'en', $timestamp = false, $exclusions = false) { + + $validUnits = array('auto', 'us', 'si', 'ca', 'uk'); + + if (in_array($units, $validUnits)) { + + $request_url = self::API_ENDPOINT . + $this->api_key . '/' . + $latitude . ',' . $longitude . + '?units=' . $units . '&lang=' . $language . + ( $timestamp ? ',' . $timestamp : '' ) . + ( $exclusions ? '&exclude=' . $exclusions : '' ); + + /** + * Use Buffer to cache API-requests if initialized + * (if not, just get the latest data) + * + * More info: http://git.io/FoO2Qw + */ + + if(class_exists('Buffer')) { + $cache = new Buffer(); + $content = $cache->data($request_url); + } else { + $content = file_get_contents($request_url); + } + + } else { + + return false; + + } + + if (!empty($content)) { + + return json_decode($content); + + } else { + + return false; + + } + + + } + + /** + * Will return the current conditions + * + * @param float $latitude + * @param float $longitude + * @return \ForecastIOConditions|boolean + */ + function getCurrentConditions($latitude, $longitude, $units = 'auto', $language) { + + $data = $this->requestData($latitude, $longitude, $units, $language); + + if ($data !== false) { + + return new ForecastIOConditions($data->currently); + + } else { + + return false; + + } + + } + + /** + * Will return historical conditions for day of given timestamp + * + * @param float $latitude + * @param float $longitude + * @param int $timestamp + * @return \ForecastIOConditions|boolean + */ + function getHistoricalConditions($latitude, $longitude, $units = 'auto', $language, $timestamp) { + + $exclusions = 'currently,minutely,hourly,alerts,flags'; + + $data = $this->requestData($latitude, $longitude, $units, $language, $timestamp, $exclusions); + + if ($data !== false) { + + return new ForecastIOConditions($data->daily->data[0]); + + } else { + + return false; + + } + + } + + /** + * Will return conditions on hourly basis for today + * + * @param type $latitude + * @param type $longitude + * @return \ForecastIOConditions|boolean + */ + function getForecastToday($latitude, $longitude, $units = 'auto', $language) { + + $data = $this->requestData($latitude, $longitude, $units, $language); + + if ($data !== false) { + + $conditions = array(); + + $today = date('Y-m-d'); + + foreach ($data->hourly->data as $raw_data) { + + if (date('Y-m-d', $raw_data->time) == $today) { + + $conditions[] = new ForecastIOConditions($raw_data); + + } + + } + + return $conditions; + + } else { + + return false; + + } + + } + + + /** + * Will return daily conditions for next seven days + * + * @param float $latitude + * @param float $longitude + * @return \ForecastIOConditions|boolean + */ + function getForecastWeek($latitude, $longitude, $units = 'auto', $language) { + + $data = $this->requestData($latitude, $longitude, $units, $language); + + if ($data !== false) { + + $conditions = array(); + + foreach ($data->daily->data as $raw_data) { + + $conditions[] = new ForecastIOConditions($raw_data); + + } + + return $conditions; + + } else { + + return false; + + } + + } + + +} + + +/** + * Wrapper for get data by getters + */ +class ForecastIOConditions{ + + private $raw_data; + + function __construct($raw_data) { + + $this->raw_data = $raw_data; + + } + + /** + * Will return the temperature + * + * @return String + */ + function getTemperature() { + + return $this->raw_data->temperature; + + } + + /** + * get the min temperature + * + * only available for week forecast + * + * @return type + */ + function getMinTemperature() { + + return $this->raw_data->temperatureMin; + + } + + /** + * get max temperature + * + * only available for week forecast + * + * @return type + */ + function getMaxTemperature() { + + return $this->raw_data->temperatureMax; + + } + + /** + * get apparent temperature (heat index/wind chill) + * + * only available for current conditions + * + * @return type + */ + function getApparentTemperature() { + + return $this->raw_data->apparentTemperature; + + } + + /** + * Get the summary of the conditions + * + * @return String + */ + function getSummary() { + + return $this->raw_data->summary; + + } + + /** + * Get the icon of the conditions + * + * @return String + */ + function getIcon() { + + return $this->raw_data->icon; + + } + + /** + * Get the time, when $format not set timestamp else formatted time + * + * @param String $format + * @return String + */ + function getTime($format = null) { + + if (!isset($format)) { + + return $this->raw_data->time; + + } else { + + return date($format, $this->raw_data->time); + + } + + } + + /** + * Get the pressure + * + * @return String + */ + function getPressure() { + + return $this->raw_data->pressure; + + } + + /** + * Get the dew point + * + * Available in the current conditions + * + * @return String + */ + function getDewPoint() { + + return $this->raw_data->dewPoint; + + } + + /** + * get humidity + * + * @return String + */ + function getHumidity() { + + return $this->raw_data->humidity; + + } + + /** + * Get the wind speed + * + * @return String + */ + function getWindSpeed() { + + return $this->raw_data->windSpeed; + + } + + /** + * Get wind direction + * + * @return type + */ + function getWindBearing() { + + return $this->raw_data->windBearing; + + } + + /** + * get precipitation type + * + * @return type + */ + function getPrecipitationType() { + + return $this->raw_data->precipType; + + } + + /** + * get the probability 0..1 of precipitation type + * + * @return type + */ + function getPrecipitationProbability() { + + return $this->raw_data->precipProbability; + + } + + /** + * Get the cloud cover + * + * @return type + */ + function getCloudCover() { + + return $this->raw_data->cloudCover; + + } + + + + /** + * get sunrise time + * + * only available for week forecast + * + * @return type + */ + function getSunrise($format=null) { + + if (!isset($format)) { + + return $this->raw_data->sunriseTime; + + } else { + + return date($format, $this->raw_data->sunriseTime); + + } + + } + + /** + * get sunset time + * + * only available for week forecast + * + * @return type + */ + function getSunset($format=null) { + + if (!isset($format)) { + + return $this->raw_data->sunsetTime; + + } else { + + return date($format, $this->raw_data->sunsetTime); + + } + + } + +} +?> diff --git a/widgets/weather/update_weather.php b/widgets/weather/update_weather.php new file mode 100644 index 00000000..8d2d8be9 --- /dev/null +++ b/widgets/weather/update_weather.php @@ -0,0 +1,117 @@ +<?php + +/* + * USER CONFIG + */ +$city = "Berlin"; +$country = "DE"; +$locationSkin = "Berlin"; // location shown in skin +$units = 'si'; // Can be set to 'us', 'si', 'ca', 'uk' or 'auto' (see forecast.io API); default is auto +$degree_sign = "°C"; +$lang = 'de'; // Can be set to 'en', 'de', 'pl', 'es', 'fr', 'it', 'tet' or 'x-pig-latin' (see forecast.io API); default is 'en' +// We have only 1000 api calls per day, so please only do one update per day! +// Or request an own key for free at forecast.io +$api_key = '137f2d85a1f1db5762e5e073103541d2'; + +/* + * DO NOT CHANGE ANYTHING FROM HERE + */ +include('lib/forecast.io.php'); + +// delete old files +array_map('unlink', glob("weather.*")); + +// get lat & long from google maps +$MAPSURL = "http://maps.googleapis.com/maps/api/geocode/json?address=".$city.",".$country."&sensor=false"; +$json = file_get_contents($MAPSURL); +$data = json_decode($json, true); + +if( !isset($data['results'][0]) ) { + echo "no latitude and longitude find for: ".$city.",".$country." !\n"; + exit; +} +$latitude = $data['results'][0]['geometry']['location']['lat']; +$longitude = $data['results'][0]['geometry']['location']['lng']; + +// forecast query +$forecast = new ForecastIO($api_key); + +// get daily conditions for next 7 days +$conditions_week = $forecast->getForecastWeek($latitude, $longitude, $units, $lang); + +if( !$handle = fopen("weather.location", "w") ) { + print "can't create file!\n"; +} else { + fwrite($handle, $locationSkin); + fclose($handle); +} + + +$index = -1; +foreach($conditions_week as $conditions) { + $index++; + + if( !$handle = fopen("weather.".$index.".summary", "w") ) { + print "can't create file!\n"; + continue; + } + fwrite($handle, $conditions->getSummary()); + fclose($handle); + +/* + if( !$handle = fopen("weather.".$index.".temp", "w") ) { + print "can't create file!\n"; + continue; + } + // we only have min & max so we must calc + $temp = round(($conditions->getMinTemperature() + $conditions->getMaxTemperature()) / 2.0, 1); + fwrite($handle, $temp); + fwrite($handle, $degree_sign); + fclose($handle); + */ + if( !$handle = fopen("weather.".$index.".tempMin", "w") ) { + print "can't create file!\n"; + continue; + } + // we only have min & max so we must calc + $temp = round($conditions->getMinTemperature(), 1); + fwrite($handle, $temp); + fwrite($handle, $degree_sign); + fclose($handle); + + if( !$handle = fopen("weather.".$index.".tempMax", "w") ) { + print "can't create file!\n"; + continue; + } + // we only have min & max so we must calc + $temp = round($conditions->getMaxTemperature(), 1); + fwrite($handle, $temp); + fwrite($handle, $degree_sign); + fclose($handle); + + + if( !$handle = fopen("weather.".$index.".precipitation", "w") ) { + print "can't create file!\n"; + continue; + } + fwrite($handle, $conditions->getPrecipitationProbability()); + fclose($handle); + + if( !$handle = fopen("weather.".$index.".precipitationType", "w") ) { + print "can't create file!\n"; + continue; + } + if( $conditions->getPrecipitationProbability() > 0 ) + fwrite($handle, $conditions->getPrecipitationType()); + else + fwrite($handle, "none"); + fclose($handle); + + if( !$handle = fopen("weather.".$index.".icon", "w") ) { + print "can't create file!\n"; + continue; + } + fwrite($handle, $conditions->getIcon()); + fclose($handle); +} +?> |