From e2a48d8701f91b8e24fbe9e99e91eb72a87bb749 Mon Sep 17 00:00:00 2001 From: horchi Date: Sun, 5 Mar 2017 16:39:28 +0100 Subject: git init --- PLUGINS/epgdata/Makefile | 52 ++ .../epgdata/configs/channelmap.conf-epgdata-astra | 176 +++++ PLUGINS/epgdata/configs/epgd.conf | 10 + PLUGINS/epgdata/configs/epgdata-category.xml | 143 ++++ PLUGINS/epgdata/configs/epgdata-genre.xml | 507 ++++++++++++++ PLUGINS/epgdata/configs/epgdata-iso-8859-1.xsl | 8 + PLUGINS/epgdata/configs/epgdata-utf-8.xsl | 8 + PLUGINS/epgdata/configs/epgdata.xsl | 208 ++++++ PLUGINS/epgdata/epgdata.c | 760 +++++++++++++++++++++ PLUGINS/epgdata/epgdata.h | 52 ++ PLUGINS/epgdata/scripts/getepgdataids | 37 + PLUGINS/epgdata/scripts/getincludes | 6 + 12 files changed, 1967 insertions(+) create mode 100644 PLUGINS/epgdata/Makefile create mode 100644 PLUGINS/epgdata/configs/channelmap.conf-epgdata-astra create mode 100644 PLUGINS/epgdata/configs/epgd.conf create mode 100644 PLUGINS/epgdata/configs/epgdata-category.xml create mode 100644 PLUGINS/epgdata/configs/epgdata-genre.xml create mode 100644 PLUGINS/epgdata/configs/epgdata-iso-8859-1.xsl create mode 100644 PLUGINS/epgdata/configs/epgdata-utf-8.xsl create mode 100644 PLUGINS/epgdata/configs/epgdata.xsl create mode 100644 PLUGINS/epgdata/epgdata.c create mode 100644 PLUGINS/epgdata/epgdata.h create mode 100755 PLUGINS/epgdata/scripts/getepgdataids create mode 100755 PLUGINS/epgdata/scripts/getincludes (limited to 'PLUGINS/epgdata') diff --git a/PLUGINS/epgdata/Makefile b/PLUGINS/epgdata/Makefile new file mode 100644 index 0000000..837c3c1 --- /dev/null +++ b/PLUGINS/epgdata/Makefile @@ -0,0 +1,52 @@ +# +# Makefile +# +# See the README file for copyright information and how to reach the author. +# +# + +EPGD_SRC ?= ../.. + +include $(EPGD_SRC)/Make.config + +PLUGIN = epgdata + +SOFILE = libepgd-epgdata.so +OBJS = epgdata.o + +CFLAGS += -I$(EPGD_SRC) + +all: $(SOFILE) + +$(SOFILE): $(OBJS) + $(CC) $(CFLAGS) -shared $(OBJS) $(LIBS) -o $@ + +install: $(SOFILE) install-config + install -D $(SOFILE) $(_PLGDEST)/ + +clean: + @-rm -f $(OBJS) core* *~ *.so + +install-config: + if ! test -d $(CONFDEST); then \ + mkdir -p $(CONFDEST); \ + chmod a+rx $(CONFDEST); \ + fi + if ! test -f $(CONFDEST)/channelmap.conf-epgdata-astra; then \ + install --mode=644 -D ./configs/channelmap.conf-epgdata-astra $(CONFDEST)/; \ + fi + for i in $(wildcard ./configs/epgdata*.xml) $(wildcard ./configs/*.xsl); do\ + if ! test -f "$(CONFDEST)/`basename $$i`"; then\ + install --mode=644 -D "$$i" $(CONFDEST)/; \ + fi;\ + done; + if ! grep -q "^epgdata" $(CONFDEST)/epgd.conf; then \ + cat ./configs/epgd.conf >> $(CONFDEST)/epgd.conf; \ + fi + + +#*************************************************************************** +# dependencies +#*************************************************************************** + +epgdata.o : epgdata.c epgdata.h diff --git a/PLUGINS/epgdata/configs/channelmap.conf-epgdata-astra b/PLUGINS/epgdata/configs/channelmap.conf-epgdata-astra new file mode 100644 index 0000000..7a3af70 --- /dev/null +++ b/PLUGINS/epgdata/configs/channelmap.conf-epgdata-astra @@ -0,0 +1,176 @@ +epgdata:71 = S19.2E-1-1019-10301 // Das Erste HD +epgdata:37 = S19.2E-1-1011-11110 // ZDF HD +epgdata:194 = S19.2E-1-1025-10331 // PHOENIX HD +epgdata:56 = S19.2E-1-1010-11150 // 3sat HD +epgdata:58 = S19.2E-1-1019-10302 // arte HD +epgdata:146 = S19.2E-1-1201-28396 // Einsfestival HD +epgdata:57 = S19.2E-1-1010-11160 // KiKA HD +epgdata:275 = S19.2E-1-1011-11140 // zdf.kultur HD +epgdata:276 = S19.2E-1-1010-11170 // ZDFinfo HD +epgdata:659 = S19.2E-1-1011-11130 // zdf_neo HD + +epgdata:71 = S19.2E-1-1101-28106 // Das Erste +epgdata:37 = S19.2E-1-1079-28006 // ZDF +epgdata:194 = S19.2E-1-1051-28725 // PHOENIX +epgdata:56 = S19.2E-1-1079-28007 // 3sat +epgdata:58 = S19.2E-1-1051-28724 // arte +epgdata:146 = S19.2E-1-1051-28722 // Einsfestival +epgdata:475 = S19.2E-1-1051-28723 // EinsPlus +epgdata:57 = S19.2E-1-1079-28008 // KiKA +epgdata:100 = S19.2E-1-1051-28721 // tagesschau24 +epgdata:275 = S19.2E-1-1079-28016 // zdf.kultur +epgdata:276 = S19.2E-1-1079-28011 // ZDFinfo +epgdata:659 = S19.2E-1-1079-28014 // zdf_neo + +epgdata:38 = S19.2E-1-1089-12003 // RTL Television +epgdata:41 = S19.2E-1-1089-12020 // RTL2 +epgdata:43 = S19.2E-1-1089-12040 // SUPER RTL +epgdata:763 = S19.2E-1-1089-12061 // RTLNITRO +epgdata:39 = S19.2E-1-1107-17500 // SAT.1 +epgdata:774 = S19.2E-1-1107-17504 // SAT.1 Gold +epgdata:40 = S19.2E-1-1107-17501 // ProSieben +epgdata:44 = S19.2E-1-1107-17502 // kabel eins +epgdata:507 = S19.2E-133-33-63 // DMAX +epgdata:694 = S19.2E-133-5-776 // SIXX +epgdata:42 = S19.2E-1-1089-12060 // VOX +epgdata:660 = S19.2E-1-1115-13110 // ServusTV Deutschland +epgdata:64 = S19.2E-133-33-9001 // SPORT1 +epgdata:65 = S19.2E-1-1091-31200 // Eurosport Deutschland +epgdata:66 = S19.2E-1-1089-12090 // n-tv +epgdata:175 = S19.2E-1-1107-17503 // N24 +epgdata:391 = S19.2E-1-1115-13102 // GoTV +// = S19.2E-133-7-65 // DELUXE MUSIC +// = S19.2E-1-1078-28676 // VIVA Germany +// = S19.2E-1-1021-4600 // a.tv + +epgdata:471 = S19.2E-133-1-42 // 13th Street +epgdata:123 = S19.2E-133-17-21 // Beate-Uhse.TV +epgdata:133 = S19.2E-133-17-24 // Classica +epgdata:138 = S19.2E-133-4-14 // Discovery Channel +epgdata:139 = S19.2E-133-17-34 // Disney Channel +epgdata:460 = S19.2E-133-17-26 // Disney Junior +epgdata:657 = S19.2E-133-17-28 // Disney XD +// = S19.2E-133-1-16 // Fox Serie +epgdata:152 = S19.2E-133-17-518 // Goldstar TV +epgdata:154 = S19.2E-133-17-22 // Heimatkanal +epgdata:160 = S19.2E-133-17-19 // Junior +epgdata:627 = S19.2E-133-1-168 // Motorvision TV +epgdata:626 = S19.2E-133-4-12 // NatGeo Wild +epgdata:453 = S19.2E-133-4-13 // National Geographic Channel +epgdata:527 = S19.2E-133-1-27 // RTL Crime +epgdata:529 = S19.2E-133-1-29 // RTL Passion +epgdata:701 = S19.2E-133-10-117 // Sky 3D +epgdata:615 = S19.2E-133-1-23 // Sky Krimi +epgdata:625 = S19.2E-133-4-52 // Spiegel Geschichte +epgdata:472 = S19.2E-133-17-36 // Syfy +epgdata:590 = S19.2E-133-1-50 // TNT Serie + +// = S19.2E-133-13-127 // 13th Street HD +// = S19.2E-133-10-125 // AXN HD +epgdata:490 = S19.2E-133-6-130 // Discovery HD +// = S19.2E-133-11-116 // Disney Channel HD +// = S19.2E-133-14-128 // E! Entertainm. HD +// = S19.2E-133-10-124 // Fox HD +epgdata:632 = S19.2E-133-11-113 // History HD +// = S19.2E-133-6-118 // Nat Geo Wild HD +// = S19.2E-133-13-112 // NatGeo HD +epgdata:762 = S19.2E-133-12-108 // Sky Sport News HD +// = S19.2E-133-12-126 // Syfy HD +// = S19.2E-133-11-123 // TNT Serie HD +// = S19.2E-133-14-101 // Universal HD +epgdata:10058 = S19.2E-133-10-106 // Sky Action HDD +epgdata:10059 = S19.2E-133-12-107 // Sky Hits HD + +epgdata:539 = S19.2E-1-1037-5253 // Animax +// = S19.2E-133-15-37 // AXN Action +epgdata:536 = S19.2E-133-15-57 // Biography Channel +epgdata:127 = S19.2E-133-15-56 // Bloomberg TV +epgdata:531 = S19.2E-133-15-39 // Cartoon Network (S) +// = S19.2E-1-1115-13105 // ESPN America (S) +epgdata:452 = S19.2E-133-15-58 // History +epgdata:492 = S19.2E-1-1107-17506 // kabel eins classics +epgdata:450 = S19.2E-133-15-33 // Kinowelt TV +// = S19.2E-133-15-38 // Romance TV +epgdata:528 = S19.2E-1-1089-12030 // RTL Living +epgdata:766 = S19.2E-1-1015-4701 // SAT.1 emotions +// = S19.2E-1-1107-17505 // ProSieben MAXX +epgdata:633 = S19.2E-133-15-35 // TNT Film (TCM) + +epgdata:631 = S19.2E-133-13-111 // Disney Cinemagic HD +// = S19.2E-133-12-115 // MGM HD +// = S19.2E-133-10-106 // Sky Action HD +epgdata:767 = S19.2E-133-13-110 // Sky Atlantic HD +epgdata:629 = S19.2E-133-6-131 // Sky Cinema HD +// = S19.2E-133-12-107 // Sky Hits HD + +epgdata:610 = S19.2E-133-2-10 // Sky Cinema +epgdata:611 = S19.2E-133-2-11 // Sky Cinema +1 +epgdata:612 = S19.2E-133-2-43 // Sky Cinema +24 +epgdata:630 = S19.2E-133-3-25 // Disney Cinemagic +epgdata:1196 = S19.2E-133-3-515 // MGM +epgdata:613 = S19.2E-133-2-9 // Sky Action +epgdata:617 = S19.2E-133-2-8 // Sky Comedy +epgdata:616 = S19.2E-133-2-20 // Sky Emotion +epgdata:618 = S19.2E-133-3-41 // Sky Hits +epgdata:614 = S19.2E-133-3-516 // Sky Nostalgie +// = S19.2E-133-3-17 // Sky Sport News + +epgdata:784 = S19.2E-133-14-119 // Sport1 US HD +epgdata:621 = S19.2E-133-6-129 // Sky Sport HD 1 +epgdata:697 = S19.2E-133-13-114 // Sky Sport HD 2 +// = S19.2E-133-6-268 // Sky Sport HD 3 +// = S19.2E-133-11-122 // Sport1+ HD +epgdata:619 = S19.2E-133-4-221 // Sky Sport 1 +epgdata:620 = S19.2E-133-4-222 // Sky Sport 2 +epgdata:564 = S19.2E-133-15-59 // sportdigital + +// = S19.2E-133-11-132 // Eurosport HD +// = S19.2E-133-14-109 // Eurosport 2 HD + +epgdata:54 = S19.2E-1-1117-13001 // ORF1 +epgdata:55 = S19.2E-1-1117-13002 // ORF2 +epgdata:757 = S19.2E-1-1115-13101 // ORF III +epgdata:759 = S19.2E-1-1003-13221 // ORF SPORT+ + +epgdata:115 = S19.2E-1-1117-13012 // ATV +epgdata:761 = S19.2E-1-1003-13223 // ATV2 +// = S19.2E-1-1082-20007 // PULS 4 Austria +epgdata:622 = S19.2E-133-1-30 // Sky Sport Austria +// = S19.2E-1-1115-13104 // LT1-OOE +// = S19.2E-1-1115-13111 // ServusTV Oesterreich + +// epgdata:10100 // Sat.1 Emotions HD +epgdata:104 = S19.2E-1-1093-28487 // BR alpha + +// epgdata:1183 = // Animal Planet +// epgdata:211 = // Rhein-Neckar-Fernsehen +// epgdata:266 = // VIVA +epgdata:277 = S19.2E-133-33-51 // Tele 5 +// epgdata:455 = // Fashion TV +// epgdata:465 = // MTV Dance +// epgdata:466 = // MTV Hits UK +// epgdata:468 = // AXN +// epgdata:469 = // Extreme Sports Channel +// epgdata:46 = // WDR +// epgdata:473 = // ESPN Classic +// epgdata:47 = // NDR +epgdata:486 = S19.2E-133-5-1793 // Das VIERTE +// epgdata:48 = // MDR +// epgdata:49 = // HR +// epgdata:504 = // Eurosport 2 +// epgdata:50 = // SWR +// epgdata:51 = // BR +// epgdata:52 = // RBB +// epgdata:537 = // Anixe HD +// epgdata:590 = // TNT Serie + +// epgdata:623 = // Sky Bundesliga +// epgdata:624 = // National Geographic Channel HD +// epgdata:628 = // Sky Select +// epgdata:698 = // SPORT1+ +// epgdata:743 = // Sky Sport HD Extra +// epgdata:756 = // Spiegel TV Wissen +// epgdata:758 = // E! Entertainment + + + diff --git a/PLUGINS/epgdata/configs/epgd.conf b/PLUGINS/epgdata/configs/epgd.conf new file mode 100644 index 0000000..e5c2073 --- /dev/null +++ b/PLUGINS/epgdata/configs/epgd.conf @@ -0,0 +1,10 @@ + +# --------------- +# epgdata plugin +# --------------- + +epgdata.url = http://www.epgdata.com +epgdata.pin = insert-your-pin-here + +# Download timeout in seconds (default 180) +#epgdata.timeout = 180 diff --git a/PLUGINS/epgdata/configs/epgdata-category.xml b/PLUGINS/epgdata/configs/epgdata-category.xml new file mode 100644 index 0000000..c047314 --- /dev/null +++ b/PLUGINS/epgdata/configs/epgdata-category.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + 100 + Spielfilm + Spielfilm + + + 200 + Serie + Serie + + + 300 + Sport + Sport + + + 400 + Show + Show + + + 500 + Information + Information + + + 600 + Musik + Musik + + + 700 + Kinder + Kinder + + \ No newline at end of file diff --git a/PLUGINS/epgdata/configs/epgdata-genre.xml b/PLUGINS/epgdata/configs/epgdata-genre.xml new file mode 100644 index 0000000..ff63eaf --- /dev/null +++ b/PLUGINS/epgdata/configs/epgdata-genre.xml @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + 101 + Verschiedenes + + + 102 + Abenteuer + + + 103 + Action + + + 104 + Dokumentarfilm + + + 105 + Drama + + + 106 + Erotik + + + 108 + Fantasy + + + 109 + Heimat + + + 110 + Humor + + + 112 + Krimi + + + 113 + Kultur + + + 114 + Kurzfilm + + + 115 + Musik + + + 116 + Mystery + Horror + + + 117 + Romantik/Liebe + + + 119 + Science Fiction + + + 121 + Thriller + + + 122 + Western + + + 123 + Zeichentrick + + + 201 + Verschiedenes + + + 202 + Abenteuer + + + 203 + Action + + + 205 + Drama + + + 206 + Erotik + + + 207 + Familie + + + 208 + Fantasy + + + 210 + Humor + + + 211 + Krankenhaus + + + 212 + Krimi + + + 214 + Jugend + + + 216 + Mystery + Horror + + + 218 + Reality + + + 219 + Science Fiction + + + 220 + Soap + + + 221 + Thriller + + + 222 + Western + + + 223 + Zeichentrick + + + 301 + Verschiedenes + + + 331 + Boxen + + + 332 + Eishockey + + + 334 + Fußball + + + 335 + Olympia + + + 336 + Golf + + + 337 + Gymnastik + + + 338 + Handball + + + 339 + Motorsport + + + 340 + Radsport + + + 341 + Tennis + + + 342 + Wassersport + + + 343 + Wintersport + + + 344 + US-Sport + + + 345 + Leichtathletik + + + 346 + Volleyball + + + 347 + Extremsport + + + 348 + Reportagen + + + 401 + Verschiedenes + + + 406 + Erotik + + + 418 + Reality + + + 450 + Comedy + + + 451 + Familien-Show + + + 452 + Spielshows + + + 453 + Talkshows + + + 454 + Gerichtsshow + + + 455 + Homeshopping + + + 456 + Kochshow + + + 457 + Heimwerken + + + 501 + Verschiedenes + + + 560 + Geschichte + + + 561 + Magazin + + + 564 + Gesundheit + + + 565 + Motor + Verkehr + + + 566 + Nachrichten + + + 567 + Natur + + + 568 + Politik + + + 569 + Ratgeber + + + 570 + Reise + + + 571 + Wirtschaft + + + 572 + Wissen + + + 573 + Dokumentation + + + 601 + Verschiedenes + + + 680 + Jazz + + + 681 + Klassik + + + 682 + Musical + + + 683 + Rock + + + 684 + Volksmusik + + + 685 + Alternative + + + 686 + Pop + + + 687 + Clips + + + 688 + Show + + + 689 + Interview + + + 690 + Theater + + + 691 + Kino + + + 692 + Kultur + + + 701 + Verschiedenes + + + 790 + Filme + + + 791 + Nachrichten + + + 792 + Serien + + + 793 + Shows + + + 795 + Zeichentrick + + + 796 + Anime + + \ No newline at end of file diff --git a/PLUGINS/epgdata/configs/epgdata-iso-8859-1.xsl b/PLUGINS/epgdata/configs/epgdata-iso-8859-1.xsl new file mode 100644 index 0000000..24024ac --- /dev/null +++ b/PLUGINS/epgdata/configs/epgdata-iso-8859-1.xsl @@ -0,0 +1,8 @@ + + + + + + diff --git a/PLUGINS/epgdata/configs/epgdata-utf-8.xsl b/PLUGINS/epgdata/configs/epgdata-utf-8.xsl new file mode 100644 index 0000000..96a7b92 --- /dev/null +++ b/PLUGINS/epgdata/configs/epgdata-utf-8.xsl @@ -0,0 +1,8 @@ + + + + + + diff --git a/PLUGINS/epgdata/configs/epgdata.xsl b/PLUGINS/epgdata/configs/epgdata.xsl new file mode 100644 index 0000000..d5795ee --- /dev/null +++ b/PLUGINS/epgdata/configs/epgdata.xsl @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <xsl:value-of select="d19"/> + + + + + Serie + + + + + + + + + + + + + + + + TagesTipp + TopTipp + + + + + + + + + + + + + Sehr empfehlenswert + + + Empfehlenswert + + + Eher durchschnittlich + + + Eher uninteressant + + + + + + + + + + + + + DolbyDigital + Stereo + Zweikanal + + + + + + + + [PrimeTime] + [SchwarzWeiss] + [Untertitel] + [PayTV] + [Hörfilm] + [16:9] + + + + + + + + + + + jpg + + + + + + + + + + + + + + + + + / Allgemein * + / Allgemein ** + / Allgemein *** + / Allgemein **** + / Allgemein ***** + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +02:00 + +01:00 + + + +01:00 + + + + + + + diff --git a/PLUGINS/epgdata/epgdata.c b/PLUGINS/epgdata/epgdata.c new file mode 100644 index 0000000..3cf31ef --- /dev/null +++ b/PLUGINS/epgdata/epgdata.c @@ -0,0 +1,760 @@ +/* + * epgdata.c + * + * See the README file for copyright information + * + */ + +#include +#include + +#include "epgdata.h" + +//*************************************************************************** +// Epgdata +//*************************************************************************** + +Epgdata::Epgdata() + : Plugin() +{ + pxsltStylesheet = 0; + stmtByFileRef = 0; + stmtCleanDouble = 0; + stmtMarkOldEvents = 0; + selectByDate = 0; + selectId = 0; + + pin = 0; + timeout = 3 * tmeSecondsPerMinute; + baseurl = strdup("http://www.epgdata.com"); +} + +Epgdata::~Epgdata() +{ + if (pxsltStylesheet) + xsltFreeStylesheet(pxsltStylesheet); + + delete stmtByFileRef; + delete selectByDate; + delete stmtCleanDouble; + delete stmtMarkOldEvents; + + free(baseurl); + free(pin); +} + +int Epgdata::init(cEpgd* aObject, int aUtf8) +{ + Plugin::init(aObject, aUtf8); + + pxsltStylesheet = loadXSLT(getSource(), confDir, utf8); + + return done; +} + +int Epgdata::initDb() +{ + int status = success; + + // -------- + // by fileref (for pictures) + // select name from fileref + // where source = ? and fileref = ? + + stmtByFileRef = new cDbStatement(obj->fileDb); + + stmtByFileRef->build("select "); + stmtByFileRef->bind("NAME", cDBS::bndOut); + stmtByFileRef->build(" from %s where ", obj->fileDb->TableName()); + stmtByFileRef->bind("SOURCE", cDBS::bndIn | cDBS::bndSet); + stmtByFileRef->bind("FILEREF", cDBS::bndIn | cDBS::bndSet, " and "); + + status += stmtByFileRef->prepare(); + + // --------------- + // (for cleanup double) + // select name from fileref + // where source = ? order by name desc + + stmtCleanDouble = new cDbStatement(obj->fileDb); + + stmtCleanDouble->build("select "); + stmtCleanDouble->bind("NAME", cDBS::bndOut); + stmtCleanDouble->build(" from %s where ", obj->fileDb->TableName()); + stmtCleanDouble->bind("SOURCE", cDBS::bndIn | cDBS::bndSet); + stmtCleanDouble->build(" order by name desc"); + + status += stmtCleanDouble->prepare(); + + // --------- + // select channelid, merge, mergesp from channelmap + // where source = ? and extid = ? + + selectId = new cDbStatement(obj->mapDb); + + selectId->build("select "); + selectId->bind("CHANNELID", cDBS::bndOut); + selectId->bind("MERGESP", cDBS::bndOut, ", "); + selectId->bind("MERGE", cDBS::bndOut, ", "); + selectId->build(" from %s where ", obj->mapDb->TableName()); + selectId->bind("SOURCE", cDBS::bndIn | cDBS::bndSet); + selectId->bind("EXTERNALID", cDBS::bndIn | cDBS::bndSet, " and "); + + status += selectId->prepare(); + + // --------- + // select name, tag from filerf + // where source = 'epgdata' + // and name like ? + + valueName.setField(obj->fileDb->getField("NAME")); + valueNameLike.setField(obj->fileDb->getField("NAME")); + + selectByDate = new cDbStatement(obj->fileDb); + + selectByDate->build("select "); + selectByDate->bind(&valueName, cDBS::bndOut); + selectByDate->bind("FILEREF", cDBS::bndOut, ", "); + selectByDate->build(" from %s where source = '%s' and ", + obj->fileDb->TableName(), getSource()); + selectByDate->bindCmp(0, &valueNameLike, "like"); + + status += selectByDate->prepare(); + +// // -------- +// // update events set delflg = ?, updflg = ?, fileref = ?, updsp = ? +// // where fileref = ? +// // and source = ?; +// // and updflg in (....) + +// valueFileRef.setField(obj->eventsDb->getField("FileRef")); +// stmtSetDelByFileref = new cDbStatement(obj->eventsDb); + +// stmtSetDelByFileref->build("update %s set ", obj->eventsDb->TableName()); +// stmtSetDelByFileref->bind("DelFlg", cDbService::bndIn |cDbService:: bndSet); +// stmtSetDelByFileref->bind("UpdFlg", cDbService::bndIn |cDbService:: bndSet, ", "); +// stmtSetDelByFileref->bind("FileRef", cDbService::bndIn | cDbService::bndSet, ", "); +// stmtSetDelByFileref->bind("UpdSp", cDbService::bndIn | cDbService::bndSet, ", "); +// stmtSetDelByFileref->build( " where "); +// stmtSetDelByFileref->bind(&valueFileRef, cDbService::bndIn |cDbService:: bndSet); +// stmtSetDelByFileref->bind("Source", cDbService::bndIn | cDbService::bndSet, " and "); +// stmtSetDelByFileref->build(" and updflg in (%s)", Us::getDeletable()); + +// status += stmtSetDelByFileref->prepare(); + + // ---------- + // update events + // set updflg = case when updflg in (...) then 'D' else updflg end, + // delflg = 'Y', + // updsp = unix_timestamp() + // where source = '...' + // and (source, fileref) not in (select source,fileref from fileref) + + stmtMarkOldEvents = new cDbStatement(obj->eventsDb); + + stmtMarkOldEvents->build("update %s set ", obj->eventsDb->TableName()); + stmtMarkOldEvents->build("updflg = case when updflg in (%s) then 'D' else updflg end, ", cEventState::getDeletable()); + stmtMarkOldEvents->build("delflg = 'Y', updsp = unix_timestamp()"); + stmtMarkOldEvents->build(" where source = '%s'", getSource()); + stmtMarkOldEvents->build(" and (source, fileref) not in (select source,fileref from fileref)"); + + status += stmtMarkOldEvents->prepare(); + + // ---------- + // if no epgdata entry in fileref read files from FS to table + + int count = 0; + obj->fileDb->countWhere("source = 'epgdata'", count); + + if (!count) + { + char* path = 0; + DIR* dir; + dirent* dp; + + asprintf(&path, "%s/%s", EpgdConfig.cachePath, getSource()); + chkDir(path); + + if (!(dir = opendir(path))) + { + tell(0, "Error: Opening cache path '%s' failed, %s", path, strerror(errno)); + free(path); + return fail; + } + + while ((dp = readdir(dir))) + { + char* fileRef = 0; + char* file = 0; + char* tag = 0; + struct stat sb; + + if (!strstr(dp->d_name, "_de_qy.zip")) + continue; + + asprintf(&file, "%s/%s", path, dp->d_name); + stat(file, &sb); + free(file); + + asprintf(&tag, "%ld", sb.st_size); + asprintf(&fileRef, "%s-%s", dp->d_name, tag); + + // store file and let tag NULL to indicate that processing is needed + + obj->fileDb->clear(); + obj->fileDb->setValue("NAME", dp->d_name); + obj->fileDb->setValue("SOURCE", getSource()); + obj->fileDb->setValue("EXTERNALID", "0"); + obj->fileDb->setValue("FILEREF", fileRef); + obj->fileDb->store(); + + tell(1, "Added '%s' to table fileref", dp->d_name); + free(fileRef); + free(tag); + } + + free(path); + closedir(dir); + } + + return success; +} + +int Epgdata::exitDb() +{ + delete stmtByFileRef; stmtByFileRef = 0; + delete stmtCleanDouble; stmtCleanDouble = 0; + delete selectByDate; selectByDate = 0; + delete selectId; selectId = 0; + delete stmtMarkOldEvents; stmtMarkOldEvents = 0; + + return success; +} + +//*************************************************************************** +// At Config Item +//*************************************************************************** + +int Epgdata::atConfigItem(const char* Name, const char* Value) +{ + if (!strcasecmp(Name, "Url")) { free(baseurl); baseurl = strdup(Value); } + else if (!strcasecmp(Name, "Pin")) { free(pin); pin = strdup(Value); } + else if (!strcasecmp(Name, "Timeout")) { timeout = atoi(Value); } + + else return fail; + + return success; +} + +//*************************************************************************** +// Ready +//*************************************************************************** + +int Epgdata::ready() +{ + static int count = na; + + if (isEmpty(pin)) + return no; + + if (count == na) + { + char* where; + + asprintf(&where, "source = '%s'", getSource()); + + if (obj->mapDb->countWhere(where, count) != success) + count = na; + + free(where); + } + + return count > 0; +} + +//*************************************************************************** +// Process Day +//*************************************************************************** + +int Epgdata::processDay(int day, int fullupdate, Statistic* statistic) +{ + char* directory = 0; + char* fspath = 0; + char* path = 0; // name of the zip file including the path + int haveOneForThisDay = no; + MemoryStruct data; + int fileSize = 0; + char* fileRef = 0; + char* url = 0; + char* logurl = 0; + int load = yes; + char* like = 0; + int bSize = 0; + char entryName[200+TB]; + MemoryStruct uzdata; + // char* oldFileRef = 0; + + int status; + + // path to zip files, url, .. + + asprintf(&directory, "%s/%s", EpgdConfig.cachePath, getSource()); + chkDir(directory); + asprintf(&url, "%s/index.php?action=sendPackage&iOEM=VDR&pin=%s&dayOffset=%d&dataType=xml", baseurl, pin, day); + asprintf(&logurl, "%s/index.php?action=sendPackage&iOEM=VDR&pin=%s&dayOffset=%d&dataType=xml", baseurl, "insert-your-pin-here", day); + + // first get the http header + + data.clear(); + data.headerOnly = yes; + + status = obj->downloadFile(url, fileSize, &data); + + if (status != success || isEmpty(data.name)) + { + tell(1, "Download header for day (%d) at '%s' failed, aborting, got name '%s', status was %d", + day, logurl, data.name ? data.name : "", status); + status = fail; + goto Exit; + } + + tell(2, "Got info for day (%d), file '%s' with tag '%s'", day, data.name, data.tag); + + asprintf(&fileRef, "%s-%s", data.name, data.tag); + asprintf(&path, "%s/%s", directory, data.name); + + // lookup file + + obj->fileDb->clear(); + obj->fileDb->setValue("NAME", data.name); + obj->fileDb->setValue("SOURCE", getSource()); + + // 1:1 match ? + + obj->fileDb->find(); + + asprintf(&like, "%.8s_%%", data.name); + valueNameLike.setValue(like); + free(like); + + // check for update + + if (selectByDate->find()) + { + haveOneForThisDay = yes; + // oldFileRef = strdup(obj->fileDb->getStrValue("FileRef")); + } + + if (haveOneForThisDay && day >= EpgdConfig.upddays) + { + // don't check for update of existing files more than 'upddays' in the future + + tell(2, "Skipping update check of file '%s' for day %d", data.name, day); + + statistic->nonUpdates++; + status = success; + load = no; + } + else if (haveOneForThisDay && obj->fileDb->hasValue("FileRef", fileRef)) + { + tell(2, "Skipping download of day (%d) due to non-update", day); + statistic->nonUpdates++; + status = success; + load = no; + } + + if (!load && !obj->fileDb->getRow()->getValue("Tag")->isNull()) + goto Exit; + + // not exist, update or not processed -> work + + // first check if we have it already on fs + + asprintf(&fspath, "%s/%s", directory, valueName.getStrValue()); + + if (!load && fileExists(fspath)) + { + tell(1, "File '%s' exist, loading from filesystem", fspath); + + obj->loadFromFs(&data, valueName.getStrValue(), getSource()); + + free(fileRef); + free(path); + path = strdup(fspath); + asprintf(&fileRef, "%s-%s", valueName.getStrValue(), data.tag); + + obj->fileDb->clear(); + obj->fileDb->setValue("NAME", valueName.getStrValue()); + obj->fileDb->setValue("SOURCE", getSource()); + } + + free(fspath); + + if (load) + { + tell(0, "Download file: '%s' to '%s", logurl, data.name); + + data.clear(); + + if (obj->downloadFile(url, fileSize, &data, timeout) != success) + { + tell(0, "Download of day (%d) from '%s' failed", day, logurl); + status = fail; + goto Exit; + } + + statistic->bytes += data.size; + statistic->files++; + + // store zip to FS + + obj->storeToFs(&data, data.name, getSource()); + } + + if (data.isEmpty()) + goto Exit; + + // unzip ... + + uzdata.clear(); + + if (unzip(path, /*filter*/ ".xml", uzdata.memory, bSize, entryName) == success) + { + tell(0, "Processing file '%s' for day %d (%d/%d)", + fileRef, day, haveOneForThisDay, load); + + uzdata.size = bSize; + + // store ? + + if (EpgdConfig.storeXmlToFs) + obj->storeToFs(&uzdata, entryName, getSource()); + + // process file .. + + obj->connection->startTransaction(); + + if ((status = processFile(uzdata.memory, uzdata.size, fileRef)) != success) + statistic->rejected++; + + if (!obj->dbConnected()) + { + status = fail; + goto Exit; + } + +// we can use this code instead of "stmtMarkOldEvents" !! +// but we have to complete it like tvm plugin! +// if (haveOneForThisDay && load && strcmp(oldFileRef, fileRef) != 0) +// { +// // mark 'old' entrys in events table as deleted +// // and 'fake' fileref to new to avoid deletion at cleanup + +// tell(0, "Removing events of fileref '%s' for day %d", oldFileRef, day); + +// obj->eventsDb->clear(); +// obj->eventsDb->setValue("DelFlg", "Y"); +// obj->eventsDb->setValue("UpdFlg", "D"); +// obj->eventsDb->setValue("FileRef", fileRef); // fake to new fileref +// obj->eventsDb->setValue("UpdSp", time(0)); +// obj->eventsDb->setValue("Source", getSource()); +// valueFileRef.setValue(oldFileRef); // old fileref +// stmtSetDelByFileref->execute(); +// } + + // Confirm processing of file + + obj->fileDb->setValue("EXTERNALID", "0"); + obj->fileDb->setValue("TAG", data.tag); + obj->fileDb->setValue("FILEREF", fileRef); + obj->fileDb->store(); + + obj->connection->commit(); + } + + Exit: + + // free(oldFileRef); + obj->fileDb->reset(); + selectByDate->freeResult(); + + uzdata.clear(); + free(url); + free(logurl); + free(fileRef); + free(directory); + free(path); + + return status; +} + +//*************************************************************************** +// Process File +//*************************************************************************** + +int Epgdata::processFile(const char* data, int size, const char* fileRef) +{ + xmlDocPtr transformedDoc; + xmlNodePtr xmlRoot; + int count = 0; + + if ((transformedDoc = obj->transformXml(data, size, pxsltStylesheet, fileRef)) == 0) + { + tell(0, "XSLT transformation for '%s' failed, ignoring", fileRef); + return fail; + } + + if (!(xmlRoot = xmlDocGetRootElement(transformedDoc))) + { + tell(0, "Invalid xml document returned from xslt for '%s', ignoring", fileRef); + return fail; + } + + // DEBUG: xmlSaveFile("/tmp/test.xml", transformedDoc); + + for (xmlNodePtr node = xmlRoot->xmlChildrenNode; node && obj->dbConnected(); node = node->next) + { + char* prop = 0; + tEventId eventid; + char* extid = 0; + + // skip all unexpected elements + + if (node->type != XML_ELEMENT_NODE || strcmp((char*)node->name, "event") != 0) + continue; + + // get/check eventid + + if (!(prop = (char*)xmlGetProp(node, (xmlChar*)"id")) || !*prop || !(eventid = atoll(prop))) + { + xmlFree(prop); + tell(0, "Missing event id, ignoring!"); + continue; + } + + xmlFree(prop); + + // get/check provider id + + if (!(prop = (char*)xmlGetProp(node, (xmlChar*)"provid")) || !*prop || !atoi(prop)) + { + xmlFree(prop); + tell(0, "Missing provider id, ignoring!"); + continue; + } + + extid = strdup(prop); + xmlFree(prop); + + obj->mapDb->clear(); + obj->mapDb->setValue("EXTERNALID", extid); + obj->mapDb->setValue("SOURCE", getSource()); + free(extid); + + for (int f = selectId->find(); f; f = selectId->fetch()) + { + int insert; + const char* channelId = obj->mapDb->getStrValue("CHANNELID"); + + // create event .. + + obj->eventsDb->clear(); + obj->eventsDb->setBigintValue("EVENTID", eventid); + obj->eventsDb->setValue("CHANNELID", channelId); + + insert = !obj->eventsDb->find(); + + obj->eventsDb->setValue("SOURCE", getSource()); + obj->eventsDb->setValue("FILEREF", fileRef); + + // auto parse and set other fields + + obj->parseEvent(obj->eventsDb->getRow(), node); + + // ... + + time_t mergesp = obj->mapDb->getIntValue("MERGESP"); + long starttime = obj->eventsDb->getIntValue("STARTTIME"); + int merge = obj->mapDb->getIntValue("MERGE"); + + // store .. + + if (insert) + { + // handle insert + + obj->eventsDb->setValue("VERSION", 0xFF); + obj->eventsDb->setValue("TABLEID", 0L); + obj->eventsDb->setValue("USEID", 0L); + + if (starttime <= mergesp) + obj->eventsDb->setCharValue("UPDFLG", cEventState::usInactive); + else + obj->eventsDb->setCharValue("UPDFLG", merge > 1 ? cEventState::usMergeSpare : cEventState::usActive); + + obj->eventsDb->insert(); + } + else + { + if (obj->eventsDb->hasValue("DELFLG", "Y")) + obj->eventsDb->setValue("DELFLG", "N"); + + if (obj->eventsDb->hasValue("UPDFLG", "D")) + { + if (starttime <= mergesp) + obj->eventsDb->setCharValue("UPDFLG", cEventState::usInactive); + else + obj->eventsDb->setCharValue("UPDFLG", merge > 1 ? cEventState::usMergeSpare : cEventState::usActive); + } + + obj->eventsDb->update(); + } + + obj->eventsDb->reset(); + count++; + } + } + + selectId->freeResult(); + + xmlFreeDoc(transformedDoc); + + tell(2, "XML File '%s' processed, updated %d events", fileRef, count); + + return success; +} + +//*************************************************************************** +// Get Picture +//*************************************************************************** + +int Epgdata::getPicture(const char* imagename, const char* fileRef, MemoryStruct* data) +{ + int fileSize = 0; + char* path = 0; + char entryName[200+TB]; + + data->clear(); + + // lookup file information + + obj->fileDb->clear(); + obj->fileDb->setValue("FILEREF", fileRef); + obj->fileDb->setValue("SOURCE", getSource()); + + if (stmtByFileRef->find()) + asprintf(&path, "%s/epgdata/%s", EpgdConfig.cachePath, + obj->fileDb->getStrValue("Name")); + + stmtByFileRef->freeResult(); + + if (!path) + { + tell(0, "Error: No entry with fileref '%s' to lookup image '%s' found", + fileRef, imagename); + return 0; + } + + if (unzip(path, imagename, data->memory, fileSize, entryName) == success) + { + data->size = fileSize; + tell(2, "Unzip of image '%s' succeeded", imagename); + } + + free(path); + + return fileSize; +} + +int Epgdata::cleanupAfter() +{ + const char* ext = ".zip"; + struct dirent* dirent; + DIR* dir; + char* pdir; + int count = 0; + char* last = 0; + + // cleanup *.zip in FS cache ... + + // remove old versions for each day + + obj->fileDb->clear(); + obj->fileDb->setValue("SOURCE", getSource()); + + for (int f = stmtCleanDouble->find(); f; f = stmtCleanDouble->fetch()) + { + const char* name = obj->fileDb->getStrValue("NAME"); + + if (last && strncmp(name, last, 8) == 0) + { + char* where; + tell(1, "Remove old epgdata file '%s' from table", name); + asprintf(&where, "name = '%s'", name); + obj->fileDb->deleteWhere("%s", where); + free(where); + } + + free(last); + last = strdup(name); + } + + free(last); + stmtCleanDouble->freeResult(); + + // mark wasted events (delflg, ...) + + stmtMarkOldEvents->execute(); + + // cleanup filesystem, remove files which not referenced in table + + asprintf(&pdir, "%s/%s", EpgdConfig.cachePath, getSource()); + + if (!(dir = opendir(pdir))) + { + tell(1, "Can't open directory '%s', '%s'", pdir, strerror(errno)); + free(pdir); + + return done; + } + + tell(1, "Starting cleanup of epgdata zip's in '%s'", pdir); + + free(pdir); + + while ((dirent = readdir(dir))) + { + // check extension + + if (strncmp(dirent->d_name + strlen(dirent->d_name) - strlen(ext), ext, strlen(ext)) != 0) + continue; + + // lookup file + + obj->fileDb->clear(); + obj->fileDb->setValue("NAME", dirent->d_name); + obj->fileDb->setValue("SOURCE", getSource()); + + if (!obj->fileDb->find()) + { + asprintf(&pdir, "%s/%s/%s", EpgdConfig.cachePath, getSource(), dirent->d_name); + + if (!removeFile(pdir)) + count++; + + free(pdir); + } + + obj->fileDb->reset(); + } + + closedir(dir); + + tell(1, "Cleanup finished, removed (%d) epgdata files", count); + + return success; +} + +//*************************************************************************** + +extern "C" void* EPGPluginCreator() { return new Epgdata(); } diff --git a/PLUGINS/epgdata/epgdata.h b/PLUGINS/epgdata/epgdata.h new file mode 100644 index 0000000..0bb0d88 --- /dev/null +++ b/PLUGINS/epgdata/epgdata.h @@ -0,0 +1,52 @@ +/* + * epgdata.h + * + * See the README file for copyright information + * + */ + +#include "epgd.h" + +//*************************************************************************** +// Epgdata +//*************************************************************************** + +class Epgdata : public Plugin +{ + public: + + Epgdata(); + virtual ~Epgdata(); + + int init(cEpgd* aObject, int aUtf8); + int initDb(); + int exitDb(); + int atConfigItem(const char* Name, const char* Value); + + const char* getSource() { return "epgdata"; } + + int getPicture(const char* imagename, const char* fileRef, MemoryStruct* data); + int processDay(int day, int fullupdate, Statistic* statistic); + int cleanupAfter(); + int ready(); + + protected: + + int processFile(const char* data, int size, const char* fileRef); + + cDbValue valueNameLike; + cDbValue valueName; + cDbValue valueFileRef; + cDbStatement* stmtByFileRef; + cDbStatement* stmtCleanDouble; + cDbStatement* selectId; + cDbStatement* selectByDate; + cDbStatement* stmtMarkOldEvents; + xsltStylesheetPtr pxsltStylesheet; + + // config + + char* baseurl; + int timeout; + char* pin; +}; diff --git a/PLUGINS/epgdata/scripts/getepgdataids b/PLUGINS/epgdata/scripts/getepgdataids new file mode 100755 index 0000000..898a647 --- /dev/null +++ b/PLUGINS/epgdata/scripts/getepgdataids @@ -0,0 +1,37 @@ + +path="/tmp/epgdata/" +file=$path/"info.zip" + +mkdir -p $path + +cd $path +rm -f * + +wget "http://www.epgdata.com/index.php?action=sendInclude&iOEM=&pin=XYZ&dataType=xml" -q -O $file + +unzip $file > /dev/null 2>&1 +rm $file + +chanfile="channel_y.xml" + +cat $chanfile | while read line; do + + if [[ ${line} =~ "" ]]; then + + chan=${line#*>} + chan=${chan%<*} + + else + + if [[ ${line} =~ "" ]]; then + + id=${line#*>} + id=${id%<*} + + echo "epgdata:$id // $chan" + + fi + + fi + +done | sort diff --git a/PLUGINS/epgdata/scripts/getincludes b/PLUGINS/epgdata/scripts/getincludes new file mode 100755 index 0000000..120f1c1 --- /dev/null +++ b/PLUGINS/epgdata/scripts/getincludes @@ -0,0 +1,6 @@ + +rm -f include.zip +wget "http://www.epgdata.com/index.php?action=sendInclude&iOEM=&pin=&dataType=xml" -q -O include.zip +unzip include.zip +rm -f include.zip + -- cgit v1.2.3