Skip to content

Commit

Permalink
Very basic repeating timer support through menu hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Glenn-1990 committed May 18, 2015
1 parent 86eb1cc commit c1e728f
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 6 deletions.
34 changes: 34 additions & 0 deletions pvr.hts/resources/language/English/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,37 @@ msgstr ""
msgctxt "#30201"
msgid "Trace (detailed)"
msgstr ""

#empty strings from id 30202 to 30249

msgctxt "#30250"
msgid "Record any time"
msgstr ""

msgctxt "#30251"
msgid "Record daily around this time"
msgstr ""

msgctxt "#30252"
msgid "Record weekly around this time"
msgstr ""

msgctxt "#30253"
msgid "Record any time on weekdays"
msgstr ""

msgctxt "#30254"
msgid "Record any time on weekends"
msgstr ""

msgctxt "#30255"
msgid "Delete the complete timer schedule"
msgstr ""

msgctxt "#30256"
msgid "Delete this timer only"
msgstr ""

msgctxt "#30257"
msgid "This show is already scheduled for recording"
msgstr ""
154 changes: 154 additions & 0 deletions src/Tvheadend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,160 @@ PVR_ERROR CTvheadend::GetEpg
return PVR_ERROR_NO_ERROR;
}

/* **************************************************************************
* Menu Hooks
* *************************************************************************/

PVR_ERROR CTvheadend::CallMenuHook(const PVR_MENUHOOK &menuhook, const PVR_MENUHOOK_DATA &item )
{
if (menuhook.category == PVR_MENUHOOK_EPG)
{
SEvent event;
if (GetEventFromId(item.data.iEpgUid, event))
{
/* Check if event is already scheduled for recording */
for (SRecordings::const_iterator it = m_recordings.begin(); it != m_recordings.end(); ++it)
{
if (it->second.eventId == event.id)
{
if (!it->second.autorecId.empty())
{
XBMC->QueueNotification(QUEUE_INFO, XBMC->GetLocalizedString(30257));
// 30257 = 'This show is already scheduled for recording'
return PVR_ERROR_NO_ERROR;
}
}
}

return AddAutoRecording(menuhook.iHookId, event);
}
else
return PVR_ERROR_SERVER_ERROR;
}
else if (menuhook.category == PVR_MENUHOOK_TIMER)
{
SRecording rec = m_recordings.at(item.data.timer.iClientIndex);

/* Delete complete schedule if possible */
if (menuhook.iHookId == TIMER_DELETESCHEDULE)
{
if (!rec.autorecId.empty())
return SendScheduleDelete(rec.autorecId, "deleteAutorecEntry");

if (!rec.timerecId.empty())
return SendScheduleDelete(rec.timerecId, "deleteTimerecEntry");
}

/* Delete timer */
if (menuhook.iHookId == TIMER_DELETEDVRENTRY ||
menuhook.iHookId == TIMER_DELETESCHEDULE)
{
return SendDvrDelete(item.data.timer.iClientIndex, "cancelDvrEntry");
}
}
return PVR_ERROR_NOT_IMPLEMENTED;
}

PVR_ERROR CTvheadend::AddAutoRecording( uint32_t typeId, const SEvent &event )
{
uint32_t u32, days_of_week;
int32_t approx_time;
dvr_prio_t prio;
struct tm *tmi;

/* Time conversion */
tmi=localtime(&event.start);
approx_time = (tmi->tm_hour*60)+(tmi->tm_min);
days_of_week = tmi->tm_wday > 0 ? (1<<(tmi->tm_wday-1)) : (1<<6);

/* Build message */
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_u32(m, "channelId", event.channel);
htsmsg_add_str(m, "title", event.title.c_str());
htsmsg_add_str(m, "name", event.title.c_str());
htsmsg_add_str(m, "comment", "Created by Kodi Media Center");

if (typeId == REC_EVERY_WEEK_THIS_TIME || typeId == REC_EVERY_DAY_THIS_TIME )
htsmsg_add_s32(m, "approxTime", approx_time >= 0 ? approx_time : -1);
if (typeId == REC_EVERYTIME || typeId == REC_EVERY_DAY_THIS_TIME)
htsmsg_add_u32(m, "daysOfWeek", 0x007F);
if (typeId == REC_WEEKENDS)
htsmsg_add_u32(m, "daysOfWeek", 0x0060);
if (typeId == REC_WEEKDAYS)
htsmsg_add_u32(m, "daysOfWeek", 0x001F);
if (typeId == REC_EVERY_WEEK_THIS_TIME)
htsmsg_add_u32(m, "daysOfWeek", days_of_week);

/* Send and Wait */
{
CLockObject lock(m_conn.Mutex());
m = m_conn.SendAndWait("addAutorecEntry", m);
}

if (m == NULL)
return PVR_ERROR_SERVER_ERROR;

/* Check for error */
if (htsmsg_get_u32(m, "success", &u32))
{
tvherror("failed to parse addDvrAutorecEntry response");
}

htsmsg_destroy(m);

return u32 > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_FAILED;
}

PVR_ERROR CTvheadend::SendScheduleDelete ( std::string id, const char *method )
{
uint32_t u32;

CLockObject lock(m_conn.Mutex());

/* Build message */
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "id", id.c_str());

/* Send and wait a bit longer than usual */
if ((m = m_conn.SendAndWait(method, m,
std::max(30000, m_settings.iResponseTimeout))) == NULL)
return PVR_ERROR_SERVER_ERROR;

/* Check for error */
if (htsmsg_get_u32(m, "success", &u32))
{
tvherror("malformed %s response: 'success' missing", method);
}
htsmsg_destroy(m);

return u32 > 0 ? PVR_ERROR_NO_ERROR : PVR_ERROR_FAILED;
}

