add option to read (online) xmltv epg

Signed-off-by: Thilo Graf <dbt@novatux.de>
This commit is contained in:
TangoCash
2018-08-31 20:49:47 +02:00
committed by Thilo Graf
parent 04f1219a1e
commit a9bb08df0d
6 changed files with 193 additions and 2 deletions

View File

@@ -67,6 +67,8 @@ struct sectionsd
setConfig, // commandSetConfig setConfig, // commandSetConfig
readSIfromIPTVXML, // commandReadSIfromIPTVXML
numberOfCommands // <- no actual command, end of command marker numberOfCommands // <- no actual command, end of command marker
}; };

View File

@@ -194,6 +194,14 @@ void CSectionsdClient::readSIfromXML(const char * epgxmlname)
close_connection(); close_connection();
} }
void CSectionsdClient::readSIfromIPTVXML(const char * url)
{
send(sectionsd::readSIfromIPTVXML, (char*) url, strlen(url));
readResponse();
close_connection();
}
void CSectionsdClient::writeSI2XML(const char * epgxmlname) void CSectionsdClient::writeSI2XML(const char * epgxmlname)
{ {
send(sectionsd::writeSI2XML, (char*) epgxmlname, strlen(epgxmlname)); send(sectionsd::writeSI2XML, (char*) epgxmlname, strlen(epgxmlname));

View File

@@ -200,6 +200,8 @@ class CSectionsdClient : private CBasicClient
void readSIfromXML(const char * epgxmlname); void readSIfromXML(const char * epgxmlname);
void readSIfromIPTVXML(const char * url);
void writeSI2XML(const char * epgxmlname); void writeSI2XML(const char * epgxmlname);
/* /*

View File

@@ -1213,7 +1213,7 @@ static void commandFreeMemory(int connfd, char * /*data*/, const unsigned /*data
static void commandReadSIfromXML(int connfd, char *data, const unsigned dataLength) static void commandReadSIfromXML(int connfd, char *data, const unsigned dataLength)
{ {
pthread_t thrInsert; pthread_t thrInsertXML;
sendEmptyResponse(connfd, NULL, 0); sendEmptyResponse(connfd, NULL, 0);
@@ -1230,7 +1230,33 @@ static void commandReadSIfromXML(int connfd, char *data, const unsigned dataLeng
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 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()"); perror("sectionsd: pthread_create()");
} }
@@ -1272,6 +1298,7 @@ static s_cmd_table connectionCommands[sectionsd::numberOfCommands] = {
{ commandReadSIfromXML, "commandReadSIfromXML" }, { commandReadSIfromXML, "commandReadSIfromXML" },
{ commandWriteSI2XML, "commandWriteSI2XML" }, { commandWriteSI2XML, "commandWriteSI2XML" },
{ commandSetConfig, "commandSetConfig" }, { commandSetConfig, "commandSetConfig" },
{ commandReadSIfromIPTVXML, "commandReadSIfromIPTVXML" },
}; };
bool sectionsd_parse_command(CBasicMessage::Header &rmsg, int connfd) bool sectionsd_parse_command(CBasicMessage::Header &rmsg, int connfd)

View File

@@ -33,8 +33,11 @@
#include <string> #include <string>
#include <system/helpers.h> #include <system/helpers.h>
#include <system/helpers.h>
#include <xmltree/xmlinterface.h> #include <xmltree/xmlinterface.h>
#include <zapit/client/zapittools.h> #include <zapit/client/zapittools.h>
#include <zapit/include/zapit/bouquets.h>
#include <driver/abstime.h> #include <driver/abstime.h>
@@ -48,6 +51,7 @@ extern MySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey mySIeventsOrd
extern bool reader_ready; extern bool reader_ready;
extern pthread_rwlock_t eventsLock; extern pthread_rwlock_t eventsLock;
extern bool dvb_time_update; extern bool dvb_time_update;
extern CBouquetManager *g_bouquetManager;
std::string epg_filter_dir = CONFIGDIR "/zapit/epgfilter.xml"; std::string epg_filter_dir = CONFIGDIR "/zapit/epgfilter.xml";
std::string dvbtime_filter_dir = CONFIGDIR "/zapit/dvbtimefilter.xml"; std::string dvbtime_filter_dir = CONFIGDIR "/zapit/dvbtimefilter.xml";
@@ -445,6 +449,112 @@ bool readEventsFromFile(std::string &epgname, int &ev_count)
return true; 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) static int my_filter(const struct dirent *entry)
{ {
int len = strlen(entry->d_name); int len = strlen(entry->d_name);
@@ -523,6 +633,45 @@ void *insertEventsfromFile(void * data)
pthread_exit(NULL); 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) 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, fprintf(fd,

View File

@@ -35,9 +35,12 @@
#include <zapit/types.h> #include <zapit/types.h>
void *insertEventsfromFile(void * data); void *insertEventsfromFile(void * data);
void *insertEventsfromHttp(void * data);
bool readEventsFromFile(std::string &epgname, int &ev_count); bool readEventsFromFile(std::string &epgname, int &ev_count);
bool readEventsFromHttpFile(std::string &epgname, int &ev_count);
bool readEventsFromDir(std::string &epgdir, int &ev_count); bool readEventsFromDir(std::string &epgdir, int &ev_count);
void writeEventsToFile(const char *epgdir); void writeEventsToFile(const char *epgdir);
t_channel_id getepgid(std::string epg_name);
bool readEPGFilter(void); bool readEPGFilter(void);
void readDVBTimeFilter(void); void readDVBTimeFilter(void);