Skip to content

Commit

Permalink
Merge pull request #145 from Glenn-1990/htspv25
Browse files Browse the repository at this point in the history
Support for autorec/timerec update (new htsp v25 methods)
  • Loading branch information
ksooo committed Jan 4, 2016
2 parents b13750d + 6598b9d commit c4d79d8
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 133 deletions.
1 change: 1 addition & 0 deletions pvr.hts/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
2.2.11
- updated language files from Transifex
- added: proper autorec/timerec support for HTSP v25 and above

2.2.10
- updated language files from Transifex
Expand Down
131 changes: 86 additions & 45 deletions src/AutoRecordings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,57 @@ const unsigned int AutoRecordings::GetTimerIntIdFromStringId(const std::string &
return 0;
}

const std::string AutoRecordings::GetTimerStringIdFromIntId(int intId) const
{
for (auto tit = m_autoRecordings.begin(); tit != m_autoRecordings.end(); ++tit)
{
if (tit->second.GetId() == intId)
return tit->second.GetStringId();
}

Logger::Log(LogLevel::ERROR, "Autorec: Unable to obtain string id for int id %s", intId);
return "";
}

PVR_ERROR AutoRecordings::SendAutorecAdd(const PVR_TIMER &timer)
{
return SendAutorecAddOrUpdate(timer, false);
}

PVR_ERROR AutoRecordings::SendAutorecUpdate(const PVR_TIMER &timer)
{
if (m_conn.GetProtocol() >= 25)
return SendAutorecAddOrUpdate(timer, true);

/* Note: there is no "updateAutorec" htsp method for htsp version < 25, thus delete + add. */
PVR_ERROR error = SendAutorecDelete(timer);

if (error == PVR_ERROR_NO_ERROR)
error = SendAutorecAdd(timer);

return error;
}

PVR_ERROR AutoRecordings::SendAutorecAddOrUpdate(const PVR_TIMER &timer, bool update)
{
uint32_t u32;
const std::string method = update ? "updateAutorecEntry" : "addAutorecEntry";

/* Build message */
htsmsg_t *m = htsmsg_create_map();

if (update)
{
std::string strId = GetTimerStringIdFromIntId(timer.iClientIndex);
if (strId.empty())
{
htsmsg_destroy(m);
return PVR_ERROR_FAILED;
}

htsmsg_add_str(m, "id", strId.c_str()); // Autorec DVR Entry ID (string!
}

htsmsg_add_str(m, "name", timer.strTitle);

/* epg search data match string (regexp) */
Expand All @@ -158,12 +203,22 @@ PVR_ERROR AutoRecordings::SendAutorecAdd(const PVR_TIMER &timer)

htsmsg_add_s64(m, "startExtra", timer.iMarginStart);
htsmsg_add_s64(m, "stopExtra", timer.iMarginEnd);
htsmsg_add_u32(m, "retention", timer.iLifetime); // remove from tvh database

if (m_conn.GetProtocol() >= 24)
htsmsg_add_u32(m, "removal", timer.iLifetime); // remove from disk
if (m_conn.GetProtocol() >= 25)
{
htsmsg_add_u32(m, "removal", timer.iLifetime); // remove from disk
htsmsg_add_u32(m, "retention", DVR_RET_ONREMOVE); // remove from tvh database
htsmsg_add_s64(m, "channelId", timer.iClientChannelUid); // channelId is signed for >= htspv25, -1 = any
}
else
{
htsmsg_add_u32(m, "retention", timer.iLifetime); // remove from tvh database

if (timer.iClientChannelUid >= 0)
htsmsg_add_u32(m, "channelId", timer.iClientChannelUid); // channelId is unsigned for < htspv25, not sending = any
}

htsmsg_add_u32(m, "daysOfWeek", timer.iWeekdays);
htsmsg_add_u32(m, "daysOfWeek", timer.iWeekdays);

if (m_conn.GetProtocol() >= 20)
htsmsg_add_u32(m, "dupDetect", timer.iPreventDuplicateEpisodes);
Expand All @@ -177,9 +232,6 @@ PVR_ERROR AutoRecordings::SendAutorecAdd(const PVR_TIMER &timer)
if (strcmp(timer.strDirectory, "/") != 0)
htsmsg_add_str(m, "directory", timer.strDirectory);

/* Note: not sending any of the following three values will be interpreted by tvh as "any". */
if (timer.iClientChannelUid >= 0)
htsmsg_add_u32(m, "channelId", timer.iClientChannelUid);

/* bAutorecApproxTime enabled: => start time in kodi = approximate start time in tvh */
/* => 'approximate' = starting window / 2 */
Expand Down Expand Up @@ -231,7 +283,7 @@ PVR_ERROR AutoRecordings::SendAutorecAdd(const PVR_TIMER &timer)
/* Send and Wait */
{
CLockObject lock(m_conn.Mutex());
m = m_conn.SendAndWait("addAutorecEntry", m);
m = m_conn.SendAndWait(method.c_str(), m);
}

if (m == NULL)
Expand All @@ -240,39 +292,21 @@ PVR_ERROR AutoRecordings::SendAutorecAdd(const PVR_TIMER &timer)
/* Check for error */
if (htsmsg_get_u32(m, "success", &u32))
{
Logger::Log(LogLevel::ERROR, "malformed addAutorecEntry response: 'success' missing");
Logger::Log(LogLevel::ERROR, "malformed %s response: 'success' missing", method.c_str());
u32 = PVR_ERROR_FAILED;
}
htsmsg_destroy(m);

return u32 == 1 ? PVR_ERROR_NO_ERROR : PVR_ERROR_FAILED;
}

