controlapi: add /getchannel function to get infos about current channel.

- controlapi: copy event to prevent crash in multi-threaded mode


Origin commit data
------------------
Branch: ni/coolstream
Commit: e855ceef8e
Author: vanhofen <vanhofen@gmx.de>
Date: 2016-02-24 (Wed, 24 Feb 2016)

Origin message was:
------------------
- controlapi: add /getchannel function to get infos about current channel.

- controlapi: copy event to prevent crash in multi-threaded mode


------------------
This commit was generated by Migit
This commit is contained in:
vanhofen
2016-02-24 13:48:01 +01:00
parent 819a626b18
commit eda0c8dc4a
2 changed files with 90 additions and 41 deletions

View File

@@ -163,6 +163,7 @@ const CControlAPI::TyCgiCall CControlAPI::yCgiCallList[]=
{"channellist", &CControlAPI::ChannellistCGI, "text/plain"}, {"channellist", &CControlAPI::ChannellistCGI, "text/plain"},
{"logolist", &CControlAPI::LogolistCGI, "text/plain"}, {"logolist", &CControlAPI::LogolistCGI, "text/plain"},
{"getbouquet", &CControlAPI::GetBouquetCGI, "+xml"}, {"getbouquet", &CControlAPI::GetBouquetCGI, "+xml"},
{"getchannel", &CControlAPI::GetChannelCGI, ""},
{"getbouquets", &CControlAPI::GetBouquetsCGI, "+xml"}, {"getbouquets", &CControlAPI::GetBouquetsCGI, "+xml"},
{"getmode", &CControlAPI::GetModeCGI, "text/plain"}, {"getmode", &CControlAPI::GetModeCGI, "text/plain"},
{"setmode", &CControlAPI::SetModeCGI, "text/plain"}, {"setmode", &CControlAPI::SetModeCGI, "text/plain"},
@@ -981,28 +982,33 @@ std::string CControlAPI::_GetBouquetActualEPGItem(CyhookHandler *hh, CZapitChann
CShortEPGData epg; CShortEPGData epg;
CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo; CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo;
CChannelEvent *event; CChannelEvent event;
event.eventID = 0;
NeutrinoAPI->Lock(); NeutrinoAPI->Lock();
event = NeutrinoAPI->ChannelListEvents[channel->getChannelID()]; CChannelEvent * evt = NeutrinoAPI->ChannelListEvents[channel->getChannelID()];
if (evt)
event = *evt;
NeutrinoAPI->Unlock(); NeutrinoAPI->Unlock();
if (event) { result += hh->outPair("isActiveChannel", (channel->getChannelID() == current_channel) ? "true" : "false", false);
if (event.eventID) {
int percentage = 100; int percentage = 100;
if (event->duration > 0) if (event.duration > 0)
percentage = 100 * (time(NULL) - event->startTime) / event->duration; percentage = 100 * (time(NULL) - event.startTime) / event.duration;
CEitManager::getInstance()->getCurrentNextServiceKey(channel->getChannelID(), currentNextInfo); CEitManager::getInstance()->getCurrentNextServiceKey(channel->getChannelID(), currentNextInfo);
timestr = timeString(event->startTime); timestr = timeString(event.startTime);
firstEPG += hh->outPair("eventid", string_printf("%llu", currentNextInfo.current_uniqueKey), true); firstEPG += hh->outPair("eventid", string_printf("%llu", currentNextInfo.current_uniqueKey), true);
firstEPG += hh->outPair("description", hh->outValue(event->description), true); firstEPG += hh->outPair("description", hh->outValue(event.description), true);
if (CEitManager::getInstance()->getEPGidShort(currentNextInfo.current_uniqueKey, &epg)) if (CEitManager::getInstance()->getEPGidShort(currentNextInfo.current_uniqueKey, &epg))
{ {
firstEPG += hh->outPair("info1", hh->outValue(epg.info1), true); firstEPG += hh->outPair("info1", hh->outValue(epg.info1), true);
firstEPG += hh->outPair("info2", hh->outValue(epg.info2), true); firstEPG += hh->outPair("info2", hh->outValue(epg.info2), true);
} }
firstEPG += hh->outPair("startTime", timestr, true); firstEPG += hh->outPair("startTime", timestr, true);
firstEPG += hh->outPair("timeTotal", string_printf("%d", event->duration / 60), true); firstEPG += hh->outPair("timeTotal", string_printf("%d", event.duration / 60), true);
firstEPG += hh->outPair("timeElapsed", string_printf("%d", (time(NULL) - event->startTime) / 60), true); firstEPG += hh->outPair("timeElapsed", string_printf("%d", (time(NULL) - event.startTime) / 60), true);
firstEPG += hh->outPair("percentage", string_printf("%d", percentage), false); firstEPG += hh->outPair("percentage", string_printf("%d", percentage), false);
if (currentNextInfo.flags & CSectionsdClient::epgflags::has_next) { if (currentNextInfo.flags & CSectionsdClient::epgflags::has_next) {
@@ -1019,8 +1025,8 @@ std::string CControlAPI::_GetBouquetActualEPGItem(CyhookHandler *hh, CZapitChann
} }
} }
result += hh->outPair("isActiveChannel", (channel->getChannelID() == current_channel) ? "true" : "false", (!firstEPG.empty()));
if(!firstEPG.empty()) { if(!firstEPG.empty()) {
result += hh->outNext();
result += hh->outObject("firstEPG", firstEPG); result += hh->outObject("firstEPG", firstEPG);
} }
if(!secondEPG.empty()) { if(!secondEPG.empty()) {
@@ -1032,38 +1038,49 @@ std::string CControlAPI::_GetBouquetActualEPGItem(CyhookHandler *hh, CZapitChann
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// produce data (collection) for given channel // produce data (collection) for given channel
std::string CControlAPI::_GetBouquetWriteItem(CyhookHandler *hh, CZapitChannel * channel, int bouquetNr, int nr) { std::string CControlAPI::_GetBouquetWriteItem(CyhookHandler *hh, CZapitChannel * channel, int bouquetNr, int channelNr) {
std::string result = ""; std::string result = "";
bool isEPGdetails = !(hh->ParamList["epg"].empty()); bool isEPGdetails = !(hh->ParamList["epg"].empty());
if (hh->outType == json || hh->outType == xml) { if (hh->outType == json || hh->outType == xml) {
result += hh->outPair("number", string_printf("%u", nr), true); if (channelNr > -1)
result += hh->outPair("number", string_printf("%u", channelNr), true);
result += hh->outPair("id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID()), true); result += hh->outPair("id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID()), true);
result += hh->outPair("short_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID()&0xFFFFFFFFFFFFULL), true); result += hh->outPair("short_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID()&0xFFFFFFFFFFFFULL), true);
result += hh->outPair("name", hh->outValue(channel->getName()), true); result += hh->outPair("name", hh->outValue(channel->getName()), true);
result += hh->outPair("logo", hh->outValue(NeutrinoAPI->getLogoFile(hh->WebserverConfigList["Tuxbox.LogosURL"], channel->getChannelID())), true); result += hh->outPair("logo", hh->outValue(NeutrinoAPI->getLogoFile(hh->WebserverConfigList["Tuxbox.LogosURL"], channel->getChannelID())), false);
result += hh->outPair("bouquetnr", string_printf("%d", bouquetNr), isEPGdetails); if (bouquetNr > -1)
{
result += hh->outNext();
result += hh->outPair("bouquetnr", string_printf("%d", bouquetNr), false);
}
if (isEPGdetails) if (isEPGdetails)
{
result += hh->outNext();
result += _GetBouquetActualEPGItem(hh, channel); result += _GetBouquetActualEPGItem(hh, channel);
}
result = hh->outArrayItem("channel", result, false); result = hh->outArrayItem("channel", result, false);
} }
else { else {
CChannelEvent *event; CChannelEvent event;
event.eventID = 0;
NeutrinoAPI->Lock(); NeutrinoAPI->Lock();
event = NeutrinoAPI->ChannelListEvents[channel->getChannelID()]; CChannelEvent * evt = NeutrinoAPI->ChannelListEvents[channel->getChannelID()];
if (evt)
event = *evt;
NeutrinoAPI->Unlock(); NeutrinoAPI->Unlock();
if (event && isEPGdetails) { if (event.eventID && isEPGdetails) {
result += string_printf("%u " result += string_printf("%u "
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
" %s (%s)\n", " %s (%s)\n",
nr, channelNr,
channel->getChannelID(), channel->getChannelID(),
channel->getName().c_str(), event->description.c_str()); channel->getName().c_str(), event.description.c_str());
} else { } else {
result += string_printf("%u " result += string_printf("%u "
PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
" %s\n", " %s\n",
nr, channelNr,
channel->getChannelID(), channel->getChannelID(),
channel->getName().c_str()); channel->getName().c_str());
} }
@@ -1212,6 +1229,31 @@ void CControlAPI::GetBouquetCGI(CyhookHandler *hh) {
hh->SendError("no parameter"); hh->SendError("no parameter");
} }
//-------------------------------------------------------------------------
// get actual channel info
void CControlAPI::GetChannelCGI(CyhookHandler *hh)
{
hh->outStart();
t_channel_id channel_id = 0;
if (hh->ParamList["id"].empty())
channel_id = CZapit::getInstance()->GetCurrentChannelID();
else
sscanf(hh->ParamList["id"].c_str(), SCANF_CHANNEL_ID_TYPE, &channel_id);
if (channel_id != 0)
{
NeutrinoAPI->GetChannelEvents();
CZapitChannel * channel = CServiceManager::getInstance()->FindChannel(channel_id);
std::string result = _GetBouquetWriteItem(hh, channel, -1, -1);
result = hh->outArray("channel", result);
hh->SendResult(result);
}
else
hh->SendError();
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/** Return all bouquets /** Return all bouquets
* @param hh CyhookHandler * @param hh CyhookHandler
@@ -1339,9 +1381,11 @@ std::string CControlAPI::channelEPGformated(CyhookHandler *hh, int bouquetnr, t_
std::string result = ""; std::string result = "";
std::string channelData = ""; std::string channelData = "";
CEitManager::getInstance()->getEventsServiceKey(channel_id, NeutrinoAPI->eList); CEitManager::getInstance()->getEventsServiceKey(channel_id, NeutrinoAPI->eList);
channelData += hh->outPair("channel_name", hh->outValue(NeutrinoAPI->GetServiceName(channel_id)), true);
channelData += hh->outPair("channel_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id), true); channelData += hh->outPair("channel_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id), true);
channelData += hh->outPair("channel_short_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id & 0xFFFFFFFFFFFFULL), true); channelData += hh->outPair("channel_short_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id & 0xFFFFFFFFFFFFULL), (bouquetnr > -1));
channelData += hh->outPair("channel_name", hh->outValue(NeutrinoAPI->GetServiceName(channel_id)), false); if (bouquetnr > -1)
channelData += hh->outPair("bouquetnr", string_printf("%d", bouquetnr), false);
if (hh->outType == json) if (hh->outType == json)
channelData = hh->outObject("channelData", channelData); channelData = hh->outObject("channelData", channelData);
int i = 0; int i = 0;
@@ -1351,8 +1395,17 @@ std::string CControlAPI::channelEPGformated(CyhookHandler *hh, int bouquetnr, t_
if ((max != -1 && i >= max) || (stoptime != -1 && eventIterator->startTime >= stoptime)) if ((max != -1 && i >= max) || (stoptime != -1 && eventIterator->startTime >= stoptime))
break; break;
std::string prog = ""; std::string prog = "";
prog += hh->outPair("bouquetnr", string_printf("%d", bouquetnr), true); if (hh->outType == plain)
prog += hh->outPair("channel_id", string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id), true); prog += hh->outSingle("");
prog += hh->outPair("description", hh->outValue(eventIterator->description), true);
if (!(hh->ParamList["details"].empty())) {
CShortEPGData epg;
if (CEitManager::getInstance()->getEPGidShort(eventIterator->eventID, &epg)) {
prog += hh->outPair("info1", hh->outValue(epg.info1), true);
prog += hh->outPair("info2", hh->outValue(epg.info2), true);
}
}
prog += hh->outPair("eventid", string_printf("%llu", eventIterator->eventID), true); prog += hh->outPair("eventid", string_printf("%llu", eventIterator->eventID), true);
prog += hh->outPair("eventid_hex", string_printf("%llx", eventIterator->eventID), true); prog += hh->outPair("eventid_hex", string_printf("%llx", eventIterator->eventID), true);
prog += hh->outPair("start_sec", string_printf("%ld", eventIterator->startTime), true); prog += hh->outPair("start_sec", string_printf("%ld", eventIterator->startTime), true);
@@ -1368,16 +1421,8 @@ std::string CControlAPI::channelEPGformated(CyhookHandler *hh, int bouquetnr, t_
mtime = localtime(&_stoptime); mtime = localtime(&_stoptime);
strftime(zbuffer, 20, "%H:%M", mtime); strftime(zbuffer, 20, "%H:%M", mtime);
prog += hh->outPair("stop_t", std::string(zbuffer), true); prog += hh->outPair("stop_t", std::string(zbuffer), true);
prog += hh->outPair("duration_min", string_printf("%d", (int) (eventIterator->duration / 60)), true); prog += hh->outPair("duration_min", string_printf("%d", (int) (eventIterator->duration / 60)), false);
if (!(hh->ParamList["details"].empty())) {
CShortEPGData epg;
if (CEitManager::getInstance()->getEPGidShort(eventIterator->eventID, &epg)) {
prog += hh->outPair("info1", hh->outValue(epg.info1), true);
prog += hh->outPair("info2", hh->outValue(epg.info2), true);
}
}
prog += hh->outPair("description", hh->outValue(eventIterator->description), false);
if(isFirstLine) if(isFirstLine)
isFirstLine = false; isFirstLine = false;
else else
@@ -1690,24 +1735,27 @@ void CControlAPI::EpgCGI(CyhookHandler *hh) {
else if (param_empty || hh->ParamList["1"] == "ext") { else if (param_empty || hh->ParamList["1"] == "ext") {
hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8"); hh->SetHeader(HTTP_OK, "text/plain; charset=UTF-8");
bool isExt = (hh->ParamList["1"] == "ext"); bool isExt = (hh->ParamList["1"] == "ext");
CChannelEvent *event = NULL; CChannelEvent event;
NeutrinoAPI->GetChannelEvents(); NeutrinoAPI->GetChannelEvents();
int mode = NeutrinoAPI->Zapit->getMode(); int mode = NeutrinoAPI->Zapit->getMode();
CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin(); CBouquetManager::ChannelIterator cit = mode == CZapitClient::MODE_RADIO ? g_bouquetManager->radioChannelsBegin() : g_bouquetManager->tvChannelsBegin();
for (; !(cit.EndOfChannels()); cit++) { for (; !(cit.EndOfChannels()); cit++) {
CZapitChannel * channel = *cit; CZapitChannel * channel = *cit;
event.eventID = 0;
NeutrinoAPI->Lock(); NeutrinoAPI->Lock();
event = NeutrinoAPI->ChannelListEvents[channel->getChannelID()]; CChannelEvent * evt = NeutrinoAPI->ChannelListEvents[channel->getChannelID()];
if (evt)
event = *evt;
NeutrinoAPI->Unlock(); NeutrinoAPI->Unlock();
if (event) { if (event.eventID) {
if (!isExt) { if (!isExt) {
hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
" %llu %s\n", channel->getChannelID(), event->eventID, event->description.c_str()); " %llu %s\n", channel->getChannelID(), event.eventID, event.description.c_str());
} }
else { // ext output else { // ext output
hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS hh->printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
" %ld %u %llu %s\n", channel->getChannelID(), event->startTime, event->duration, event->eventID, event->description.c_str()); " %ld %u %llu %s\n", channel->getChannelID(), event.startTime, event.duration, event.eventID, event.description.c_str());
} }
} }
} }

View File

@@ -62,7 +62,7 @@ private:
void doModifyTimer(CyhookHandler *hh); void doModifyTimer(CyhookHandler *hh);
void doNewTimer(CyhookHandler *hh); void doNewTimer(CyhookHandler *hh);
void _SendTime(CyhookHandler *hh, struct tm *Time, int digits); void _SendTime(CyhookHandler *hh, struct tm *Time, int digits);
std::string _GetBouquetWriteItem(CyhookHandler *hh, CZapitChannel * channel, int bouquetNr, int nr); std::string _GetBouquetWriteItem(CyhookHandler *hh, CZapitChannel * channel, int bouquetNr, int channelNr);
std::string channelEPGformated(CyhookHandler *hh, int bouquetnr, t_channel_id channel_id, int max, long stoptime); std::string channelEPGformated(CyhookHandler *hh, int bouquetnr, t_channel_id channel_id, int max, long stoptime);
std::string _GetBouquetActualEPGItem(CyhookHandler *hh, CZapitChannel * channel); std::string _GetBouquetActualEPGItem(CyhookHandler *hh, CZapitChannel * channel);
@@ -94,6 +94,7 @@ private:
void ChannellistCGI(CyhookHandler *hh); void ChannellistCGI(CyhookHandler *hh);
void LogolistCGI(CyhookHandler *hh); void LogolistCGI(CyhookHandler *hh);
void GetBouquetCGI(CyhookHandler *hh); void GetBouquetCGI(CyhookHandler *hh);
void GetChannelCGI(CyhookHandler *hh);
void GetBouquetsCGI(CyhookHandler *hh); void GetBouquetsCGI(CyhookHandler *hh);
void EpgCGI(CyhookHandler *hh); void EpgCGI(CyhookHandler *hh);
void VersionCGI(CyhookHandler *hh); void VersionCGI(CyhookHandler *hh);