bool CTvheadend::GetEventFromId ( uint32_t id, SEvent &evt )
{
uint32_t u32;
bool bReturn = false;

/* Build message */
htsmsg_t *msg = htsmsg_create_map();
htsmsg_add_u32(msg, "eventId", id);

/* Send and Wait */
{
CLockObject lock(m_conn.Mutex());

if ((msg = m_conn.SendAndWait("getEvent", msg)) != NULL)
bReturn = true;
}

if (bReturn)
bReturn = ParseEvent(msg, true, evt);

htsmsg_destroy(msg);

return bReturn;
}

/* **************************************************************************
* Connection
* *************************************************************************/
Expand Down
27 changes: 27 additions & 0 deletions src/Tvheadend.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ extern "C" {
#define UNNUMBERED_CHANNEL (10000)
#define INVALID_SEEKTIME (-1)

/*
* Recording types available through menu hooks
*/
#define REC_EVERYTIME 1
#define REC_EVERY_DAY_THIS_TIME 2
#define REC_EVERY_WEEK_THIS_TIME 3
#define REC_WEEKDAYS 4
#define REC_WEEKENDS 5

/*
* Timer options available through menu hooks
*/
#define TIMER_DELETESCHEDULE 6
#define TIMER_DELETEDVRENTRY 7

/*
* Log wrappers
*/
Expand Down Expand Up @@ -381,6 +396,14 @@ class CTvheadend
PVR_ERROR GetEpg ( ADDON_HANDLE handle, const PVR_CHANNEL &chn,
time_t start, time_t end );

/*
* Methods only used by menuhooks
*/
PVR_ERROR CallMenuHook ( const PVR_MENUHOOK &menuhook, const PVR_MENUHOOK_DATA &item );
PVR_ERROR AddAutoRecording ( uint32_t typeId, const SEvent &event );
PVR_ERROR SendScheduleDelete ( std::string id, const char *method );
bool GetEventFromId ( uint32_t id, SEvent &evt );

private:
uint32_t GetNextUnnumberedChannelNumber ( void );

Expand Down Expand Up @@ -481,6 +504,10 @@ class CTvheadend
{
return m_conn.GetServerVersion();
}
inline const int GetProtocolVersion ( void )
{
return m_conn.GetProtocol();
}
inline const char *GetServerString ( void )
{
return m_conn.GetServerString();
Expand Down
47 changes: 41 additions & 6 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ bool g_bAsyncEpg = false;
CHelper_libXBMC_addon *XBMC = NULL;
CHelper_libXBMC_pvr *PVR = NULL;
CHelper_libXBMC_codec *CODEC = NULL;
PVR_MENUHOOK *menuHook = NULL;
CTvheadend *tvh = NULL;

/* **************************************************************************
Expand Down Expand Up @@ -156,6 +155,45 @@ ADDON_STATUS ADDON_Create(void* hdl, void* _unused(props))
return ADDON_STATUS_LOST_CONNECTION;
}

if (tvh->GetProtocolVersion() > 12)
{
XBMC->Log(LOG_DEBUG, "Creating menu hooks...");

PVR_MENUHOOK menuhookEpg;
menuhookEpg.category = PVR_MENUHOOK_EPG;
menuhookEpg.iHookId = REC_EVERYTIME;
menuhookEpg.iLocalizedStringId = 30250;
PVR->AddMenuHook(&menuhookEpg);

menuhookEpg.iHookId = REC_EVERY_DAY_THIS_TIME;
menuhookEpg.iLocalizedStringId = 30251;
PVR->AddMenuHook(&menuhookEpg);

menuhookEpg.iHookId = REC_EVERY_WEEK_THIS_TIME;
menuhookEpg.iLocalizedStringId = 30252;
PVR->AddMenuHook(&menuhookEpg);

menuhookEpg.iHookId = REC_WEEKDAYS;
menuhookEpg.iLocalizedStringId = 30253;
PVR->AddMenuHook(&menuhookEpg);

menuhookEpg.iHookId = REC_WEEKENDS;
menuhookEpg.iLocalizedStringId = 30254;
PVR->AddMenuHook(&menuhookEpg);

PVR_MENUHOOK menuhookTimer;
menuhookTimer.category = PVR_MENUHOOK_TIMER;
menuhookTimer.iHookId = TIMER_DELETESCHEDULE;
menuhookTimer.iLocalizedStringId = 30255;
PVR->AddMenuHook(&menuhookTimer);

menuhookTimer.iHookId = TIMER_DELETEDVRENTRY;
menuhookTimer.iLocalizedStringId = 30256;
PVR->AddMenuHook(&menuhookTimer);

XBMC->Log(LOG_DEBUG, "Creating menu hooks...done");
}

m_CurStatus = ADDON_STATUS_OK;
return m_CurStatus;
}
Expand All @@ -178,7 +216,6 @@ void ADDON_Destroy()
SAFE_DELETE(PVR);
SAFE_DELETE(CODEC);
SAFE_DELETE(XBMC);
SAFE_DELETE(menuHook);
m_CurStatus = ADDON_STATUS_UNKNOWN;
}

Expand Down Expand Up @@ -330,11 +367,9 @@ PVR_ERROR GetDriveSpace(long long *iTotal, long long *iUsed)
* GUI hooks
* *************************************************************************/

PVR_ERROR CallMenuHook
(const PVR_MENUHOOK &_unused(menuhook),
const PVR_MENUHOOK_DATA &_unused(data))
PVR_ERROR CallMenuHook(const PVR_MENUHOOK &menuhook, const PVR_MENUHOOK_DATA &data)
{
return PVR_ERROR_NO_ERROR;
return tvh->CallMenuHook(menuhook, data);
}

/* **************************************************************************
Expand Down

0 comments on commit c1e728f

Please sign in to comment.