From b091b77794ba673ef186f989bf5ae870a8b6b3f0 Mon Sep 17 00:00:00 2001 From: TangoCash Date: Wed, 20 Mar 2019 15:27:14 +0100 Subject: [PATCH] add weather via Dark Sky API -step1- Origin commit data ------------------ Branch: ni/coolstream Commit: https://github.com/neutrino-images/ni-neutrino/commit/ed4d4e0c46fc3b5582e02e697ad48d3d29376e0f Author: TangoCash Date: 2019-03-20 (Wed, 20 Mar 2019) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- acinclude.m4 | 17 ++ configure.ac | 1 + data/icons/Makefile.am | 3 +- data/icons/weather/Makefile.am | 14 + data/icons/weather/clear-day.png | Bin 0 -> 15373 bytes data/icons/weather/clear-night.png | Bin 0 -> 15644 bytes data/icons/weather/cloudy.png | Bin 0 -> 15336 bytes data/icons/weather/fog.png | Bin 0 -> 15325 bytes data/icons/weather/partly-cloudy-day.png | Bin 0 -> 15642 bytes data/icons/weather/partly-cloudy-night.png | Bin 0 -> 15874 bytes data/icons/weather/rain.png | Bin 0 -> 15723 bytes data/icons/weather/sleet.png | Bin 0 -> 15725 bytes data/icons/weather/snow.png | Bin 0 -> 15431 bytes data/icons/weather/unknown.png | Bin 0 -> 15486 bytes data/icons/weather/wind.png | Bin 0 -> 539 bytes data/locale/deutsch.locale | 8 +- data/locale/english.locale | 8 +- src/driver/lcd4l.cpp | 26 +- src/driver/lcd4l.h | 5 +- src/gui/Makefile.am | 1 + src/gui/miscsettings_menu.cpp | 69 +++++ src/gui/miscsettings_menu.h | 3 + src/gui/weather.cpp | 193 ++++++++++++++ src/gui/weather.h | 78 ++++++ src/gui/weather_locations.h | 294 +++++++++++++++++++++ src/neutrino.cpp | 24 +- src/system/locals.h | 6 + src/system/locals_intern.h | 6 + src/system/setting_helpers.h | 1 + src/system/settings.h | 4 + 30 files changed, 755 insertions(+), 6 deletions(-) create mode 100644 data/icons/weather/Makefile.am create mode 100644 data/icons/weather/clear-day.png create mode 100644 data/icons/weather/clear-night.png create mode 100644 data/icons/weather/cloudy.png create mode 100644 data/icons/weather/fog.png create mode 100644 data/icons/weather/partly-cloudy-day.png create mode 100644 data/icons/weather/partly-cloudy-night.png create mode 100644 data/icons/weather/rain.png create mode 100644 data/icons/weather/sleet.png create mode 100644 data/icons/weather/snow.png create mode 100644 data/icons/weather/unknown.png create mode 100644 data/icons/weather/wind.png create mode 100644 src/gui/weather.cpp create mode 100644 src/gui/weather.h create mode 100644 src/gui/weather_locations.h 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 0000000000000000000000000000000000000000..d8aedc46e28b4de31bdffd5596f5e9b2aa55a0fb GIT binary patch literal 15373 zcmeI3dsGuw9>;GKq{iX{Ur;%cjkSx`WRgID%!Y^%5RL{BBSO`hVKNDG%*$jV3Dy-s zj?W%lU9DRm)#AEa9}BuYE7mHoN^y@?y6t+T6cuF^izvEfdvK|`Gf51W08ZP}KPTse z`El>}`}^Jb+(+i0*_f3%JCy$#9{>=Vk*?0BuSv}Jm0|SXBjk!3^kuj$J)xQ95Rt5uv~% zp_V5KXE6l@xtc6Niq%dC2$;NBzST)33WZD||HpSt4Uvi^$Ur7N z?)TW7c9UmldK@84gqg5V4%#Oj&}S>KQdUQSb&!(&?m-LFbE47sYY#YHvw6VM4k~pe zjlhR=K&M0Nwh>4+;jlXGIFY)NzLhBh-91GbdMBq(CZ=c5u@f$G5F69uwRx6;cZQVo zy`m|00;8;Ut<`E$c~@E13xtA{6lPV$3!*g`PFfhQ)09Y{sdvVE^AT!{B2iYYok?I4I156B%k1 z-5@4OJ!+7|$mDW)f(VZ_#EN3$6XYTVZqSPi`LUQxL1UH3^d5*B4Q%h1T5ZLh%zp8u z*8jxRkiB2(d3KUM>o60fVMhN`OAL^vU#WD`L9b9Zv~ub7>p9I95G(q&zUVNKo>R$& z*&PJ4=Msf4Hl6<%^Pf_T$Fp})3}? zFWXSwR36pfNgP%KRfyS%Sw?zI{J7oj&D+-)SU`y|zW^q(?^JkO`_9mdHQRqimCV70 z(yM_U8RnSNSVJrE8HDu&3m~O?hdr}Iu}|V|`dJ0>KdkhfWdBz9g@fKZ`h^q2>9`^=4c3^$#fk_PaJXO^tTBg+ z6%j1paKSWKV-6Q9B3QuTf@!eE94=Nwuz;u%;9211PeG^Fb&q2!^MgS7I3&=8muvgixm+p;Bdh-SYr+sDxL6Uv0uC2UgEi)Gu_A&694?p!Ys}$d zMFa~tTrdsRn8U@22o`X-U>dA3hl>>vEZ}g#G+1K}7b_xIz~O>vu*NUN#qWLnkFe11 z{1wtK_iae)+C;w?D8SRRH2@S%1)#VTfG5xC>$d=SR06=#GFwwewSzQ_cLziW! zXK7tc9ZmBtY8QsrKW^AIe&gBTzkO79RCKv4=g`y%f6fx|w`7eImQN6AE0g~5MQWL4 z-1xFZhf12%sagLzoLV9(x~_gME&F1$>EO20lIYhrlaKeWJx>^RuWGwdc-P*rc5U00 zX2;#Vor(tcZ`)3vx@tKkKmBo7agczQ4tg&-{T=t-x@(%C%E+6}|9z9dot;wupM6(4#vVt96pV_fsIE<^eKvYedyrt{V&jRbpbf`S z-Uef5+z)w``yM1LsVPevdEol&5#!AF7at3k7w>eTpe#=nhq>f)dP96T>SiRB7+qSdz_^*uBE0d!q$v0hiw6ZSZ zaGoOcvo(*V>73b(Pnj?Gb*kzFJaoz6W;%cQ%s*so zL>^>!#y&iL5?{z`933|48`<_QjVYq?UCr-4eps+M21}hW$p}`ofAU_ZC4NWe;yroo zQDwHTMLQzr-25^p?Q3w--Sf0@=|A7j=C70SE^Iv-Ep=X>J@M7hgEPS6J(JyAYZe%? z+h&hQ4sSm;e?sxq?jtoVtzX?q9Jc0UWJ+VnsrtI$yKNnFKRt10b*f?H!(E*#ez-^_ zRcya8nna6BT~izPQE!!l3#)2MyU&r}4V&tnoGl*?{dVcCzDxS>uIC|O!V~wlr2S(K Q(AyGZq-LuBlB_HFKjCRc4FCWD literal 0 HcmV?d00001 diff --git a/data/icons/weather/clear-night.png b/data/icons/weather/clear-night.png new file mode 100644 index 0000000000000000000000000000000000000000..837f94eb217dfa2c984538a7051ea42d6a547a9c GIT binary patch literal 15644 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 WdnfVk>u|G0#{yyj+tgy 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 Q*jIgXGIKSpbM*E91NPEAX8-^I literal 0 HcmV?d00001 diff --git a/data/icons/weather/unknown.png b/data/icons/weather/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa32c1f59b421c15487cc3662ca7929d17e9 GIT binary patch literal 15486 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 S`Q8VNMg~t;KbLh*2~7Ztn(W>H literal 0 HcmV?d00001 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;