diff options
author | Jochen Dolze <vdr@dolze.de> | 2011-07-24 16:50:37 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2011-07-24 16:50:37 +0200 |
commit | 653b36f3db380683e73cb0ae3c17ddc28bd41fa1 (patch) | |
tree | 15cfb0b6299213d92bbfc2869607b1263146a3e4 | |
parent | 107836c3b0f013e73c6cf572d8947c8d9133d39d (diff) | |
download | vdr-plugin-xmltv2vdr-653b36f3db380683e73cb0ae3c17ddc28bd41fa1.tar.gz vdr-plugin-xmltv2vdr-653b36f3db380683e73cb0ae3c17ddc28bd41fa1.tar.bz2 |
Added epgdata importer
-rw-r--r-- | dist/epgdata2xmltv/Makefile | 83 | ||||
-rw-r--r-- | dist/epgdata2xmltv/epgdata2xmltv.cpp | 588 | ||||
-rw-r--r-- | dist/epgdata2xmltv/epgdata2xmltv.dist | 109 | ||||
-rw-r--r-- | dist/epgdata2xmltv/epgdata2xmltv.h | 52 | ||||
-rw-r--r-- | dist/epgdata2xmltv/epgdata2xmltv.xsl | 238 | ||||
-rw-r--r-- | xmltv2vdr.cpp | 4 |
6 files changed, 1072 insertions, 2 deletions
diff --git a/dist/epgdata2xmltv/Makefile b/dist/epgdata2xmltv/Makefile new file mode 100644 index 0000000..7c63b0c --- /dev/null +++ b/dist/epgdata2xmltv/Makefile @@ -0,0 +1,83 @@ +# +# Makefile for epgdata2xmltv +# + +### The C++ compiler and options: + +CXX ?= g++ +CXXFLAGS ?= -g -rdynamic -O2 -Wall -Wextra -Woverloaded-virtual -Wno-parentheses +PKG-CONFIG ?= pkg-config +STRIP ?= strip + +### Includes and Defines (add further entries here): + +PKG-LIBS += libxml-2.0 libxslt libexslt libcurl libzip +PKG-INCLUDES += libxml-2.0 libxslt libexslt libcurl libzip + +DEFINES += -D_GNU_SOURCE +DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE +DEFINES += -D__STDC_CONSTANT_MACROS -D__USE_XOPEN_EXTENDED + +INCLUDES += $(shell $(PKG-CONFIG) --cflags $(PKG-INCLUDES)) +LIBS += $(shell $(PKG-CONFIG) --libs $(PKG-LIBS)) + +INCLUDES += -I.. + +### directory environment + +TMPDIR = /tmp + +### install directory ### + +INSTALL = /usr/bin + +### The object files (add further files here): + +OBJS = epgdata2xmltv.o + +### The main target: + +all: epgdata2xmltv_xsl epgdata2xmltv + +### Implicit rules: + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +### Dependencies: + +MAKEDEP = $(CXX) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.cpp) > $@ + +-include $(DEPFILE) + +### Targets: + +epgdata2xmltv_xsl: + echo -n "char xsl[]=\"" > epgdata2xmltv_xsl.h + sed -e "s/\"/\\\\\"/g;" epgdata2xmltv.xsl | awk '{ printf("%s",$$0); }' >> epgdata2xmltv_xsl.h + echo "\";" >> epgdata2xmltv_xsl.h + +epgdata2xmltv: $(OBJS) + $(CXX) $(CXXFLAGS) $(OBJS) $(LIBS) -o $@ + +install: epgdata2xmltv_xsl epgdata2xmltv + @cp epgdata2xmltv $(INSTALL) + $(STRIP) $(INSTALL)/epgdata2xmltv + @mkdir -p /var/lib/epgsources + @cp epgdata2xmltv.dist /var/lib/epgsources/epgdata2xmltv + +dist: clean + @-rm -rf $(TMPDIR)/epgdata2xmltv + @mkdir $(TMPDIR)/epgdata2xmltv + @cp -a *.cpp *.h *.xsl epgdata2xmltv.dist Makefile $(TMPDIR)/epgdata2xmltv + @tar cfz epgdata2xmltv.tgz -C $(TMPDIR) epgdata2xmltv + @-rm -rf $(TMPDIR)/epgdata2xmltv + +clean: + @-rm -f $(OBJS) $(DEPFILE) epgdata2xmltv epgdata2xmltv_xsl.h + +distclean: clean + @-rm -f *~ *.tgz diff --git a/dist/epgdata2xmltv/epgdata2xmltv.cpp b/dist/epgdata2xmltv/epgdata2xmltv.cpp new file mode 100644 index 0000000..0ccc1d9 --- /dev/null +++ b/dist/epgdata2xmltv/epgdata2xmltv.cpp @@ -0,0 +1,588 @@ +/* + * epgdata2xmltv.cpp: a grabber for the xmltv2vdr plugin + * + */ + +#include <sys/types.h> +#include <dirent.h> +#include <string.h> +#include <locale.h> +#include <zip.h> +#include "epgdata2xmltv.h" +#include "epgdata2xmltv_xsl.h" + +#include <fcntl.h> + +#define xstr(s) str(s) +#define str(s) #s + +int SysLogLevel=1; + +void syslog_with_tid(const char *format, ...) +{ + va_list ap; + char fmt[255]; + snprintf(fmt, sizeof(fmt), "%s", format); + va_start(ap, format); + vfprintf(stderr,fmt,ap); + va_end(ap); + fprintf(stderr,"\n"); + fflush(stderr); +} + +cepgdata2xmltv::cepgdata2xmltv () +{ + data.size = 0; + data.fd=-1; + pxsltStylesheet = NULL; + sxmlDoc=NULL; +} + +cepgdata2xmltv::~cepgdata2xmltv () +{ + if (pxsltStylesheet) + { + xsltFreeStylesheet(pxsltStylesheet); + xsltCleanupGlobals(); + xmlCleanupParser(); + } +} + +void cepgdata2xmltv::LoadXSLT() +{ + if (pxsltStylesheet) return; + xmlSubstituteEntitiesDefault (1); + xmlLoadExtDtdDefaultValue = 1; + exsltRegisterAll(); + + if ((sxmlDoc = xmlReadMemory (xsl, sizeof(xsl), NULL,NULL,0)) != NULL) + { + pxsltStylesheet=xsltParseStylesheetDoc(sxmlDoc); + if (!pxsltStylesheet) + { + esyslog("can't parse stylesheet"); + xmlFreeDoc (sxmlDoc); + sxmlDoc=NULL; + } + } +} + +static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *dataptr) +{ + struct data *data = (struct data *) dataptr; + size_t realsize = size * nmemb; + if (data->fd!=-1) + { + write(data->fd,ptr,realsize); + data->size+=realsize; + } + return realsize; +} + + +int cepgdata2xmltv::DownloadData(const char *url) +{ + CURL *curl_handle; + data.size=0; + + int ret; + ret=curl_global_init(CURL_GLOBAL_NOTHING); + if (ret) return ret; + + curl_handle = curl_easy_init(); + if (!curl_handle) return -40; // unused curl error + curl_easy_setopt(curl_handle, CURLOPT_URL, url); // Specify URL to get + curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 0); // don't follow redirects + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); // Send all data to this function + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &data); // Pass our 'data' struct to the callback function + curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 20971520); // Set maximum file size to get (bytes) + curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1); // No progress meter + curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); // No signaling + curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 240); // Set timeout to 240 seconds + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, EPGDATA2XMLTV_USERAGENT); // Some servers don't like requests that are made without a user-agent field + + ret=curl_easy_perform(curl_handle); + if (!ret) + { + long code; + curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &code); + if (code==407) + { + ret=10; + } + else + { + if (code!=200) ret=22; + } + } + + if ((data.size<120) && (!ret)) ret=22; + + curl_easy_cleanup(curl_handle); // Cleanup curl stuff + curl_global_cleanup(); + return -ret; +} + +int cepgdata2xmltv::Fetch(const char *dest, const char *pin, int day) +{ + char *url = NULL; + char *filename = NULL; + + if (asprintf (&filename, "%i&pin=%s",day,pin)==-1) + { + esyslog("failed to allocate string"); + return 1; + } + if (asprintf (&url, EPGDATA2XMLTV_URL, filename) == -1) + { + esyslog("failed to allocate string"); + free(filename); + return 1; + } + if (filename) free(filename); + + data.fd=open(dest,O_CREAT|O_TRUNC|O_WRONLY,0664); + if (data.fd==-1) + { + esyslog("failed to open %s",dest); + return 1; + } + + int ret=DownloadData(url); + close(data.fd); + if (ret) unlink(dest); + data.fd=-1; + + free (url); + // -40 fatal curl error + // -10 wrong proxy auth + // -7 couldn't connect + // -6 couldn't resolve host (proxy) + // -22 not found + if (ret==-40) + { + esyslog("fatal curl error"); + return 1; + } + if (ret==-28) + { + esyslog("timeout"); + return 1; + } + if (ret==-10) + { + esyslog("wrong proxy auth"); + return 1; + } + if (ret==-7) + { + esyslog("failed to connect"); + return 2; + } + if (ret==-6) + { + esyslog("failed to resolve host"); + return 2; + } + if (ret==-22) + { + esyslog("wrong pin"); + return 1; + + } + return 0; +} + +char *cepgdata2xmltv::strreplace(char *s, const char *s1, const char *s2) +{ + char *p = strstr(s, s1); + if (p) + { + int of = p - s; + int l = strlen(s); + int l1 = strlen(s1); + int l2 = strlen(s2); + if (l2 > l1) + s = (char *)realloc(s, l + l2 - l1 + 1); + char *sof = s + of; + if (l2 != l1) + memmove(sof + l2, sof + l1, l - of - l1 + 1); + strncpy(sof, s2, l2); + } + return s; +} + +int cepgdata2xmltv::Process(int argc, char *argv[]) +{ + FILE *f=fopen("/var/lib/epgsources/epgdata2xmltv","r"); + if (!f) + { + esyslog("failed to open epgdata2xmltv config"); + return 1; + } + char *line=NULL,*lptr=NULL; + size_t size; + getline(&line,&size,f); + getline(&line,&size,f); + char *sc=strchr(line,';'); + if (sc) + { + *sc=0; + sc++; + } + else + { + sc=line; + } + int daysmax=atoi(sc); + if (daysmax<0) daysmax=1; + int daysinadvance=atoi(argv[1]); + if (daysinadvance<0) daysinadvance=1; + if (daysinadvance>daysmax) daysinadvance=daysmax; + + bool head=false; + char *xmlmem=NULL; + + time_t t=time(NULL); + + for (int day=0; day<=daysinadvance; day++) + { + time_t td=t+(day*86400); + struct tm *tm; + tm=localtime(&td); + char vgl[10]; + sprintf(vgl,"%04i%02i%02i",tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday); + + char *dest=NULL; + if (asprintf(&dest,"/tmp/epgdata_%02i.zip",day)==-1) + { + esyslog("failed to allocate string"); + continue; + } + + bool ok=false; + do + { + bool offline=true; + struct stat statbuf; + if (stat(dest,&statbuf)==-1) + { + if (Fetch(dest,argv[2],day)) + { + ok=true; + break; + } + offline=false; + } + + struct zip *zip=zip_open(dest,0,NULL); + if (!zip) + { + if (offline) + { + if (unlink(dest)==-1) + { + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + esyslog("failed to open %s",dest); + ok=true; + break; + } + + int i=zip_name_locate(zip,"qy.dtd",ZIP_FL_NOCASE); + if (i==-1) + { + if (offline) + { + if (unlink(dest)==-1) + { + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + esyslog("failed read qy.dtd in %s",dest); + ok=true; + break; + } + + struct zip_file *zfile=zip_fopen_index(zip,i,0); + if (!zfile) + { + if (offline) + { + if (unlink(dest)==-1) + { + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + esyslog("failed to read qy.dtd from %s",dest); + ok=true; + break; + } + struct zip_stat sb; + memset(&sb,0,sizeof(sb)); + if (zip_stat_index(zip,i,ZIP_FL_UNCHANGED,&sb)==-1) + { + if (offline) + { + if (unlink(dest)==-1) + { + zip_fclose(zfile); + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + zip_fclose(zfile); + esyslog("failed to stat qy.dtd in %s",dest); + ok=true; + break; + } + if (sizeof(sb.size>4)) sb.size &= 0x00FFFFFF; // just to be sure + xmlmem=(char *) malloc(sb.size+1); + int size=zip_fread(zfile,xmlmem,sb.size); + if (size!=sb.size) + { + zip_fclose(zfile); + esyslog("failed to read qy.dtd from %s",dest); + ok=true; + break; + } + xmlmem[size]=0; + zip_fclose(zfile); + xmlmem=strreplace(xmlmem,"?>\n","?>\n<!DOCTYPE pack [\n"); + + int entries=zip_get_num_files(zip); + for (int i=0; i<entries; i++) + { + const char *name=zip_get_name(zip,i,0); + if (strstr(name,"xml")) + { + // check date of xml + if (strstr(name,vgl)) + { + struct zip_file *zfile=zip_fopen_index(zip,i,0); + if (!zfile) + { + if (offline) + { + if (unlink(dest)==-1) + { + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + esyslog("failed to read %s from %s",name,dest); + ok=true; + break; + } + struct zip_stat sb; + memset(&sb,0,sizeof(sb)); + if (zip_stat_index(zip,i,ZIP_FL_UNCHANGED,&sb)==-1) + { + if (offline) + { + if (unlink(dest)==-1) + { + esyslog("cannot unlink %s",dest); + ok=true; + break; + } + continue; + } + esyslog("failed to stat %s in %s",name,dest); + ok=true; + break; + } + if (sizeof(sb.size>4)) sb.size &= 0x00FFFFFF; // just to be sure + int lpos=strlen(xmlmem); + char *nptr=(char *) realloc(xmlmem,lpos+sb.size+1); + if (nptr) + { + xmlmem=nptr; + } + else + { + zip_fclose(zfile); + free(xmlmem); + xmlmem=NULL; + esyslog("out of memory"); + ok=true; + break; + } + int size=zip_fread(zfile,xmlmem+lpos,sb.size); + if (size!=sb.size) + { + zip_fclose(zfile); + free(xmlmem); + xmlmem=NULL; + esyslog("failed to read %s from %s",name,dest); + ok=true; + break; + } + zip_fclose(zfile); + xmlmem[lpos+size]=0; + xmlmem[lpos++]=']'; + xmlmem[lpos++]='>'; + xmlmem[lpos++]='\n'; + while (xmlmem[lpos]!='?') + { + xmlmem[lpos]=' '; + lpos++; + } + xmlmem[lpos++]=' '; + xmlmem[lpos++]=' '; + while (xmlmem[lpos]!='>') + { + xmlmem[lpos]=' '; + lpos++; + } + xmlmem[lpos++]=' '; + ok=true; + } + } + } + zip_close(zip); + if (!ok) + { + if (offline) + { + if (unlink(dest)==-1) + { + ok=true; + break; + } + continue; + } + else + { + esyslog("found no valid data in %s",dest); + if (xmlmem) free(xmlmem); + xmlmem=NULL; + ok=true; + break; + } + } + } + while (ok==false); + free(dest); + + if (!line) + { + line=(char *) malloc(81); + size=80; + } + if (!xmlmem) continue; + long offset=ftell(f); + + xmlDocPtr pxmlDoc; + if (!pxsltStylesheet) LoadXSLT(); + if ((pxmlDoc=xmlParseMemory(xmlmem,strlen(xmlmem)))==NULL) + { + esyslog("failed parsing xml"); + free(xmlmem); + continue; + } + + for (;;) + { + lptr=line+1; + line[0]=' '; + if (getline(&lptr,&size,f)==-1) break; + char *channel=line; + char *sc=strchr(channel,';'); + if (sc) *sc=0; + + bool use=false; + for (int i=3; i<argc; i++) + { + if (!strcasecmp(lptr,argv[i])) + { + use=true; + break; + } + } + + if (use) + { + if (!head) + { + printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); + printf("<tv generator-info-name=\"epgdata2xmltv\">\n"); + + for (int i=3; i<argc; i++) + { + printf("<channel id=\"%s\">\n",argv[i]); + printf("<display-name lang=\"de\">%s</display-name>\n",argv[i]); + printf("</channel>\n"); + } + head=true; + } + + int num=atoi(sc+1); + if (num>0) + { + char *channelnum=strdup(sc+1); + char *lf=strchr(channelnum,10); + if (lf) *lf=0; + channel[0]='"'; + *sc++='"'; + *sc=0; + const char *params[5] = + { + "channelid", channel, "channelnum",channelnum,NULL + }; + Translate(pxmlDoc,params); + if (channelnum) free(channelnum); + } + } + } + xmlFreeDoc (pxmlDoc); + fseek(f,offset,SEEK_SET); + if (xmlmem) free(xmlmem); + xmlmem=NULL; + } + if (line) free(line); + fclose(f); + + if (head) printf("</tv>\n"); + return head ? 0 : 1; +} + +bool cepgdata2xmltv::Translate(xmlDocPtr pxmlDoc, const char **params) +{ + xmlDocPtr res=NULL; + if ((res = xsltApplyStylesheet (pxsltStylesheet, pxmlDoc, (const char **)params)) == NULL) + { + dsyslog("error applying xslt stylesheet"); + return false; + } + else + { + xsltSaveResultToFile(stdout,res,pxsltStylesheet); + xmlFreeDoc (res); + } + return true; +} + +int main(int argc, char *argv[]) +{ + if (argc<4) return 132; + cepgdata2xmltv *epgdata2xmltv = new cepgdata2xmltv; + int ret=epgdata2xmltv->Process(argc, argv); + delete epgdata2xmltv; + return ret; +} + diff --git a/dist/epgdata2xmltv/epgdata2xmltv.dist b/dist/epgdata2xmltv/epgdata2xmltv.dist new file mode 100644 index 0000000..110eeb0 --- /dev/null +++ b/dist/epgdata2xmltv/epgdata2xmltv.dist @@ -0,0 +1,109 @@ +pipe;00:00;1 +17 +ard.de;71 +zdf.de;37 +arte.de;58 +3sat.de;56 +br-alpha.de;104 +einsmuxx.de;475 +einsfestival.de;146 +einsextra.de;100 +zdfinfo.de;276 +zdf-theaterkanal.de;275 +zdfneo.de;659 +phoenix.de;194 +bayern3.de;51 +hessen3.de;49 +rbb.de;52 +swr.de;50 +wdr.de;46 +ndr.de;47 +kika.de;57 +mdr.de;48 +rtl.de;38 +sat1.de;39 +rtl2.de;41 +prosieben.de;40 +superrtl.de;43 +kabel1.de;44 +vox.de;42 +sixx.de;694 +das-vierte.de;486 +tele5.de;277 +9live.de;1179 +ntv.de;66 +euronews.de;68 +n24.de;175 +bloombergtv.de;127 +cnn.de;69 +eurosport.de;65 +dsf.de;64 +nickcomedy.de;589 +dmax.de;507 +hse24.de;159 +qvc.de;208 +bibeltv.de;280 +timm.de;588 +orf1.at;54 +orf2.at;55 +atvplus.at;115 +tw1.at;265 +viva.de;266 +mtv.de;70 +gotv.at;391 +fashiontv.fr;455 + + Sky Deutschland +610 = S19.2E-133-2-10 Sky Cinema,Cinema;SKY +611 = S19.2E-133-2-11 Sky Cinema +1,Cinema1;SKY +612 = S19.2E-133-2-43 Sky Cinema +24,Cinema24;SKY +613 = S19.2E-133-2-9 Sky Action,Action;SKY +617 = S19.2E-133-2-8 Sky Comedy,Comedy;SKY +616 = S19.2E-133-2-20 Sky Emotion,Emotion;SKY +614 = S19.2E-133-3-516 Sky Nostalgie,Nostalgie;SKY +618 = S19.2E-133-3-41 Sky Cinema Hits,CineHits;SKY +630 = S19.2E-133-3-25 Disney Cinemagic,Cinemagic;SKY +1196 = S19.2E-133-3-515 MGM;SKY +138 = S19.2E-133-4-14 Discovery Channel,Discovery;SKY +453 = S19.2E-133-4-13 National Geographic,NatGeo;SKY +626 = S19.2E-133-4-12 NatGeo Wild,NG Wild;SKY +625 = S19.2E-133-4-52 Spiegel Geschichte,SpiegelG;SKY +627 = S19.2E-133-1-168 Motorvision TV,Motorvis;SKY +476 = S19.2E-133-4-15 Focus Gesundheit,Focus;SKY +615 = S19.2E-133-1-23 Sky Krimi,SkyKrimi;SKY +527 = S19.2E-133-1-27 RTL Crime,RTLCrime;SKY +471 = S19.2E-133-1-42 13th Street,13Street;SKY +472 = S19.2E-133-17-36 SciFi;SKY +565 = S19.2E-133-1-16 Fox Serie,Fox;SKY +590 = S19.2E-133-1-50 TNT Serie,TNTSerie;SKY +529 = S19.2E-133-1-29 RTL Passion,Passion;SKY +154 = S19.2E-133-17-22 Heimatkanal,Heimat;SKY +139 = S19.2E-133-17-34 Disney Channel,Disney;SKY +460 = S19.2E-133-17-26 Playhouse Disney,Playhouse;SKY ??? +160 = S19.2E-133-17-19 Junior;SKY + = S19.2E-133-17-28 Disney XD,DisneyXD;SKY ??? +152 = S19.2E-133-17-518 Goldstar TV,Goldstar;SKY +133 = S19.2E-133-17-24 Classica;SKY +123 = S19.2E-133-17-21 Beate-Uhse.TV,BeateU;SKY +491 = S19.2E-1-1107-17505 Sat.1 Comedy;ProSiebenSat.1 +468 = S19.2E-133-9-62 AXN Action,AXN;arena/SKY +633 = S19.2E-133-9-61 TNT Film (TCM),TNT Film;arena/SKY +492 = S19.2E-1-1107-17506 kabel eins classics;ProSiebenSat.1 +450 = S19.2E-133-9-60 Kinowelt TV,Kinowelt;SKY ??? +552 = S19.2E-133-9-63 Romance TV,Romance;SKY ??? +551 = S19.2E-1-1078-28682 NICK PREMIUM (S);MTV Networks Europe ??? +493 = S19.2E-133-9-66 Boomerang;arena/SKY ??? +132 = S19.2E-1-1102-13204 Cartoon Network (a/S);arena/SKY +452 = S19.2E-133-9-68 History;SKY +536 = S19.2E-1-1102-13208 Biography Channel;arena/SKY ??? +528 = S19.2E-1-1102-13207 RTL Living;arena/SKY + = S19.2E-133-9-67 e.clips;SKY ??? +539 = S19.2E-1-1102-13203 ANIMAX;arena/SKY +553 = S19.2E-1-1078-28681 MTV ENTERTAINMENT (S);MTV Networks Europe ??? +496 = S19.2E-1-1066-28657 VH1 Classic;MTV Networks Europe ??? +504 = S19.2E-1-1102-13205 EuroSport 2 (a/S);arena/SKY +591 = S19.2E-1-1115-13105 ESPN America (S);SKY +622 = S19.2E-133-7-53 Sky Sport Austria,SportAut;SKY +628 = S19.2E-133-4-18 Sky Select,SkySel;SKY + + Musik diff --git a/dist/epgdata2xmltv/epgdata2xmltv.h b/dist/epgdata2xmltv/epgdata2xmltv.h new file mode 100644 index 0000000..3748c5d --- /dev/null +++ b/dist/epgdata2xmltv/epgdata2xmltv.h @@ -0,0 +1,52 @@ +/* + * epgdata2xmltv.h: a grabber for the xmltv2vdr plugin + * + */ + +#ifndef __EPGDATA2XMLTV_H +#define __EPGDATA2XMLTV_H + +#include <curl/curl.h> +#include <curl/types.h> +#include <curl/easy.h> + +#include <libxslt/transform.h> +#include <libxslt/xsltutils.h> +#include <libexslt/exslt.h> + +#include <stdio.h> +#include <sys/stat.h> +#include <unistd.h> + +#define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(a) : void() ) +#define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(a) : void() ) +#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(a) : void() ) +#define tsyslog(a...) void( (SysLogLevel > 3) ? syslog_with_tid(a) : void() ) + +#define EPGDATA2XMLTV_USERAGENT "libcurl-agent/1.0" +#define EPGDATA2XMLTV_URL "http://www.epgdata.com/index.php?action=sendPackage&iOEM=VDR&dataType=xml&dayOffset=%s" + +struct data +{ + size_t size; + int fd; +}; + +class cepgdata2xmltv +{ +private: + struct data data; + xsltStylesheetPtr pxsltStylesheet; + xmlDocPtr sxmlDoc; + char *strreplace(char *s, const char *s1, const char *s2); + int Fetch(const char *path, const char *pin, int day); + int DownloadData(const char *url); + bool Translate(xmlDocPtr pxmlDoc, const char **params); + void LoadXSLT(); +public: + cepgdata2xmltv(); + ~cepgdata2xmltv(); + int Process(int argc, char *argv[]); +}; + +#endif //__EPGDATA2XMLTV_H diff --git a/dist/epgdata2xmltv/epgdata2xmltv.xsl b/dist/epgdata2xmltv/epgdata2xmltv.xsl new file mode 100644 index 0000000..a85e0c2 --- /dev/null +++ b/dist/epgdata2xmltv/epgdata2xmltv.xsl @@ -0,0 +1,238 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:exsl="http://exslt.org/common" + xmlns:date="http://exslt.org/dates-and-times" + xmlns:str="http://exslt.org/strings"> +<xsl:output method="xml" omit-xml-declaration="yes" encoding='utf-8'/> + +<xsl:template match="/"> +<xsl:for-each select="//data[d2=$channelnum]"> + +<!-- +<xsl:variable name="start_xmltv"> +<xsl:value-of select="d4"/> +</xsl:variable> + +<xsl:variable name="stop_xmltv"> +<xsl:value-of select="d5"/> +</xsl:variable> + +<xsl:variable name="vps_xmltv"> +<xsl:value-of select="d8"/> +</xsl:variable> +--> + +<xsl:variable name="EVENTID"> +<xsl:value-of select="d0"/> +</xsl:variable> + +<xsl:variable name="INHALT"> +<xsl:value-of select="translate(d22,'|','
')"/> +</xsl:variable> + +<xsl:variable name="THEMEN"> +<xsl:value-of select="translate(d24,'|','
')"/> +</xsl:variable> + +<xsl:variable name="JAHR"> +<xsl:value-of select="d33"/> +</xsl:variable> + +<xsl:variable name="LAND"> +<xsl:value-of select="translate(d32,'|','/')"/> +</xsl:variable> + +<xsl:variable name="GENRE"> +G <xsl:value-of select="d25"/> +</xsl:variable> + +<xsl:variable name="CREW"> + +<xsl:if test="string-length(d36)"> +<xsl:call-template name="output-tokens"> +<xsl:with-param name="list"><xsl:value-of select="d36"/></xsl:with-param> +<xsl:with-param name="tag">director</xsl:with-param> +<xsl:with-param name="delimiter">|</xsl:with-param> +</xsl:call-template> +</xsl:if> + +<xsl:if test="string-length(d37)"> +<xsl:call-template name="output-tokens"> +<xsl:with-param name="list"><xsl:value-of select="d37"/></xsl:with-param> +<xsl:with-param name="tag">actor</xsl:with-param> +<xsl:with-param name="delimiter"> - </xsl:with-param> +</xsl:call-template> +</xsl:if> + +<xsl:if test="string-length(d34)"> +<xsl:call-template name="output-tokens"> +<xsl:with-param name="list"><xsl:value-of select="d34"/></xsl:with-param> +<xsl:with-param name="tag">presenter</xsl:with-param> +<xsl:with-param name="delimiter">|</xsl:with-param> +</xsl:call-template> +</xsl:if> + +<xsl:if test="string-length(d35)"> +<xsl:call-template name="output-tokens"> +<xsl:with-param name="list"><xsl:value-of select="d35"/></xsl:with-param> +<xsl:with-param name="tag">guest</xsl:with-param> +<xsl:with-param name="delimiter"> - </xsl:with-param> +</xsl:call-template> +</xsl:if> + +</xsl:variable> + +<xsl:variable name="VIDEO"> +</xsl:variable> + +<xsl:variable name="AUDIO"> +</xsl:variable> + + +<xsl:variable name="vps_iso8601"> +<xsl:if test="string-length(d8)"> +<xsl:call-template name="date2UTC"> +<xsl:with-param name="date" select="concat(substring-before(d4,' '),'T',d8,':00')"/> +</xsl:call-template> +</xsl:if> +</xsl:variable> + +<xsl:variable name="start_iso8601"> +<xsl:call-template name="date2UTC"> +<xsl:with-param name="date" select="concat(substring-before(d4,' '),'T',substring-after(d4,' '))"/> +</xsl:call-template> +</xsl:variable> + +<xsl:variable name="stop_iso8601"> +<xsl:call-template name="date2UTC"> +<xsl:with-param name="date" select="concat(substring-before(d5,' '),'T',substring-after(d5,' '))"/> +</xsl:call-template> +</xsl:variable> + +<xsl:variable name="start_xmltv"> +<xsl:value-of select="concat(translate($start_iso8601,'-:ZT',''),' +0000')"/> +</xsl:variable> + +<xsl:variable name="vps_xmltv"> +<xsl:if test="string-length($vps_iso8601)"> +<xsl:value-of select="concat(translate($vps_iso8601,'-:ZT',''),' +0000')"/> +</xsl:if> +</xsl:variable> + +<xsl:variable name="stop_xmltv"> +<xsl:value-of select="concat(translate($stop_iso8601,'-:ZT',''),' +0000')"/> +</xsl:variable> + +<xsl:element name="programme"> +<xsl:attribute name="start"> +<xsl:value-of select="$start_xmltv"/> +</xsl:attribute> +<xsl:attribute name="stop"> +<xsl:value-of select="$stop_xmltv"/> +</xsl:attribute> +<xsl:if test="string-length($vps_xmltv)"> +<xsl:attribute name="vps-start"> +<xsl:value-of select="$vps_xmltv"/> +</xsl:attribute> +</xsl:if> +<xsl:attribute name="channel"> +<xsl:value-of select="$channelid"/> +</xsl:attribute> +<xsl:text>
</xsl:text> + +<title lang="de"><xsl:value-of select="d19"/></title><xsl:text>
</xsl:text> +<xsl:if test="string-length(d20)"> +<sub-title lang="de"><xsl:value-of select="d20"/></sub-title><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($THEMEN)"> +<desc lang="de"><xsl:value-of select="$THEMEN"/></desc><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($INHALT)"> +<desc lang="de"><xsl:value-of select="$INHALT"/></desc><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($CREW)"> +<credits><xsl:text>
</xsl:text><xsl:copy-of select="$CREW"/></credits><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($JAHR)"> +<date><xsl:value-of select="$JAHR"/></date><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($GENRE)"> +<category lang="de"><xsl:value-of select="$GENRE"/></category><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($EVENTID)"> +<category lang="de"><xsl:value-of select="$EVENTID"/></category><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($LAND)"> +<country><xsl:value-of select="$LAND"/></country><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($VIDEO)"> +<video><xsl:text>
</xsl:text><xsl:copy-of select="$VIDEO"/></video><xsl:text>
</xsl:text> +</xsl:if> +<xsl:if test="string-length($AUDIO)"> +<audio><xsl:text>
</xsl:text><stereo><xsl:value-of select="$AUDIO"/></stereo><xsl:text>
</xsl:text></audio><xsl:text>
</xsl:text> +</xsl:if> + +</xsl:element> +<xsl:text>
</xsl:text> +</xsl:for-each> +</xsl:template> + +<xsl:template name="date2UTC"> + <xsl:param name="date"/> + + <xsl:variable name="dststart"> + <xsl:value-of select="concat(date:year($date),'-03-',32-date:day-in-week(concat(date:year($date),'-03-31')),'T02:00:00')"/> + </xsl:variable> + + <xsl:variable name="dstend"> + <xsl:value-of select="concat(date:year($date),'-10-',32-date:day-in-week(concat(date:year($date),'-10-31')),'T03:00:00')"/> + </xsl:variable> + + <xsl:variable name="tz"> + <xsl:choose> + <xsl:when test="date:seconds(date:difference($dststart,$date)) >= 0"> + <xsl:choose> + <xsl:when test="date:seconds(date:difference($date,$dstend)) >= 0">-PT2H</xsl:when> + <xsl:otherwise>-PT1H</xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:otherwise>-PT1H</xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:value-of select="date:add($date,$tz)"/> +</xsl:template> + +<xsl:template name="output-tokens"> + <xsl:param name="list" /> + <xsl:param name="delimiter" /> + <xsl:param name="tag" /> + <xsl:param name="last"/> + <xsl:variable name="newlist"> + <xsl:choose> + <xsl:when test="contains($list, $delimiter)"><xsl:value-of select="normalize-space($list)" /></xsl:when> + + <xsl:otherwise><xsl:value-of select="concat(normalize-space($list), $delimiter)"/></xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="first" select="substring-before($newlist, $delimiter)" /> + <xsl:variable name="remaining" select="substring-after($newlist, $delimiter)" /> + <xsl:if test="$first != $last"> + <xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="$tag"/><xsl:text disable-output-escaping="yes">></xsl:text> + <xsl:value-of select="$first" /> + <xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="$tag"/><xsl:text disable-output-escaping="yes">></xsl:text> + <xsl:text>
</xsl:text> + </xsl:if> + <xsl:if test="$remaining"> + <xsl:call-template name="output-tokens"> + <xsl:with-param name="list" select="$remaining" /> + <xsl:with-param name="delimiter"><xsl:value-of select="$delimiter"/></xsl:with-param> + <xsl:with-param name="tag" select="$tag"/> + <xsl:with-param name="last" select="$first"/> + </xsl:call-template> + </xsl:if> +</xsl:template> + + + +</xsl:stylesheet> diff --git a/xmltv2vdr.cpp b/xmltv2vdr.cpp index 9f79c01..b225274 100644 --- a/xmltv2vdr.cpp +++ b/xmltv2vdr.cpp @@ -104,7 +104,7 @@ bool cEPGSource::ReadConfig() esyslog("xmltv2vdr: '%s' out of memory",name); return false; } - FILE *f=fopen(fname,"r+"); + FILE *f=fopen(fname,"r"); if (!f) { esyslog("xmltv2vdr: '%s' ERROR cannot read config file %s",name,fname); @@ -542,7 +542,7 @@ void cPluginXmltv2vdr::ReadInEPGSources(bool Reload) char *path=NULL; if (asprintf(&path,"%s/%s",EPGSOURCES,dirent->d_name)!=-1) { - if (access(path,R_OK|W_OK)!=-1) + if (access(path,R_OK)!=-1) { int fd=open(path,O_RDONLY); if (fd!=-1) |