diff options
-rw-r--r-- | pages/edit_timer.ecpp | 33 | ||||
-rw-r--r-- | timers.cpp | 93 | ||||
-rw-r--r-- | timers.h | 17 |
3 files changed, 138 insertions, 5 deletions
diff --git a/pages/edit_timer.ecpp b/pages/edit_timer.ecpp index 2630914..f093c99 100644 --- a/pages/edit_timer.ecpp +++ b/pages/edit_timer.ecpp @@ -1,4 +1,5 @@ <%pre> +#include <sstream> #include <vdr/plugin.h> #include <vdr/config.h> #include <vdr/i18n.h> @@ -6,11 +7,13 @@ #include "tools.h" #include "timers.h" +using namespace std; using namespace vdrlive; </%pre> <%args> timerid; +bool submit = false; bool active = true; channel = ""; title = ""; @@ -29,8 +32,9 @@ int end_m = StringToInt( FormatDateTime( "%M", time( 0 ) ) ); bool vps = ::Setup.UseVps; int priority = ::Setup.DefaultPriority; int lifetime = ::Setup.DefaultLifetime; +aux = ""; </%args> -<{ +<%cpp> ReadLock channelsLock( Channels ); if (!channelsLock) return DECLINED; // XXX error page @@ -48,7 +52,7 @@ int lifetime = ::Setup.DefaultLifetime; if ( request.getMethod() != "POST" && timer != 0 ) { active = timer->Flags() & tfActive; channel = *timer->Channel()->GetChannelID().ToString(); - title = timer->File(); + title = timer->File() ? timer->File() : ""; day = timer->Day() ? FormatDateTime( "%d", timer->Day() ) : ""; wday_mon = timer->WeekDays() & 0x01; wday_tue = timer->WeekDays() & 0x02; @@ -64,8 +68,28 @@ int lifetime = ::Setup.DefaultLifetime; vps = timer->Flags() & tfVps; priority = timer->Priority(); lifetime = timer->Lifetime(); + aux = timer->Aux() ? timer->Aux() : ""; } -}> + + std::string result; + if ( submit ) { + uint flags = ( active ? tfActive : 0 ) | ( vps ? tfVps : 0 ); + string weekdays = string( wday_mon ? "M" : "-" ) + ( wday_tue ? "T" : "-" ) + ( wday_wed ? "W" : "-" ) + + ( wday_thu ? "T" : "-" ) + ( wday_fri ? "F" : "-" ) + ( wday_sat ? "S" : "-" ) + + ( wday_sun ? "S" : "-" ); + //( wday_mon ? 0x01 : 0 ) | ( wday_tue ? 0x02 : 0 ) | ( wday_wed ? 0x04 : 0 ) | + //( wday_thu ? 0x08 : 0 ) | ( wday_fri ? 0x10 : 0 ) | ( wday_sat ? 0x20 : 0 ) | + //( wday_sun ? 0x40 : 0 ); + ostringstream builder; + builder << flags << ":" << channel << ":" << ( weekdays != "-------" ? weekdays : "" ) + << ( weekdays == "-------" || day.empty() ? "" : "@" ) << day << ":" << ( start_h * 100 + start_m ) + << ":" << ( end_h * 100 + end_m ) << ":" << priority << ":" << lifetime << ":" << title << ":" << aux; + + std::string error = LiveTimerManager().UpdateTimer( timer, builder.str() ); + if ( !error.empty() ) + reply.out() << error; + } +</%cpp> <html> <head> <title>VDR Live - <$ timer ? tr("Edit timer") : tr("New timer") $></title> @@ -80,6 +104,7 @@ int lifetime = ::Setup.DefaultLifetime; <div class="head_box"><$ timer ? tr("Edit timer") : tr("New timer") $></div> <form method="POST" name="edit_timer"> <input type="hidden" name="timerid" value="<$ timerid $>"/> + <input type="hidden" name="aux" value="<$ aux $>"/> <table> <tr> <td>Timer aktiv: </td> @@ -147,7 +172,7 @@ int lifetime = ::Setup.DefaultLifetime; </tr> <tr> - <td class="buttonpanel" colspan="2"><button type="submit"><$ tr("Save") $></button></td> + <td class="buttonpanel" colspan="2"><button name="submit" type="submit" value="1"><$ tr("Save") $></button></td> </tr> </table> </form> @@ -1,3 +1,4 @@ +#include <memory> #include <sstream> #include <vector> #include "timers.h" @@ -64,7 +65,7 @@ void SortedTimers::ReloadTimers( bool initial ) if ( !Timers.Modified( m_state ) && !initial ) return; - dsyslog("reloading timers"); + dsyslog("live reloading timers"); clear(); for ( cTimer* timer = Timers.First(); timer != 0; timer = Timers.Next( timer ) ) { @@ -77,12 +78,102 @@ TimerManager::TimerManager() { } +string TimerManager::UpdateTimer( cTimer* timer, std::string const& timerString ) +{ + TimerPair timerData( timer, timerString ); + + dsyslog("SV: in UpdateTimer"); + m_updateTimers.push_back( timerData ); + dsyslog("SV: wait for update"); + m_updateWait.Wait( *this ); + dsyslog("SV: update done"); + return GetError( timerData ); +} + void TimerManager::DoPendingWork() { cMutexLock lock( this ); + if ( m_updateTimers.size() > 0 ) + DoUpdateTimers(); m_timers.ReloadTimers(); } +void TimerManager::DoUpdateTimers() +{ + dsyslog("SV: updating timers"); + for ( TimerList::iterator timer = m_updateTimers.begin(); timer != m_updateTimers.end(); ++timer ) { + if ( timer->first == 0 ) // new timer + DoInsertTimer( *timer ); + else if ( timer->second == "" ) // delete timer + ; // XXX + else // update timer + DoUpdateTimer( *timer ); + } + m_updateTimers.clear(); + dsyslog("SV: signalling waiters"); + m_updateWait.Broadcast(); +} + +void TimerManager::DoInsertTimer( TimerPair& timerData ) +{ + auto_ptr< cTimer > newTimer( new cTimer ); + if ( !newTimer->Parse( timerData.second.c_str() ) ) { + StoreError( timerData, tr("Error in timer settings") ); + return; + } + + cTimer* checkTimer = Timers.GetTimer( newTimer.get() ); + if ( checkTimer != 0 ) { + StoreError( timerData, tr("Timer already defined") ); + return; + } + + Timers.Add( newTimer.release() ); + Timers.SetModified(); + isyslog( "live timer %s added", *newTimer->ToDescr() ); +} + +void TimerManager::DoUpdateTimer( TimerPair& timerData ) +{ + if ( Timers.BeingEdited() ) { + StoreError( timerData, tr("Timers are being edited - try again later") ); + return; + } + + cTimer* oldTimer = Timers.GetTimer( timerData.first ); + if ( oldTimer == 0 ) { + StoreError( timerData, tr("Timer not defined") ); + return; + } + + cTimer copy = *oldTimer; + if ( !copy.Parse( timerData.second.c_str() ) ) { + StoreError( timerData, tr("Error in timer settings") ); + return; + } + + *oldTimer = copy; + Timers.SetModified(); + isyslog("live timer %s modified (%s)", *oldTimer->ToDescr(), oldTimer->HasFlags(tfActive) ? "active" : "inactive"); +} + +void TimerManager::StoreError( TimerPair const& timerData, std::string const& error ) +{ + m_failedUpdates.push_back( ErrorPair( timerData, error ) ); +} + +string TimerManager::GetError( TimerPair const& timerData ) +{ + for ( ErrorList::iterator error = m_failedUpdates.begin(); error != m_failedUpdates.end(); ++error ) { + if ( error->first == timerData ) { + string message = error->second; + m_failedUpdates.erase( error ); + return message; + } + } + return ""; +} + TimerManager& LiveTimerManager() { static TimerManager instance; @@ -33,14 +33,31 @@ class TimerManager: public cMutex public: SortedTimers& GetTimers() { return m_timers; } + std::string UpdateTimer( cTimer* timer, std::string const& timerString ); + // may only be called from Plugin::MainThreadHook void DoPendingWork(); private: + typedef std::pair< cTimer*, std::string > TimerPair; + typedef std::pair< TimerPair, std::string > ErrorPair; + typedef std::list< TimerPair > TimerList; + typedef std::list< ErrorPair > ErrorList; + TimerManager(); TimerManager( TimerManager const& ); SortedTimers m_timers; + TimerList m_updateTimers; + ErrorList m_failedUpdates; + cCondVar m_updateWait; + + void DoUpdateTimers(); + void DoInsertTimer( TimerPair& timerData ); + void DoUpdateTimer( TimerPair& timerData ); + + void StoreError( TimerPair const& timerData, std::string const& error ); + std::string GetError( TimerPair const& timerData ); }; TimerManager& LiveTimerManager(); |