PVR_ERROR AutoRecordings::SendAutorecUpdate(const PVR_TIMER &timer)
{
/* Note: there is no "updateAutorec" htsp method, thus delete + add. */

PVR_ERROR error = SendAutorecDelete(timer);

if (error == PVR_ERROR_NO_ERROR)
error = SendAutorecAdd(timer);

return error;
}

PVR_ERROR AutoRecordings::SendAutorecDelete(const PVR_TIMER &timer)
{
uint32_t u32;

std::string strId;
for (auto tit = m_autoRecordings.begin(); tit != m_autoRecordings.end(); ++tit)
{
if (tit->second.GetId() == timer.iClientIndex)
{
strId = tit->second.GetStringId();
break;
}
}
std::string strId = GetTimerStringIdFromIntId(timer.iClientIndex);
if (strId.empty())
return PVR_ERROR_FAILED;

htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "id", strId.c_str()); // Autorec DVR Entry ID (string!)
Expand Down Expand Up @@ -327,24 +361,29 @@ bool AutoRecordings::ParseAutorecAddOrUpdate(htsmsg_t *msg, bool bAdd)
return false;
}

if (!htsmsg_get_u32(msg, "retention", &u32))
{
rec.SetRetention(u32);
}
else if (bAdd)
{
Logger::Log(LogLevel::ERROR, "malformed autorecEntryAdd: 'retention' missing");
return false;
}

if (!htsmsg_get_u32(msg, "removal", &u32))
if (m_conn.GetProtocol() >= 25)
{
rec.SetRemoval(u32);
if (!htsmsg_get_u32(msg, "removal", &u32))
{
rec.SetLifetime(u32);
}
else if (bAdd)
{
Logger::Log(LogLevel::ERROR, "malformed autorecEntryAdd: 'removal' missing");
return false;
}
}
else if (bAdd && (m_conn.GetProtocol() >= 24))
else
{
Logger::Log(LogLevel::ERROR, "malformed autorecEntryAdd: 'removal' missing");
return false;
if (!htsmsg_get_u32(msg, "retention", &u32))
{
rec.SetLifetime(u32);
}
else if (bAdd)
{
Logger::Log(LogLevel::ERROR, "malformed autorecEntryAdd: 'retention' missing");
return false;
}
}

if (!htsmsg_get_u32(msg, "daysOfWeek", &u32))
Expand Down Expand Up @@ -447,6 +486,8 @@ bool AutoRecordings::ParseAutorecAddOrUpdate(htsmsg_t *msg, bool bAdd)
{
rec.SetChannel(u32);
}
else
rec.SetChannel(PVR_TIMER_ANY_CHANNEL); // an empty channel field = any channel

if (!htsmsg_get_u32(msg, "fulltext", &u32))
{
Expand Down
3 changes: 3 additions & 0 deletions src/AutoRecordings.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class AutoRecordings
bool ParseAutorecDelete(htsmsg_t *msg);

private:
const std::string GetTimerStringIdFromIntId(int intId) const;
PVR_ERROR SendAutorecAddOrUpdate(const PVR_TIMER &timer, bool update);

CHTSPConnection &m_conn;
tvheadend::entity::AutoRecordingsMap m_autoRecordings;
};

0 comments on commit c4d79d8

Please sign in to comment.