mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-26 23:13:13 +02:00
add option to read (online) xmltv epg
Signed-off-by: Thilo Graf <dbt@novatux.de>
This commit is contained in:
@@ -67,6 +67,8 @@ struct sectionsd
|
||||
|
||||
setConfig, // commandSetConfig
|
||||
|
||||
readSIfromIPTVXML, // commandReadSIfromIPTVXML
|
||||
|
||||
numberOfCommands // <- no actual command, end of command marker
|
||||
};
|
||||
|
||||
|
@@ -194,6 +194,14 @@ void CSectionsdClient::readSIfromXML(const char * epgxmlname)
|
||||
close_connection();
|
||||
}
|
||||
|
||||
void CSectionsdClient::readSIfromIPTVXML(const char * url)
|
||||
{
|
||||
send(sectionsd::readSIfromIPTVXML, (char*) url, strlen(url));
|
||||
|
||||
readResponse();
|
||||
close_connection();
|
||||
}
|
||||
|
||||
void CSectionsdClient::writeSI2XML(const char * epgxmlname)
|
||||
{
|
||||
send(sectionsd::writeSI2XML, (char*) epgxmlname, strlen(epgxmlname));
|
||||
|
@@ -200,6 +200,8 @@ class CSectionsdClient : private CBasicClient
|
||||
|
||||
void readSIfromXML(const char * epgxmlname);
|
||||
|
||||
void readSIfromIPTVXML(const char * url);
|
||||
|
||||
void writeSI2XML(const char * epgxmlname);
|
||||
|
||||
/*
|
||||
|
@@ -1213,7 +1213,7 @@ static void commandFreeMemory(int connfd, char * /*data*/, const unsigned /*data
|
||||
|
||||
static void commandReadSIfromXML(int connfd, char *data, const unsigned dataLength)
|
||||
{
|
||||
pthread_t thrInsert;
|
||||
pthread_t thrInsertXML;
|
||||
|
||||
sendEmptyResponse(connfd, NULL, 0);
|
||||
|
||||
@@ -1230,7 +1230,33 @@ static void commandReadSIfromXML(int connfd, char *data, const unsigned dataLeng
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
if (pthread_create (&thrInsert, &attr, insertEventsfromFile, (void *)epg_dir_tmp.c_str() ))
|
||||
if (pthread_create (&thrInsertXML, &attr, insertEventsfromFile, (void *)epg_dir_tmp.c_str() ))
|
||||
{
|
||||
perror("sectionsd: pthread_create()");
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
static void commandReadSIfromIPTVXML(int connfd, char *data, const unsigned dataLength)
|
||||
{
|
||||
pthread_t thrInsertIPTV;
|
||||
|
||||
sendEmptyResponse(connfd, NULL, 0);
|
||||
|
||||
if (dataLength > 100)
|
||||
return ;
|
||||
static std::string url_tmp = "";
|
||||
writeLockMessaging();
|
||||
data[dataLength] = '\0';
|
||||
url_tmp = (std::string)data;
|
||||
unlockMessaging();
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
if (pthread_create (&thrInsertIPTV, &attr, insertEventsfromHttp, (void *)url_tmp.c_str() ))
|
||||
{
|
||||
perror("sectionsd: pthread_create()");
|
||||
}
|
||||
@@ -1272,6 +1298,7 @@ static s_cmd_table connectionCommands[sectionsd::numberOfCommands] = {
|
||||
{ commandReadSIfromXML, "commandReadSIfromXML" },
|
||||
{ commandWriteSI2XML, "commandWriteSI2XML" },
|
||||
{ commandSetConfig, "commandSetConfig" },
|
||||
{ commandReadSIfromIPTVXML, "commandReadSIfromIPTVXML" },
|
||||
};
|
||||
|
||||
bool sectionsd_parse_command(CBasicMessage::Header &rmsg, int connfd)
|
||||
|
@@ -33,8 +33,11 @@
|
||||
#include <string>
|
||||
#include <system/helpers.h>
|
||||
|
||||
#include <system/helpers.h>
|
||||
|
||||
#include <xmltree/xmlinterface.h>
|
||||
#include <zapit/client/zapittools.h>
|
||||
#include <zapit/include/zapit/bouquets.h>
|
||||
|
||||
#include <driver/abstime.h>
|
||||
|
||||
@@ -48,6 +51,7 @@ extern MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey mySIeventsOrd
|
||||
extern bool reader_ready;
|
||||
extern pthread_rwlock_t eventsLock;
|
||||
extern bool dvb_time_update;
|
||||
extern CBouquetManager *g_bouquetManager;
|
||||
|
||||
std::string epg_filter_dir = CONFIGDIR "/zapit/epgfilter.xml";
|
||||
std::string dvbtime_filter_dir = CONFIGDIR "/zapit/dvbtimefilter.xml";
|
||||
@@ -445,6 +449,112 @@ bool readEventsFromFile(std::string &epgname, int &ev_count)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readEventsFromHttpFile(std::string &epgname, int &ev_count)
|
||||
{
|
||||
xmlDocPtr event_parser = NULL;
|
||||
xmlNodePtr tv;
|
||||
xmlNodePtr programme;
|
||||
t_original_network_id onid = 0;
|
||||
t_transport_stream_id tsid = 0;
|
||||
t_service_id sid = 0;
|
||||
|
||||
if (!(event_parser = parseXmlFile(epgname.c_str())))
|
||||
{
|
||||
printf("unable to open %s for reading\n", epgname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
tv = xmlDocGetRootElement(event_parser);
|
||||
programme = xmlChildrenNode(tv);
|
||||
|
||||
while ((programme = xmlGetNextOccurence(programme,"programme")))
|
||||
{
|
||||
|
||||
const char *chan = xmlGetAttribute(programme, "channel");
|
||||
const char *start = xmlGetAttribute(programme, "start");
|
||||
const char *stop = xmlGetAttribute(programme, "stop");
|
||||
|
||||
struct tm starttime, stoptime;
|
||||
strptime(start, "%Y%m%d%H%M%S %z", &starttime);
|
||||
strptime(stop, "%Y%m%d%H%M%S %z", &stoptime);
|
||||
time_t start_time = mktime(&starttime);
|
||||
time_t duration = mktime(&stoptime)-start_time;
|
||||
|
||||
t_channel_id epgid = getepgid(chan);
|
||||
if (epgid != 0)
|
||||
{
|
||||
//printf("\e[1;34m%s - %d - %s 0x%012" PRIx64 "(%ld) (%ld)\e[0m\n",__func__, __LINE__,chan, epgid, start_time, duration);
|
||||
onid = GET_ORIGINAL_NETWORK_ID_FROM_CHANNEL_ID(epgid);
|
||||
tsid = GET_TRANSPORT_STREAM_ID_FROM_CHANNEL_ID(epgid);
|
||||
sid = GET_SERVICE_ID_FROM_CHANNEL_ID(epgid);
|
||||
|
||||
SIevent e(onid, tsid, sid, ev_count+0x8000);
|
||||
e.table_id = 0x50;
|
||||
e.times.insert(SItime(start_time, duration));
|
||||
xmlNodePtr node;
|
||||
node = xmlChildrenNode(programme);
|
||||
while ((node = xmlGetNextOccurence(node, "title")))
|
||||
{
|
||||
const char *title = xmlGetData(node);
|
||||
if(title != NULL)
|
||||
e.setName(std::string(ZapitTools::UTF8_to_Latin1("deu")), std::string(title));
|
||||
node = xmlNextNode(node);
|
||||
}
|
||||
node = xmlChildrenNode(programme);
|
||||
while ((node = xmlGetNextOccurence(node, "sub-title")))
|
||||
{
|
||||
const char *subtitle = xmlGetData(node);
|
||||
if(subtitle != NULL)
|
||||
e.setText(std::string(ZapitTools::UTF8_to_Latin1("deu")), std::string(subtitle));
|
||||
node = xmlNextNode(node);
|
||||
}
|
||||
node = xmlChildrenNode(programme);
|
||||
while ((node = xmlGetNextOccurence(node, "desc")))
|
||||
{
|
||||
const char *description = xmlGetData(node);
|
||||
if(description != NULL)
|
||||
e.appendExtendedText(std::string(ZapitTools::UTF8_to_Latin1("deu")), std::string(description));
|
||||
node = xmlNextNode(node);
|
||||
}
|
||||
dprintf("XML DEBUG: %s channel 0x%012" PRIx64 "\n", chan, epgid);
|
||||
|
||||
addEvent(e, 0);
|
||||
|
||||
ev_count++;
|
||||
}
|
||||
programme = xmlNextNode(programme);
|
||||
}
|
||||
|
||||
xmlFreeDoc(event_parser);
|
||||
return true;
|
||||
}
|
||||
|
||||
t_channel_id getepgid(std::string epg_name)
|
||||
{
|
||||
t_channel_id epgid;
|
||||
|
||||
CBouquetManager::ChannelIterator cit = g_bouquetManager->tvChannelsBegin();
|
||||
|
||||
for (; !(cit.EndOfChannels()); cit++)
|
||||
{
|
||||
std::string tvg_id = (*cit)->getScriptName();
|
||||
|
||||
if (tvg_id.empty())
|
||||
continue;
|
||||
|
||||
std::size_t found = tvg_id.find("#"+epg_name);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
tvg_id = tvg_id.substr(tvg_id.find_first_of("="));
|
||||
sscanf(tvg_id.c_str(), "=%" SCNx64, &epgid);
|
||||
return epgid;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_filter(const struct dirent *entry)
|
||||
{
|
||||
int len = strlen(entry->d_name);
|
||||
@@ -523,6 +633,45 @@ void *insertEventsfromFile(void * data)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void *insertEventsfromHttp(void * data)
|
||||
{
|
||||
set_threadname(__func__);
|
||||
reader_ready=false;
|
||||
int ev_count = 0;
|
||||
if (!data)
|
||||
{
|
||||
reader_ready = true;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
std::string url = (char *) data;
|
||||
std::string tmp_name = tmpnam (NULL);
|
||||
std::string url_ext = getFileExt(url);
|
||||
tmp_name = tmp_name + "." + url_ext;
|
||||
|
||||
int64_t now = time_monotonic_ms();
|
||||
|
||||
if (url.compare(0,1,"/") == 0)
|
||||
readEventsFromHttpFile(url, ev_count);
|
||||
else if (::downloadUrl(url,tmp_name))
|
||||
{
|
||||
readEventsFromHttpFile(tmp_name, ev_count);
|
||||
remove(tmp_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
reader_ready = true;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
printdate_ms(stdout);
|
||||
printf("[sectionsd] Reading Information finished after %" PRId64 " milliseconds (%d events)\n",
|
||||
time_monotonic_ms()-now, ev_count);
|
||||
|
||||
reader_ready = true;
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void write_epg_xml_header(FILE * fd, const t_original_network_id onid, const t_transport_stream_id tsid, const t_service_id sid)
|
||||
{
|
||||
fprintf(fd,
|
||||
|
@@ -35,9 +35,12 @@
|
||||
#include <zapit/types.h>
|
||||
|
||||
void *insertEventsfromFile(void * data);
|
||||
void *insertEventsfromHttp(void * data);
|
||||
bool readEventsFromFile(std::string &epgname, int &ev_count);
|
||||
bool readEventsFromHttpFile(std::string &epgname, int &ev_count);
|
||||
bool readEventsFromDir(std::string &epgdir, int &ev_count);
|
||||
void writeEventsToFile(const char *epgdir);
|
||||
t_channel_id getepgid(std::string epg_name);
|
||||
|
||||
bool readEPGFilter(void);
|
||||
void readDVBTimeFilter(void);
|
||||
|
Reference in New Issue
Block a user