diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 00d20b221..f87c2006e 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -2355,6 +2355,7 @@ timerlist.type.execplugin Plugin ausführen timerlist.type.nextprogram Nächstes Programm timerlist.type.record Aufnahme timerlist.type.remind Erinnerung +timerlist.type.remotebox Remote-Aufnahme timerlist.type.shutdown Shutdown timerlist.type.sleeptimer Sleeptimer timerlist.type.standby Standby diff --git a/data/locale/english.locale b/data/locale/english.locale index 3c0a9f71b..a599cea3c 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -2355,6 +2355,7 @@ timerlist.type.execplugin Execute plugin timerlist.type.nextprogram Next program timerlist.type.record Record timerlist.type.remind Reminder +timerlist.type.remotebox Remote-Record timerlist.type.shutdown Shutdown timerlist.type.sleeptimer Sleeptimer timerlist.type.standby Standby diff --git a/lib/timerdclient/timerdtypes.h b/lib/timerdclient/timerdtypes.h index 4e0c5001f..39481b97f 100644 --- a/lib/timerdclient/timerdtypes.h +++ b/lib/timerdclient/timerdtypes.h @@ -68,7 +68,8 @@ class CTimerd TIMER_REMIND, TIMER_SLEEPTIMER, TIMER_EXEC_PLUGIN, - TIMER_IMMEDIATE_RECORD + TIMER_IMMEDIATE_RECORD, + TIMER_REMOTEBOX }; enum CTimerEventStates diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index 8ba90569f..dc8966629 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -67,6 +67,9 @@ #include #include #include +#include + +#include #include #include @@ -249,6 +252,15 @@ public: } }; +std::string string_printf_helper(const char *fmt, ...) { + va_list arglist; + const int bufferlen = 4*1024; + char buffer[bufferlen] = {0}; + va_start(arglist, fmt); + vsnprintf(buffer, bufferlen, fmt, arglist); + va_end(arglist); + return std::string(buffer); +} CTimerList::CTimerList() { @@ -297,6 +309,23 @@ int CTimerList::exec(CMenuTarget* parent, const std::string & actionKey) timerlist[selected].alarmTime, timerlist[selected].stopTime, timerlist[selected].eventRepeat, timerlist[selected].repeatCount,timerlist[selected].recordingDir); + } else if (timerlist[selected].eventType == CTimerd::TIMER_REMOTEBOX) + { + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?action=new&update=1"; + r_url += "&alarm=" + to_string((int)timerlist[selected].alarmTime); + r_url += "&stop=" + to_string((int)timerlist[selected].stopTime); + r_url += "&announce=" + to_string((int)timerlist[selected].announceTime); + r_url += "&channel_id=" + string_printf_helper(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, timerlist[selected].channel_id); + r_url += "&aj=on"; + r_url += "&rs=on"; + r_url += "&id=" + to_string((int)timerlist[selected].eventID); + //printf("[remotetimer] url:%s\n",r_url.c_str()); + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] status:%s\n",r_url.c_str()); } else { Timer->modifyTimerEvent(timerlist[selected].eventID, timerlist[selected].announceTime, @@ -306,6 +335,71 @@ int CTimerList::exec(CMenuTarget* parent, const std::string & actionKey) } return menu_return::RETURN_EXIT; } + else if (strcmp(key, "send_remotetimer") == 0) + { + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?action=new"; + r_url += "&alarm=" + to_string((int)timerlist[selected].alarmTime); + r_url += "&stop=" + to_string((int)timerlist[selected].stopTime); + r_url += "&announce=" + to_string((int)timerlist[selected].announceTime); + r_url += "&channel_id=" + string_printf_helper(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, timerlist[selected].channel_id); + r_url += "&aj=on"; + r_url += "&rs=on"; + //printf("[remotetimer] url:%s\n",r_url.c_str()); + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] status:%s\n",r_url.c_str()); + if (r_url=="ok") + Timer->removeTimerEvent(timerlist[selected].eventID); + } + else if (strcmp(key, "fetch_remotetimer") == 0) + { + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?action=remove"; + r_url += "&id=" + to_string((int)timerlist[selected].eventID); + //printf("[remotetimer] url:%s\n",r_url.c_str()); + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] status:%s\n",r_url.c_str()); + if (r_url=="ok") { + Timer->addRecordTimerEvent(timerlist[selected].channel_id, timerlist[selected].alarmTime, + timerlist[selected].stopTime, 0, 0, timerlist[selected].announceTime, + TIMERD_APIDS_CONF, true, timerlist[selected].announceTime > time(NULL)); + } + } + else if (strcmp(key, "del_remotetimer") == 0) + { + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?action=remove"; + r_url += "&id=" + to_string((int)timerlist[selected].eventID); + //printf("[remotetimer] url:%s\n",r_url.c_str()); + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] status:%s\n",r_url.c_str()); + } + else if (strcmp(key, "update_remotetimer") == 0) + { + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?action=new&update=1"; + r_url += "&alarm=" + to_string((int)timerlist[selected].alarmTime); + r_url += "&stop=" + to_string((int)timerlist[selected].stopTime); + r_url += "&announce=" + to_string((int)timerlist[selected].announceTime); + r_url += "&channel_id=" + string_printf_helper(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, timerlist[selected].channel_id); + r_url += "&aj=on"; + r_url += "&rs=on"; + //printf("[remotetimer] url:%s\n",r_url.c_str()); + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] status:%s\n",r_url.c_str()); + } else if (strcmp(key, "newtimer") == 0) { timerNew.announceTime=timerNew.alarmTime-60; @@ -429,20 +523,22 @@ int CTimerList::exec(CMenuTarget* parent, const std::string & actionKey) }*/ } -#define TimerListButtonsCount 5 +#define TimerListButtonsCount 6 struct button_label TimerListButtons[TimerListButtonsCount] = { { NEUTRINO_ICON_BUTTON_RED , LOCALE_TIMERLIST_DELETE }, { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_TIMERLIST_NEW }, { NEUTRINO_ICON_BUTTON_YELLOW , LOCALE_TIMERLIST_RELOAD }, { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_TIMERLIST_MODIFY }, - { NEUTRINO_ICON_BUTTON_INFO_SMALL, NONEXISTANT_LOCALE } + { NEUTRINO_ICON_BUTTON_INFO_SMALL, NONEXISTANT_LOCALE }, + { NEUTRINO_ICON_BUTTON_MENU_SMALL, NONEXISTANT_LOCALE } }; void CTimerList::updateEvents(void) { timerlist.clear(); Timer->getTimerList (timerlist); + remoteTimerList (timerlist); sort(timerlist.begin(), timerlist.end()); theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); @@ -472,6 +568,55 @@ void CTimerList::updateEvents(void) y = getScreenStartY(height); } +void CTimerList::remoteTimerList(CTimerd::TimerList &rtimerlist) +{ + if (g_settings.remotebox_address.empty()) + return; + CHTTPTool httpTool; + std::string r_url; + r_url = "http://"; + r_url += g_settings.remotebox_address; + r_url += "/control/timer?format=json"; + r_url = httpTool.downloadString(r_url); + //printf("[remotetimer] timers:%s\n",r_url.c_str()); + + Json::Value root; + Json::Reader reader; + bool parsedSuccess = reader.parse(r_url, root, false); + if (!parsedSuccess) { + printf("Failed to parse JSON\n"); + printf("%s\n", reader.getFormattedErrorMessages().c_str()); + } + + Json::Value remotetimers = root["data"]["timer"][0]["timer_list"]; + + for (unsigned int i= 0; iremoveTimerEvent(timerlist[selected].eventID); update = true; } @@ -589,6 +757,13 @@ int CTimerList::show() else update=true; } + else if (msg==CRCInput::RC_setup) + { + hide(); + enterRemoteBox(); + update=true; + paint(); + } else if (msg==CRCInput::RC_yellow) { update=true; @@ -612,7 +787,7 @@ int CTimerList::show() CTimerd::responseGetTimer* timer=&timerlist[selected]; if (timer!=NULL) { - if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_ZAPTO) + if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_REMOTEBOX || timer->eventType == CTimerd::TIMER_ZAPTO) { hide(); if (timer->epgID != 0) @@ -655,6 +830,15 @@ void CTimerList::hide() } } +void CTimerList::enterRemoteBox() +{ + CMenuWidget* remboxmenu = new CMenuWidget(LOCALE_MAINSETTINGS_HEAD, NEUTRINO_ICON_SETTINGS, 40, MN_WIDGET_ID_NETWORKSETUP); + CIPInput remotebox_NetworkIP(LOCALE_NETWORKMENU_IPADDRESS , &g_settings.remotebox_address); + CMenuForwarder *m1 = new CMenuForwarder(LOCALE_NETWORKMENU_IPADDRESS , true, g_settings.remotebox_address , &remotebox_NetworkIP ); + remboxmenu->addItem( m1); + remboxmenu->exec(NULL, ""); +} + void CTimerList::paintItem(int pos) { int ypos = y+ theight+ pos*fheight*2; @@ -736,6 +920,7 @@ void CTimerList::paintItem(int pos) //case CTimerd::TIMER_NEXTPROGRAM : case CTimerd::TIMER_ZAPTO : case CTimerd::TIMER_RECORD : + case CTimerd::TIMER_REMOTEBOX : { zAddData = convertChannelId2String(timer.channel_id); // UTF-8 if (timer.apids != TIMERD_APIDS_CONF) @@ -848,7 +1033,7 @@ void CTimerList::paintFoot() if (timer != NULL) { //replace info button with dummy if timer is not type REC or ZAP - if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_ZAPTO) + if (timer->eventType == CTimerd::TIMER_RECORD || timer->eventType == CTimerd::TIMER_REMOTEBOX || timer->eventType == CTimerd::TIMER_ZAPTO) TimerListButtons[4].button = NEUTRINO_ICON_BUTTON_INFO_SMALL; else TimerListButtons[4].button = NEUTRINO_ICON_BUTTON_DUMMY_SMALL; @@ -914,6 +1099,8 @@ const char * CTimerList::convertTimerType2String(const CTimerd::CTimerEventTypes return g_Locale->getText(LOCALE_TIMERLIST_TYPE_SLEEPTIMER ); case CTimerd::TIMER_EXEC_PLUGIN : return g_Locale->getText(LOCALE_TIMERLIST_TYPE_EXECPLUGIN ); + case CTimerd::TIMER_REMOTEBOX : + return g_Locale->getText(LOCALE_TIMERLIST_TYPE_REMOTEBOX ); default : return g_Locale->getText(LOCALE_TIMERLIST_TYPE_UNKNOWN ); } diff --git a/src/gui/timerlist.h b/src/gui/timerlist.h index 6ca937ecb..65494d813 100644 --- a/src/gui/timerlist.h +++ b/src/gui/timerlist.h @@ -85,6 +85,8 @@ class CTimerList : public CMenuTarget, public CListHelpers int newTimer(); /* todo: properly import the enum CVFD::MODES */ int saved_dispmode; + void remoteTimerList(CTimerd::TimerList &timerlist); + void enterRemoteBox(); public: CTimerList(); diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 4b85e0928..9a4f346e0 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -458,6 +458,8 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.shutdown_min = configfile.getInt32("shutdown_min", 180); g_settings.sleeptimer_min = configfile.getInt32("sleeptimer_min", 0); + g_settings.remotebox_address = configfile.getString("timer_remotebox", ""); + g_settings.infobar_sat_display = configfile.getBool("infobar_sat_display" , true ); g_settings.infobar_show_channeldesc = configfile.getBool("infobar_show_channeldesc" , false ); g_settings.infobar_subchan_disp_pos = configfile.getInt32("infobar_subchan_disp_pos" , 0 ); @@ -1043,6 +1045,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("shutdown_count" , g_settings.shutdown_count); configfile.setInt32("shutdown_min" , g_settings.shutdown_min ); configfile.setInt32("sleeptimer_min", g_settings.sleeptimer_min); + configfile.setString("timer_remotebox", g_settings.remotebox_address); configfile.setBool("infobar_sat_display" , g_settings.infobar_sat_display ); configfile.setBool("infobar_show_channeldesc" , g_settings.infobar_show_channeldesc ); configfile.setInt32("infobar_subchan_disp_pos" , g_settings.infobar_subchan_disp_pos ); diff --git a/src/system/httptool.cpp b/src/system/httptool.cpp index 8f89db96f..9f8aca4a4 100644 --- a/src/system/httptool.cpp +++ b/src/system/httptool.cpp @@ -41,6 +41,14 @@ void CHTTPTool::setStatusViewer( CProgressWindow* statusview ) statusViewer = statusview; } +size_t CHTTPTool::CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data) +{ + if (size * nmemb > 0) { + std::string* pStr = (std::string*) data; + pStr->append((char*) ptr, nmemb); + } + return size*nmemb; +} int CHTTPTool::show_progress( void *clientp, double dltotal, double dlnow, double /*ultotal*/, double /*ulnow*/ ) { @@ -127,3 +135,62 @@ printf("download code %d\n", res); return res==CURLE_OK; } + +std::string CHTTPTool::downloadString(const std::string & URL, int globalProgressEnd) +{ + CURL *curl; + CURLcode res; + std::string retString = ""; +#ifdef DEBUG +printf("url is %s\n", URL.c_str()); +#endif + res = (CURLcode) 1; + curl = curl_easy_init(); + if(curl) + { + iGlobalProgressEnd = globalProgressEnd; + if(statusViewer) + { + iGlobalProgressBegin = statusViewer->getGlobalStatus(); + } + curl_easy_setopt(curl, CURLOPT_URL, URL.c_str() ); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CHTTPTool::CurlWriteToString); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&retString); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str()); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1800); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); +#ifdef DEBUG + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); +#endif + + if (!g_settings.softupdate_proxyserver.empty()) {//use proxyserver +#ifdef DEBUG +printf("use proxyserver : %s\n", g_settings.softupdate_proxyserver.c_str()); +#endif + curl_easy_setopt(curl, CURLOPT_PROXY, g_settings.softupdate_proxyserver.c_str()); + + if (!g_settings.softupdate_proxyusername.empty()) {//use auth + //printf("use proxyauth\n"); + std::string tmp = g_settings.softupdate_proxyusername; + tmp += ":"; + tmp += g_settings.softupdate_proxypassword; + curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, tmp.c_str()); + } + } +#ifdef DEBUG +printf("going to download\n"); +#endif + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + } +#ifdef DEBUG +printf("download code %d\n", res); +#endif + return (res==CURLE_OK) ? retString : ""; +} diff --git a/src/system/httptool.h b/src/system/httptool.h index c0b3f487f..93a5f43c3 100644 --- a/src/system/httptool.h +++ b/src/system/httptool.h @@ -46,12 +46,14 @@ class CHTTPTool CProgressWindow* statusViewer; static int show_progress( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); + static size_t CurlWriteToString(void *ptr, size_t size, size_t nmemb, void *data); public: CHTTPTool(); void setStatusViewer( CProgressWindow* statusview ); bool downloadFile( const std::string & URL, const char * const downloadTarget, int globalProgressEnd=-1 ); + std::string downloadString(const std::string & URL, int globalProgressEnd=-1 ); }; diff --git a/src/system/locals.h b/src/system/locals.h index 1def8f162..1d7b43b3a 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -2382,6 +2382,7 @@ typedef enum LOCALE_TIMERLIST_TYPE_NEXTPROGRAM, LOCALE_TIMERLIST_TYPE_RECORD, LOCALE_TIMERLIST_TYPE_REMIND, + LOCALE_TIMERLIST_TYPE_REMOTEBOX, LOCALE_TIMERLIST_TYPE_SHUTDOWN, LOCALE_TIMERLIST_TYPE_SLEEPTIMER, LOCALE_TIMERLIST_TYPE_STANDBY, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 62c654dab..f8bfb6dec 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -2382,6 +2382,7 @@ const char * locale_real_names[] = "timerlist.type.nextprogram", "timerlist.type.record", "timerlist.type.remind", + "timerlist.type.remotebox", "timerlist.type.shutdown", "timerlist.type.sleeptimer", "timerlist.type.standby", diff --git a/src/system/settings.h b/src/system/settings.h index 3128c4c16..87e7504b4 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -450,6 +450,7 @@ struct SNeutrinoSettings int recording_slow_warning; int recording_startstop_msg; int shutdown_timer_record_type; + std::string remotebox_address; std::string recording_filename_template; int recording_already_found_check;