diff --git a/acinclude.m4 b/acinclude.m4 index 24d344696..9ebdfd241 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -24,6 +24,23 @@ if test "$DEBUG" = "yes"; then AC_DEFINE(DEBUG, 1, [enable debugging code]) fi +# weather +AC_ARG_WITH(weather-dev-key, + AS_HELP_STRING([--with-weather-dev-key=KEY], [API dev key to get data from weather data base, required for additional weather informations]), + [WEATHER_DEV_KEY="$withval"], + [WEATHER_DEV_KEY=""]) +AC_DEFINE_UNQUOTED([WEATHER_DEV_KEY], ["$WEATHER_DEV_KEY"], [API dev key to get data from weather data base, required for additional weather informations]) + +AC_ARG_ENABLE([weather-key-manage], + AS_HELP_STRING([--enable-weather-key-manage], [Enable manage weather api dev key via gui for additional weather informations @<:@default=yes@:>@]), + [enable_weather_key_manage="$enableval"], + [enable_weather_key_manage="yes"]) + +if test "$enable_weather_key_manage" = "yes" ; then + AC_DEFINE([ENABLE_WEATHER_KEY_MANAGE], 1, [Enable manage weather api dev key via gui for additional weather informations]) +fi +# weather end + # tmdb AC_ARG_WITH(tmdb-dev-key, AS_HELP_STRING([--with-tmdb-dev-key=KEY], [API dev key to get data from tmdb data base, required for additional movie informations]), diff --git a/configure.ac b/configure.ac index dd8e65ed6..9b85820ec 100644 --- a/configure.ac +++ b/configure.ac @@ -344,6 +344,7 @@ data/icons/status/info/Makefile data/icons/status/markers/Makefile data/icons/status/various/Makefile data/icons/various/Makefile +data/icons/weather/Makefile data/inetradio/Makefile data/initial/Makefile data/iso-codes/Makefile diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 184a6edbf..b73f283c1 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -8,7 +8,8 @@ SUBDIRS = \ radar \ slider \ status \ - various + various \ + weather install-data-hook: $(INSTALL) -d $(DESTDIR)/$(ICONSDIR)/logo diff --git a/data/icons/weather/Makefile.am b/data/icons/weather/Makefile.am new file mode 100644 index 000000000..70ea8f26e --- /dev/null +++ b/data/icons/weather/Makefile.am @@ -0,0 +1,14 @@ +installdir = $(ICONSDIR)/weather + +install_DATA = \ + clear-day.png \ + clear-night.png \ + cloudy.png \ + fog.png \ + partly-cloudy-day.png \ + partly-cloudy-night.png \ + rain.png \ + sleet.png \ + snow.png \ + unknown.png \ + wind.png diff --git a/data/icons/weather/clear-day.png b/data/icons/weather/clear-day.png new file mode 100644 index 000000000..d8aedc46e Binary files /dev/null and b/data/icons/weather/clear-day.png differ diff --git a/data/icons/weather/clear-night.png b/data/icons/weather/clear-night.png new file mode 100644 index 000000000..837f94eb2 Binary files /dev/null and b/data/icons/weather/clear-night.png differ diff --git a/data/icons/weather/cloudy.png b/data/icons/weather/cloudy.png new file mode 100644 index 000000000..97ffcb85b Binary files /dev/null and b/data/icons/weather/cloudy.png differ diff --git a/data/icons/weather/fog.png b/data/icons/weather/fog.png new file mode 100644 index 000000000..c6056e0b0 Binary files /dev/null and b/data/icons/weather/fog.png differ diff --git a/data/icons/weather/partly-cloudy-day.png b/data/icons/weather/partly-cloudy-day.png new file mode 100644 index 000000000..29b46e725 Binary files /dev/null and b/data/icons/weather/partly-cloudy-day.png differ diff --git a/data/icons/weather/partly-cloudy-night.png b/data/icons/weather/partly-cloudy-night.png new file mode 100644 index 000000000..9e8d62ee7 Binary files /dev/null and b/data/icons/weather/partly-cloudy-night.png differ diff --git a/data/icons/weather/rain.png b/data/icons/weather/rain.png new file mode 100644 index 000000000..443c1b328 Binary files /dev/null and b/data/icons/weather/rain.png differ diff --git a/data/icons/weather/sleet.png b/data/icons/weather/sleet.png new file mode 100644 index 000000000..e9a32d44b Binary files /dev/null and b/data/icons/weather/sleet.png differ diff --git a/data/icons/weather/snow.png b/data/icons/weather/snow.png new file mode 100644 index 000000000..3042052f6 Binary files /dev/null and b/data/icons/weather/snow.png differ diff --git a/data/icons/weather/unknown.png b/data/icons/weather/unknown.png new file mode 100644 index 000000000..2ba1aa32c Binary files /dev/null and b/data/icons/weather/unknown.png differ diff --git a/data/icons/weather/wind.png b/data/icons/weather/wind.png new file mode 100644 index 000000000..0d8e26651 Binary files /dev/null and b/data/icons/weather/wind.png differ diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index f0cb8008a..b508f0f92 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1430,7 +1430,7 @@ menu.hint_misc_energy Energieverbrauchs- und Standby-Optionen, verzögertes Auss menu.hint_misc_epg Diverse EPG-Einstellungen und Speicherverzeichnis für EPG-Daten menu.hint_misc_filebrowser Dateisystem, Dateirechte anzeigen im Dateibrowser, Startverzeichnisoptionen menu.hint_misc_general Standby-, Teletext- und Rotor-Einstellungen, Pluginverzeichnis auf externem Datenträger -menu.hint_misc_onlineservices Konfigurieren und steuern von Online-Diensten wie YouTube, SHOUTCast und TMDb +menu.hint_misc_onlineservices Konfigurieren und steuern von Online-Diensten wie Wetter, YouTube, SHOUTCast und TMDb menu.hint_misc_zapit Verwaltung der Start-Kanäle für den TV/Radio-Modus menu.hint_movie Wiedergabe von Filmen menu.hint_moviebrowser_fonts Ändern Sie die Schriftgrößen im Moviebrowser (Meine Aufnahmen) @@ -1732,6 +1732,9 @@ menu.hint_volume Wählen Sie die Anzeigeoptionen für die Lautstärke menu.hint_volume_digits Zifferndarstellung der Lautstärkeanzeige ein- oder ausschalten menu.hint_volume_pos Wählen Sie die Position der Lautstärkeanzeige aus menu.hint_volume_size Wählen Sie die Höhe der Lautstärkeanzeige +menu.hint_weather_api_key Geben Sie den Dark Sky API Schlüssel ein. Eine leere Eingabe schaltet die Wetter-Unterstützung aus +menu.hint_weather_enabled Schaltet die Wetter-Unterstützung (darksky.net) ein bzw. aus +menu.hint_weather_location Wählen Sie eine Stadt in ihrer Nähe zur Anzeige der Wetterdaten aus menu.hint_webradio_setup Hier konfigurierte WebRadio-Kanäle finden Sie in der Kanalverwaltung. menu.hint_webradio_xml_auto Lädt automatisch alle WebRadio-Dateien aus %s/ und %s/ menu.hint_webtv_setup Hier konfigurierte WebTV-Kanäle finden Sie in der Kanalverwaltung. @@ -2827,6 +2830,9 @@ videomenu.videoformat_149 14:9 videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Videosystem +weather.api_key Dark Sky API Schlüssel +weather.enabled Wetter-Unterstützung +weather.location Wetter-Standort webradio.head WebRadio webradio.xml WebRadio-Dateien webradio.xml.auto WebRadio-Dateien automatisch laden diff --git a/data/locale/english.locale b/data/locale/english.locale index d31030a45..bc7782055 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1430,7 +1430,7 @@ menu.hint_misc_energy Enable soft-standby, delayed shutdown\ninactivity timers menu.hint_misc_epg Save/load EPG options, EPG cache options\nEPG save directory menu.hint_misc_filebrowser Filesystem encoding, file rights\ndeny directory leave menu.hint_misc_general Start to standby, cache teletext, swp rotor\nplugin hdd dir -menu.hint_misc_onlineservices Configure and control online services like YouTube, SHOUTCast and TMDb +menu.hint_misc_onlineservices Configure and control online services like Weather, YouTube, SHOUTCast and TMDb menu.hint_misc_zapit Initial TV/Radio channels menu.hint_movie Play movies menu.hint_moviebrowser_fonts Change moviebrowser (My recordings) font sizes @@ -1732,6 +1732,9 @@ menu.hint_volume Configure Volume GUI options menu.hint_volume_digits Numeric display of the volumebar on/off menu.hint_volume_pos Select volume indicator position menu.hint_volume_size Select volume indicator height +menu.hint_weather_api_key Type your Dark Sky API key. An empty input disables Weather support +menu.hint_weather_enabled Enable or disable Weather support (darksky.net) +menu.hint_weather_location Select your weather location menu.hint_webradio_setup WebRadio channels configured here will be available in the standard channel lists. menu.hint_webradio_xml_auto Auto-load all existing WebRadio files from %s/ and %s/ menu.hint_webtv_setup WebTV channels configured here will be available in the standard channel lists. @@ -2827,6 +2830,9 @@ videomenu.videoformat_149 14:9 videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Digital video mode +weather.api_key Dark Sky API key +weather.enabled Weather support +weather.location Weather Location webradio.head WebRadio webradio.xml WebRadio files webradio.xml.auto Auto-load WebRadio files diff --git a/src/driver/lcd4l.cpp b/src/driver/lcd4l.cpp index 7a0833399..3771baedc 100644 --- a/src/driver/lcd4l.cpp +++ b/src/driver/lcd4l.cpp @@ -7,7 +7,7 @@ Copyright (C) 2012-2018 'vanhofen' Homepage: http://www.neutrino-images.de/ - Copyright (C) 2016-2018 'TangoCash' + Copyright (C) 2016-2019 'TangoCash' License: GPL @@ -52,6 +52,7 @@ #include #include #include +#include #include "lcd4l.h" @@ -103,6 +104,9 @@ extern CPictureViewer *g_PicViewer; #define FCOLOR2 LCD_DATADIR "fcolor2" #define PBCOLOR LCD_DATADIR "pbcolor" +#define WEATHER_TEMP LCD_DATADIR "weather_temp" +#define WEATHER_ICON LCD_DATADIR "weather_icon" + #define FLAG_LCD4LINUX "/tmp/.lcd4linux" #define PIDFILE "/var/run/lcd4linux.pid" @@ -249,6 +253,9 @@ void CLCD4l::Init() m_Start = "00:00"; m_End = "00:00"; + m_wtemp = ""; + m_wicon = ""; + if (!access(LCD_DATADIR, F_OK) == 0) mkdir(LCD_DATADIR, 0755); @@ -1008,6 +1015,23 @@ void CLCD4l::ParseInfo(uint64_t parseID, bool newID, bool firstRun) WriteFile(DURATION, (std::string)Duration); strcpy(m_Duration, Duration); } + + if (g_settings.weather_enabled && CWeather::getInstance()->checkUpdate()) + { + std::string wtemp = CWeather::getInstance()->getActTemp(); + std::string wicon = CWeather::getInstance()->getActIcon(); + if (m_wtemp.compare(wtemp)) + { + WriteFile(WEATHER_TEMP, wtemp); + m_wtemp = wtemp; + } + if (m_wicon.compare(wicon)) + { + WriteFile(WEATHER_ICON, wicon); + m_wicon = wicon; + } + } + } /* ----------------------------------------------------------------- */ diff --git a/src/driver/lcd4l.h b/src/driver/lcd4l.h index 0e6ba9d36..dcbd83c7d 100644 --- a/src/driver/lcd4l.h +++ b/src/driver/lcd4l.h @@ -7,7 +7,7 @@ Copyright (C) 2012-2018 'vanhofen' Homepage: http://www.neutrino-images.de/ - Copyright (C) 2016-2018 'TangoCash' + Copyright (C) 2016-2019 'TangoCash' License: GPL @@ -125,6 +125,9 @@ class CLCD4l std::string m_fcolor1; std::string m_fcolor2; std::string m_pbcolor; + + std::string m_wtemp; + std::string m_wicon; }; #endif diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 201cadef8..ba3b462d9 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -112,6 +112,7 @@ libneutrino_gui_a_SOURCES = \ vfd_setup.cpp \ videosettings.cpp \ volumebar.cpp \ + weather.cpp \ webtv_setup.cpp \ xmltv_setup.cpp \ zapit_setup.cpp diff --git a/src/gui/miscsettings_menu.cpp b/src/gui/miscsettings_menu.cpp index 163fc93e6..5b7299aa4 100644 --- a/src/gui/miscsettings_menu.cpp +++ b/src/gui/miscsettings_menu.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -147,6 +148,10 @@ int CMiscMenue::exec(CMenuTarget* parent, const std::string &actionKey) { return showMiscSettingsMenuPlugins(); } + else if(actionKey == "select_location") + { + return showMiscSettingsSelectWeatherLocation(); + } else if(actionKey == "epg_read_now") { struct stat my_stat; @@ -168,6 +173,8 @@ int CMiscMenue::exec(CMenuTarget* parent, const std::string &actionKey) return showMiscSettingsMenu(); } +#include + #if 0 //not used #define MISCSETTINGS_FB_DESTINATION_OPTION_COUNT 3 const CMenuOptionChooser::keyval MISCSETTINGS_FB_DESTINATION_OPTIONS[MISCSETTINGS_FB_DESTINATION_OPTION_COUNT] = @@ -596,6 +603,25 @@ int CMiscMenue::showMiscSettingsMenuOnlineServices() CMenuWidget *ms_oservices = new CMenuWidget(LOCALE_MISCSETTINGS_HEAD, NEUTRINO_ICON_SETTINGS, width, MN_WIDGET_ID_MISCSETUP_ONLINESERVICES); ms_oservices->addIntroItems(LOCALE_MISCSETTINGS_ONLINESERVICES); + // weather + weather_onoff = new CMenuOptionChooser(LOCALE_WEATHER_ENABLED, &g_settings.weather_enabled, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, CApiKey::check_weather_api_key()); + weather_onoff->setHint(NEUTRINO_ICON_HINT_SETTINGS, LOCALE_MENU_HINT_WEATHER_ENABLED); + ms_oservices->addItem(weather_onoff); + + CMenuForwarder *mf_wl = new CMenuForwarder(LOCALE_WEATHER_LOCATION, g_settings.weather_enabled, NULL, this, "select_location"); + mf_wl->setHint(NEUTRINO_ICON_HINT_SETTINGS, LOCALE_MENU_HINT_WEATHER_LOCATION); + ms_oservices->addItem(mf_wl); + +#if ENABLE_WEATHER_KEY_MANAGE + changeNotify(LOCALE_WEATHER_API_KEY, NULL); + CKeyboardInput weather_api_key_input(LOCALE_WEATHER_API_KEY, &g_settings.weather_api_key, 32, this); + CMenuForwarder *mf_we = new CMenuForwarder(LOCALE_WEATHER_API_KEY, true, weather_api_key_short, &weather_api_key_input); + mf_we->setHint(NEUTRINO_ICON_HINT_SETTINGS, LOCALE_MENU_HINT_WEATHER_API_KEY); + ms_oservices->addItem(mf_we); + + ms_oservices->addItem(GenericMenuSeparator); +#endif + // tmdb tmdb_onoff = new CMenuOptionChooser(LOCALE_TMDB_ENABLED, &g_settings.tmdb_enabled, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, CApiKey::check_tmdb_api_key()); tmdb_onoff->setHint(NEUTRINO_ICON_HINT_SETTINGS, LOCALE_MENU_HINT_TMDB_ENABLED); @@ -685,6 +711,40 @@ int CMiscMenue::showMiscSettingsMenuPlugins() return res; } +int CMiscMenue::showMiscSettingsSelectWeatherLocation() +{ + int select = 0; + int res = 0; + + if (WEATHER_LOCATION_OPTION_COUNT > 1) + { + CMenuWidget *m = new CMenuWidget(LOCALE_WEATHER_LOCATION, NEUTRINO_ICON_LANGUAGE); + CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); + + m->addItem(GenericMenuSeparator); + + CMenuForwarder* mf; + for (size_t i = 0; i < WEATHER_LOCATION_OPTION_COUNT; i++) + { + mf = new CMenuForwarder(WEATHER_LOCATION_OPTIONS[i].key, true, NULL, selector, to_string(i).c_str()); + mf->setHint(NEUTRINO_ICON_HINT_SETTINGS, WEATHER_LOCATION_OPTIONS[i].value.c_str()); + m->addItem(mf); + } + + m->enableSaveScreen(); + res = m->exec(NULL, ""); + + if (!m->gotAction()) + return res; + + delete selector; + } + g_settings.weather_location = WEATHER_LOCATION_OPTIONS[select].value; + g_settings.weather_city = std::string(WEATHER_LOCATION_OPTIONS[select].key); + CWeather::getInstance()->setCoords(g_settings.weather_location, g_settings.weather_city); + return res; +} + #ifdef CPU_FREQ //CPU void CMiscMenue::showMiscSettingsMenuCPUFreq(CMenuWidget *ms_cpu) @@ -771,6 +831,15 @@ bool CMiscMenue::changeNotify(const neutrino_locale_t OptionName, void * /*data* ret = menu_return::RETURN_REPAINT; } #endif + else if (ARE_LOCALES_EQUAL(OptionName, LOCALE_WEATHER_API_KEY)) + { + g_settings.weather_enabled = g_settings.weather_enabled && CApiKey::check_weather_api_key(); + if (g_settings.weather_enabled) + weather_api_key_short = g_settings.weather_api_key.substr(0, 8) + "..."; + else + weather_api_key_short.clear(); + weather_onoff->setActive(CApiKey::check_weather_api_key()); + } else if (ARE_LOCALES_EQUAL(OptionName, LOCALE_TMDB_API_KEY)) { g_settings.tmdb_enabled = g_settings.tmdb_enabled && CApiKey::check_tmdb_api_key(); diff --git a/src/gui/miscsettings_menu.h b/src/gui/miscsettings_menu.h index 2dfcc0790..c8d0e98a4 100644 --- a/src/gui/miscsettings_menu.h +++ b/src/gui/miscsettings_menu.h @@ -47,6 +47,7 @@ class CMiscMenue : public CMenuTarget, CChangeObserver CMenuOptionChooser * epg_read; CMenuOptionChooser * epg_read_frequently; CMenuOptionChooser * epg_scan; + CMenuOptionChooser * weather_onoff; CMenuOptionChooser * tmdb_onoff; CMenuOptionChooser * omdb_onoff; CMenuOptionChooser * youtube_onoff; @@ -59,6 +60,7 @@ class CMiscMenue : public CMenuTarget, CChangeObserver std::string epg_old_events; std::string epg_max_events; + std::string weather_api_key_short; std::string tmdb_api_key_short; std::string omdb_api_key_short; std::string youtube_dev_id_short; @@ -71,6 +73,7 @@ class CMiscMenue : public CMenuTarget, CChangeObserver int showMiscSettingsMenuEnergy(); int showMiscSettingsMenuChanlist(); int showMiscSettingsMenuOnlineServices(); + int showMiscSettingsSelectWeatherLocation(); int showMiscSettingsMenuPlugins(); #ifdef CPU_FREQ void showMiscSettingsMenuCPUFreq(CMenuWidget *ms_cpu); diff --git a/src/gui/weather.cpp b/src/gui/weather.cpp new file mode 100644 index 000000000..a9ede371c --- /dev/null +++ b/src/gui/weather.cpp @@ -0,0 +1,193 @@ +/* + Copyright (C) 2017,2018,2019 TangoCash + + “Powered by Dark Sky” https://darksky.net/poweredby/ + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "system/set_threadname.h" +#include "gui/widget/hintbox.h" + +#include +#include + +#include +#include + +#include "weather.h" + +#define MINUTES 15*60 + +CWeather* CWeather::getInstance() +{ + static CWeather* weather = NULL; + if(!weather) + weather = new CWeather(); + return weather; +} + +CWeather::CWeather() +{ + act_temp = 0; + act_wicon = "unknown.png"; + key = g_settings.weather_api_key; + form = NULL; + v_forecast.clear(); + last_time = 0; + coords = ""; + city = ""; +} + +CWeather::~CWeather() +{ + v_forecast.clear(); + hide(); +} + +void CWeather::setCoords(std::string new_coords, std::string new_city) +{ + if (coords.compare(new_coords)) + { + coords = new_coords; + city = new_city; + GetWeatherDetails(); + } +} + +bool CWeather::checkUpdate() +{ + time_t current_time = time(NULL); + if (difftime(current_time,last_time) > MINUTES) + return GetWeatherDetails(); + else + return false; +} + +bool CWeather::GetWeatherDetails() +{ + printf("[CWeather]: %s\n",__func__); + + last_time = time(NULL); + + if (!g_settings.weather_enabled) + return false; + + std::string data = "https://api.darksky.net/forecast/"+key+"/"+coords+"?units=si&lang=de&exclude=minutely,hourly,flags,alerts"; + std::string answer; + double found = 0; + + v_forecast.clear(); + + Json::Value DataValues; + Json::Reader DataReader; + bool parsedSuccess = false; + + answer = ""; + if (!getUrl(data, answer)) + return false; + + parsedSuccess = DataReader.parse(answer, DataValues, false); + if (!parsedSuccess) + { + printf("Failed to parse JSON\n"); + printf("%s\n", DataReader.getFormattedErrorMessages().c_str()); + return false; + } + + found = DataValues["currently"].get("time",0).asDouble(); + + printf("[CWeather]: results found: %lf\n",found); + + if (found > 0) + { + act_temp = DataValues["currently"].get("temperature","").asFloat(); + timezone = DataValues["timezone"].asString(); + act_wicon = DataValues["currently"].get("icon","").asString(); + if (act_wicon.empty()) + act_wicon = "unknown.png"; + else + act_wicon = act_wicon+".png"; + printf("[CWeather]: temp in %s (%s): %.1f - %s\n", city.c_str(), timezone.c_str(), act_temp, act_wicon.c_str()); + + forecast_data weatherinfo; + Json::Value elements = DataValues["daily"]["data"]; + for (unsigned int i = 0; i %s\n", timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year+1900, weatherinfo.min_temp,weatherinfo.max_temp,weatherinfo.wicon.c_str()); + v_forecast.push_back(weatherinfo); + } + return true; + } + return false; +} + +void CWeather::show(int x, int y) +{ + checkUpdate(); + + if (form == NULL) + form = new CComponentsForm(); + + if (!g_settings.weather_enabled || coords.empty() ) + return; + + CComponentsPicture *ptmp = new CComponentsPicture(RADIUS_MID, RADIUS_MID, getActIcon()); + ptmp->setColorBody(form->getColorBody()); + form->addCCItem(ptmp); + + CComponentsText *temp = new CComponentsText(ptmp->getWidth()+2*RADIUS_MID, ptmp->getHeight()/2 + RADIUS_MID - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_NUMBER]->getHeight()/2, 0, 0, getActTemp(), CTextBox::AUTO_WIDTH,g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_NUMBER]); + temp->doPaintBg(false); + temp->setTextColor(COL_INFOBAR_TEXT); + form->addCCItem(temp); + + form->setDimensionsAll(x, y, ptmp->getWidth()+temp->getWidth()+2*RADIUS_MID, ptmp->getHeight()+2*RADIUS_MID); + form->enableShadow(); + form->paint(); +} + +void CWeather::hide() +{ + if (form->isPainted()) + { + form->hide(); + delete form; + form = NULL; + } +} diff --git a/src/gui/weather.h b/src/gui/weather.h new file mode 100644 index 000000000..c89d4e033 --- /dev/null +++ b/src/gui/weather.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2017,2018,2019 TangoCash + + “Powered by Dark Sky” https://darksky.net/poweredby/ + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __WEATHER__ +#define __WEATHER__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "system/settings.h" +#include "system/helpers.h" + +#include + +typedef struct +{ + std::string wicon; + float min_temp; + float max_temp; + time_t timestamp; +} forecast_data; + +class CWeather +{ +private: + std::string coords; + std::string city; + std::string timezone; + std::string act_wicon; + float act_temp; + std::vector v_forecast; + CComponentsForm *form; + std::string key; + bool GetWeatherDetails(); + time_t last_time; + +public: + static CWeather* getInstance(); + CWeather(); + ~CWeather(); + bool checkUpdate(); + void setCoords(std::string new_coords, std::string new_city = "Unknown"); + void show(int x = 50, int y = 50); + void hide(); + std::string getActTemp() + { + return to_string((int)(act_temp+0.5))+"°C"; + }; + std::string getActIcon() + { + return ICONSDIR"/weather/"+act_wicon; + }; +}; + +#endif diff --git a/src/gui/weather_locations.h b/src/gui/weather_locations.h new file mode 100644 index 000000000..f16eb5acd --- /dev/null +++ b/src/gui/weather_locations.h @@ -0,0 +1,294 @@ +struct weather_loc +{ + const char *key; + const std::string value; +}; + +// locations and coords taken from tuxwetter plugin +const weather_loc WEATHER_LOCATION_OPTIONS[] = +{ + { "Aachen", "50.77,6.13" }, + { "Ahaus", "52.07,7.00" }, + { "Ahrensburg", "53.06,10.25" }, + { "Allendorf", "51.28,7.95" }, + { "Alsenz", "49.72,7.82" }, + { "Altenbruch", "53.82,8.77" }, + { "Amberg", "49.44,11.86" }, + { "Ansbach", "49.30,10.58" }, + { "Aschaffenburg", "49.97,9.15" }, + { "Augsburg", "48.37,10.88" }, + { "Aurich", "53.47,7.48" }, + { "Bad Hersfeld", "50.870,9.702" }, + { "Bad Tölz", "47.77,11.57" }, + { "Bamberg", "50.87,9.70" }, + { "Barweiler", "50.35,6.98" }, + { "Bayreuth", "49.95,11.56" }, + { "Bergisch-Gladbach", "49.94,11.57" }, + { "Bergen auf Rügen", "54.42,13.44" }, + { "Berlin", "52.52,13.40" }, + { "Bielefeld", "52.03,8.53" }, + { "Bitburg", "49.96,6.52" }, + { "Blexen", "49.96,6.52" }, + { "Bonn", "50.73,7.09" }, + { "Bottrop", "51.52,6.94" }, + { "Brandenburg", "52.41,12.53" }, + { "Braunschweig", "52.26,10.52" }, + { "Bremen", "53.07,8.80" }, + { "Bremerhaven", "53.53,8.58" }, + { "Brüggen", "51.03,6.33" }, + { "Brunsbüttel", "53.89,9.13" }, + { "Bückeburg", "52.25,9.05" }, + { "Büttgen", "51.19,6.60" }, + { "Celle", "52.25,9.05" }, + { "Chemnitz", "50.82,12.92" }, + { "Cloppenburg", "50.82,12.92" }, + { "Coburg", "50.26,10.96" }, + { "Cottbus", "51.75,14.33" }, + { "Cuxhaven", "53.85,8.68" }, + { "Dachau", "48.26,11.43" }, + { "Darmstadt", "49.87,8.65" }, + { "Deggendorf", "48.84,12.95" }, + { "Delmenhorst", "53.05,8.63" }, + { "Dessau", "51.82,12.24" }, + { "Detmold", "51.93,8.86" }, + { "Döbeln", "51.12,13.11" }, + { "Donaueschingen", "47.95,8.49" }, + { "Dortmund", "51.51,7.46" }, + { "Dresden", "51.05,13.73" }, + { "Duhnen", "53.88,8.64" }, + { "Duisburg", "51.43,6.76" }, + { "Düsseldorf", "51.22,6.77" }, + { "Ebersberg", "48.07,11.96" }, + { "Eberswalde", "52.837,13.788" }, + { "Eckernförde", "54.469,9.838" }, + { "Eggenfelden", "48.40,12.75" }, + { "Eichstätt", "48.89,11.18" }, + { "Elmshorn", "53.75,9.66" }, + { "Emden", "53.35,7.20" }, + { "Erding", "48.31,11.91" }, + { "Erfurt", "50.98,11.02" }, + { "Erkrath", "51.22,6.91" }, + { "Erlangen", "49.58,11.01" }, + { "Eschlkam", "49.29,12.91" }, + { "Eschwege", "51.18,10.03" }, + { "Essen", "51.45,7.01" }, + { "Esslingen", "48.74,9.32" }, + { "Euskirchen", "50.65,6.78" }, + { "Eutin", "54.13,10.60" }, + { "Falkensee", "52.56,13.07" }, + { "Feucht", "49.37,11.21" }, + { "Flensburg", "54.79,9.44" }, + { "Frankfurt am Main", "50.11,8.68" }, + { "Frankfurt an der Oder", "52.350,14.550" }, + { "Freiburg", "47.99,7.84" }, + { "Freising", "48.40,11.74" }, + { "Freudenstadt", "48.46,8.41" }, + { "Freyung", "48.80,13.54" }, + { "Friedrichshafen", "47.66,9.48" }, + { "Friesoythe", "53.02,7.85" }, + { "Fritzlar", "51.13,9.27" }, + { "Fulda", "50.55,9.68" }, + { "Fürstenfeldbruck", "48.17,11.24" }, + { "Fürth", "49.47,10.98" }, + { "Garmisch-Partenkirchen", "47.49,11.10" }, + { "Geilenkirchen", "50.97,6.12" }, + { "Gelnhausen", "50.20,9.19" }, + { "Gelsenkirchen", "51.52,7.09" }, + { "Gera", "50.89,12.08" }, + { "Geretsried", "47.86,11.49" }, + { "Germersheim", "49.21,8.37" }, + { "Gettorf", "54.41,9.98" }, + { "Gießen", "50.58,8.68" }, + { "Glauchau", "50.82,12.55" }, + { "Göppingen", "48.71,9.65" }, + { "Görlitz", "51.15,14.97" }, + { "Göttingen", "51.54,9.92" }, + { "Grafenau", "48.86,13.39" }, + { "Grafenwöhr", "49.71,11.91" }, + { "Greifswald", "54.09,13.39" }, + { "Grünberg", "50.59,8.96" }, + { "Gütersloh", "51.90,8.39" }, + { "Hagen", "51.37,7.46" }, + { "Hahn", "49.96,7.27" }, + { "Halle (Saale)", "51.497,11.969" }, + { "Halle (Westfalen)", "52.06,8.36" }, + { "Hamburg", "53.55,9.99" }, + { "Hamm", "51.67,7.82" }, + { "Hanau", "50.13,8.93" }, + { "Hannover", "52.38,9.73" }, + { "Harrislee", "54.80,9.39" }, + { "Heidelberg", "49.40,8.67" }, + { "Heilbronn", "49.14,9.21" }, + { "Helgoland", "54.18,7.89" }, + { "Hennigsdorf", "52.63,13.20" }, + { "Herne", "51.54,7.20" }, + { "Hilden", "51.17,6.93" }, + { "Hildesheim", "52.15,9.96" }, + { "Hinte", "53.41,7.20" }, + { "Hochheim", "50.01,8.36" }, + { "Hockenheimring", "49.33,8.57" }, + { "Hof", "50.31,11.91" }, + { "Holzkirchen", "47.88,11.70" }, + { "Hosten", "49.89,6.62" }, + { "Hürth", "50.88,6.89" }, + { "Husby", "54.50,9.48" }, + { "Husum", "54.48,9.06" }, + { "Idar-Oberstein", "49.71,7.31" }, + { "Ingolstadt", "48.77,11.43" }, + { "Iserlohn", "51.38,7.70" }, + { "Itzehoe", "53.93,9.51" }, + { "Jever", "53.57,7.90" }, + { "Jülich", "50.92,6.36" }, + { "Kall", "50.54,6.56" }, + { "Karlsruhe", "49.01,8.40" }, + { "Kassel", "51.31,9.48" }, + { "Kaufbeuren", "47.88,10.63" }, + { "Kempten", "47.73,10.32" }, + { "Kiel", "54.32,10.12" }, + { "Kitzingen", "49.73,10.15" }, + { "Koblenz", "50.36,7.59" }, + { "Köln", "50.94,6.96" }, + { "Konstanz", "47.68,9.17" }, + { "Krefeld", "51.34,6.59" }, + { "Kronshagen", "54.34,10.09" }, + { "Krumbach", "48.25,10.37" }, + { "Laarbruch", "51.60,6.15" }, + { "Lahr", "48.33,7.87" }, + { "Landshut", "48.54,12.15" }, + { "Langenhagen", "52.45,9.74" }, + { "Lausitzring", "51.54,13.89" }, + { "Lechfeld", "48.19,10.86" }, + { "Leck", "54.77,8.98" }, + { "Leer", "53.24,7.47" }, + { "Leipzig", "51.34,12.37" }, + { "Leverkusen", "51.05,7.02" }, + { "Lindenberg", "47.60,9.89" }, + { "List", "55.02,8.43" }, + { "Lübeck", "53.87,10.69" }, + { "Lüchow", "52.97,11.15" }, + { "Luckenwalde", "52.09,13.16" }, + { "Ludwigsburg", "48.89,9.20" }, + { "Ludwigshafen", "49.48,8.45" }, + { "Lüneburg", "53.25,10.41" }, + { "Magdeburg", "52.12,11.63" }, + { "Mainz", "49.99,8.25" }, + { "Mannheim", "49.49,8.47" }, + { "Marburg", "50.80,8.77" }, + { "Marienfelde", "52.42,13.37" }, + { "Marktbreit", "49.67,10.15" }, + { "Meiningen", "50.57,10.42" }, + { "Memmingen", "47.98,10.18" }, + { "Meppen", "52.70,7.30" }, + { "Merzig", "49.45,6.64" }, + { "Minden", "52.30,8.89" }, + { "Mönchengladbach", "51.18,6.44" }, + { "Oldersum", "53.33,7.34" }, + { "Mühldorf", "48.25,12.52" }, + { "München", "48.14,11.58" }, + { "Münster", "51.96,7.63" }, + { "Murnau", "47.68,11.20" }, + { "Mylau", "50.62,12.26" }, + { "Naumburg (Saale)", "51.15,11.82" }, + { "Neuberg", "48.11,12.12" }, + { "Neubrandenburg", "53.57,13.28" }, + { "Neumarkt", "49.28,11.47" }, + { "Neumünster", "54.07,9.98" }, + { "Neunkirchen", "49.35,7.19" }, + { "Neuruppin", "52.92,12.80" }, + { "Neuss", "51.20,6.69" }, + { "Neuwied", "50.44,7.47" }, + { "Niendorf (Ostsee)", "53.99,10.83" }, + { "Norden", "53.60,7.20" }, + { "Nordenham", "53.50,8.49" }, + { "Norderney", "53.71,7.16" }, + { "Nordhausen", "51.50,10" }, + { "Nordheide", "53.12,8.46" }, + { "Nordhausen", "51.50,10" }, + { "Nordhorn", "52.43,7.07" }, + { "Nördlingen", "48.85,10.49" }, + { "Nürburgring", "50.34,6.95" }, + { "Oberhausen", "51.50,6.86" }, + { "Oberpfaffenhofen", "48.07,11.26" }, + { "Oberstdorf", "47.41,10.28" }, + { "Ochsenfurt", "49.66,10.07" }, + { "Oeversee", "54.70,9.43" }, + { "Offenbach", "50.10,8.78" }, + { "Oldenburg", "53.14,8.21" }, + { "Oranienburg", "52.75,13.24" }, + { "Osnabrück", "52.28,8.05" }, + { "Otterndorf", "53.81,8.90" }, + { "Paderborn", "51.72,8.76" }, + { "Passau", "48.57,13" }, + { "Peine", "52.32,10.24" }, + { "Pfaffenhofen", "48.52,11.50" }, + { "Pfarrkirchen", "48.42,12.94" }, + { "Pforzheim", "48.89,8.69" }, + { "Pinneberg", "53.65,9.79" }, + { "Pirmasens", "49.20,7.60" }, + { "Plauen", "50.50,12.14" }, + { "Pocking", "48.40,13.32" }, + { "Potsdam", "52.39,13.06" }, + { "Prenzlau", "53.32,13.86" }, + { "Quickborn", "53.73,9.91" }, + { "Rastede", "53.24,8.20" }, + { "Recklinghausen", "51.61,7.20" }, + { "Regensburg", "49.01,12.10" }, + { "Remscheid", "51.18,7.19" }, + { "Rendsburg", "54.31,9.66" }, + { "Rennerod", "50.61,8.07" }, + { "Rosenheim", "47.86,12.12" }, + { "Rostock", "54.09,12.10" }, + { "Rüsselsheim", "50.00,8.42" }, + { "Saarbrücken", "49.230,7.000" }, + { "Sahlenburg", "53.870,8.630" }, + { "Salzgitter", "52.080,10.330" }, + { "Salzwedel", "52.850,11.150" }, + { "Schiffdorf", "53.530,8.650" }, + { "Schleswig", "54.520,9.550" }, + { "Schrobenhausen", "48.550,11.270" }, + { "Schwabach", "49.330,11.030" }, + { "Schwäbisch Hall", "49.110,9.730" }, + { "Schweinfurt", "50.050,10.230" }, + { "Schwerin", "53.630,11.380" }, + { "Siegburg", "50.800,7.200" }, + { "Siegen", "50.870,8.030" }, + { "Solingen", "51.180,7.080" }, + { "Starnberg", "48.000,11.350" }, + { "Straubing", "48.880,12.570" }, + { "Stuttgart", "48.770,9.180" }, + { "Sulingen", "52.680,8.800" }, + { "Sylt", "54.880,8.350" }, + { "Tönning", "54.320,8.950" }, + { "Traunstein", "47.87,12.62" }, + { "Travemünde", "53.970,10.870" }, + { "Trier", "49.750,6.630" }, + { "Tübingen", "48.530,9.050" }, + { "Ulm", "48.400,10.000" }, + { "Varel", "53.18,9.49" }, + { "Veitsbronn", "49.520,10.880" }, + { "Villingen-Schwenningen", "48.070,8.450" }, + { "Vilsbiburg", "48.450,12.350" }, + { "Vilshofen", "49.23,12.04" }, + { "Waldkirchen/Bayr.-Wald", "48.730,13.600" }, + { "Wallsbüll", "54.580,9.000" }, + { "Warnemünde", "54.170,12.080" }, + { "Weiden", "49.680,12.160" }, + { "Weimar", "50.980,11.320" }, + { "Weißenburg/Bayern", "49.030,10.980" }, + { "Wernigerode", "51.830,10.780" }, + { "Westerland/Sylt", "54.900,8.300" }, + { "Westerstede", "53.250,7.930" }, + { "Wetzlar", "50.550,8.500" }, + { "Wiesbaden", "50.080,8.250" }, + { "Wilhelmshaven", "53.520,8.130" }, + { "Wittenberge", "53.000,11.750" }, + { "Wittingen", "52.730,10.720" }, + { "Wolfsburg", "52.430,10.800" }, + { "Wuppertal", "51.270,7.180" }, + { "Würzburg", "49.790,9.940" }, + { "Zeven", "53.300,9.280" }, + { "Zirndorf", "49.450,10.950" }, + { "Zwickau", "50.720,12.500" } +}; + +#define WEATHER_LOCATION_OPTION_COUNT (sizeof(WEATHER_LOCATION_OPTIONS)/sizeof(weather_loc)) diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 5909c7988..9a2ce77db 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -94,6 +94,7 @@ #include "gui/update_check.h" #include "gui/videosettings.h" #include "gui/audio_select.h" +#include #include "gui/webtv_setup.h" //NI #include "gui/widget/hintbox.h" @@ -1007,10 +1008,21 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.movieplayer_timeosd_while_searching = configfile.getInt32("movieplayer_timeosd_while_searching", 1); //online services + ///weather + g_settings.weather_api_key = WEATHER_DEV_KEY; +#if ENABLE_WEATHER_KEY_MANAGE + g_settings.weather_api_key = configfile.getString("weather_api_key", g_settings.weather_api_key.empty() ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : g_settings.weather_api_key); +#endif + g_settings.weather_enabled = configfile.getInt32("weather_enabled", 1); + g_settings.weather_enabled = g_settings.weather_enabled && CApiKey::check_weather_api_key(); + + g_settings.weather_location = configfile.getString("weather_location", "52.52,13.40" ); + g_settings.weather_city = configfile.getString("weather_city", "Berlin" ); + ///youtube g_settings.youtube_dev_id = YT_DEV_KEY; #if ENABLE_YOUTUBE_KEY_MANAGE - g_settings.youtube_dev_id = configfile.getString("youtube_dev_id", g_settings.youtube_dev_id .empty() ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : g_settings.youtube_dev_id); + g_settings.youtube_dev_id = configfile.getString("youtube_dev_id", g_settings.youtube_dev_id.empty() ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : g_settings.youtube_dev_id); #endif g_settings.youtube_enabled = configfile.getInt32("youtube_enabled", 1); g_settings.youtube_enabled = g_settings.youtube_enabled && CApiKey::check_youtube_dev_id(); @@ -1811,6 +1823,14 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32( "movieplayer_timeosd_while_searching", g_settings.movieplayer_timeosd_while_searching ); //online services +#if ENABLE_WEATHER_KEY_MANAGE + configfile.setString( "weather_api_key", g_settings.weather_api_key ); +#endif + configfile.setInt32( "weather_enabled", g_settings.weather_enabled ); + + configfile.setString( "weather_location", g_settings.weather_location ); + configfile.setString( "weather_city", g_settings.weather_city ); + #if ENABLE_YOUTUBE_KEY_MANAGE configfile.setString( "youtube_dev_id", g_settings.youtube_dev_id ); #endif @@ -2873,6 +2893,8 @@ TIMER_START(); CFileHelpers::createDir(WEBTVDIR_VAR); CFileHelpers::createDir(PUBLIC_HTTPDDIR); + CWeather::getInstance()->setCoords(g_settings.weather_location, g_settings.weather_city); + TIMER_STOP("################################## after all ##################################"); if (g_settings.softupdate_autocheck) { #if 0 diff --git a/src/system/locals.h b/src/system/locals.h index fd3aa6457..ec545d7dd 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1759,6 +1759,9 @@ typedef enum LOCALE_MENU_HINT_VOLUME_DIGITS, LOCALE_MENU_HINT_VOLUME_POS, LOCALE_MENU_HINT_VOLUME_SIZE, + LOCALE_MENU_HINT_WEATHER_API_KEY, + LOCALE_MENU_HINT_WEATHER_ENABLED, + LOCALE_MENU_HINT_WEATHER_LOCATION, LOCALE_MENU_HINT_WEBRADIO_SETUP, LOCALE_MENU_HINT_WEBRADIO_XML_AUTO, LOCALE_MENU_HINT_WEBTV_SETUP, @@ -2854,6 +2857,9 @@ typedef enum LOCALE_VIDEOMENU_VIDEOFORMAT_169, LOCALE_VIDEOMENU_VIDEOFORMAT_43, LOCALE_VIDEOMENU_VIDEOMODE, + LOCALE_WEATHER_API_KEY, + LOCALE_WEATHER_ENABLED, + LOCALE_WEATHER_LOCATION, LOCALE_WEBRADIO_HEAD, LOCALE_WEBRADIO_XML, LOCALE_WEBRADIO_XML_AUTO, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 17f0eee9b..ab1b02c61 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1759,6 +1759,9 @@ const char * locale_real_names[] = "menu.hint_volume_digits", "menu.hint_volume_pos", "menu.hint_volume_size", + "menu.hint_weather_api_key", + "menu.hint_weather_enabled", + "menu.hint_weather_location", "menu.hint_webradio_setup", "menu.hint_webradio_xml_auto", "menu.hint_webtv_setup", @@ -2854,6 +2857,9 @@ const char * locale_real_names[] = "videomenu.videoformat_169", "videomenu.videoformat_43", "videomenu.videomode", + "weather.api_key", + "weather.enabled", + "weather.location", "webradio.head", "webradio.xml", "webradio.xml.auto", diff --git a/src/system/setting_helpers.h b/src/system/setting_helpers.h index a14cbf092..3d7794105 100644 --- a/src/system/setting_helpers.h +++ b/src/system/setting_helpers.h @@ -167,6 +167,7 @@ class CApiKey } static int check_shoutcast_dev_id() { return CApiKey::check_api_key(g_settings.shoutcast_dev_id, "XXXXXXXXXXXXXXXX"); } static int check_youtube_dev_id() { return CApiKey::check_api_key(g_settings.youtube_dev_id, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } + static int check_weather_api_key() { return CApiKey::check_api_key(g_settings.weather_api_key, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } static int check_tmdb_api_key() { return CApiKey::check_api_key(g_settings.tmdb_api_key, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } static int check_omdb_api_key() { return CApiKey::check_api_key(g_settings.omdb_api_key, "XXXXXXXX"); } }; diff --git a/src/system/settings.h b/src/system/settings.h index 579a74068..11de45eb6 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -852,6 +852,10 @@ struct SNeutrinoSettings int movieplayer_timeosd_while_searching; //online services + std::string weather_api_key; + int weather_enabled; + std::string weather_location; + std::string weather_city; std::string youtube_dev_id; int youtube_enabled; std::string tmdb_api_key;