From 2897776ceea4177e110b22e7efefd5dce50304a8 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sun, 28 Oct 2012 16:53:08 +0100 Subject: Extract the the Short Text from the Extended description for MHW2 and Sky --- eepg.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- eepg.h | 1 + 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/eepg.c b/eepg.c index 2ba6008..a53d823 100644 --- a/eepg.c +++ b/eepg.c @@ -222,7 +222,7 @@ protected: //virtual void FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]); virtual void WriteToSchedule (tChannelID channelID, cSchedules* s, unsigned int EventId, unsigned int StartTime, unsigned int Duration, char *Text, char *SummText, unsigned short int ThemeId, - unsigned short int TableId, unsigned short int Version, char Rating = 0x00); + unsigned short int TableId, unsigned short int Version, char Rating = 0x00, unsigned char ShortTextLenght = 0); virtual void LoadIntoSchedule (void); //virtual void LoadEquivalentChannels (void); @@ -1235,7 +1235,11 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse * \param Duration the Duration of the event in minutes * \param ps points to array of schedules ps[eq], where eq is equivalence number of the channel. If channelId is invalid then ps[eq]=NULL */ -void cFilterEEPG::WriteToSchedule (tChannelID channelID, cSchedules* pSchedules, unsigned int EventId, unsigned int StartTime, unsigned int Duration, char *Text, char *SummText, unsigned short int ThemeId, unsigned short int TableId, unsigned short int Version, char Rating) +void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, + unsigned int EventId, unsigned int StartTime, unsigned int Duration, + char *Text, char *SummText, unsigned short int ThemeId, + unsigned short int TableId, unsigned short int Version, char Rating, + unsigned char ShTxtLen) { bool WrittenTitle = false; bool WrittenSummary = false; @@ -1277,21 +1281,53 @@ void cFilterEEPG::WriteToSchedule (tChannelID channelID, cSchedules* pSchedules, if (Rating) { Event->SetParentalRating(Rating); } - char *tmp; if (Text != 0x00) { WrittenTitle = true; CleanString ((uchar *) Text); Event->SetTitle (Text); } - Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); + + char *tmp = NULL; + if (SummText && ShTxtLen) { + + //TODO DPE template + tmp = (char *) malloc(2*ShTxtLen); + if (!tmp) { + LogE(0, prep("tmp memory allocation error.")); + return; + } +// decodeText2((unsigned char *)SummText, ShTxtLen, tmp, ShTxtLen + 1); + memcpy(tmp, SummText, ShTxtLen); + tmp[ShTxtLen] = '\0'; + + //Do not use Subtitle if it is substring of Title + if (strncmp(Text, tmp, ShTxtLen) == 0) { + free(tmp); + tmp = NULL; + } + + } + if (!tmp) + Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); Event->SetShortText (tmp); free(tmp); + +/* + char *tmp; + if (!ShortText || strcmp(ShortText, Text) == 0) { + Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); + Event->SetShortText (tmp); + free(tmp); + } else + Event->SetShortText (ShortText); +*/ //strreplace(t, '|', '\n'); if (SummText != 0x00) { WrittenSummary = true; CleanString ((uchar *) SummText); //Add themes and categories epgsearch style + //TODO DPE move this char *theme; Asprintf (&theme, "%s", Themes[ThemeId]); if (theme && 0 != strcmp(theme,"")) { @@ -2008,6 +2044,7 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length) S->NumReplays = Summary->NumReplays; S->EventId = HILO32 (Summary->ProgramId); S->Text = Text; + S->ShortTextLength = 0; //TODO find for MHW1 int i = 0; do { S->Replays[i].MjdTime = 0; //only used for SKY @@ -2118,14 +2155,18 @@ int cFilterEEPG::GetSummariesMHW2 (const u_char * Data, int Length) } } S->Text = (unsigned char *) malloc (SummaryLength + 2); - S->Text[SummaryLength] = '\0'; //end string with NULL character if (S->Text == NULL) { LogE(0, prep("Summaries memory allocation error.")); return 0; //fatal error } + S->Text[SummaryLength] = '\0'; //end string with NULL character + //memcpy (S->Text, tmp, SummaryLength); decodeText2(tmp,SummaryLength,(char*)S->Text,SummaryLength + 1); CleanString (S->Text); + char * delim = strchr ( (char *)S->Text, '\n' ); + S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; + LogI(3, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); nSummaries++; } else { @@ -2349,6 +2390,7 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) unsigned short int MjdTime; int Len1; int Len2; + const char* STxtDelim = Format == SKY_UK?": ":" - "; if (Length < 20) { return 1; //non fatal error I assume @@ -2372,6 +2414,7 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) S->Replays[0].MjdTime = MjdTime; S->NumReplays = 0; //not used S->EventId = (Data[p] << 8) | Data[p + 1]; + S->ShortTextLength = 0; Len1 = ((Data[p + 2] & 0x0f) << 8) | Data[p + 3]; if (Data[p + 4] != 0xb9) { LogD(5, prep("Data error signature for title - Data[p + 4] != 0xb5")); @@ -2397,6 +2440,8 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) memcpy (S->Text, tmp, Len2); S->Text[Len2] = '\0'; //end string with NULL character CleanString (S->Text); + char * delim = strstr ( (char *)S->Text, STxtDelim ); + S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; LogI(3, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); p += Len1; nSummaries++; @@ -2518,9 +2563,13 @@ void cFilterEEPG::LoadIntoSchedule (void) TableId = T->TableId; } +// LogD (0, prep("EventId %08x Titlenr %d:SummAv:%x,Un1:%x,Un2:%x,Un3:%x,Name:%s,STxtLn:%dSummary:%s."), +// T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text, S->ShortTextLength, S->Text); + WriteToSchedule (chanID, s, T->EventId, StartTime, T->Duration / 60, (char *) T->Text, - (char *) S->Text, T->ThemeId, TableId, 0, rating); + (char *) S->Text, T->ThemeId, TableId, 0, rating, S->ShortTextLength); sortSchedules(s, chanID); + //if (shortText != NULL) delete [] shortText; //FinishWriteToSchedule (C, s, p); //Replays--; @@ -2563,7 +2612,7 @@ void cFilterEEPG::LoadIntoSchedule (void) rating = T->Rating; } WriteToSchedule (chanID, s, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text, - NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating); + NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating, S->ShortTextLength); //FinishWriteToSchedule (C, s, p); sortSchedules(s, chanID); diff --git a/eepg.h b/eepg.h index 7e1cc74..8eb3f2d 100644 --- a/eepg.h +++ b/eepg.h @@ -70,6 +70,7 @@ typedef struct { unsigned int EventId;//short is not sufficient for Nagra unsigned short int NumReplays; unsigned char * Text; + unsigned char ShortTextLength; } Summary_t; -- cgit v1.2.3 From 023c24e88bae40f472cb0c37fc02ea67d4a5b5bc Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 29 Oct 2012 11:18:28 +0100 Subject: use std string for manipulation of Short Text from description --- eepg.c | 55 +++++++++++++++++++++++++++++++++++++------------------ epghandler.c | 6 ++++++ epghandler.h | 2 +- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/eepg.c b/eepg.c index c740f8e..0afecc7 100644 --- a/eepg.c +++ b/eepg.c @@ -266,6 +266,13 @@ void cFilterEEPG::SetStatus (bool On) for (int i = 0; i <= HIGHEST_FORMAT; i++) UnprocessedFormat[i] = 0; //pid 0 is assumed to be nonvalid for EEPG transfers AddFilter (0, 0); + if (Channel()->Nid() == 0x01) { + setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); + LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); + } else { + unsetenv("VDR_CHARSET_OVERRIDE"); + LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); + } } cFilter::SetStatus (On); Trigger (); @@ -1288,30 +1295,43 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, } char *tmp = NULL; + string shText; if (SummText && ShTxtLen) { - //TODO DPE template - tmp = (char *) malloc(2*ShTxtLen); - if (!tmp) { - LogE(0, prep("tmp memory allocation error.")); - return; + shText.assign(SummText,ShTxtLen); + + string tmpTitle(Text); + if (Format == MHW2 && !shText.empty()) { + //TODO (HD) channels + size_t found = tmpTitle.find(" (HD)"); + if (found != string::npos) + tmpTitle.erase(found, 5); + found = shText.compare(0, tmpTitle.size() + 2, string(tmpTitle + ": ")); + if (shText.compare(0, tmpTitle.size() + 2, string(tmpTitle + ": "))==0) + shText.erase(0, tmpTitle.size() + 2); } -// decodeText2((unsigned char *)SummText, ShTxtLen, tmp, ShTxtLen + 1); - memcpy(tmp, SummText, ShTxtLen); - tmp[ShTxtLen] = '\0'; - //Do not use Subtitle if it is substring of Title - if (strncmp(Text, tmp, ShTxtLen) == 0) { - free(tmp); - tmp = NULL; - } + //Do not use Subtitle if it is substring of Title + if (tmpTitle.compare(0, shText.size(), shText) == 0) + shText.clear(); + +#define MAX_USEFUL_EPISODE_LENGTH 40 + // From VDR FixEPG Bugs + // Some channels put a whole lot of information in the ShortText and leave + // the Description totally empty. So if the ShortText length exceeds + // MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description + // instead: + if (!shText.empty() && shText.size() > MAX_USEFUL_EPISODE_LENGTH) + shText.clear(); } - if (!tmp) + if (!shText.empty()) + Event->SetShortText (shText.c_str()); + else { Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); - Event->SetShortText (tmp); - free(tmp); - + Event->SetShortText (tmp); + free(tmp); + } /* char *tmp; if (!ShortText || strcmp(ShortText, Text) == 0) { @@ -2159,7 +2179,6 @@ int cFilterEEPG::GetSummariesMHW2 (const u_char * Data, int Length) LogE(0, prep("Summaries memory allocation error.")); return 0; //fatal error } - //memcpy (S->Text, tmp, SummaryLength); //S->Text[SummaryLength] = '\0'; //end string with NULL character decodeText2(tmp,SummaryLength,(char*)S->Text,2 * SummaryLength + 1); diff --git a/epghandler.c b/epghandler.c index a1b92c3..4e7ab30 100644 --- a/epghandler.c +++ b/epghandler.c @@ -184,6 +184,12 @@ bool cEEpgHandler::SortSchedule(cSchedule* Schedule) { return true; } +bool cEEpgHandler::FixEpgBugs(cEvent* Event) +{ + //TODO to see which channels have bugs - disable fixing with true + return false; +} + bool cEEpgHandler::DropOutdated(cSchedule* Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; diff --git a/epghandler.h b/epghandler.h index 003fd32..feaad9d 100644 --- a/epghandler.h +++ b/epghandler.h @@ -29,7 +29,7 @@ public: virtual bool SetStartTime(cEvent *Event, time_t StartTime); virtual bool SetDuration(cEvent *Event, int Duration); virtual bool SetVps(cEvent *Event, time_t Vps); - virtual bool FixEpgBugs(cEvent *Event) { return false; } + virtual bool FixEpgBugs(cEvent *Event); virtual bool HandleEvent(cEvent *Event); virtual bool SortSchedule(cSchedule *Schedule); virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); -- cgit v1.2.3 From 89602f07f60672d0d7ab1dbf8f06be9e8f6566d1 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 29 Oct 2012 11:33:53 +0100 Subject: Try to fix the charset override by setting the envioronment variable Add option to setup not to set Category and Genere to empty short texts --- eepg.c | 18 ++++++++++++++++-- setupeepg.c | 2 ++ setupeepg.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/eepg.c b/eepg.c index 0afecc7..5bcd1d4 100644 --- a/eepg.c +++ b/eepg.c @@ -121,7 +121,9 @@ cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void) Add (new cMenuEditBoolItem (tr ("Show order information"), &data->OrderInfo)); Add (new cMenuEditBoolItem (tr ("Show rating information"), &data->RatingInfo)); Add (new cMenuEditBoolItem (tr ("Fix EPG data"), &data->FixEpg)); + SetSection (tr ("General")); Add (new cMenuEditBoolItem (tr ("Display summary message"), &data->DisplayMessage)); + Add (new cMenuEditBoolItem (tr ("Replace Empty Short Text with Category - Genre"), &data->ReplaceEmptyShText)); #ifdef DEBUG Add (new cMenuEditIntItem (tr ("Level of logging verbosity"), &data->LogLevel, 0, 5)); Add (new cMenuEditBoolItem (tr ("Process EIT info with EEPG"), &data->ProcessEIT)); @@ -136,6 +138,7 @@ void cMenuSetupPremiereEpg::Store (void) SetupStore ("RatingInfo", SetupPE->RatingInfo); SetupStore ("FixEpg", SetupPE->FixEpg); SetupStore ("DisplayMessage", SetupPE->DisplayMessage); + SetupStore ("ReplaceEmptyShText", SetupPE->ReplaceEmptyShText); #ifdef DEBUG SetupStore ("LogLevel", SetupPE->LogLevel); SetupStore ("ProcessEIT", SetupPE->ProcessEIT); @@ -1294,7 +1297,8 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, Event->SetTitle (Text); } - char *tmp = NULL; + char* tmp = NULL; + string shText; string shText; if (SummText && ShTxtLen) { @@ -1327,7 +1331,7 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, } if (!shText.empty()) Event->SetShortText (shText.c_str()); - else { + else if (SetupPE->ReplaceEmptyShText) { Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); Event->SetShortText (tmp); free(tmp); @@ -2842,6 +2846,14 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len // LogD(2, prep("Pid: 0x%02x Tid: %d Length: %d PMT pid: 0x%04x"), Pid, Tid, Length, pmtpid); // LogD(2, prep("Source: %d Transponder: %d"), Source () , Transponder ()); + if (Channel()->Nid() == 0x01) { + setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); + LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); + } + else { + unsetenv("VDR_CHARSET_OVERRIDE"); + LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); + } if (Pid == 0 && Tid == SI::TableIdPAT) { if (!pmtnext || now > pmtnext) { if (pmtpid) @@ -3687,6 +3699,8 @@ bool cPluginEEPG::SetupParse (const char *Name, const char *Value) SetupPE->FixEpg = atoi (Value); else if (!strcasecmp (Name, "DisplayMessage")) SetupPE->DisplayMessage = atoi (Value); + else if (!strcasecmp (Name, "ReplaceEmptyShText")) + SetupPE->ReplaceEmptyShText = atoi (Value); #ifdef DEBUG else if (!strcasecmp (Name, "LogLevel")) SetupPE->LogLevel = atoi (Value); diff --git a/setupeepg.c b/setupeepg.c index c0dff6a..bfbb26f 100644 --- a/setupeepg.c +++ b/setupeepg.c @@ -22,6 +22,8 @@ cSetupEEPG::cSetupEEPG (void) FixEpg = 0; DisplayMessage = 1; ProcessEIT = 0; + ReplaceEmptyShText = 0; + #ifdef DEBUG LogLevel = 0; #endif diff --git a/setupeepg.h b/setupeepg.h index 4c30ede..eb3c53e 100644 --- a/setupeepg.h +++ b/setupeepg.h @@ -18,6 +18,7 @@ public: int FixEpg; int DisplayMessage; int ProcessEIT; + int ReplaceEmptyShText; #ifdef DEBUG int LogLevel; #endif -- cgit v1.2.3 From 168f5d7c0b3b2b543ece04ccf09616c8a6b302b2 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 29 Oct 2012 11:38:01 +0100 Subject: error in merge --- eepg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/eepg.c b/eepg.c index 5bcd1d4..370c848 100644 --- a/eepg.c +++ b/eepg.c @@ -1299,7 +1299,6 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, char* tmp = NULL; string shText; - string shText; if (SummText && ShTxtLen) { shText.assign(SummText,ShTxtLen); -- cgit v1.2.3 From 9f123334782232413a36836d0894949bc7928cc9 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 29 Oct 2012 14:02:33 +0100 Subject: modified Makefile according to the VDR newplugin script which fixes pot generation added po thranslation support added Macednonian translation --- Makefile | 78 +++++++++++++++++++++++++++++++------------------------------ po/mk_MK.po | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 38 deletions(-) create mode 100644 po/mk_MK.po diff --git a/Makefile b/Makefile index 49e8770..2adfd09 100644 --- a/Makefile +++ b/Makefile @@ -35,16 +35,20 @@ CXXFLAGS ?= -O2 -fPIC -Wall -Woverloaded-virtual ### The directory environment: -VDRDIR = ../../.. -LIBDIR = ../../lib -TMPDIR = /tmp +VDRDIR ?= ../../.. +LIBDIR ?= ../../lib +TMPDIR ?= /tmp + +### Make sure that necessary options are included: + +include $(VDRDIR)/Make.global ### Allow user defined options to overwrite defaults: -include $(VDRDIR)/Make.config -include Make.config -### The version number of VDR (taken from VDR's "config.h"): +### The version number of VDR's plugin API (taken from VDR's "config.h"): VDRVERSION = $(shell sed -ne '/define VDRVERSION/ s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h) APIVERSION = $(shell sed -ne '/define APIVERSION/ s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h) @@ -63,24 +67,22 @@ INCLUDES += -I$(VDRDIR)/include DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -### The object files (add further files here): - -OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o eit2.o - ifdef DBG CXXFLAGS += -g endif -### Internationalization (I18N): +### The object files (add further files here): -PODIR = po -I18Npot = $(PODIR)/$(PLUGIN).pot -I18Nmsgs = $(addprefix $(LOCALEDIR)/,$(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo,$(notdir $(foreach file, $(wildcard $(PODIR)/*.po), $(basename $(file)))))) -LOCALEDIR = $(VDRDIR)/locale +OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o eit2.o ### Default Target default: $(OBJS) +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + ### Dependencies: MAKEDEP = $(CXX) -MM -MG @@ -90,47 +92,47 @@ $(DEPFILE): Makefile -include $(DEPFILE) -### Targets: - -TARGETS = libvdr-$(PLUGIN).so -ifneq ($(shell grep -l 'Phrases' $(VDRDIR)/i18n.c),$(VDRDIR)/i18n.c) -TARGETS += i18n -endif +### Internationalization (I18N): -all: $(TARGETS) -.PHONY: i18n +PODIR = po +LOCALEDIR = $(VDRDIR)/locale +I18Npo = $(wildcard $(PODIR)/*.po) +I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) +I18Npot = $(PODIR)/$(PLUGIN).pot -%.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< +### target All not default since it stops VDR +all: libvdr-$(PLUGIN).so i18n -libvdr-$(PLUGIN).so: $(OBJS) - $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ - @cp $@ $(LIBDIR)/$@.$(APIVERSION) +%.mo: %.po + msgfmt -c -o $@ $< -$(I18Npot): $(shell grep -rl '\(tr\|trNOOP\)(\".*\")' *.c $(SYSDIR)) - xgettext -C -cTRANSLATORS --no-wrap -F -k -ktr -ktrNOOP -o $@ $^ +$(I18Npot): $(wildcard *.c) + xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ $^ %.po: $(I18Npot) - msgmerge -U --no-wrap -F --backup=none -q $@ $< + msgmerge -U --no-wrap --no-location --backup=none -q $@ $< @touch $@ -%.mo: %.po - msgfmt -c -o $@ $< - $(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo @mkdir -p $(dir $@) cp $< $@ -i18n: $(I18Nmsgs) +.PHONY: i18n +i18n: $(I18Nmsgs) $(I18Npot) + +### Targets: + +libvdr-$(PLUGIN).so: $(OBJS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ + @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) -dist: clean +dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @mkdir $(TMPDIR)/$(ARCHIVE) @cp -a * $(TMPDIR)/$(ARCHIVE) - @tar czf $(PACKAGE).tar.gz -C $(TMPDIR) $(ARCHIVE) + @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) @-rm -rf $(TMPDIR)/$(ARCHIVE) - @echo Distribution package created as $(PACKAGE).tar.gz + @echo Distribution package created as $(PACKAGE).tgz clean: - @-rm -f $(OBJS) $(DEPFILE) *.so *.tar.gz core* *~ -# @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot diff --git a/po/mk_MK.po b/po/mk_MK.po new file mode 100644 index 0000000..b7701bf --- /dev/null +++ b/po/mk_MK.po @@ -0,0 +1,74 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012 +# This file is distributed under the same license as the VDR package. +# Dimitar Petrovski , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: vdr-eepg 0.0.6pre\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-10-29 13:42+0100\n" +"PO-Revision-Date: 2012-10-29 13:44+0100\n" +"Last-Translator: Dimitar Petrovski \n" +"Language-Team: Macedonian \n" +"Language: mk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Parses Extended EPG data" +msgstr "Анализира Опширни ЕПГ податоци" + +msgid "PremiereEPG" +msgstr "Премиер ЕПГ" + +msgid "off" +msgstr "исклучено" + +msgid "Tag option events" +msgstr "Тагуван опцоини настани" + +msgid "Show order information" +msgstr "Прикажи информации за нарачка" + +msgid "Show rating information" +msgstr "Прикажи информации за рејтинг" + +msgid "Fix EPG data" +msgstr "Поправи ЕПГ податоци" + +msgid "General" +msgstr "Општо" + +msgid "Display summary message" +msgstr "Прикажи сумарна порака" + +msgid "Replace Empty Short Text with Category - Genre" +msgstr "Замени празен Краток Текст со Категорија - Жанр" + +msgid "Level of logging verbosity" +msgstr "Ниво на логирање" + +msgid "Process EIT info with EEPG" +msgstr "Процесирај ЕИТ информации со ЕЕПГ" + +msgid "Ordernumber" +msgstr "Бр. на нарачка" + +msgid "Price" +msgstr "Цена" + +msgid "Ordering" +msgstr "Нарачка" + +msgid "SMS" +msgstr "СМС" + +msgid "WWW" +msgstr "WWW" + +msgid "Rating" +msgstr "Рејтинг" + +msgid "years" +msgstr "години" -- cgit v1.2.3 From e6817415cfb958010c64f22b98f4536817223098 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Tue, 30 Oct 2012 11:24:18 +0100 Subject: add separators in setup menu change charset export logic change thread times --- eepg.c | 41 +++++++++++++++++++++++++---------------- epghandler.c | 2 +- po/mk_MK.po | 2 +- util.c | 4 ++-- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/eepg.c b/eepg.c index 370c848..7239c23 100644 --- a/eepg.c +++ b/eepg.c @@ -111,7 +111,13 @@ public: cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void) { data = cSetupEEPG::getInstance(); - SetSection (tr ("PremiereEPG")); + cOsdItem *item = new cOsdItem(tr ("PremiereEPG")); + + if (item) { + item->SetSelectable(false); + Add(item); + } +// AddCategory (tr ("PremiereEPG")); optDisp[0] = tr ("off"); for (unsigned int i = 1; i < NUM_PATS; i++) { snprintf (buff[i], sizeof (buff[i]), optPats[i], "Event", 1); @@ -121,7 +127,12 @@ cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void) Add (new cMenuEditBoolItem (tr ("Show order information"), &data->OrderInfo)); Add (new cMenuEditBoolItem (tr ("Show rating information"), &data->RatingInfo)); Add (new cMenuEditBoolItem (tr ("Fix EPG data"), &data->FixEpg)); - SetSection (tr ("General")); + item = new cOsdItem(tr ("General")); + if (item) { + item->SetSelectable(false); + Add(item); + } +// AddCategory (tr ("General")); Add (new cMenuEditBoolItem (tr ("Display summary message"), &data->DisplayMessage)); Add (new cMenuEditBoolItem (tr ("Replace Empty Short Text with Category - Genre"), &data->ReplaceEmptyShText)); #ifdef DEBUG @@ -178,6 +189,7 @@ private: bool EndChannels, EndThemes; //only used for ?? int MHWStartTime; //only used for MHW1 bool ChannelsOk; + int prevNid; //int Format; //the format that this filter currently is processing std::map < int, int >ChannelSeq; // ChannelSeq[ChannelId] returns the recordnumber of the channel @@ -243,6 +255,7 @@ cFilterEEPG::cFilterEEPG (void) { nSummaries = 0; nTitles = 0; + prevNid = 0; Trigger (); //Set (0x00, 0x00); } @@ -269,12 +282,16 @@ void cFilterEEPG::SetStatus (bool On) for (int i = 0; i <= HIGHEST_FORMAT; i++) UnprocessedFormat[i] = 0; //pid 0 is assumed to be nonvalid for EEPG transfers AddFilter (0, 0); - if (Channel()->Nid() == 0x01) { - setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); - LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); - } else { - unsetenv("VDR_CHARSET_OVERRIDE"); - LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); + int nid = Channel()->Nid(); + if (nid != prevNid) { + if (nid == 0x01 && prevNid != 0x01) { + setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); + LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); + } else if (nid != 0x01 && (prevNid == 0x01 || prevNid == 0)){ + unsetenv("VDR_CHARSET_OVERRIDE"); + LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); + } + prevNid = nid; } } cFilter::SetStatus (On); @@ -2845,14 +2862,6 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len // LogD(2, prep("Pid: 0x%02x Tid: %d Length: %d PMT pid: 0x%04x"), Pid, Tid, Length, pmtpid); // LogD(2, prep("Source: %d Transponder: %d"), Source () , Transponder ()); - if (Channel()->Nid() == 0x01) { - setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); - LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); - } - else { - unsetenv("VDR_CHARSET_OVERRIDE"); - LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); - } if (Pid == 0 && Tid == SI::TableIdPAT) { if (!pmtnext || now > pmtnext) { if (pmtpid) diff --git a/epghandler.c b/epghandler.c index 4e7ab30..5bfabf1 100644 --- a/epghandler.c +++ b/epghandler.c @@ -163,7 +163,7 @@ bool cEEpgHandler::HandleEvent(cEvent* Event) { if (equivHandler->getEquiChanMap().count(*Event->ChannelID().ToString()) <= 0) return true; - //if (modified) + if (modified) equivHandler->updateEquivalent(Event->ChannelID(), Event); //TODO just to see the difference diff --git a/po/mk_MK.po b/po/mk_MK.po index b7701bf..5224001 100644 --- a/po/mk_MK.po +++ b/po/mk_MK.po @@ -26,7 +26,7 @@ msgid "off" msgstr "исклучено" msgid "Tag option events" -msgstr "Тагуван опцоини настани" +msgstr "Таг за опцоини настани" msgid "Show order information" msgstr "Прикажи информации за нарачка" diff --git a/util.c b/util.c index 415f213..7554319 100644 --- a/util.c +++ b/util.c @@ -150,7 +150,7 @@ struct tChannelIDCompare }; cTimeMs LastAddEventThread; -enum { INSERT_TIMEOUT_IN_MS = 10000 }; +enum { INSERT_TIMEOUT_IN_MS = 5000 }; class cAddEventThread : public cThread { @@ -250,7 +250,7 @@ void AddEvent(cEvent *Event, tChannelID ChannelID) // if (!AddEventThread.Active()) // AddEventThread.Start(); if (!AddEventThread.Active() && LastAddEventThread.TimedOut()){ - LastAddEventThread.Set(INSERT_TIMEOUT_IN_MS * 2); + LastAddEventThread.Set(INSERT_TIMEOUT_IN_MS * 1.5); AddEventThread.Start(); } -- cgit v1.2.3 From fddfe7581dc85bf74bae1aa7d12304acd941f351 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Tue, 20 Nov 2012 18:58:11 +0100 Subject: new way of fixing of charset without patching VDR, unfortunately this makes two more conversions handle some more duplicate events in the event handler extract category and genre when needed --- eepg.c | 29 ++++++++--- epghandler.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- epghandler.h | 8 ++- 3 files changed, 180 insertions(+), 15 deletions(-) diff --git a/eepg.c b/eepg.c index 7060168..0c4608c 100644 --- a/eepg.c +++ b/eepg.c @@ -189,7 +189,6 @@ private: bool EndChannels, EndThemes; //only used for ?? int MHWStartTime; //only used for MHW1 bool ChannelsOk; - int prevNid; //int Format; //the format that this filter currently is processing std::map < int, int >ChannelSeq; // ChannelSeq[ChannelId] returns the recordnumber of the channel @@ -255,7 +254,6 @@ cFilterEEPG::cFilterEEPG (void) { nSummaries = 0; nTitles = 0; - prevNid = 0; Trigger (); //Set (0x00, 0x00); } @@ -282,7 +280,7 @@ void cFilterEEPG::SetStatus (bool On) for (int i = 0; i <= HIGHEST_FORMAT; i++) UnprocessedFormat[i] = 0; //pid 0 is assumed to be nonvalid for EEPG transfers AddFilter (0, 0); - int nid = Channel()->Nid(); +/* int nid = Channel()->Nid(); if (nid != prevNid) { if (nid == 0x01 && prevNid != 0x01) { setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); @@ -293,6 +291,7 @@ void cFilterEEPG::SetStatus (bool On) } prevNid = nid; } + */ } cFilter::SetStatus (On); Trigger (); @@ -1322,7 +1321,6 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, string tmpTitle(Text); if (Format == MHW2 && !shText.empty()) { - //TODO (HD) channels size_t found = tmpTitle.find(" (HD)"); if (found != string::npos) tmpTitle.erase(found, 5); @@ -1331,10 +1329,15 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, shText.erase(0, tmpTitle.size() + 2); } - //Do not use Subtitle if it is substring of Title + //Do not use Subtitle if it is substring of Title if (tmpTitle.compare(0, shText.size(), shText) == 0) shText.clear(); + //The subtitle is wrong if contains '.' + if (Format == SKY_UK && !shText.empty() && shText.find('.') != string::npos) { + shText.clear(); + } + #define MAX_USEFUL_EPISODE_LENGTH 40 // From VDR FixEPG Bugs // Some channels put a whole lot of information in the ShortText and leave @@ -1366,6 +1369,18 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, WrittenSummary = true; CleanString ((uchar *) SummText); + //Fix MHW1 formating + if (Format == MHW1) { + char * pch; + pch=strchr(SummText,'s'); + while (pch!=NULL) + { + if (*(pch-1) != ' ' && *(pch-1) != '\n') + *pch = ' '; + pch=strchr(pch+1,'s'); + } + } + //Add themes and categories epgsearch style //TODO DPE move this char *theme; @@ -2070,7 +2085,7 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length) LogE(0, prep("Summaries memory allocation error.")); return 0; } - Text[SummaryLength+1] = '\0'; //end string with NULL character + //Text[SummaryLength+1] = '\0'; //end string with NULL character //memcpy (Text, &Data[SummaryOffset], SummaryLength); decodeText2(&Data[SummaryOffset], SummaryLength, (char*)Text, 2*SummaryLength + 1); // CleanString (Text); @@ -2083,6 +2098,8 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length) Summaries[nSummaries] = S; S->NumReplays = Summary->NumReplays; S->EventId = HILO32 (Summary->ProgramId); +// unsigned short SectionLength = ((Summary->SectionLengthHigh & 0x0f) << 8) | Summary->SectionLengthLow; +// Asprintf((char **)&Text, "%s \n\n SecLength:%d SLHigh:%d SLLow:%d", Text, SectionLength, Summary->SectionLengthHigh, Summary->SectionLengthLow); S->Text = Text; S->ShortTextLength = 0; //TODO find for MHW1 int i = 0; diff --git a/epghandler.c b/epghandler.c index 1753ab7..109cecc 100644 --- a/epghandler.c +++ b/epghandler.c @@ -16,17 +16,29 @@ using namespace util; +cCharSetConv* conv;//("UTF-8",CharsetOverride); +cCharSetConv* conv2;//(fixCharset.c_str()); + cEEpgHandler::cEEpgHandler() { LogD(4, prep("cEEpgHandler()")); equivHandler = new cEquivHandler(); modified = false; + + CharsetOverride = getenv("VDR_CHARSET_OVERRIDE"); + if (!CharsetOverride) CharsetOverride = "ISO6937"; + } cEEpgHandler::~cEEpgHandler() { delete equivHandler; equivHandler = NULL; + delete conv; + conv = NULL; + delete conv2; + conv2 = NULL; } + bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, const SI::EIT::Event* EitEvent, uchar TableID, uchar Version) { //LogD(1, prep("HandleEitEvent")); @@ -86,13 +98,61 @@ bool cEEpgHandler::SetEventID(cEvent* Event, tEventID EventID) { return true; } +const char* cEEpgHandler::FixCharset(const char* text) +{ + if (!text) return text; + + //LogD(0, prep("FixCharset fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); + const char* fixed = NULL; + if (!fixCharset.empty()) { + + if (fixCharset != CharsetOverride) { + //LogD(0, prep("FixCharset2 fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); + fixed = conv->Convert(text); + //LogD(0, prep("conv 1 fixed:%s"),fixed); + fixed = conv2->Convert(fixed); + //LogD(0, prep("Fixed text:%s"), fixed); + } + } + if (!fixed) fixed = text; + return fixed; +} + bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - if (!Event->Title() || (Title && (!strcmp(Event->Title(),"") || (strcmp(Title,"") && strcmp(Event->Title(),Title))))) { + const char* title = FixCharset(Title); + + //Sometimes same events overlap and have different EventID + if (origDescription.empty() && origShortText.empty()) { + cEvent* eqEvent = NULL; + cEvent* ev = (cEvent*)Event->Next(); + if (ev && strcasecmp(ev->Title(),title) == 0 + && Event->StartTime() <= ev->StartTime() && Event->EndTime() > ev->StartTime()) + eqEvent = ev; + if (!eqEvent && (ev = (cEvent*)Event->Prev()) != NULL && strcasecmp(ev->Title(),title) == 0 + && ev->StartTime() <= Event->StartTime() && ev->EndTime() > Event->StartTime()) + eqEvent = ev; + if (eqEvent) { + if (ev->Description() && strcmp(ev->Description(),"") != 0) + origDescription = ev->Description(); + if (ev->ShortText() && strcmp(ev->ShortText(),"") != 0) + origShortText = ev->ShortText(); + //origDescription = eqEvent->Description(); + //origShortText = eqEvent->ShortText(); + + LogD(0, prep("!!! !Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d") + , ev->EventID(), ev->Title(), ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); + + cSchedule* schedule = (cSchedule*)Event->Schedule(); + schedule->DelEvent((cEvent*)eqEvent); + } + } + + if (!Event->Title() || (title && (!strcmp(Event->Title(),"") || (strcmp(Title,"") && strcmp(Event->Title(),title))))) { //LogD(0, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); modified = true; - Event->SetTitle(Title); + Event->SetTitle(title); } return true; } @@ -107,8 +167,10 @@ bool cEEpgHandler::SetShortText(cEvent* Event, const char* ShortText) { origShortText.clear(); } + const char* shText = FixCharset(ShortText); + //if (!Event->ShortText() || ShortText && (!strcmp(Event->ShortText(),"") || (strcmp(ShortText,"") && strcmp(Event->ShortText(),ShortText)))) - Event->SetShortText(ShortText); + Event->SetShortText(shText); return true; } @@ -119,13 +181,15 @@ bool cEEpgHandler::SetDescription(cEvent* Event, const char* Description) { origDescription = Event->Description(); else origDescription.clear(); - + + const char* desc = FixCharset(Description); + //Based on asumption that SetDescription is always called after SetTitle - if (!modified && Description && (!Event->Description() || strcmp(Event->Description(),Description) )) + if (!modified && desc && (!Event->Description() || strcmp(Event->Description(),desc) )) modified = true; //if (!Event->Description() || Description && (!strcmp(Event->Description(),"") || (strcmp(Description,"") && strcmp(Event->Description(),Description)))) - Event->SetDescription(Description); + Event->SetDescription(desc); return true; } @@ -157,13 +221,52 @@ bool cEEpgHandler::SetVps(cEvent* Event, time_t Vps) { bool cEEpgHandler::HandleEvent(cEvent* Event) { LogD(3, prep("HandleEvent st:%s ost:%s desc:%s odesc:%s"),Event->ShortText(),origShortText.c_str(),Event->Description(),origDescription.c_str()); - //After FixEpgBugs of cEvent set the original Short Text if empty if (!Event->ShortText() || !strcmp(Event->ShortText(),"")) Event->SetShortText(origShortText.c_str()); - if ((!Event->Description() && !origDescription.empty()) || (Event->Description() && !origDescription.empty() && origDescription.find(Event->Description()) != string::npos) ) { + /*old if ((!Event->Description() && !origDescription.empty()) || (Event->Description() && !origDescription.empty() && origDescription.find(Event->Description()) != string::npos) ) { Event->SetDescription(origDescription.c_str()); + }*/ + + //Handle the Category and Genre, and optionally future tags + if (!origDescription.empty() && + (!Event->Description() || + (Event->Description() && origDescription.find(Event->Description()) != string::npos))) { + Event->SetDescription(origDescription.c_str()); + } else if (!origDescription.empty() && Event->Description()) { + string category, genre; + + //LogD(0, prep("HandleEvent origDescription:%s"),origDescription.c_str()); + size_t catpos = origDescription.find("Category: "); + size_t genpos = origDescription.find("Genre: "); + + if (catpos != string::npos) { + size_t pos = origDescription.find('\n',catpos+10); + category = origDescription.substr(catpos+10, pos-catpos-10); + //LogD(0, prep("HandleEvent category:%s, catpos:%i, pos:%i"),category.c_str(), catpos, pos); + } + if (genpos != string::npos) { + size_t pos = origDescription.find('\n',genpos+7); + genre = origDescription.substr(genpos+7, pos-genpos-7); + //LogD(0, prep("HandleEvent genre:%s, genpos:%i, pos:%i"),genre.c_str(), genpos, pos); + } + + char* tmp = NULL; + + string fmt; + fmt = "%s"; + if (!category.empty()) { + fmt += "\nCategory: %s"; + } + if (!genre.empty()) { + fmt += "\nGenre: %s"; + } + Asprintf (&tmp, fmt.c_str(), Event->Description(), category.c_str(), genre.c_str()); + + Event->SetDescription (tmp); + free(tmp); + } if (equivHandler->getEquiChanMap().count(*Event->ChannelID().ToString()) <= 0) @@ -196,6 +299,45 @@ bool cEEpgHandler::FixEpgBugs(cEvent* Event) return false; } +bool cEEpgHandler::IgnoreChannel(const cChannel* Channel) +{ + + //TODO + //return false; + + if (conv) { + delete conv; + conv = NULL; + } + if (conv2) { + delete conv2; + conv2 = NULL; + } + if (strcasecmp( Channel->Provider(), "Skylink") == 0 || strcasecmp( Channel->Provider(), "UPC Direct") == 0 + || strcasecmp( Channel->Provider(), "CYFRA +") == 0) { + fixCharset = "ISO6937"; + } else if (strcasecmp( Channel->Provider(), "Polsat") != 0) { + fixCharset = "ISO-8859-2"; + } else if (Channel->Nid() == 0x01) { + fixCharset = "ISO-8859-9"; + } else { + fixCharset = ""; + } + + + if (!fixCharset.empty()) { + conv2 = new cCharSetConv(fixCharset.c_str()); + if (strcasecmp( Channel->Provider(), "CYFRA +") == 0) { + conv = new cCharSetConv(NULL,"ISO-8859-5"); + }else { + conv = new cCharSetConv(NULL,CharsetOverride); + } + } + + + return false; +} + bool cEEpgHandler::DropOutdated(cSchedule* Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; diff --git a/epghandler.h b/epghandler.h index feaad9d..92b7d0b 100644 --- a/epghandler.h +++ b/epghandler.h @@ -18,7 +18,7 @@ class cEEpgHandler : public cEpgHandler { public: cEEpgHandler(); virtual ~cEEpgHandler(); - virtual bool IgnoreChannel(const cChannel *Channel) { return false; } + virtual bool IgnoreChannel(const cChannel *Channel); virtual bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version); virtual bool SetEventID(cEvent *Event, tEventID EventID); virtual bool SetTitle(cEvent *Event, const char *Title); @@ -35,13 +35,19 @@ public: virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); // bool ParseEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version); +private: + const char* FixCharset(const char* text); + private: std::string origShortText; std::string origDescription; + std::string fixCharset; cEquivHandler* equivHandler; static const int _LONG_EVENT_HOURS = 10; bool modified; + const char* CharsetOverride; + }; #endif /*APIVERSNUM > 10725*/ -- cgit v1.2.3 From a6207b35db9e524fef7243faab839c4d98e318f1 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Tue, 20 Nov 2012 21:56:56 +0100 Subject: code cleanup and refactoring --- eepg.c | 149 +++++------------------------------------------------------ epghandler.c | 54 ++++++++-------------- epghandler.h | 2 +- util.h | 5 ++ 4 files changed, 37 insertions(+), 173 deletions(-) diff --git a/eepg.c b/eepg.c index 0c4608c..8a65609 100644 --- a/eepg.c +++ b/eepg.c @@ -280,18 +280,6 @@ void cFilterEEPG::SetStatus (bool On) for (int i = 0; i <= HIGHEST_FORMAT; i++) UnprocessedFormat[i] = 0; //pid 0 is assumed to be nonvalid for EEPG transfers AddFilter (0, 0); -/* int nid = Channel()->Nid(); - if (nid != prevNid) { - if (nid == 0x01 && prevNid != 0x01) { - setenv("VDR_CHARSET_OVERRIDE", "ISO-8859-9", true); - LogD(0, prep("setenv VDR_CHARSET_OVERRIDE ISO-8859-9")); - } else if (nid != 0x01 && (prevNid == 0x01 || prevNid == 0)){ - unsetenv("VDR_CHARSET_OVERRIDE"); - LogD(0, prep("clear VDR_CHARSET_OVERRIDE")); - } - prevNid = nid; - } - */ } cFilter::SetStatus (On); Trigger (); @@ -330,23 +318,6 @@ void syslog_with_tid (int priority, const char *format, ...) __attribute__ ((for #define isyslog(a...) fprintf(stderr,a) #endif - - -//struct hufftab { -// unsigned int value; -// short bits; -// char next; -//}; -// -//#define START '\0' -//#define STOP '\0' -//#define ESCAPE '\1' - - -//int freesat_decode_error = 0; /* If set an error has occurred during decoding */ - -//static struct hufftab *tables[2][128]; -//static int table_size[2][128]; static sNodeH* sky_tables[2]; /** \brief Convert a textual character description into a value @@ -765,11 +736,6 @@ nextloop1: return p; } -//here all declarations for global variables over all devices - -//char *ConfDir; - -//unsigned char DecodeErrorText[4096]; //TODO only used for debugging? bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB stream? { @@ -858,29 +824,6 @@ bool cFilterEEPG::InitDictionary (void) return true; } -//void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize) -//{ -// if (from[0] == 0x1f) { -// char *temp = freesat_huffman_decode (from, len); -// if (temp) { -// len = strlen (temp); -// len = len < buffsize - 1 ? len : buffsize - 1; -// strncpy (buffer, temp, len); -// buffer[len] = 0; -// free (temp); -// return; -// } -// } -// -// SI::String convStr; -// SI::CharArray charArray; -// charArray.assign(from, len); -// convStr.setData(charArray, len); -// //LogE(5, prep("decodeText2 from %s - length %d"), from, len); -// convStr.getText(buffer, buffsize); -// //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize); -//} - /** * \brief Get MHW channels * @@ -1218,42 +1161,6 @@ char *cFilterEEPG::GetSummaryTextNagra (const u_char * DataStart, long int Offse return (char *) Text; } -/** - * \brief Prepare to Write to Schedule - * - * gets a channel and returns an array of schedules that WriteToSchedule can write to. - * Call this routine before a batch of titles with the same ChannelId will be WriteToScheduled; batchsize can be 1 - * - * \param C channel to prepare - * \param s VDR epg schedules - * \param ps pointer to the schedules that WriteToSchedule can write to - */ -//void cFilterEEPG::PrepareToWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps/*[MAX_EQUIVALENCES]*/) -//{ -// //for (int eq = 0; eq < C->NumberOfEquivalences; eq++) { -// tChannelID channelID = tChannelID (C->Src/*[eq]*/, C->Nid/*[eq]*/, C->Tid/*[eq]*/, C->Sid/*[eq]*/); -//#ifdef USE_NOEPG -// if (allowedEPG (channelID) && (channelID.Valid ())) -//#else -// if (channelID.Valid ()) //only add channels that are known to vdr -//#endif /* NOEPG */ -// ps/*[eq]*/ = s->AddSchedule (channelID); //open a a schedule for each equivalent channel -// else { -// ps/*[eq]*/ = NULL; -//// LogE(5, prep("ERROR: Title block has invalid (equivalent) channel ID: Equivalence: %i, Source:%x, C->Nid:%x,C->Tid:%x,C->Sid:%x."), -//// eq, C->Src[eq], C->Nid[eq], C->Tid[eq], C->Sid[eq]); -// } -// //} -//} - -//void cFilterEEPG::FinishWriteToSchedule (sChannel * C, cSchedules * s, cSchedule * ps[MAX_EQUIVALENCES]) -//{ -// for (int eq = 0; eq < C->NumberOfEquivalences; eq++) -// if (ps[eq]) { -// ps[eq]->Sort (); -// s->SetModified (ps[eq]); -// } -//} /** * \brief write event to schedule @@ -1355,17 +1262,8 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, Event->SetShortText (tmp); free(tmp); } -/* - char *tmp; - if (!ShortText || strcmp(ShortText, Text) == 0) { - Asprintf (&tmp, "%s - %d\'", Themes[ThemeId], Duration); - Event->SetShortText (tmp); - free(tmp); - } else - Event->SetShortText (ShortText); -*/ - //strreplace(t, '|', '\n'); - if (SummText != 0x00) { + + if (SummText) { WrittenSummary = true; CleanString ((uchar *) SummText); @@ -1397,6 +1295,7 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, }else{ category = theme; } + /* string fmt; fmt = "%s"; if (stripspace(category)) { @@ -1409,6 +1308,13 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, Event->SetDescription (tmp); free(tmp); + */ + string desc = SummText; + if (stripspace(category)) desc.append("\n").append(CATEGORY).append(category); + //if (stripspace(category)) desc += '\n' << CATEGORY << category; + if (stripspace(genre)) desc += '\n' + string(GENRE) + genre; + Event->SetDescription (desc.c_str()); + free(theme); } else @@ -1988,29 +1894,7 @@ int cFilterEEPG::GetTitlesMHW2 (const u_char * Data, int Length) if (Length > 18) { int Pos = 18; int Len = 0; - /*bool Check = false; - while (Pos < Length) { - Check = false; - Pos += 7; - if (Pos < Length) { - Pos += 3; - if (Pos < Length) - if (Data[Pos] > 0xc0) { - Pos += (Data[Pos] - 0xc0); - Pos += 4; - if (Pos < Length) { - if (Data[Pos] == 0xff) { - Pos += 1; - Check = true; - } - } - } - } - if (Check == false){ - isyslog ("EEPGDebug: Check==false"); - return 1; // I assume nonfatal error or success - } - }*/ + if (memcmp (InitialTitle, Data, 16) == 0) { //data is the same as initial title return 2; //last item processed } else { @@ -3697,17 +3581,6 @@ cMenuSetupPage *cPluginEEPG::SetupMenu (void) bool cPluginEEPG::SetupParse (const char *Name, const char *Value) { -// LogF(0, "!!!! Dime test LogF"); -// LogF(0, "!!!! Dime test LogF %d", 2); -// LogI(0, "!!!! Dime test LogI"); -// LogI(0, "!!!! Dime test LogI %d", 2); -// LogI(0, prep2("!!!! Dime test prep")); -// LogI(0, prep2("!!!! Dime test prep %d"), 2); -// LogD(0, "!!!! Dime test LogD"); -// LogD(0, "!!!! Dime test LogD %d", 2); -// LogE(0, "!!!! Dime test LogE"); -// LogE(0, "!!!! Dime test LogE %d", 2); - if (!strcasecmp (Name, "OptionPattern")) SetupPE->OptPat = atoi (Value); diff --git a/epghandler.c b/epghandler.c index 109cecc..01cccea 100644 --- a/epghandler.c +++ b/epghandler.c @@ -218,6 +218,19 @@ bool cEEpgHandler::SetVps(cEvent* Event, time_t Vps) { return true; } +string cEEpgHandler::ExtractAttribute(const char* name) +{ + string attribute; + size_t apos = origDescription.find(name); + if (apos != string::npos) { + apos += strlen(name); + size_t npos = origDescription.find('\n', apos); + attribute = origDescription.substr(apos, npos - apos); + //LogD(0, prep("ExtractAttribute attribute:%s, apos:%i, pos:%i"),attribute.c_str(), catpos, pos); + } + return attribute; +} + bool cEEpgHandler::HandleEvent(cEvent* Event) { LogD(3, prep("HandleEvent st:%s ost:%s desc:%s odesc:%s"),Event->ShortText(),origShortText.c_str(),Event->Description(),origDescription.c_str()); @@ -225,47 +238,20 @@ bool cEEpgHandler::HandleEvent(cEvent* Event) { if (!Event->ShortText() || !strcmp(Event->ShortText(),"")) Event->SetShortText(origShortText.c_str()); - /*old if ((!Event->Description() && !origDescription.empty()) || (Event->Description() && !origDescription.empty() && origDescription.find(Event->Description()) != string::npos) ) { - Event->SetDescription(origDescription.c_str()); - }*/ - //Handle the Category and Genre, and optionally future tags if (!origDescription.empty() && (!Event->Description() || (Event->Description() && origDescription.find(Event->Description()) != string::npos))) { Event->SetDescription(origDescription.c_str()); } else if (!origDescription.empty() && Event->Description()) { - string category, genre; - - //LogD(0, prep("HandleEvent origDescription:%s"),origDescription.c_str()); - size_t catpos = origDescription.find("Category: "); - size_t genpos = origDescription.find("Genre: "); - if (catpos != string::npos) { - size_t pos = origDescription.find('\n',catpos+10); - category = origDescription.substr(catpos+10, pos-catpos-10); - //LogD(0, prep("HandleEvent category:%s, catpos:%i, pos:%i"),category.c_str(), catpos, pos); - } - if (genpos != string::npos) { - size_t pos = origDescription.find('\n',genpos+7); - genre = origDescription.substr(genpos+7, pos-genpos-7); - //LogD(0, prep("HandleEvent genre:%s, genpos:%i, pos:%i"),genre.c_str(), genpos, pos); - } - - char* tmp = NULL; - - string fmt; - fmt = "%s"; - if (!category.empty()) { - fmt += "\nCategory: %s"; - } - if (!genre.empty()) { - fmt += "\nGenre: %s"; - } - Asprintf (&tmp, fmt.c_str(), Event->Description(), category.c_str(), genre.c_str()); + string category = ExtractAttribute(CATEGORY); + string genre = ExtractAttribute(GENRE); - Event->SetDescription (tmp); - free(tmp); + string desc = Event->Description() ? Event->Description() : ""; + if (!category.empty()) desc += '\n' + string(CATEGORY) + category; + if (!genre.empty()) desc += '\n' + string(GENRE) + genre; + Event->SetDescription (desc.c_str()); } @@ -316,7 +302,7 @@ bool cEEpgHandler::IgnoreChannel(const cChannel* Channel) if (strcasecmp( Channel->Provider(), "Skylink") == 0 || strcasecmp( Channel->Provider(), "UPC Direct") == 0 || strcasecmp( Channel->Provider(), "CYFRA +") == 0) { fixCharset = "ISO6937"; - } else if (strcasecmp( Channel->Provider(), "Polsat") != 0) { + } else if (strcasestr( Channel->Provider(), "Polsat") != 0) { fixCharset = "ISO-8859-2"; } else if (Channel->Nid() == 0x01) { fixCharset = "ISO-8859-9"; diff --git a/epghandler.h b/epghandler.h index 92b7d0b..23874b9 100644 --- a/epghandler.h +++ b/epghandler.h @@ -37,7 +37,7 @@ public: // bool ParseEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version); private: const char* FixCharset(const char* text); - + std::string ExtractAttribute(const char* attr); private: std::string origShortText; diff --git a/util.h b/util.h index dec5b70..4b3ce9b 100644 --- a/util.h +++ b/util.h @@ -20,11 +20,16 @@ class cSchedules; #define STOP '\0' #define ESCAPE '\1' + + #define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() ) namespace util { +static const char CATEGORY[] = "Category: "; +static const char GENRE[] = "Genre: "; + extern int AvailableSources[32]; extern int NumberOfAvailableSources; -- cgit v1.2.3 From c72251596c42864a959aedd7d916e834aac276e9 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 21 Nov 2012 09:11:04 +0100 Subject: Moved charset fixing code to a separate class Added setup option to enable/dissable charset fixing --- eepg.c | 6 ++++- epghandler.c | 70 ++++-------------------------------------------------- epghandler.h | 7 +++--- po/mk_MK.po | 7 ++++-- setupeepg.c | 1 + setupeepg.h | 1 + util.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 19 +++++++++++++++ 8 files changed, 117 insertions(+), 71 deletions(-) diff --git a/eepg.c b/eepg.c index 8a65609..29bd4d4 100644 --- a/eepg.c +++ b/eepg.c @@ -134,7 +134,8 @@ cMenuSetupPremiereEpg::cMenuSetupPremiereEpg (void) } // AddCategory (tr ("General")); Add (new cMenuEditBoolItem (tr ("Display summary message"), &data->DisplayMessage)); - Add (new cMenuEditBoolItem (tr ("Replace Empty Short Text with Category - Genre"), &data->ReplaceEmptyShText)); + Add (new cMenuEditBoolItem (tr ("Replace empty Short Text with Category - Genre"), &data->ReplaceEmptyShText)); + Add (new cMenuEditBoolItem (tr ("Try to fix CharSet for events"), &data->FixCharset)); #ifdef DEBUG Add (new cMenuEditIntItem (tr ("Level of logging verbosity"), &data->LogLevel, 0, 5)); Add (new cMenuEditBoolItem (tr ("Process EIT info with EEPG"), &data->ProcessEIT)); @@ -150,6 +151,7 @@ void cMenuSetupPremiereEpg::Store (void) SetupStore ("FixEpg", SetupPE->FixEpg); SetupStore ("DisplayMessage", SetupPE->DisplayMessage); SetupStore ("ReplaceEmptyShText", SetupPE->ReplaceEmptyShText); + SetupStore ("FixCharset", SetupPE->FixCharset); #ifdef DEBUG SetupStore ("LogLevel", SetupPE->LogLevel); SetupStore ("ProcessEIT", SetupPE->ProcessEIT); @@ -3594,6 +3596,8 @@ bool cPluginEEPG::SetupParse (const char *Name, const char *Value) SetupPE->DisplayMessage = atoi (Value); else if (!strcasecmp (Name, "ReplaceEmptyShText")) SetupPE->ReplaceEmptyShText = atoi (Value); + else if (!strcasecmp (Name, "FixCharset")) + SetupPE->FixCharset = atoi (Value); #ifdef DEBUG else if (!strcasecmp (Name, "LogLevel")) SetupPE->LogLevel = atoi (Value); diff --git a/epghandler.c b/epghandler.c index 01cccea..ca214c7 100644 --- a/epghandler.c +++ b/epghandler.c @@ -16,26 +16,18 @@ using namespace util; -cCharSetConv* conv;//("UTF-8",CharsetOverride); -cCharSetConv* conv2;//(fixCharset.c_str()); cEEpgHandler::cEEpgHandler() { LogD(4, prep("cEEpgHandler()")); equivHandler = new cEquivHandler(); modified = false; - - CharsetOverride = getenv("VDR_CHARSET_OVERRIDE"); - if (!CharsetOverride) CharsetOverride = "ISO6937"; + charsetFixer = new cCharsetFixer(); } cEEpgHandler::~cEEpgHandler() { delete equivHandler; equivHandler = NULL; - delete conv; - conv = NULL; - delete conv2; - conv2 = NULL; } @@ -98,30 +90,10 @@ bool cEEpgHandler::SetEventID(cEvent* Event, tEventID EventID) { return true; } -const char* cEEpgHandler::FixCharset(const char* text) -{ - if (!text) return text; - - //LogD(0, prep("FixCharset fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); - const char* fixed = NULL; - if (!fixCharset.empty()) { - - if (fixCharset != CharsetOverride) { - //LogD(0, prep("FixCharset2 fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); - fixed = conv->Convert(text); - //LogD(0, prep("conv 1 fixed:%s"),fixed); - fixed = conv2->Convert(fixed); - //LogD(0, prep("Fixed text:%s"), fixed); - } - } - if (!fixed) fixed = text; - return fixed; -} - bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - const char* title = FixCharset(Title); + const char* title = charsetFixer->FixCharset(Title); //Sometimes same events overlap and have different EventID if (origDescription.empty() && origShortText.empty()) { @@ -167,7 +139,7 @@ bool cEEpgHandler::SetShortText(cEvent* Event, const char* ShortText) { origShortText.clear(); } - const char* shText = FixCharset(ShortText); + const char* shText = charsetFixer->FixCharset(ShortText); //if (!Event->ShortText() || ShortText && (!strcmp(Event->ShortText(),"") || (strcmp(ShortText,"") && strcmp(Event->ShortText(),ShortText)))) Event->SetShortText(shText); @@ -182,7 +154,7 @@ bool cEEpgHandler::SetDescription(cEvent* Event, const char* Description) { else origDescription.clear(); - const char* desc = FixCharset(Description); + const char* desc = charsetFixer->FixCharset(Description); //Based on asumption that SetDescription is always called after SetTitle if (!modified && desc && (!Event->Description() || strcmp(Event->Description(),desc) )) @@ -287,39 +259,7 @@ bool cEEpgHandler::FixEpgBugs(cEvent* Event) bool cEEpgHandler::IgnoreChannel(const cChannel* Channel) { - - //TODO - //return false; - - if (conv) { - delete conv; - conv = NULL; - } - if (conv2) { - delete conv2; - conv2 = NULL; - } - if (strcasecmp( Channel->Provider(), "Skylink") == 0 || strcasecmp( Channel->Provider(), "UPC Direct") == 0 - || strcasecmp( Channel->Provider(), "CYFRA +") == 0) { - fixCharset = "ISO6937"; - } else if (strcasestr( Channel->Provider(), "Polsat") != 0) { - fixCharset = "ISO-8859-2"; - } else if (Channel->Nid() == 0x01) { - fixCharset = "ISO-8859-9"; - } else { - fixCharset = ""; - } - - - if (!fixCharset.empty()) { - conv2 = new cCharSetConv(fixCharset.c_str()); - if (strcasecmp( Channel->Provider(), "CYFRA +") == 0) { - conv = new cCharSetConv(NULL,"ISO-8859-5"); - }else { - conv = new cCharSetConv(NULL,CharsetOverride); - } - } - + charsetFixer->InitCharsets(Channel); return false; } diff --git a/epghandler.h b/epghandler.h index 23874b9..b37f7c2 100644 --- a/epghandler.h +++ b/epghandler.h @@ -13,6 +13,9 @@ #include class cEquivHandler; +namespace util { +class cCharsetFixer; +} class cEEpgHandler : public cEpgHandler { public: @@ -36,17 +39,15 @@ public: // bool ParseEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version); private: - const char* FixCharset(const char* text); std::string ExtractAttribute(const char* attr); private: std::string origShortText; std::string origDescription; - std::string fixCharset; cEquivHandler* equivHandler; + util::cCharsetFixer* charsetFixer; static const int _LONG_EVENT_HOURS = 10; bool modified; - const char* CharsetOverride; }; diff --git a/po/mk_MK.po b/po/mk_MK.po index 5224001..69936f2 100644 --- a/po/mk_MK.po +++ b/po/mk_MK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-eepg 0.0.6pre\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-29 13:42+0100\n" +"POT-Creation-Date: 2012-11-20 23:13+0100\n" "PO-Revision-Date: 2012-10-29 13:44+0100\n" "Last-Translator: Dimitar Petrovski \n" "Language-Team: Macedonian \n" @@ -43,9 +43,12 @@ msgstr "Општо" msgid "Display summary message" msgstr "Прикажи сумарна порака" -msgid "Replace Empty Short Text with Category - Genre" +msgid "Replace empty Short Text with Category - Genre" msgstr "Замени празен Краток Текст со Категорија - Жанр" +msgid "Try to fix CharSet for events" +msgstr "Пробај да го поправиш сетот на карактери за настаните" + msgid "Level of logging verbosity" msgstr "Ниво на логирање" diff --git a/setupeepg.c b/setupeepg.c index bfbb26f..c6056d8 100644 --- a/setupeepg.c +++ b/setupeepg.c @@ -23,6 +23,7 @@ cSetupEEPG::cSetupEEPG (void) DisplayMessage = 1; ProcessEIT = 0; ReplaceEmptyShText = 0; + FixCharset = 0; #ifdef DEBUG LogLevel = 0; diff --git a/setupeepg.h b/setupeepg.h index 089eb82..ed0f04e 100644 --- a/setupeepg.h +++ b/setupeepg.h @@ -19,6 +19,7 @@ public: int DisplayMessage; int ProcessEIT; int ReplaceEmptyShText; + int FixCharset; #ifdef DEBUG int LogLevel; #endif diff --git a/util.c b/util.c index 7554319..49f863a 100644 --- a/util.c +++ b/util.c @@ -7,6 +7,7 @@ #include "util.h" #include "log.h" #include "equivhandler.h" +#include "setupeepg.h" #include #include #include @@ -388,5 +389,81 @@ void sortSchedules(cSchedules * Schedules, tChannelID channelID){ EquivHandler->sortEquivalents(channelID, Schedules); } +cCharsetFixer::cCharsetFixer() +{ + charsetOverride = getenv("VDR_CHARSET_OVERRIDE"); + if (!charsetOverride) charsetOverride = "ISO6937"; + initialCharset = charsetOverride; + fixedCharset = ""; + conv_revert = NULL; + conv_to = NULL; + +} + +cCharsetFixer::~cCharsetFixer() +{ +} + +const char* cCharsetFixer::FixCharset(const char* text) +{ + if (!text || !conv_revert || !conv_to) return text; + + //LogD(0, prep("FixCharset fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); + const char* fixed = NULL; + if (!fixedCharset.empty()) { + + if (fixedCharset != charsetOverride) { + //LogD(0, prep("FixCharset2 fixCharset:%s charsetOverride:%s text:%s"), fixCharset.c_str(), CharsetOverride, text); + fixed = conv_revert->Convert(text); + //LogD(0, prep("conv 1 fixed:%s"),fixed); + fixed = conv_to->Convert(fixed); + //LogD(0, prep("Fixed text:%s"), fixed); + } + } + if (!fixed) fixed = text; + return fixed; + +} + +void cCharsetFixer::InitCharsets(const cChannel* Channel) +{ + if (!cSetupEEPG::getInstance()->FixCharset) return; + + if (strcasecmp( Channel->Provider(), "Skylink") == 0 || strcasecmp( Channel->Provider(), "UPC Direct") == 0 + || strcasecmp( Channel->Provider(), "CYFRA +") == 0) { + fixedCharset = "ISO6937"; + } else if (strcasestr( Channel->Provider(), "Polsat") != 0) { + fixedCharset = "ISO-8859-2"; + } else if (Channel->Nid() == 0x01) { + fixedCharset = "ISO-8859-9"; + } else { + fixedCharset = ""; + } + + + if (!fixedCharset.empty()) { + delete conv_to; + conv_to = new cCharSetConv(fixedCharset.c_str()); + + + const char* chrs; + if (strcasecmp( Channel->Provider(), "CYFRA +") == 0) { + chrs = "ISO-8859-5"; + }else { + chrs = charsetOverride; + } + + if (initialCharset != chrs) { + delete conv_revert; + conv_revert = NULL; + } + if (!conv_revert || initialCharset != chrs) + conv_revert = new cCharSetConv(NULL,chrs); + + initialCharset = chrs; + } + +} + } diff --git a/util.h b/util.h index 4b3ce9b..bef2a3e 100644 --- a/util.h +++ b/util.h @@ -9,12 +9,14 @@ #define UTIL_H_ #include #include +#include class cChannel; struct tChannelID; class cEvent; class cEquivHandler; class cSchedules; +class cCharSetConv; #define START '\0' #define STOP '\0' @@ -94,5 +96,22 @@ extern struct hufftab *tables[2][128]; extern int table_size[2][128]; //static sNodeH* sky_tables[2]; +class cCharsetFixer +{ +public: + cCharsetFixer(); + virtual ~cCharsetFixer(); + const char* FixCharset(const char* text); + void InitCharsets(const cChannel* Channel); + +private: + cCharSetConv* conv_revert;//("UTF-8",CharsetOverride); + cCharSetConv* conv_to;//(fixCharset.c_str()); + const char* charsetOverride; + std::string fixedCharset; + std::string initialCharset; + +}; + } #endif /* UTIL_H_ */ -- cgit v1.2.3 From 0b2e0195683f8e21e1c666c6c1606cb31e3baaaf Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 21 Nov 2012 13:21:49 +0100 Subject: Move duplicate events handling to separate method --- epghandler.c | 86 +++++++++++++++++++++++++++++++++--------------------------- epghandler.h | 2 ++ 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/epghandler.c b/epghandler.c index ca214c7..d6b01af 100644 --- a/epghandler.c +++ b/epghandler.c @@ -22,6 +22,7 @@ cEEpgHandler::cEEpgHandler() { equivHandler = new cEquivHandler(); modified = false; charsetFixer = new cCharsetFixer(); + schedule = NULL; } @@ -33,9 +34,10 @@ cEEpgHandler::~cEEpgHandler() { bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, const SI::EIT::Event* EitEvent, uchar TableID, uchar Version) { + schedule = Schedule; //LogD(1, prep("HandleEitEvent")); //DISH NID 0x1001 to 0x100B BEV 0x100 and 0x101 - int nid = Schedule->ChannelID().Nid(); + int nid = schedule->ChannelID().Nid(); if ((nid >= 0x1001 && nid <= 0x100B) || nid == 0x101 || nid == 0x100) { //Set the Format for Eit events so that the new lines are not erased with FixEpgBugs if (Format != DISH_BEV) Format = DISH_BEV; @@ -59,25 +61,25 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, } modified = false; - //VDR creates new event if the EitEvent StartTime is different than EEPG time so - //the EEPG event has to be deleted but the data should be kept - const cEvent* ev = Schedule->GetEvent(EitEvent->getEventId(),EitEvent->getStartTime()); - if (!ev){ - ev = Schedule->GetEvent(EitEvent->getEventId()); - if (ev && ((ev->StartTime()>EitEvent->getStartTime() && ev->StartTime()<=EitEvent->getStartTime()+EitEvent->getDuration()) - || (EitEvent->getStartTime() > ev->StartTime() && EitEvent->getStartTime() <= ev->EndTime()))) { - LogD(0, prep("!!!Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d"), ev->EventID(), ev->Title(), ev->StartTime(), EitEvent->getStartTime(), ev->Duration(), EitEvent->getDuration()); - - if (ev->Description() && strcmp(ev->Description(),"") != 0) - origDescription = ev->Description(); - if (ev->ShortText() && strcmp(ev->ShortText(),"") != 0) - origShortText = ev->ShortText(); - Schedule->DelEvent((cEvent *) ev); -// Schedule->DropOutdated(ev->StartTime()-1,ev->EndTime()+1,ev->TableID()-1,ev->Version()); - LogD(0, prep("!!!End Deleting Event")); - //TODO equivalent channels !!! - } - } +// //VDR creates new event if the EitEvent StartTime is different than EEPG time so +// //the EPG event has to be deleted but the data should be kept +// const cEvent* ev = schedule->GetEvent(EitEvent->getEventId(),EitEvent->getStartTime()); +// if (!ev){ +// ev = schedule->GetEvent(EitEvent->getEventId()); +// if (ev && ((ev->StartTime()>EitEvent->getStartTime() && ev->StartTime()<=EitEvent->getStartTime()+EitEvent->getDuration()) +// || (EitEvent->getStartTime() > ev->StartTime() && EitEvent->getStartTime() <= ev->EndTime()))) { +// LogD(0, prep("!!!Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d"), ev->EventID(), ev->Title(), ev->StartTime(), EitEvent->getStartTime(), ev->Duration(), EitEvent->getDuration()); +// +// if (ev->Description() && strcmp(ev->Description(),"") != 0) +// origDescription = ev->Description(); +// if (ev->ShortText() && strcmp(ev->ShortText(),"") != 0) +// origShortText = ev->ShortText(); +// schedule->DelEvent((cEvent *) ev); +//// Schedule->DropOutdated(ev->StartTime()-1,ev->EndTime()+1,ev->TableID()-1,ev->Version()); +// LogD(0, prep("!!!End Deleting Event")); +// //TODO equivalent channels !!! +// } +// } @@ -90,36 +92,42 @@ bool cEEpgHandler::SetEventID(cEvent* Event, tEventID EventID) { return true; } -bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { - LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - - const char* title = charsetFixer->FixCharset(Title); - +//VDR creates new event if the EitEvent StartTime is different than EEPG time so +//the EPG event has to be deleted but the data should be kept +void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) +{ //Sometimes same events overlap and have different EventID if (origDescription.empty() && origShortText.empty()) { cEvent* eqEvent = NULL; - cEvent* ev = (cEvent*)Event->Next(); - if (ev && strcasecmp(ev->Title(),title) == 0 - && Event->StartTime() <= ev->StartTime() && Event->EndTime() > ev->StartTime()) + cEvent* ev = (cEvent*) Event->Next(); + if (ev && (ev->EventID() == Event->EventID() || strcasecmp(ev->Title(), newTitle) == 0) + && Event->StartTime() <= ev->StartTime() && Event->EndTime() > ev->StartTime()) eqEvent = ev; - if (!eqEvent && (ev = (cEvent*)Event->Prev()) != NULL && strcasecmp(ev->Title(),title) == 0 - && ev->StartTime() <= Event->StartTime() && ev->EndTime() > Event->StartTime()) + if (!eqEvent && (ev = (cEvent*) Event->Prev()) != NULL + && (ev->EventID() == Event->EventID() || strcasecmp(ev->Title(), newTitle) == 0) + && ev->StartTime() <= Event->StartTime() && ev->EndTime() > Event->StartTime()) eqEvent = ev; if (eqEvent) { - if (ev->Description() && strcmp(ev->Description(),"") != 0) + if (ev->Description() && strcmp(ev->Description(), "") != 0) origDescription = ev->Description(); - if (ev->ShortText() && strcmp(ev->ShortText(),"") != 0) + if (ev->ShortText() && strcmp(ev->ShortText(), "") != 0) origShortText = ev->ShortText(); - //origDescription = eqEvent->Description(); - //origShortText = eqEvent->ShortText(); - LogD(0, prep("!!! !Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d") - , ev->EventID(), ev->Title(), ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); + LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%d; start_time o:%d n:%d; duration o:%d n:%d"), + ev->EventID(), Event->EventID(), ev->Title(), newTitle, ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); - cSchedule* schedule = (cSchedule*)Event->Schedule(); - schedule->DelEvent((cEvent*)eqEvent); + schedule->DelEvent((cEvent*) eqEvent); } } +} + +bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { + LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); + + const char* title = charsetFixer->FixCharset(Title); + + //Sometimes same events overlap and have different EventID + FindDuplicate(Event, title); if (!Event->Title() || (title && (!strcmp(Event->Title(),"") || (strcmp(Title,"") && strcmp(Event->Title(),title))))) { //LogD(0, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); @@ -233,6 +241,8 @@ bool cEEpgHandler::HandleEvent(cEvent* Event) { if (modified) equivHandler->updateEquivalent(Event->ChannelID(), Event); + //Release the schedule + schedule = NULL; //TODO just to see the difference //else if (!origDescription.empty() && !origDescription.compare(Event->Description())) { // origDescription.append(" | EIT: "); diff --git a/epghandler.h b/epghandler.h index b37f7c2..c0c5f0a 100644 --- a/epghandler.h +++ b/epghandler.h @@ -40,12 +40,14 @@ public: // bool ParseEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version); private: std::string ExtractAttribute(const char* attr); + void FindDuplicate(cEvent* Event, const char* newTitle); private: std::string origShortText; std::string origDescription; cEquivHandler* equivHandler; util::cCharsetFixer* charsetFixer; + cSchedule* schedule; static const int _LONG_EVENT_HOURS = 10; bool modified; -- cgit v1.2.3 From e806e6ac89fa61fc6683bb14ac73d3173450226a Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 21 Nov 2012 15:38:48 +0100 Subject: change table ID numbers to enums vdr or extended --- eepg.c | 163 +++++++++++++++++++++++++---------------------------------------- eit2.h | 27 +++++++++++ 2 files changed, 90 insertions(+), 100 deletions(-) diff --git a/eepg.c b/eepg.c index 29bd4d4..d20c1f5 100644 --- a/eepg.c +++ b/eepg.c @@ -289,7 +289,7 @@ void cFilterEEPG::SetStatus (bool On) void cFilterEEPG::NextPmt (void) { - Del (pmtpid, 0x02); + Del (pmtpid, SI::TableIdPMT); pmtpid = 0; pmtidx++; LogE(3, prep("PMT next\n")); @@ -2692,28 +2692,28 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) EndThemes = false; switch (Format) { case PREMIERE: - AddFilter (pid, 0xA0); + AddFilter (pid, SI::TableIdPremiereCIT); break; case MHW1: - AddFilter (0xd3, 0x92); //ThemesMHW1//TODO: all filters are serialized, strictly speaking Themes is non-fatal... + AddFilter (0xd3, SI::TableIdMHW1Themes); //ThemesMHW1//TODO: all filters are serialized, strictly speaking Themes is non-fatal... break; case MHW2: - AddFilter (0x231, 0xc8); //MHW2 Channels & Themes + AddFilter (0x231, SI::TableIdMHW2ChannelsThemes); //MHW2 Channels & Themes break; case SKY_IT: case SKY_UK: - AddFilter (0x11, 0x4a); //Sky Channels + AddFilter (0x11, SI::TableIdSKYChannels); //Sky Channels break; case FREEVIEW: //Freeview, CONT mode //TODO streamline this for other modes InitDictionary (); - AddFilter (pid, 0x4e, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following - AddFilter (pid, 0x50, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X) - AddFilter (pid, 0x60, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X) - AddFilter (0x39, 0x50, 0xf0); //event info, actual TS, Viasat - AddFilter (0x39, 0x60, 0xf0); //event info, other TS, Viasat + AddFilter (pid, SI::TableIdEIT_presentFollowing, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following + AddFilter (pid, SI::TableIdEIT_schedule_first, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X) + AddFilter (pid, SI::TableIdEIT_schedule_Other_first, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X) + AddFilter (0x39, SI::TableIdEIT_schedule_first, 0xf0); //event info, actual TS, Viasat + AddFilter (0x39, SI::TableIdEIT_schedule_Other_first, 0xf0); //event info, other TS, Viasat break; case NAGRA: - AddFilter (pid, 0xb0); //perhaps TID is equal to first data byte? + AddFilter (pid, SI::TableIdNagraCIT); //perhaps TID is equal to first data byte? break; case DISH_BEV: #if APIVERSNUM < 10726 @@ -2725,9 +2725,9 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) // AddFilter (0x0441, 0x60, 0xf0); // Bell ExpressVU EEPG break; case EIT: - AddFilter (pid, 0x4e, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following - AddFilter (pid, 0x50, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X) - AddFilter (pid, 0x60, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X) + AddFilter (pid, SI::TableIdEIT_presentFollowing, 0xfe); //event info, actual(0x4e)/other(0x4f) TS, present/following + AddFilter (pid, SI::TableIdEIT_schedule_first, 0xf0); //event info, actual TS, schedule(0x50)/schedule for future days(0x5X) + AddFilter (pid, SI::TableIdEIT_schedule_Other_first, 0xf0); //event info, other TS, schedule(0x60)/schedule for future days(0x6X) break; default: break; @@ -2780,7 +2780,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (idx++ == pmtidx) { pmtpid = assoc.getPid (); pmtsid = assoc.getServiceId (); - Add (pmtpid, 0x02); + Add (pmtpid, SI::TableIdPMT); pmtnext = now + PMT_SCAN_TIMEOUT; LogI(3, prep("PMT pid now 0x%04x (idx=%d)\n"), pmtpid, pmtidx); break; @@ -2833,12 +2833,12 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (d->getLength () == 6 && d->getData ().FourBytes (2) == 0x46534154) //Freeview prvFRV = true; break; - case 0x52: + case SI::StreamIdentifierDescriptorTag: //if (d->getLength () == 3 && d->getData ().FourBytes (2) == 0xb07ea882) { if (d->getLength () == 3 && ((d->getData ().TwoBytes (2) & 0xff00) == 0xb000)) UnprocessedFormat[NAGRA] = stream.getPid (); break; - case 0x90: + case SI::SkyOTVDescriptorTag: //esyslog ("usr: %d %08x\n", d->getLength (), d->getData ().FourBytes (2)); if (d->getLength () == 6 && d->getData ().FourBytes (2) == 0x0000ffff) usrData = true; @@ -2850,19 +2850,19 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len usrOTV = SKY_UK; //Format = SKY_UK; break; - case 0xc1: //MHW1, MHW2 + case SI::MHW1DescriptorTag: //MHW1, MHW2 // esyslog("EEPGDEBUG:d->getDescriptorTAG:%d %08x\n",d->getLength(),d->getData().FourBytes(2)); if (d->getLength () == 10 && d->getData ().FourBytes (2) == 0x50555348) //MHw1 Cyfra UnprocessedFormat[MHW1] = stream.getPid (); break; - case 0xc2: //MHW1, MHW2 + case SI::MHW1_2DescriptorTag: //MHW1, MHW2 if (d->getLength () == 10 && d->getData ().FourBytes (2) == 0x45504700) //MHw1 CanDigNL and CSat UnprocessedFormat[MHW1] = stream.getPid (); else if (d->getLength () == 10 && d->getData ().FourBytes (2) == 0x46494348) { //MHW2 UnprocessedFormat[MHW2] = stream.getPid (); } break; - case 0xd1: //Freeview + case SI::FreeviewDescriptorTag: //Freeview LogD(4, prep("case 0xd1: //Freeview")); if (d->getLength () == 3 && ((d->getData ().TwoBytes (2) & 0xff00) == 0x0100)) usrFRV = 0x01; @@ -2919,39 +2919,34 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len else if (Source ()) { if ( Pid == EIT_PID || Pid == 0x0300 || Pid == 0x0441 ) { - if (Tid >= 0x4E) + if (Tid >= SI::TableIdEIT_presentFollowing) ProccessContinuous(Pid, Tid, Length, Data); return; } int Result; switch (Tid) { - case 0xA0: + case SI::TableIdPremiereCIT: if ((Pid < 0x30) || (Pid > 0x37)) { ProcessPremiere(Data); break; } //if citpid == 0xb11 Premiere /* no break - used for sky also*/ - case 0xa1: - case 0xa2: - case 0xa3: + case SI::TableIdSKYTitles_first ... SI::TableIdSKYTitles_last: Result = GetTitlesSKYBOX (Data, Length - 4); if (Result != 1) //when fatal error or finished - Del (Pid, 0xa0, 0xfc); //kill filter + Del (Pid, SI::TableIdSKYTitlesA0, 0xfc); //kill filter if (Result == 0) { //fatal error esyslog ("EEPG: Fatal error reading titles."); ProcessNextFormat (); //and go process other formats } if (Result == 2) - AddFilter (Pid + 0x10, 0xa8, 0xfc); //Set filter that processes summaries of this batch + AddFilter (Pid + 0x10, SI::TableIdSKYSummaries_first, 0xfc); //Set filter that processes summaries of this batch break; - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: + case SI::TableIdSKYSummaries_first ... SI::TableIdSKYSummaries_last: Result = GetSummariesSKYBOX (Data, Length - 4); if (Result != 1) //when fatal error or finished - Del (Pid, 0xa8, 0xfc); //kill filter + Del (Pid, SI::TableIdSKYSummaries_first, 0xfc); //kill filter if (Result == 0) { esyslog ("EEPG: Fatal error reading summaries."); ProcessNextFormat (); @@ -2959,12 +2954,12 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (Result == 2) { LoadIntoSchedule (); if (Pid < 0x47) //this is not the last batch//FIXME chaining is easy on the PIDs and the CPU, but error when Pid,Tid is not used at the moment... - AddFilter (Pid - 0x0F, 0xa0, 0xfc); //next pid, first tid + AddFilter (Pid - 0x0F, SI::TableIdSKYTitlesA0, 0xfc); //next pid, first tid else //last pid was processed ProcessNextFormat (); } break; - case 0x90: + case SI::TableIdMHW1TitlesSummaries: if (Pid == 0xd2) { Result = GetTitlesMHW1 (Data, Length); if (Result != 1) //fatal error or last processed @@ -2974,7 +2969,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len ProcessNextFormat (); } if (Result == 2) - AddFilter (0xd3, 0x90); //SummariesMHW1 + AddFilter (0xd3, SI::TableIdMHW1TitlesSummaries); //SummariesMHW1 } else if (Pid == 0xd3) { Result = GetSummariesMHW1 (Data, Length); if (Result != 1) //fatal error or last processed @@ -2990,24 +2985,24 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } } break; - case 0xc8: //GetChannelsMHW2 or GetThemesMHW2 + case SI::TableIdMHW2ChannelsThemes: //GetChannelsMHW2 or GetThemesMHW2 if (Pid == 0x231) { if (Data[3] == 0x01) { //Themes it will be - Result = GetThemesMHW2 (Data, Length); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed + Result = GetThemesMHW2 (Data, Length); //return code 0 = fatal error, code 1 = success, code 2 = last item processed //break; if (Result != 1) EndThemes = true; //also set Endthemes on true on fatal error } //if Data else if (Data[3] == 0x00) { //Channels it will be - Result = GetChannelsMHW (Data, Length, 2); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed + Result = GetChannelsMHW (Data, Length, 2); //return code 0 = fatal error, code 1 = success, code 2 = last item processed if (Result != 1) EndChannels = true; //always remove filter, code 1 should never be returned since MHW2 always reads all channels.. ChannelsOk = (Result == 2); } - if (EndChannels && EndThemes) { //those are only set withing MHW2 - Del (0x231, 0xc8); //stop reading MHW2 themes and channels - if (ChannelsOk) //No channels = fatal, no themes = nonfatal - AddFilter (0x234, 0xe6); //start reading MHW2 titles + if (EndChannels && EndThemes) { //those are only set within MHW2 + Del (0x231, SI::TableIdMHW2ChannelsThemes); //stop reading MHW2 themes and channels + if (ChannelsOk) //No channels = fatal, no themes = non fatal + AddFilter (0x234, SI::TableIdMHW2Titles); //start reading MHW2 titles else { esyslog ("EEPG: Fatal error reading channels."); ProcessNextFormat (); @@ -3015,30 +3010,30 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } } //if Pid == 0x231 break; - case 0x91: - Result = GetChannelsMHW (Data, Length, 1); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed + case SI::TableIdMHW1Channels: + Result = GetChannelsMHW (Data, Length, 1); //return code 0 = fatal error, code 1 = success, code 2 = last item processed Del (Pid, Tid); //always remove filter, code 1 should never be returned since MHW1 always reads all channels... if (Result == 2) - AddFilter (0xd2, 0x90); //TitlesMHW1 + AddFilter (0xd2, SI::TableIdMHW1TitlesSummaries); //TitlesMHW1 else { esyslog ("EEPG: Fatal error reading channels."); ProcessNextFormat (); } break; - case 0x92: - Result = GetThemesMHW1 (Data, Length); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed + case SI::TableIdMHW1Themes: + Result = GetThemesMHW1 (Data, Length); //return code 0 = fatal error, code 1 = success, code 2 = last item processed if (Result != 1) Del (Pid, Tid); if (Result == 2) - AddFilter (0xd3, 0x91); //ChannelsMHW1 + AddFilter (0xd3, SI::TableIdMHW1Channels); //ChannelsMHW1 else { - esyslog ("EEPG: Fatal error reading themes."); //doesnt have to be fatal... + esyslog ("EEPG: Fatal error reading themes."); //Doesn't have to be fatal... ProcessNextFormat (); } break; - case 0xe6: //TitlesMHW2 + case SI::TableIdMHW2Titles: //TitlesMHW2 if (Pid == 0x234) { - Result = GetTitlesMHW2 (Data, Length); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed + Result = GetTitlesMHW2 (Data, Length); //return code 0 = fatal error, code 1 = success, code 2 = last item processed if (Result != 1) Del (Pid, Tid); if (Result == 0) { @@ -3046,10 +3041,10 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len ProcessNextFormat (); } if (Result == 2) - AddFilter (0x236, 0x96); //start reading MHW2 summaries.... + AddFilter (0x236, SI::TableIdMHW2Summaries); //start reading MHW2 summaries.... } break; - case 0x96: //Summaries MHW2 + case SI::TableIdMHW2Summaries: //Summaries MHW2 if (Pid == 0x236) { Result = GetSummariesMHW2 (Data, Length); //return code 0 = fatal error, code 1 = sucess, code 2 = last item processed if (Result != 1) @@ -3064,7 +3059,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } } //if pid break; - case 0x4a: //Sky channels + case SI::TableIdSKYChannels: //Sky channels if (Pid == 0x11) { Result = GetChannelsSKYBOX (Data, Length - 4); if (Result != 1) //only breakoff on completion or error; do NOT clean up after success, because then not all bouquets will be read @@ -3072,7 +3067,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (Result == 2) { GetThemesSKYBOX (); //Sky Themes from file; must be called AFTER first channels to have lThemes initialized FIXME if (InitDictionary ()) - AddFilter (0x30, 0xa0, 0xfc); //SKY Titles batch 0 of 7 + AddFilter (0x30, SI::TableIdSKYTitlesA0, 0xfc); //SKY Titles batch 0 of 7 else { esyslog ("EEPG: Fatal error reading huffman table."); ProcessNextFormat (); @@ -3081,7 +3076,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } //if Pid == 0x11 break; - case 0xb0: //NagraGuide + case SI::TableIdNagraCIT: //NagraGuide if (Pid == 0xc8) { Result = GetNagra (Data, Length); if (Result != 1) @@ -3100,40 +3095,9 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } break; - case 0x4E: - case 0x4F: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - case 0x66: - case 0x67: - case 0x68: - case 0x69: - case 0x6A: - case 0x6B: - case 0x6C: - case 0x6D: - case 0x6E: - case 0x6F: + case SI::TableIdEIT_presentFollowing: + case SI::TableIdEIT_presentFollowing_other: + case SI::TableIdEIT_schedule_first ... SI::TableIdEIT_schedule_Other_last: // Freesat: // Set(3842, 0x4E, 0xFE); // event info, actual(0x4E)/other(0x4F) TS, present/following // Set(3842, 0x50, 0xF0); // event info, actual TS, schedule(0x50)/schedule for future days(0x5X) @@ -3168,7 +3132,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) int now = time (0); int nCount = 0; int nRating = 0; - unsigned char Tid = 0xa0; // TODO maybe default TableID + unsigned char Tid = SI::TableIdPremiereCIT; // TODO maybe default TableID SI::ExtendedEventDescriptors * ExtendedEventDescriptors = 0; SI::ShortEventDescriptor * ShortEventDescriptor = 0; char *order = 0, *rating = 0; @@ -3182,7 +3146,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) for (SI::Loop::Iterator it; (d = cit.eventDescriptors.getNext (it));) { nDescriptorTag = d->getDescriptorTag (); switch (nDescriptorTag) { - case 0xF0: // order information + case SI::PremiereOrderInfoDescriptorTag: // order information if (SetupPE->OrderInfo) { static const char *text[] = { trNOOP ("Ordernumber"), @@ -3204,7 +3168,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) order = strdup (buff); } break; - case 0xF1: // parental rating + case SI::PremiereRatingInfoDescriptorTag: // parental rating if (SetupPE->RatingInfo) { char buff[512]; int p = 0; @@ -3287,14 +3251,13 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) int sid = pct->getServiceId (); if (SetupPE->FixEpg) { if (nid == 133) { - if (tid == 0x03 && sid == 0xf0) { - tid = 0x02; + if (tid == SI::TableIdTSDT && sid == 0xf0) { + tid = SI::TableIdPMT; sid = 0xe0; - } else if (tid == 0x03 && sid == 0xf1) { - tid = 0x02; + } else if (tid == SI::TableIdTSDT && sid == 0xf1) { + tid = SI::TableIdPMT; sid = 0xe1; - } else if (tid == 0x03 && sid == 0xf5) { - tid = 0x03; + } else if (tid == SI::TableIdTSDT && sid == 0xf5) { sid = 0xdc; } else if (tid == 0x04 && sid == 0xd2) { tid = 0x11; @@ -3355,7 +3318,7 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) } else { LogI(2, "(upd)\n"); pEvent->SetSeen (); - if (pEvent->TableID () == 0x00 || pEvent->Version () == cit.getVersionNumber ()) { + if (pEvent->TableID () == SI::TableIdPAT || pEvent->Version () == cit.getVersionNumber ()) { if (pEvent->RunningStatus () != runningStatus) pSchedule->SetRunningStatus (pEvent, runningStatus, channel); continue; diff --git a/eit2.h b/eit2.h index 7686672..c6251fe 100644 --- a/eit2.h +++ b/eit2.h @@ -7,11 +7,38 @@ namespace SI { + +enum TableIdExt { + TableIdSKYChannels = TableIdBAT, //SKYBOX channels information section 0x4A same as TableIdBAT + TableIdMHW1TitlesSummaries = 0x90, //MHW1 titles and summaries information section + TableIdMHW1Channels = 0x91, //MHW1 channels information section + TableIdMHW1Themes = 0x92, //MHW1 themes information section + TableIdMHW2Summaries = 0x96, //MHW2 summaries information section + //SKYBOX Titles range from 0xA0 to 0xA3. 0xA0 is also TableIdPremiereCIT + TableIdSKYTitlesA0 = TableIdPremiereCIT, //SKYBOX titles information section start + TableIdSKYTitles_first = 0xA1, //SKYBOX titles information section start + TableIdSKYTitles_last = 0xA3, //SKYBOX titles information section end + //SKYBOX Summaries range from 0xA8 to 0xAB. + TableIdSKYSummaries_first = 0xA8, //SKYBOX Summaries information section start + TableIdSKYSummaries_last = 0xAB, //SKYBOX Summaries information section end + TableIdNagraCIT = 0xB0, //NagraGuide content information section + TableIdMHW2ChannelsThemes = 0xC8, //MHW1 channels and themes information section + TableIdMHW2Titles = 0xE6 //MHW2 titles information section + +}; + + enum DescriptorTagExt { DishRatingDescriptorTag = 0x89, + SkyOTVDescriptorTag = 0x90, DishShortEventDescriptorTag = 0x91, DishExtendedEventDescriptorTag = 0x92, DishSeriesDescriptorTag = 0x96, + MHW1DescriptorTag = 0xC1, + MHW1_2DescriptorTag = 0xC2, + FreeviewDescriptorTag = 0xD1, + PremiereOrderInfoDescriptorTag = 0xF0, + PremiereRatingInfoDescriptorTag = 0xF1, }; // typedef InheritEnum< DescriptorTagExt, SI::DescriptorTag > ExtendedDescriptorTag; -- cgit v1.2.3 From 021190e605d10424986c616793829a7e99b3e720 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 23 Nov 2012 16:24:15 +0100 Subject: change MjdToEpochTime macro to function and use it on more locations extract SKY qualitiy info from stream. Should be added to the event description do not send already expired events to VDR so that no cleanup is required after. changed the logic of summary handling for SKY so that no SummaryAvailable bit is required, since it can not be located from the stream implement some TODOs remove commented code --- eepg.c | 251 ++++++++++++++++++++++++++++++----------------------------- eepg.h | 13 +++- epghandler.c | 6 +- 3 files changed, 142 insertions(+), 128 deletions(-) diff --git a/eepg.c b/eepg.c index d20c1f5..0c6e606 100644 --- a/eepg.c +++ b/eepg.c @@ -1297,23 +1297,9 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, }else{ category = theme; } - /* - string fmt; - fmt = "%s"; - if (stripspace(category)) { - fmt += "\nCategory: %s"; - } - if (genre) { - fmt += "\nGenre: %s"; - } - Asprintf (&tmp, fmt.c_str(), SummText, category, stripspace (genre)); - Event->SetDescription (tmp); - free(tmp); - */ string desc = SummText; if (stripspace(category)) desc.append("\n").append(CATEGORY).append(category); - //if (stripspace(category)) desc += '\n' << CATEGORY << category; if (stripspace(genre)) desc += '\n' + string(GENRE) + genre; Event->SetDescription (desc.c_str()); @@ -1910,11 +1896,8 @@ int cFilterEEPG::GetTitlesMHW2 (const u_char * Data, int Length) T->ChannelId = Data[Pos]; Pos+=11;//The date time starts here //isyslog ("EEPGDebug: ChannelID:%d", T->ChannelId); - unsigned int MjdTime = (Data[Pos] << 8) | Data[Pos + 1]; - T->MjdTime = 0; //not used for matching MHW2 - T->StartTime = ((MjdTime - 40587) * 86400) - + (((((Data[Pos + 2] & 0xf0) >> 4) * 10) + (Data[Pos + 2] & 0x0f)) * 3600) - + (((((Data[Pos + 3] & 0xf0) >> 4) * 10) + (Data[Pos + 3] & 0x0f)) * 60); + T->MjdTime = 0; //(Data[Pos] << 8) | Data[Pos + 1] not used for matching MHW2 + T->StartTime = MjdToEpochTime(Data[Pos], Data[Pos + 1], Data[Pos + 2], Data[Pos + 3]); T->Duration = (((Data[Pos + 5] << 8) | Data[Pos + 6]) >> 4) * 60; Len = Data[Pos + 7] & 0x3f; //isyslog ("EEPGDebug: Len:%d", Len); @@ -1987,7 +1970,7 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length) // unsigned short SectionLength = ((Summary->SectionLengthHigh & 0x0f) << 8) | Summary->SectionLengthLow; // Asprintf((char **)&Text, "%s \n\n SecLength:%d SLHigh:%d SLLow:%d", Text, SectionLength, Summary->SectionLengthHigh, Summary->SectionLengthLow); S->Text = Text; - S->ShortTextLength = 0; //TODO find for MHW1 + S->ShortTextLength = 0; //TODO DPE find for MHW1 int i = 0; do { S->Replays[i].MjdTime = 0; //only used for SKY @@ -2008,11 +1991,7 @@ int cFilterEEPG::GetSummariesMHW1 (const u_char * Data, int Length) S->EventId, S->Replays[i].ChannelId, sChannels[ChannelSeq[S->Replays[i].ChannelId]].Name, Hour, Minute, Sec); - S->Replays[i].StartTime = MjdToEpochTime (Date) + (((((Hour & 0xf0) >> 4) * 10) + (Hour & 0x0f)) * 3600) - + (((((Minute & 0xf0) >> 4) * 10) + (Minute & 0x0f)) * 60) - + ((((Sec & 0xf0) >> 4) * 10) + (Sec & 0x0f)); -// summary -> time[i] = ProviderLocalTime2UTC (summary -> time[i]); - S->Replays[i].StartTime = LocalTime2UTC (S->Replays[i].StartTime); + S->Replays[i].StartTime = LocalTime2UTC (MjdToEpochTime (Date_hi, Date_lo, Hour, Minute, Sec)); //} i++; } while (i < Summary->NumReplays); @@ -2155,67 +2134,64 @@ int cFilterEEPG::GetChannelsSKYBOX (const u_char * Data, int Length) while (TransportDescriptorsLength > 0) { unsigned char DescriptorTag = Data[p2]; int DescriptorLength = Data[p2 + 1]; - int p3 = (p2 + 2); + int p3 = (p2 + 4); p2 += (DescriptorLength + 2); TransportDescriptorsLength -= (DescriptorLength + 2); - switch (DescriptorTag) { //TODO switch with only 1 case??? replace this by template - case 0xb1: - p3 += 2; - DescriptorLength -= 2; - while (DescriptorLength > 0) { - // 0x01 = Video Channel - // 0x02 = Audio Channel - // 0x05 = Other Channel - //if( Data[p3+2] == 0x01 || Data[p3+2] == 0x02 || Data[p3+2] == 0x05 ) - //{ - unsigned short int Sid = (Data[p3] << 8) | Data[p3 + 1]; - unsigned short int ChannelId = (Data[p3 + 3] << 8) | Data[p3 + 4]; - unsigned short int SkyNumber = (Data[p3 + 5] << 8) | Data[p3 + 6]; - if (SkyNumber > 100 && SkyNumber < 1000) { - if (ChannelId > 0) { - sChannel *C; - if (ChannelSeq.count (ChannelId) == 0) { //not found - C = &sChannels[nChannels]; - C->ChannelId = ChannelId; - //C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1 - C->Src = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!! - C->Nid = Nid; - C->Tid = Tid; - C->Sid = Sid; - C->SkyNumber = SkyNumber; - tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); - cChannel *VC = Channels.GetByChannelID (channelID, true); - bool IsFound = (VC); - if (IsFound) - strncpy ((char *) C->Name, VC->Name (), 64); - else - C->Name[0] = '\0'; //empty string - - LogI(1, "|% 5d | %-26.26s | %-22.22s | %-3.3s | % 6d |\n", C->ChannelId - , *channelID.ToString(), C->Name, IsFound ? "YES" : "NO", C->SkyNumber); - - ChannelSeq[C->ChannelId] = nChannels; //fill lookup table to go from channel-id to sequence nr in table - nChannels++; - if (nChannels >= MAX_CHANNELS) { - LogE(0, prep("Error, %i channels found more than %i"), nChannels, MAX_CHANNELS); - return 0; - } + if (DescriptorTag != 0xB1) + continue; + + DescriptorLength -= 2; + while (DescriptorLength > 0) { + // 0x01 = Video Channel + // 0x02 = Audio Channel + // 0x05 = Other Channel + //if( Data[p3+2] == 0x01 || Data[p3+2] == 0x02 || Data[p3+2] == 0x05 ) + //{ + unsigned short int Sid = (Data[p3] << 8) | Data[p3 + 1]; + unsigned short int ChannelId = (Data[p3 + 3] << 8) | Data[p3 + 4]; + unsigned short int SkyNumber = (Data[p3 + 5] << 8) | Data[p3 + 6]; + if (SkyNumber > 100 && SkyNumber < 1000) { + if (ChannelId > 0) { + sChannel *C; + if (ChannelSeq.count (ChannelId) == 0) { //not found + C = &sChannels[nChannels]; + C->ChannelId = ChannelId; + //C->NumberOfEquivalences = 1; //there is always an original channel. every equivalence adds 1 + C->Src = Source (); //assume all EPG channels are on same satellite, if not, manage this via equivalents!!! + C->Nid = Nid; + C->Tid = Tid; + C->Sid = Sid; + C->SkyNumber = SkyNumber; + tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); + cChannel *VC = Channels.GetByChannelID (channelID, true); + bool IsFound = (VC); + if (IsFound) + strncpy ((char *) C->Name, VC->Name (), 64); + else + C->Name[0] = '\0'; //empty string + + LogI(1, "|% 5d | %-26.26s | %-22.22s | %-3.3s | % 6d |\n", C->ChannelId + , *channelID.ToString(), C->Name, IsFound ? "YES" : "NO", C->SkyNumber); + + ChannelSeq[C->ChannelId] = nChannels; //fill lookup table to go from channel-id to sequence nr in table + nChannels++; + if (nChannels >= MAX_CHANNELS) { + LogE(0, prep("Error, %i channels found more than %i"), nChannels, MAX_CHANNELS); + return 0; } } } - p3 += 9; - DescriptorLength -= 9; } - break; - default: - break; - } //switch descriptortag + p3 += 9; + DescriptorLength -= 9; + } } } //while return 1; } //else part of memcmp } + /** * \brief Get SKYBOX Titles * @@ -2237,7 +2213,7 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) if (nTitles == 0) memcpy (InitialTitle, Data, 20); //copy data into initial title ChannelId = (Data[3] << 8) | Data[4]; - MjdTime = ((Data[8] << 8) | Data[9]); + MjdTime = (Data[8] << 8) | Data[9]; if (ChannelId > 0) { if (MjdTime > 0) { p = 10; @@ -2259,12 +2235,12 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) } p += 4; Len2 = Data[p + 1] - 7; - T->StartTime = ((MjdTime - 40587) * 86400) + ((Data[p + 2] << 9) | (Data[p + 3] << 1)); + T->StartTime = MjdToEpochTime(MjdTime) + ((Data[p + 2] << 9) | (Data[p + 3] << 1)); T->Duration = ((Data[p + 4] << 9) | (Data[p + 5] << 1)); T->ThemeId = Data[p + 6]; T->TableId = DEFAULT_TABLE_ID; //TODO locate the actual table id //TODO Data[p + 7] is Quality value add it to description - //int quality = Data[p + 7]; + T->Quality = Data[p + 7]; switch (Data[p + 8] & 0x0F) { case 0x01: T->Rating = 0x00; //"U" @@ -2285,9 +2261,9 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) T->Rating = 0x00; //"-" break; } - T->Unknown1 = Data[p + 4 - 13]; //FIXME - T->Unknown2 = Data[p + 4 - 12]; //FIXME - T->Unknown3 = Data[p + 4 - 11]; //FIXME + T->Unknown1 = Data[5]; //Bound to Channel/Date + T->Unknown2 = Data[6]; //Bound to Channel/Date + T->Unknown3 = Data[7]; //Bound to Channel/Date unsigned char tmp[4096]; //TODO smarter Len2 = sky_huffman_decode (&Data[p + 9], Len2, tmp); if (Len2 == 0) { @@ -2304,8 +2280,8 @@ int cFilterEEPG::GetTitlesSKYBOX (const u_char * Data, int Length) CleanString (T->Text); T->SummaryAvailable = 1; //TODO I assume this is true? - LogI(3, prep("EventId %08x Titlenr %d,Unknown1:%x,Unknown2:%x,Un3:%x,Name:%s."), - T->EventId, nTitles, T->Unknown1, T->Unknown2, T->Unknown3, T->Text); + LogI(3, prep("EventId %08x Titlenr %d,Un1:%x,Un2:%x,Un3:%x,Quality:%x,Name:%s."), + T->EventId, nTitles, T->Unknown1, T->Unknown2, T->Unknown3, T->Quality, T->Text); p += Len1; nTitles++; @@ -2384,7 +2360,7 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) CleanString (S->Text); char * delim = strstr ( (char *)S->Text, STxtDelim ); S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; - LogI(3, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); + LogI(4, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); p += Len1; nSummaries++; if (nSummaries >= MAX_TITLES) { @@ -2407,7 +2383,9 @@ void cFilterEEPG::FreeSummaries (void) S = Summaries[i]; if (i < nSummaries - 1) { S2 = Summaries[i + 1]; //look at next summary - if (S->Text != S2->Text && S->Text != 0x00) //this is the last summary that points to this text block; needed in case NumReplays > 1, multiple pointers to same textblock + //this is the last summary that points to this text block; + // needed in case NumReplays > 1, multiple pointers to same textblock + if (S->Text != S2->Text && S->Text != 0x00) free (S->Text); } else if (S->Text != 0x00) free (S->Text); @@ -2439,13 +2417,15 @@ void cFilterEEPG::LoadIntoSchedule (void) foundtitle = false; Title_t *T; Summary_t *S; - int remembersummary; + int remembersummary = -1; //keep statistics int SummariesNotFound = 0; int NoSummary = 0; int NotMatching = 0; int LostSync = 0; - remembersummary = -1; + int OldEvents = 0; + int SummIndex = -1; + bool isOTV = Format == SKY_IT || Format == SKY_UK; { cSchedulesLock SchedulesLock (true); @@ -2453,7 +2433,6 @@ void cFilterEEPG::LoadIntoSchedule (void) if (s) { while (i < nTitles) { - T = Titles[i]; S = Summaries[j]; foundtitle = false; @@ -2470,13 +2449,16 @@ void cFilterEEPG::LoadIntoSchedule (void) if (!foundtitle) //no more titles with summaries break; - if ((T->EventId == S->EventId) && (T->MjdTime == S->Replays[0].MjdTime) - && ((T->ChannelId == S->Replays[0].ChannelId) || ((Format != SKY_IT) && (Format != SKY_UK)))) { //should always be true, titles and summaries are broadcasted in order... + time_t too_old = time(NULL) - (Setup.EPGLinger * 60 + 3600); + if ((T->EventId == S->EventId && T->MjdTime == S->Replays[0].MjdTime) && + ((T->ChannelId == S->Replays[0].ChannelId) || !isOTV)) { //should always be true, titles and summaries are broadcasted in order... LogD(3, prep("T->EventId == S->EventId")); //MjdTime = 0 for all but SKY //S->ChannelId must be equal to T->ChannelId only for SKY; in MHW1 S->ChannelId overrides T->ChannelId when NumReplays > 1 remembersummary = -1; //reset summary searcher //int Replays = S->NumReplays; + if (isOTV) + SummIndex = j; int index = 0; do { @@ -2490,6 +2472,13 @@ void cFilterEEPG::LoadIntoSchedule (void) StartTime = S->Replays[index].StartTime; } + index++; + if ((StartTime + T->Duration) < too_old) { + LogD(3, prep("Skipping old event '%s', start time:%s"), T->Text, ctime (&StartTime)); + OldEvents++; + continue; + } + //channelids are sequentially numbered and sent in MHW1 and MHW2, but not in SKY, so we need to lookup the table index sChannel *C = &sChannels[ChannelSeq[ChannelId]]; //find channel //cSchedule *p;//[MAX_EQUIVALENCES]; @@ -2497,7 +2486,7 @@ void cFilterEEPG::LoadIntoSchedule (void) tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); char rating = 0x00; - if ((Format == SKY_IT || Format == SKY_UK) && T->Rating) { //TODO only works on OTV for now + if (isOTV && T->Rating) { //TODO only works on OTV for now rating = T->Rating; } unsigned short int TableId = DEFAULT_TABLE_ID; @@ -2505,8 +2494,8 @@ void cFilterEEPG::LoadIntoSchedule (void) TableId = T->TableId; } -// LogD (0, prep("EventId %08x Titlenr %d:SummAv:%x,Un1:%x,Un2:%x,Un3:%x,Name:%s,STxtLn:%dSummary:%s."), -// T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text, S->ShortTextLength, S->Text); +// LogD (0, prep("EventId %08x Titlenr:%d,SummNr:%d,SummAv:%x,Un1:%x,Un2:%x,Un3:%x,Name:%s,STxtLn:%d,Summary:%s."), +// T->EventId, i, j, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text, S->ShortTextLength, S->Text); WriteToSchedule (chanID, s, T->EventId, StartTime, T->Duration / 60, (char *) T->Text, (char *) S->Text, T->ThemeId, TableId, 0, rating, S->ShortTextLength); @@ -2521,11 +2510,9 @@ void cFilterEEPG::LoadIntoSchedule (void) //j = 0; //S = Summaries[j]; //next summary within replay range //} - index++; } //while while (index < S->NumReplays); - //TODO: why load events that have already past, and then run Cleanup //end of putting title and summary in schedule i++; //move to next title } //if T->EventId == S->EventId @@ -2538,31 +2525,42 @@ void cFilterEEPG::LoadIntoSchedule (void) remembersummary = nSummaries; //or next test will never be succesfull for remembersummary = 0 LostSync++; // esyslog("EEPG Error: lost sync at title %d, summary %d.",i,j); - } else if (j == (remembersummary - 1)) { //the last summary to be checked has failed also + } else if (j == (remembersummary - 1) || SummIndex !=-1) { //the last summary to be checked has failed also //esyslog ("EEPG Error: could not find summary for summary-available Title %d.", i); - esyslog - ("EEPG: Error, summary not found for EventId %08x Titlenr %d:SummAv:%x,Unknown1:%x,Unknown2:%x,Un3:%x,Name:%s.", - T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text); + if ((T->StartTime + T->Duration) < too_old) { + LogD(3, prep("Skipping old event '%s' without summary, start time:%s"), T->Text, ctime ((time_t*)&T->StartTime)); + OldEvents++; + } else { - /* write Title info to schedule */ - sChannel *C = &sChannels[ChannelSeq[T->ChannelId]]; //find channel - //cSchedule *p;//[MAX_EQUIVALENCES]; - tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); - //PrepareToWriteToSchedule (C, s, p); - char rating = 0x00; - if ((Format == SKY_IT || Format == SKY_UK) && T->Rating) { //TODO only works on OTV for now - rating = T->Rating; - } - WriteToSchedule (chanID, s, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text, - NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating, S->ShortTextLength); - //FinishWriteToSchedule (C, s, p); - sortSchedules(s, chanID); + if (!isOTV) //No sense of logging for SKY when SummaryAvailable bit is not known + esyslog("EEPG: Error, summary not found for EventId %08x Titlenr %d:SummAv:%x,Un1:%x,Un2:%x,Un3:%x,Name:%s.", + T->EventId, i, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text); + + /* write Title info to schedule */ + sChannel *C = &sChannels[ChannelSeq[T->ChannelId]]; //find channel + //cSchedule *p;//[MAX_EQUIVALENCES]; + tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); + //PrepareToWriteToSchedule (C, s, p); + char rating = 0x00; + if (!isOTV && T->Rating) { //TODO only works on OTV for now + rating = T->Rating; + } + WriteToSchedule (chanID, s, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text, + NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating, S->ShortTextLength); + //FinishWriteToSchedule (C, s, p); + sortSchedules(s, chanID); - SummariesNotFound++; + SummariesNotFound++; + } i++; //move to next title, for this one no summary can be found } -// esyslog("Trying again for this title %d, remember summary %d, but advancing one Summary to %d.",i,remembersummary,j); + if (SummIndex != -1 && isOTV){ + j--; + } + +// if (SummIndex != -1) +// esyslog("Trying again for this title %d, remember summary %d, but advancing one Summary to %d.",i,remembersummary,j+1); } j++; //move to next summary if (j >= nSummaries) //do not forget to look in beginning of (ring)buffer @@ -2573,24 +2571,32 @@ void cFilterEEPG::LoadIntoSchedule (void) LogE (0, prep("Error: could not lock schedules.")); }//release ScheduleLock - cSchedules::Cleanup (true); //deletes all past events + //TODO: Test if cleanup is needed now that old events are no more + //one thing it Cleanup (true) does is write the epg.data immediately + //cSchedules::Cleanup (true); //deletes all past events + cSchedules::Cleanup (); //deletes all past events - //isyslog ("EEPG: found %i equivalents channels", nEquivChannels); isyslog ("EEPG: found %i themes", nThemes); isyslog ("EEPG: found %i channels", nChannels); isyslog ("EEPG: found %i titles", nTitles); - if (NoSummary != 0) + if (NoSummary) isyslog ("EEPG: of which %i reported to have no summary available; skipping these BIENTOT titles", NoSummary); isyslog ("EEPG: found %i summaries", nSummaries); - if (SummariesNotFound != 0) - esyslog ("EEPG: %i summaries not found", SummariesNotFound); + if (SummariesNotFound) + if (nTitles-nSummaries!=SummariesNotFound) { + esyslog ("EEPG: %i summaries not found", SummariesNotFound); + esyslog ("EEPG: %i difference between no of summaries and summaries not found", nTitles-nSummaries-SummariesNotFound); + } else + isyslog ("EEPG: %i titles without summaries", SummariesNotFound); + if (OldEvents) + isyslog ("EEPG: Skipped %i old events", OldEvents); if (NotMatching > nSummaries) - LogI (0, prep("Warning: lost sync %i times, summary did not match %i times."), - LostSync, NotMatching); + LogI (0, prep("Warning: lost sync %i times, summary did not match %i times."), LostSync, NotMatching); + FreeSummaries (); //do NOT free channels, themes and bouquets here because they will be reused in SKY! FreeTitles (); - if (!((Format == SKY_IT) || (Format == SKY_UK))) { //everything but SKY; SKY is the only protocol where LoadIntoSchedule is called repeatedly + if (!isOTV) { //everything but SKY; SKY is the only protocol where LoadIntoSchedule is called repeatedly ChannelSeq.clear (); } } @@ -2633,8 +2639,6 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) free(mesg); } - TitleCounter = 0; - SummaryCounter = 0; /*if (SummariesNotFound != 0) esyslog ("EEPG: %i summaries not found", SummariesNotFound); else if (VERBOSE >= 1) @@ -2843,7 +2847,6 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (d->getLength () == 6 && d->getData ().FourBytes (2) == 0x0000ffff) usrData = true; if (d->getLength () == 3 && ((d->getData ().TwoBytes (2) & 0xff00) == 0xb600)) //SKY IT //TODO ugly! - //if (d->getLength () == 3 && (d->getData ().TwoBytes (2) == 0xb6a5)) //SKY IT //TODO ugly! usrOTV = SKY_IT; //Format = SKY_IT; if (d->getLength () == 3 && d->getData ().FourBytes (2) == 0xc004e288) //SKY UK diff --git a/eepg.h b/eepg.h index 8eb3f2d..a2ddb0f 100644 --- a/eepg.h +++ b/eepg.h @@ -57,6 +57,7 @@ typedef struct { unsigned char Unknown2;//FIXME unsigned char Unknown3;//FIXME unsigned char Rating; + unsigned char Quality; unsigned short int TableId; } Title_t; @@ -7180,4 +7181,14 @@ typedef struct { //first three bytes form unknown header, then X blocks, where X #define HILO16( x ) ( ( ( x##High << 8 ) | x##Low ) & 0xffff ) #define HILO32( x ) ( ( ( ( ( x##High << 24 ) | ( x##MediumHigh << 16 ) ) | ( x##MediumLow << 8 ) ) | x##Low ) & 0xffffffff ) -#define MjdToEpochTime(x) (((x##_hi << 8 | x##_lo)-40587)*86400) +//#define MjdToEpochTime(x) (((x##_hi << 8 | x##_lo)-40587)*86400) +inline time_t MjdToEpochTime(u_short mjd, u_char Hour = 0, u_char Minute = 0, u_char Sec = 0) { + return ((mjd - 40587) * 86400) + ( ((((Hour & 0xf0) >> 4) * 10) + (Hour & 0x0f)) * 3600 ) + + (((((Minute & 0xf0) >> 4) * 10) + (Minute & 0x0f)) * 60) + + ((((Sec & 0xf0) >> 4) * 10) + (Sec & 0x0f)); +} +inline time_t MjdToEpochTime(u_char dateHigh, u_char dateLow, u_char Hour = 0, u_char Minute = 0,u_char Sec = 0) { + unsigned short mjd = HILO16(date); + return MjdToEpochTime(mjd, Hour, Minute, Sec); +} + diff --git a/epghandler.c b/epghandler.c index d6b01af..f7c821d 100644 --- a/epghandler.c +++ b/epghandler.c @@ -100,11 +100,11 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) if (origDescription.empty() && origShortText.empty()) { cEvent* eqEvent = NULL; cEvent* ev = (cEvent*) Event->Next(); - if (ev && (ev->EventID() == Event->EventID() || strcasecmp(ev->Title(), newTitle) == 0) + if (ev && (ev->EventID() == Event->EventID() || (newTitle && strcasecmp(ev->Title(), newTitle) == 0)) && Event->StartTime() <= ev->StartTime() && Event->EndTime() > ev->StartTime()) eqEvent = ev; if (!eqEvent && (ev = (cEvent*) Event->Prev()) != NULL - && (ev->EventID() == Event->EventID() || strcasecmp(ev->Title(), newTitle) == 0) + && (ev->EventID() == Event->EventID() || (newTitle && strcasecmp(ev->Title(), newTitle) == 0)) && ev->StartTime() <= Event->StartTime() && ev->EndTime() > Event->StartTime()) eqEvent = ev; if (eqEvent) { @@ -113,7 +113,7 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) if (ev->ShortText() && strcmp(ev->ShortText(), "") != 0) origShortText = ev->ShortText(); - LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%d; start_time o:%d n:%d; duration o:%d n:%d"), + LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%s; start_time o:%d n:%d; duration o:%d n:%d"), ev->EventID(), Event->EventID(), ev->Title(), newTitle, ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); schedule->DelEvent((cEvent*) eqEvent); -- cgit v1.2.3 From 4c2a7908ce569eb868863d07775b5f36dbea206e Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 23 Nov 2012 21:30:36 +0100 Subject: implement some more TODOs --- README | 3 --- eepg.c | 28 ++++++++++++++++------------ epghandler.c | 23 +---------------------- equivhandler.c | 5 ++--- 4 files changed, 19 insertions(+), 40 deletions(-) diff --git a/README b/README index edde5b7..28060c8 100644 --- a/README +++ b/README @@ -129,7 +129,4 @@ information. KNOWN BUGS -Equivalents file is not used for Premiere. --On Sky Italy and Sky UK, a lot of "summaries not found" are reported. This is - because it is not (yet) known where the "summary available" flag is coded in the - OpenTV protocol used, so all titles are assumed to have a summary available. diff --git a/eepg.c b/eepg.c index 0c6e606..01257fa 100644 --- a/eepg.c +++ b/eepg.c @@ -219,7 +219,7 @@ protected: virtual bool GetThemesSKYBOX (void); virtual int GetTitlesSKYBOX (const u_char * Data, int Length); virtual int GetSummariesSKYBOX (const u_char * Data, int Length); - virtual int GetChannelsMHW (const u_char * Data, int Length, int MHW); //TODO replace MHW by Format? + virtual int GetChannelsMHW (const u_char * Data, int Length); virtual int GetThemesMHW1 (const u_char * Data, int Length); virtual int GetNagra (const u_char * Data, int Length); virtual void ProcessNagra (void); @@ -831,18 +831,20 @@ bool cFilterEEPG::InitDictionary (void) * * \return 0 = fatal error, code 1 = success, code 2 = last item processed */ -int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length, int MHW) +int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length) { - if ((MHW == 1) || (nChannels == 0)) { //prevents MHW2 from reading channels twice while waiting for themes on same filter + if (Format != MHW1 && Format != MHW2) return 0; + + if ((Format == MHW1) || (nChannels == 0)) { //prevents MHW2 from reading channels twice while waiting for themes on same filter sChannelMHW1 *Channel; int Size, Off; Size = sizeof (sChannelMHW1); Off = 4; - if (MHW == 1) { + if (Format == MHW1) { //Channel = (sChannelMHW1 *) (Data + 4); nChannels = (Length - Off) / sizeof (sChannelMHW1); } - if (MHW == 2) { + if (Format == MHW2) { if (Length > 120) nChannels = Data[120]; else { @@ -874,7 +876,7 @@ int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length, int MHW) C->ChannelId = i; ChannelSeq[C->ChannelId] = i; //fill lookup table to go from channel-id to sequence nr in table C->SkyNumber = 0; - if (MHW == 1) + if (Format == MHW1) memcpy (C->Name, &Channel->Name, 16); //MHW1 else { //MHW2 int lenName = Data[pName] & 0x0f; @@ -935,13 +937,15 @@ int cFilterEEPG::GetThemesMHW1 (const u_char * Data, int Length) const u_char *ThemesIndex = (Data + 3); for (int i = 0; i < nThemes; i++) { if (ThemesIndex[ThemeId] == i) { - Offset = (Offset + 15) & 0xf0; //TODO do not understand this + //The index of the Themes in MHW1 is not incremented by 1 but with offset calculated like this + Offset = (Offset + 15) & 0xf0; ThemeId++; } memcpy (&Themes[Offset][0], &Theme->Name, 15); Themes[Offset][15] = '\0'; //trailing null CleanString (Themes[Offset]); - LogI(1, prep("%.15s"), Themes[Offset]); +// LogI(1, prep("%.15s"), Themes[Offset]); + LogI(1, prep("%.15s|Offset:%06d"), Themes[Offset],Offset); Offset++; Theme++; } @@ -2585,7 +2589,7 @@ void cFilterEEPG::LoadIntoSchedule (void) if (SummariesNotFound) if (nTitles-nSummaries!=SummariesNotFound) { esyslog ("EEPG: %i summaries not found", SummariesNotFound); - esyslog ("EEPG: %i difference between no of summaries and summaries not found", nTitles-nSummaries-SummariesNotFound); + esyslog ("EEPG: %i difference between No. of summaries and summaries not found", nTitles-nSummaries-SummariesNotFound); } else isyslog ("EEPG: %i titles without summaries", SummariesNotFound); if (OldEvents) @@ -2706,6 +2710,7 @@ void cFilterEEPG::ProcessNextFormat (bool FirstTime = false) break; case SKY_IT: case SKY_UK: + GetThemesSKYBOX (); //Sky Themes from file AddFilter (0x11, SI::TableIdSKYChannels); //Sky Channels break; case FREEVIEW: //Freeview, CONT mode //TODO streamline this for other modes @@ -2997,7 +3002,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len EndThemes = true; //also set Endthemes on true on fatal error } //if Data else if (Data[3] == 0x00) { //Channels it will be - Result = GetChannelsMHW (Data, Length, 2); //return code 0 = fatal error, code 1 = success, code 2 = last item processed + Result = GetChannelsMHW (Data, Length); //return code 0 = fatal error, code 1 = success, code 2 = last item processed if (Result != 1) EndChannels = true; //always remove filter, code 1 should never be returned since MHW2 always reads all channels.. ChannelsOk = (Result == 2); @@ -3014,7 +3019,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len } //if Pid == 0x231 break; case SI::TableIdMHW1Channels: - Result = GetChannelsMHW (Data, Length, 1); //return code 0 = fatal error, code 1 = success, code 2 = last item processed + Result = GetChannelsMHW (Data, Length); //return code 0 = fatal error, code 1 = success, code 2 = last item processed Del (Pid, Tid); //always remove filter, code 1 should never be returned since MHW1 always reads all channels... if (Result == 2) AddFilter (0xd2, SI::TableIdMHW1TitlesSummaries); //TitlesMHW1 @@ -3068,7 +3073,6 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len if (Result != 1) //only breakoff on completion or error; do NOT clean up after success, because then not all bouquets will be read Del (Pid, Tid); //Read all channels, clean up filter if (Result == 2) { - GetThemesSKYBOX (); //Sky Themes from file; must be called AFTER first channels to have lThemes initialized FIXME if (InitDictionary ()) AddFilter (0x30, SI::TableIdSKYTitlesA0, 0xfc); //SKY Titles batch 0 of 7 else { diff --git a/epghandler.c b/epghandler.c index f7c821d..328aa91 100644 --- a/epghandler.c +++ b/epghandler.c @@ -61,27 +61,6 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, } modified = false; -// //VDR creates new event if the EitEvent StartTime is different than EEPG time so -// //the EPG event has to be deleted but the data should be kept -// const cEvent* ev = schedule->GetEvent(EitEvent->getEventId(),EitEvent->getStartTime()); -// if (!ev){ -// ev = schedule->GetEvent(EitEvent->getEventId()); -// if (ev && ((ev->StartTime()>EitEvent->getStartTime() && ev->StartTime()<=EitEvent->getStartTime()+EitEvent->getDuration()) -// || (EitEvent->getStartTime() > ev->StartTime() && EitEvent->getStartTime() <= ev->EndTime()))) { -// LogD(0, prep("!!!Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d"), ev->EventID(), ev->Title(), ev->StartTime(), EitEvent->getStartTime(), ev->Duration(), EitEvent->getDuration()); -// -// if (ev->Description() && strcmp(ev->Description(),"") != 0) -// origDescription = ev->Description(); -// if (ev->ShortText() && strcmp(ev->ShortText(),"") != 0) -// origShortText = ev->ShortText(); -// schedule->DelEvent((cEvent *) ev); -//// Schedule->DropOutdated(ev->StartTime()-1,ev->EndTime()+1,ev->TableID()-1,ev->Version()); -// LogD(0, prep("!!!End Deleting Event")); -// //TODO equivalent channels !!! -// } -// } - - return false; // return true; @@ -116,7 +95,7 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%s; start_time o:%d n:%d; duration o:%d n:%d"), ev->EventID(), Event->EventID(), ev->Title(), newTitle, ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); - schedule->DelEvent((cEvent*) eqEvent); + schedule->DelEvent((cEvent*) eqEvent);//The equivalents should be handled on adding equivalent event. } } } diff --git a/equivhandler.c b/equivhandler.c index 281d2f3..1d313db 100644 --- a/equivhandler.c +++ b/equivhandler.c @@ -24,7 +24,6 @@ cEquivHandler::cEquivHandler() cEquivHandler::~cEquivHandler() { - // TODO Auto-generated destructor stub } void cEquivHandler::loadEquivalentChannelMap (void) @@ -78,7 +77,7 @@ void cEquivHandler::loadEquivalentChannelMap (void) //int i = 0; cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false); if (!OriginalChannel) { - LogI(2, prep("Warning, not found epg channel \'%s\' in channels.conf. Equivalency is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); //TODO: skip this ing? + LogI(2, prep("Warning, not found EPG channel \'%s\' in channels.conf. Equivalence is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); continue; } if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) { @@ -87,7 +86,7 @@ void cEquivHandler::loadEquivalentChannelMap (void) rid = 0; } tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); - cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); //TODO use valid function? + cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); if (EquivChannel) { ret = equiChanMap.equal_range(*OriginalChID.ToString()); for (it=ret.first; it!=ret.second; ++it) -- cgit v1.2.3 From 3a636554f2bab014d79898dc10b8ca7ea7c8f52e Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 30 Nov 2012 13:36:55 +0100 Subject: reformated MHW1 themes modified logging added hanlding for duplicate events on equivalent channels --- eepg.c | 62 ++++++++++++++++++++++++++++++++++++++++++++------------ util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 107 insertions(+), 28 deletions(-) diff --git a/eepg.c b/eepg.c index 01257fa..5ae992d 100644 --- a/eepg.c +++ b/eepg.c @@ -944,8 +944,30 @@ int cFilterEEPG::GetThemesMHW1 (const u_char * Data, int Length) memcpy (&Themes[Offset][0], &Theme->Name, 15); Themes[Offset][15] = '\0'; //trailing null CleanString (Themes[Offset]); -// LogI(1, prep("%.15s"), Themes[Offset]); - LogI(1, prep("%.15s|Offset:%06d"), Themes[Offset],Offset); + + //reformat themes + if (Offset & 0x0f) { + char* theme; + char* cat; + Asprintf (&theme, "%s", Themes[Offset]); + Asprintf (&cat, "%s", Themes[Offset& 0xf0]); + theme = strreplace(theme,"DOC","DOCUMENTAIRE"); + theme = strreplace(theme,"DOCUMENTAIRE.","DOCUMENTAIRE"); + theme = strreplace(theme,"MAG","MAGAZINE"); + //Remove category from genre. TODO Maybe they should be separated in the future + theme = strreplace(theme,cat,""); + theme = skipspace(theme); + if (theme[0] == '-') { + memmove(theme, theme+1, strlen(theme)); + theme = skipspace(theme); + } + char* buf; + Asprintf(&buf,"%s - %s",cat,theme); + memcpy(Themes[Offset],buf,strlen(buf)+1); + } + + LogI(1, prep("%-33.33s|Offset:0x%02x"), Themes[Offset],Offset); + Offset++; Theme++; } @@ -1007,7 +1029,7 @@ int cFilterEEPG::GetThemesMHW2 (const u_char * Data, int Length) //memcpy (&Themes[pThemeId][lenThemeName + 1], &Data[pSubThemeName], lenSubThemeName); } CleanString (Themes[pThemeId]); - LogI(1, prep("%.*s"), lenThemeName + 1 + lenSubThemeName, Themes[pThemeId]); + LogI(1, prep("%.40s|id:%d"), Themes[pThemeId],pThemeId); //isyslog ("%.15s", (lThemes + pThemeId)->Name); nThemes++; if (nThemes > MAX_THEMES) { @@ -1277,8 +1299,7 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, if (Format == MHW1) { char * pch; pch=strchr(SummText,'s'); - while (pch!=NULL) - { + while (pch!=NULL) { if (*(pch-1) != ' ' && *(pch-1) != '\n') *pch = ' '; pch=strchr(pch+1,'s'); @@ -1303,14 +1324,29 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, } string desc = SummText; +// if (stripspace(category)) desc.append("\n").append(CATEGORY).append(tr(category)); +// if (stripspace(genre)) desc += '\n' + string(GENRE) + tr(genre); if (stripspace(category)) desc.append("\n").append(CATEGORY).append(category); if (stripspace(genre)) desc += '\n' + string(GENRE) + genre; Event->SetDescription (desc.c_str()); free(theme); - } - else - Event->SetDescription (SummText); + } + else { +#ifdef DEBUG + string desc = SummText; + if (ThemeId) { + char *theme; + Asprintf (&theme, "0x%x", ThemeId); + LogD(0, prep("DEBUG: missing theme ID 0x%x"), ThemeId); + desc += '\n' + string(GENRE) + theme; + free(theme); + } + Event->SetDescription (desc.c_str()); +#else + Event->SetDescription (SummText); +#endif + } } if (ps && newEvent) ps->AddEvent (newEvent); @@ -2586,12 +2622,13 @@ void cFilterEEPG::LoadIntoSchedule (void) if (NoSummary) isyslog ("EEPG: of which %i reported to have no summary available; skipping these BIENTOT titles", NoSummary); isyslog ("EEPG: found %i summaries", nSummaries); - if (SummariesNotFound) + if (SummariesNotFound) { if (nTitles-nSummaries!=SummariesNotFound) { esyslog ("EEPG: %i summaries not found", SummariesNotFound); esyslog ("EEPG: %i difference between No. of summaries and summaries not found", nTitles-nSummaries-SummariesNotFound); } else isyslog ("EEPG: %i titles without summaries", SummariesNotFound); + } if (OldEvents) isyslog ("EEPG: Skipped %i old events", OldEvents); if (NotMatching > nSummaries) @@ -2609,7 +2646,7 @@ void cFilterEEPG::AddFilter (u_short Pid, u_char Tid) { if (!Matches (Pid, Tid)) { Add (Pid, Tid); - esyslog (prep("Filter Pid:%x,Tid:%x added."), Pid, Tid); + esyslog (prep("Filter Pid:0x%x,Tid:0x%x added."), Pid, Tid); } } @@ -2617,7 +2654,7 @@ void cFilterEEPG::AddFilter (u_short Pid, u_char Tid, unsigned char Mask) { if (!Matches (Pid, Tid)) { Add (Pid, Tid, Mask); - esyslog (prep("Filter Pid:%x,Tid:%x,Mask:%x added."), Pid, Tid, Mask); + esyslog (prep("Filter Pid:0x%x,Tid:0x%x,Mask:0x%x added."), Pid, Tid, Mask); } } @@ -2826,7 +2863,7 @@ void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Len usrFRV = 1; LogD(4, prep("if (data[2]==0x39) {//TODO Test This")); } - //Format = 0; // 0 = premiere, 1 = MHW1, 2 = MHW2, 3 = Sky Italy (OpenTV), 4 = Sky UK (OpenTV), 5 = Freesat (Freeview), 6 = Nagraguide + SI::Descriptor * d; unsigned char nDescriptorTag; for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext (it));) { @@ -3487,7 +3524,6 @@ bool cPluginEEPG::Start (void) CheckCreateFile("sky_uk.themes", SkyUkThemes); CheckCreateFile("freesat.t1", FreesatT1); CheckCreateFile("freesat.t2", FreesatT2); - CheckCreateFile("sky_uk.themes", SkyUkThemes); sky_tables[0] = NULL; sky_tables[1] = NULL; diff --git a/util.c b/util.c index 49f863a..e565b2e 100644 --- a/util.c +++ b/util.c @@ -159,6 +159,7 @@ private: cTimeMs LastHandleEvent; std::map*,tChannelIDCompare> *map_list; // enum { INSERT_TIMEOUT_IN_MS = 10000 }; + void MergeEquivalents(cEvent* dest, cEvent* src); protected: virtual void Action(void); public: @@ -184,7 +185,6 @@ cAddEventThread::~cAddEventThread(void) void cAddEventThread::Action(void) { - //LogD (0, prep("Action")); SetPriority(19); while (Running() && !LastHandleEvent.TimedOut()) { std::map*, tChannelIDCompare>::iterator it; @@ -200,22 +200,29 @@ void cAddEventThread::Action(void) while (((*it).second->First()) != NULL) { cEvent* event = (*it).second->First(); - cEvent *pEqvEvent = (cEvent *) schedule->GetEvent (event->EventID(), event->StartTime()); - if (pEqvEvent){ -// LogD (0, prep("schedule->DelEvent(event) size:%d"), (*it).second->Count()); - (*it).second->Del(event); -// schedule->DelEvent(pEqvEvent); - } else { - - (*it).second->Del(event, false); - EpgHandlers.DropOutdated(schedule, event->StartTime(), event->EndTime(), event->TableID(), - event->Version()); - schedule->AddEvent(event); + cEvent *pEqvEvent = (cEvent *) schedule->GetEvent (event->EventID(), event->StartTime()); + if (pEqvEvent){ + (*it).second->Del(event); + } else { + + (*it).second->Del(event, false); + + cEvent *ev = (cEvent *) schedule->GetEventAround(event->StartTime()); + if (ev && (ev->EventID() == event->EventID() || (event->Title() && strcasecmp(ev->Title(), event->Title()) == 0)) + && event->StartTime() <= ev->StartTime() && event->EndTime() > ev->StartTime()){ + MergeEquivalents(event, ev); + schedule->DelEvent(ev); + } + + event = schedule->AddEvent(event); + EpgHandlers.DropOutdated(schedule, event->StartTime(), event->EndTime(), event->TableID(), + event->Version()); + } } EpgHandlers.SortSchedule(schedule); - //sortSchedules(schedules, (*it).first); - //schedule->Sort(); + //sortSchedules(schedules, (*it).first); + //schedule->Sort(); delete (*it).second; map_list->erase(it); it = map_list->begin(); @@ -240,6 +247,43 @@ void cAddEventThread::AddEvent(cEvent *Event, tChannelID ChannelID) LastHandleEvent.Set(INSERT_TIMEOUT_IN_MS); } +string ExtractAttributes(string text) { + string attribute; + size_t apos = 0; + while ((apos = text.find('\n',apos)) != string::npos) { + size_t npos = text.find('\n', apos); + string subs = text.substr(apos, npos - apos); + if (subs.find(": ") != string::npos) + attribute += subs; + apos = npos; + //LogD(0, prep("ExtractAttribute attribute:%s, apos:%i, pos:%i"),attribute.c_str(), catpos, pos); + } + return attribute; + +} + + +inline void cAddEventThread::MergeEquivalents(cEvent* dest, cEvent* src) +{ + if (!dest->ShortText() || !strcmp(dest->ShortText(),"")) + dest->SetShortText(src->ShortText()); + + //Handle the Category and Genre, and optionally future tags + if ((dest->Description() || strcmp(src->Description(),"")) && + (!dest->Description() || + (dest->Description() && strstr(src->Description(),dest->Description())) != 0 )) { + dest->SetDescription(src->Description()); + } else if (src->Description() && !strcmp(src->Description(),"") && dest->Description()) { + + string desc = dest->Description() ? dest->Description() : ""; + desc += ExtractAttributes(desc); + dest->SetDescription (desc.c_str()); + + } + +} + + static cAddEventThread AddEventThread; // --- @@ -466,4 +510,3 @@ void cCharsetFixer::InitCharsets(const cChannel* Channel) } } - -- cgit v1.2.3 From d3de4c555013475393ad80d80d75f686eac94122 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 30 Nov 2012 13:39:35 +0100 Subject: added some new SKY themes --- eepg.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/eepg.h b/eepg.h index a2ddb0f..cfbf47b 100644 --- a/eepg.h +++ b/eepg.h @@ -1240,7 +1240,7 @@ static const char *SkyItThemes[] = { "Sport - Nuoto", // 010 10000 "Sport - Wrestling", // 010 10001 NULL, // 010 10010 - NULL, // 010 10011 + "Sport - Volley", // 010 10011 NULL, // 010 10100 NULL, // 010 10101 NULL, // 010 10110 @@ -1271,7 +1271,7 @@ static const char *SkyItThemes[] = { "Film - Musicale", // 011 01111 "Film - Corto", // 011 10000 "Film - Cortometraggio", // 011 10001 - NULL, // 011 10010 + "Film - Erotico", // 011 10010 NULL, // 011 10011 NULL, // 011 10100 NULL, // 011 10101 @@ -1358,7 +1358,7 @@ static const char *SkyItThemes[] = { "Ragazzi e Musica - Film", // 110 00110 "Ragazzi e Musica - Telefilm", // 110 00111 "Ragazzi e Musica - Magazine", // 110 01000 - NULL, // 110 01001 + "Ragazzi e Musica - Giochi", // 110 01001 NULL, // 110 01010 NULL, // 110 01011 NULL, // 110 01100 @@ -1370,7 +1370,7 @@ static const char *SkyItThemes[] = { NULL, // 110 10010 NULL, // 110 10011 "Ragazzi e Musica - Danza", // 110 10100 - NULL, // 110 10101 + "Ragazzi e Musica - Videoclip", // 110 10101 NULL, // 110 10110 NULL, // 110 10111 NULL, // 110 11000 @@ -1448,11 +1448,11 @@ static const char *SkyUkThemes[] = { NULL, // 000 11101 NULL, // 000 11110 NULL, // 000 11111 - NULL, // 001 00000 + "Specialist - Shopping", // 001 00000 NULL, // 001 00001 NULL, // 001 00010 "Shopping", // 001 00011 - NULL, // 001 00100 + "Specialist - Gaming", // 001 00100 NULL, // 001 00101 NULL, // 001 00110 NULL, // 001 00111 @@ -1488,7 +1488,7 @@ static const char *SkyUkThemes[] = { "Children - Under 5", // 010 00101 "Children - Factual", // 010 00110 "Children - Magazine", // 010 00111 - NULL, // 010 01000 + "Children - Games Shows", // 010 01000 NULL, // 010 01001 NULL, // 010 01010 NULL, // 010 01011 @@ -1557,14 +1557,14 @@ static const char *SkyUkThemes[] = { "Music - Hip Hop", // 100 01010 "Music - Soul/R&B", // 100 01011 "Music - Dance", // 100 01100 - NULL, // 100 01101 + "Music - Ballet", // 100 01101 NULL, // 100 01110 NULL, // 100 01111 "Music - Features", // 100 10000 NULL, // 100 10001 - NULL, // 100 10010 + "Music - Factual", // 100 10010 NULL, // 100 10011 - NULL, // 100 10100 + "Music - Comedy", // 100 10100 "Music - Lifestyle", // 100 10101 "Music - News and Weather", // 100 10110 "Music - Easy Listening", // 100 10111 @@ -1595,11 +1595,11 @@ static const char *SkyUkThemes[] = { "News & Documentaries - Transport", // 101 10000 "News & Documentaries - Docudrama", // 101 10001 "News & Documentaries - World Affairs", // 101 10010 - NULL, // 101 10011 - NULL, // 101 10100 - NULL, // 101 10101 + "News & Documentaries - Features", // 101 10011 + "News & Documentaries - Showbiz", // 101 10100 + "News & Documentaries - Politics", // 101 10101 NULL, // 101 10110 - NULL, // 101 10111 + "News & Documentaries - World Affairs", // 101 10111 NULL, // 101 11000 NULL, // 101 11001 NULL, // 101 11010 @@ -1627,7 +1627,7 @@ static const char *SkyUkThemes[] = { "Movie - Fantasy", // 110 10000 "Movie - Erotic", // 110 10001 "Movie - Adventure", // 110 10010 - NULL, // 110 10011 + "Movie - War", // 110 10011 NULL, // 110 10100 NULL, // 110 10101 NULL, // 110 10110 -- cgit v1.2.3 From b0a1d7d5839e135c97cbf752dd5148134f103884 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 30 Nov 2012 15:14:00 +0100 Subject: updated documentation --- HISTORY | 24 ++++++++++++++++++------ README | 6 ++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/HISTORY b/HISTORY index f3ccd4d..fa0b59a 100644 --- a/HISTORY +++ b/HISTORY @@ -7,16 +7,16 @@ Release 0.0.6pre: - Fixed charset - Added viasat support - Removed include si.c -- Changed docodeText2 to use code from vdr which also handles charset override -- Removed some gotos +- Changed docodeText2 to use code from VDR which also handles charset override +- Removed some GOTOs - Removed some code duplication -- Removed some todos +- Removed some TODOs - moved Premiere code in separate method -- Added setup option to display message after finish of writing epg +- Added setup option to display message after finish of writing EPG - Added Dish Network and Bell ExpressVU support, thanks to the VDR patch, Mrgandalf and VDR User - Applied patch to Load Huffman dictionaries only on first use, thanks to Torsten Lang - Fixed update of equivalents for Freesat -- Add category and genere to the description usable with epgsearch +- Add category and genre to the description usable with epgsearch - Added EpgHandler for manipulation of the EPG for VDR > 1.7.26 - Try to discard very long events that override more than one existing event - Equivalents stored in map for all equivalents for better handling @@ -28,7 +28,19 @@ Release 0.0.6pre: - Move cEIT2 in a separate file and try to use it in epghandler also - Drop unmanaged NOEPG support, there is a separate plugin for that - Drop unmanaged Disable Double EPG entry. EEPG tries to handle this anyway -- Aditional fixes logged at http://projects.vdr-developer.org/git/vdr-plugin-eepg.git/ +- Added Short Text to events extracted from the extended description for MHW2 and Sky +- Added option to setup not to set Category and Genre to empty short texts +- Added po Translation support +- added Macedonian translation +- Added functionality to try to fix the charset for some known providers that incorrectly announce charset. + This has to be enabled from setup menu. +- Updated handling of duplicate events, and implemented for equivalent channels. +- Dropping already expired events without adding them to the schedule, this reduces cleanups +- Changed the logic of summary handling for SKY so that no SummaryAvailable bit is required, since it can not be located from the stream +- Reformatted MHW1 themes +- Added some new/missing SKY themes + +- Additional fixes logged at http://projects.vdr-developer.org/git/vdr-plugin-eepg.git/ Release 0.0.5: -changed TableId's so that Now/Next overwrites Nagra which overwrites MHW diff --git a/README b/README index 28060c8..b898806 100644 --- a/README +++ b/README @@ -102,6 +102,12 @@ In addition there are two switches in the plugin setup menu to control inclusion of order and parental rating information into the event description. The plugin setup menu is only for Premiere protocol! +Optionally EEPG can try to fix the charset of providers that send the EPG data with no +or incorrect Charset. In order for EEPG to try to fix the charset the option must be +selected from the menu. +This is a workaround fix which does double conversion and depends on +already know data for providers that send incorrect charset. +The real solution is for Providers to follow the standards and not to do this in the first place. THANKS This code is based on: -- cgit v1.2.3 From cf4bbfad099efdc3775e6ca68ac22061a452bbc2 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 3 Dec 2012 21:00:48 +0100 Subject: added some more themes --- eepg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eepg.h b/eepg.h index cfbf47b..b553122 100644 --- a/eepg.h +++ b/eepg.h @@ -1241,9 +1241,9 @@ static const char *SkyItThemes[] = { "Sport - Wrestling", // 010 10001 NULL, // 010 10010 "Sport - Volley", // 010 10011 - NULL, // 010 10100 + "Sport - Poker", // 010 10100 NULL, // 010 10101 - NULL, // 010 10110 + "Sport - Sport Invernali", // 010 10110 NULL, // 010 10111 NULL, // 010 11000 NULL, // 010 11001 @@ -1489,7 +1489,7 @@ static const char *SkyUkThemes[] = { "Children - Factual", // 010 00110 "Children - Magazine", // 010 00111 "Children - Games Shows", // 010 01000 - NULL, // 010 01001 + "Children - Games", // 010 01001 NULL, // 010 01010 NULL, // 010 01011 NULL, // 010 01100 @@ -1518,7 +1518,7 @@ static const char *SkyUkThemes[] = { "Entertainment - Detective", // 011 00011 "Entertainment - Drama", // 011 00100 "Entertainment - Game Show", // 011 00101 - "Entertainment - Sci-FI", // 011 00110 + "Entertainment - Sci-Fi", // 011 00110 "Entertainment - Soap", // 011 00111 "Entertainment - Animation", // 011 01000 "Entertainment - Chat Show", // 011 01001 @@ -1545,7 +1545,7 @@ static const char *SkyUkThemes[] = { NULL, // 011 11110 NULL, // 011 11111 "Music", // 100 00000 - "Music - Classical ", // 100 00001 + "Music - Classical", // 100 00001 "Music - Folk and Country", // 100 00010 "Music - National Music", // 100 00011 "Music - Jazz", // 100 00100 -- cgit v1.2.3 From f3ecec54c88df783b099446b46ded1eb2ceccc4a Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 28 Dec 2012 12:31:04 +0100 Subject: removed Make.global it is removed in vdr 1.7.34 and not used in eepg --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index 2adfd09..7d82ad1 100644 --- a/Makefile +++ b/Makefile @@ -39,10 +39,6 @@ VDRDIR ?= ../../.. LIBDIR ?= ../../lib TMPDIR ?= /tmp -### Make sure that necessary options are included: - -include $(VDRDIR)/Make.global - ### Allow user defined options to overwrite defaults: -include $(VDRDIR)/Make.config -- cgit v1.2.3 From 692ebcf6a83df32c78a61faf64741b1f4efed233 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 3 Jan 2013 10:15:17 +0100 Subject: modified Makefile according to the new VDR version 1.7.35 style --- Makefile | 88 ++++++++++++++++++++++++++++++++++--------------------------- eepg.c | 2 +- po/mk_MK.po | 6 ++--- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 7d82ad1..1fc7c4d 100644 --- a/Makefile +++ b/Makefile @@ -26,53 +26,60 @@ PLUGIN = eepg ### The version number of this plugin (taken from the main source file): -VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') - -### The C++ compiler and options: - -CXX ?= g++ -CXXFLAGS ?= -O2 -fPIC -Wall -Woverloaded-virtual +RELEASE := $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') +SUBREL := $(shell if test -d .git; then \ + echo -n "-git-"; (git rev-parse --short HEAD 2>/dev/null || echo -n "Unknown") | sed -e 's/ .*//'; \ + fi) +VERSION := $(RELEASE)$(SUBREL) +#VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') ### The directory environment: -VDRDIR ?= ../../.. -LIBDIR ?= ../../lib +# Use package data if installed...otherwise assume we're under the VDR source directory: +PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc)) +LIBDIR = $(DESTDIR)$(call PKGCFG,libdir) +LOCDIR = $(DESTDIR)$(call PKGCFG,locdir) +PLGCFG = $(call PKGCFG,plgcfg) +# TMPDIR ?= /tmp -### Allow user defined options to overwrite defaults: +### The compiler options: --include $(VDRDIR)/Make.config --include Make.config +export CFLAGS = $(call PKGCFG,cflags) +export CXXFLAGS = $(call PKGCFG,cxxflags) -### The version number of VDR's plugin API (taken from VDR's "config.h"): +### The version number of VDR's plugin API: -VDRVERSION = $(shell sed -ne '/define VDRVERSION/ s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h) -APIVERSION = $(shell sed -ne '/define APIVERSION/ s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h) -ifeq ($(strip $(APIVERSION)),) - APIVERSION = $(VDRVERSION) -endif +APIVERSION = $(call PKGCFG,apiversion) + +### Allow user defined options to overwrite defaults: + +-include $(PLGCFG) +-include Make.config ### The name of the distribution archive: ARCHIVE = $(PLUGIN)-$(VERSION) PACKAGE = vdr-$(ARCHIVE) -### Includes and Defines (add further entries here): +### The name of the shared object file: + +SOFILE = libvdr-$(PLUGIN).so -INCLUDES += -I$(VDRDIR)/include +### Includes and Defines (add further entries here): -DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +#INCLUDES += -I$(VDRDIR)/include +INCLUDES += -ifdef DBG -CXXFLAGS += -g -endif +DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o eit2.o -### Default Target -default: $(OBJS) +### The main target: + +all: $(SOFILE) i18n ### Implicit rules: @@ -91,36 +98,38 @@ $(DEPFILE): Makefile ### Internationalization (I18N): PODIR = po -LOCALEDIR = $(VDRDIR)/locale I18Npo = $(wildcard $(PODIR)/*.po) -I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) +I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) +I18Nmsgs = $(addprefix $(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot -### target All not default since it stops VDR -all: libvdr-$(PLUGIN).so i18n - %.mo: %.po msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.c) - xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ $^ + xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) - msgmerge -U --no-wrap --no-location --backup=none -q $@ $< + msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ -$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo - @mkdir -p $(dir $@) - cp $< $@ +$(I18Nmsgs): $(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo + install -D -m644 $< $@ .PHONY: i18n -i18n: $(I18Nmsgs) $(I18Npot) +i18n: $(I18Nmo) $(I18Npot) + +install-i18n: $(I18Nmsgs) ### Targets: -libvdr-$(PLUGIN).so: $(OBJS) +$(SOFILE): $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ - @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) + +install-lib: $(SOFILE) + install -D $^ $(LIBDIR)/$^.$(APIVERSION) + +install: install-lib install-i18n dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) @@ -131,4 +140,5 @@ dist: $(I18Npo) clean @echo Distribution package created as $(PACKAGE).tgz clean: - @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot + @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ diff --git a/eepg.c b/eepg.c index 5ae992d..70a1134 100644 --- a/eepg.c +++ b/eepg.c @@ -52,7 +52,7 @@ #include -#if APIVERSNUM < 10401 +#if defined(APIVERSNUM) && APIVERSNUM < 10401 #error You need at least VDR API version 1.4.1 for this plugin #endif #if APIVERSNUM < 10507 diff --git a/po/mk_MK.po b/po/mk_MK.po index 69936f2..6b2ef2b 100644 --- a/po/mk_MK.po +++ b/po/mk_MK.po @@ -1,5 +1,5 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2012 +# Macedonian translations for vdr-eepg package. +# Copyright (C) 2012 THE vdr-eepg'S COPYRIGHT HOLDER # This file is distributed under the same license as the VDR package. # Dimitar Petrovski , 2012. # @@ -10,7 +10,7 @@ msgstr "" "POT-Creation-Date: 2012-11-20 23:13+0100\n" "PO-Revision-Date: 2012-10-29 13:44+0100\n" "Last-Translator: Dimitar Petrovski \n" -"Language-Team: Macedonian \n" +"Language-Team: Macedonian\n" "Language: mk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -- cgit v1.2.3 From 2d8205b11d67044725698f66344811ea38a0e51d Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 31 Jan 2013 08:46:37 +0100 Subject: Makefile again adapted to vdr-1.7.36 --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1fc7c4d..3b9c86f 100644 --- a/Makefile +++ b/Makefile @@ -37,8 +37,8 @@ VERSION := $(RELEASE)$(SUBREL) # Use package data if installed...otherwise assume we're under the VDR source directory: PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc)) -LIBDIR = $(DESTDIR)$(call PKGCFG,libdir) -LOCDIR = $(DESTDIR)$(call PKGCFG,locdir) +LIBDIR = $(call PKGCFG,libdir) +LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) # TMPDIR ?= /tmp @@ -84,14 +84,14 @@ all: $(SOFILE) i18n ### Implicit rules: %.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: MAKEDEP = $(CXX) -MM -MG DEPFILE = .dependencies $(DEPFILE): Makefile - @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ -include $(DEPFILE) @@ -100,7 +100,7 @@ $(DEPFILE): Makefile PODIR = po I18Npo = $(wildcard $(PODIR)/*.po) I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file)))) -I18Nmsgs = $(addprefix $(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) +I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file)))))) I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po @@ -113,7 +113,7 @@ $(I18Npot): $(wildcard *.c) msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ -$(I18Nmsgs): $(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo +$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo install -D -m644 $< $@ .PHONY: i18n @@ -127,7 +127,7 @@ $(SOFILE): $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ install-lib: $(SOFILE) - install -D $^ $(LIBDIR)/$^.$(APIVERSION) + install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) install: install-lib install-i18n -- cgit v1.2.3 From 1674e7952818c7deb9f826040163e3c30ad3c0ca Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 31 Jan 2013 14:07:03 +0100 Subject: reformat loadEquivalentChannelMap --- equivhandler.c | 109 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/equivhandler.c b/equivhandler.c index 1d313db..745f513 100644 --- a/equivhandler.c +++ b/equivhandler.c @@ -54,62 +54,63 @@ void cEquivHandler::loadEquivalentChannelMap (void) char origChanID[256]; char equiChanID[256]; char source[256]; - int nid = 0; - int tid = 0; - int sid = 0; - int rid = 0; + int nid, tid, sid, rid; while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) { Line = compactspace (skipspace (stripspace (Line))); - if (!isempty (Line)) { - if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", origChanID, equiChanID, source) == 3) { - if (origChanID[0] != '#' && origChanID[0] != ';') { - nid = 0; - tid = 0; - sid = 0; - rid = 0; - if (sscanf (origChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) - if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) { - if (sscanf (origChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) != 5) { - rid = 0; - } - tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); - bool found = false; - //int i = 0; - cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false); - if (!OriginalChannel) { - LogI(2, prep("Warning, not found EPG channel \'%s\' in channels.conf. Equivalence is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); - continue; - } - if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) { - if (sscanf (equiChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) - != 5) { - rid = 0; - } - tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); - cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); - if (EquivChannel) { - ret = equiChanMap.equal_range(*OriginalChID.ToString()); - for (it=ret.first; it!=ret.second; ++it) - if ((*it).second == *OriginalChID.ToString()) { - found = true; - break; - } - - if (!found) { - string origCh(*OriginalChID.ToString()); - string equiCh(*EquivChID.ToString()); - equiChanMap.insert(pair(origCh.c_str(),equiCh.c_str())); - LogD(4, prep("Found %s equivalent to %s. origCh %s"), *EquivChID.ToString(), *OriginalChID.ToString(), origCh.c_str()); - for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ ) - LogD(3, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str()); - } - } else - LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), equiChanID); - } - } //if scanf string1 - } //if string1 - } //if scanf - } //if isempty + //skip empty and commented lines + if (isempty (Line) || Line[0] == '#' || Line[0] == ';') continue; + //skip invalid line + if (sscanf (Line, "%[^ ] %[^ ] %[^\n]\n", origChanID, equiChanID, source) != 3) continue; + + nid = 0; + tid = 0; + sid = 0; + rid = 0; + //skip invalid id formats + if ((sscanf (origChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) != 4) + && (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) != 4)) + continue; + + if (sscanf (origChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) != 5) { + rid = 0; + } + tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); + bool found = false; + //int i = 0; + cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false); + if (!OriginalChannel) { + LogI(2, prep("Warning, not found EPG channel \'%s\' in channels.conf. Equivalence is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); + continue; + } + if (sscanf (equiChanID, "%[^-]-%i -%i -%i ", source, &nid, &tid, &sid) == 4) { + + if (sscanf (equiChanID, "%[^-]-%i -%i -%i -%i ", source, &nid, &tid, &sid, &rid) + != 5) { + rid = 0; + } + tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); + cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); + if (!EquivChannel) { + LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), equiChanID); + continue; + } + + //check if channel is already added + ret = equiChanMap.equal_range(*OriginalChID.ToString()); + for (it=ret.first; it!=ret.second; ++it) + if ((*it).second == *OriginalChID.ToString()) { + found = true; + break; + } + if (found) continue; + + string origCh(*OriginalChID.ToString()); + string equiCh(*EquivChID.ToString()); + equiChanMap.insert(pair(origCh.c_str(),equiCh.c_str())); + LogD(4, prep("Found %s equivalent to %s. origCh %s"), *EquivChID.ToString(), *OriginalChID.ToString(), origCh.c_str()); + for ( it2=equiChanMap.begin() ; it2 != equiChanMap.end(); it2++ ) + LogD(3, prep("Original ID %s <-> Equivalent ID %s"), (*it2).first.c_str(), it2->second.c_str()); + } } //while fclose (File); equiChanFileTime = st.st_mtim.tv_nsec; -- cgit v1.2.3 From 2eb5f7d939dd8dbcb560d03bf608e341924b0c2b Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 31 Jan 2013 14:15:37 +0100 Subject: fix creating of new theme file if missing in eepg dir --- eepg.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/eepg.c b/eepg.c index 70a1134..7a7272c 100644 --- a/eepg.c +++ b/eepg.c @@ -3466,6 +3466,7 @@ cPluginEEPG::cPluginEEPG (void) void cPluginEEPG::CheckCreateFile(const char* Name, const char *fileContent[]) { FILE *File; + bool isSkyTheme = fileContent == SkyItThemes || fileContent == SkyUkThemes; string FileName = string(cSetupEEPG::getInstance()->getConfDir()) + "/" + Name; File = fopen(FileName.c_str(), "r"); if (File == NULL) { @@ -3474,11 +3475,23 @@ void cPluginEEPG::CheckCreateFile(const char* Name, const char *fileContent[]) if (File == NULL) { LogE (0, prep("Error creating file '%s', %s"), FileName.c_str(), strerror (errno)); } else { - int i = 0; - while (fileContent[i] != NULL) { - fprintf (File, "%s\n", fileContent[i]); - i++; + if (!isSkyTheme) { + int i = 0; + while (fileContent[i] != NULL) { + fprintf (File, "%s\n", fileContent[i]); + i++; + } + } else { + for (int i = 0; i < 256; i++) { + if (fileContent[i]) { + fprintf (File, "0x%02x=%s\n", i, fileContent[i]); + } + else { + fprintf (File, "0x%02x=\n", i); + } + } } + LogI (0, prep("Success creating file '%s'"), FileName.c_str()); fclose (File); } -- cgit v1.2.3 From c9a302eff85ad0d6c337743b7373b4ee0c7bded3 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Thu, 31 Jan 2013 14:51:27 +0100 Subject: Update the sky_*.themes file if a theme is added in the source Count only nonempty themes as found themes for sky --- eepg.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/eepg.c b/eepg.c index 7a7272c..ea5fd8c 100644 --- a/eepg.c +++ b/eepg.c @@ -745,10 +745,16 @@ bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB FILE *FileThemes; char *Line; char Buffer[256]; - if (Format == SKY_IT) + const char **SkyThemes; + bool updateFile = false; + if (Format == SKY_IT) { FileName += "/sky_it.themes"; - else if (Format == SKY_UK) + SkyThemes = SkyItThemes; + } + else if (Format == SKY_UK) { FileName += "/sky_uk.themes"; + SkyThemes = SkyUkThemes; + } else { LogE (0, prep("Error, wrong format detected in GetThemesSKYBOX. Format = %i."), Format); return false; @@ -759,26 +765,49 @@ bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB LogE (0, prep("Error opening file '%s'. %s"), FileName.c_str(), strerror (errno)); return false; } else { - //int id = 0; + int id = 0; nThemes = 0; - char string1[256]; - char string2[256]; - //sTheme *T; + char thId[256]; + char theme[256]; + while ((Line = fgets (Buffer, sizeof (Buffer), FileThemes)) != NULL) { - memset (string1, 0, sizeof (string1)); - memset (string2, 0, sizeof (string2)); + memset (thId, 0, sizeof (thId)); + memset (theme, 0, sizeof (theme)); if (!isempty (Line)) { - //T = &Themes[nThemes]; - if (sscanf (Line, "%[^=] =%[^\n] ", string1, string2) == 2) { - snprintf ((char *) Themes[nThemes], 255, "%s", string2); + if (sscanf (Line, "%[^=] =%[^\n] ", thId, theme) == 2 && !isempty (theme)) { + snprintf ((char *) Themes[id], 255, "%s", theme); + nThemes++; } else { - Themes[nThemes][0] = '\0'; + if (SkyThemes[id]) { + updateFile = true; + snprintf ((char *) Themes[id], 255, "%s", SkyThemes[id]); + LogD (1, prep("Theme '%s' missing in theme file '%s'"), SkyThemes[id], FileName.c_str()); + } else + Themes[id][0] = '\0'; } - //id ++; - nThemes++; + id ++; } } fclose (FileThemes); + + if (updateFile) { + FileThemes = fopen (FileName.c_str(), "w"); + if (FileThemes == NULL) { + LogE (0, prep("Error re-creating file '%s', %s"), FileName.c_str(), strerror (errno)); + } else { + for (int i = 0; i < 256; i++) { + if (Themes[nThemes]) { + fprintf (FileThemes, "0x%02x=%s\n", i, (char *) Themes[nThemes]); + } + else { + fprintf (FileThemes, "0x%02x=\n", i); + } + } + + LogI (0, prep("Success updating file '%s'"), FileName.c_str()); + fclose (FileThemes); + } + } } return true; } -- cgit v1.2.3 From 60376c4c1f0a4b65cb07b89d5c095015ec3b1215 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 22 Feb 2013 09:52:10 +0100 Subject: Added ability to translate themes. Examples added Fixed handling of duplicate epg entries Added new SKY themes Added checking/updating of themes files on load --- HISTORY | 1 + README | 5 + eepg.c | 115 ++++++++++++++++--- eepg.h | 10 +- epghandler.c | 64 +++++++---- epghandler.h | 6 +- extra/en-themes/mhw1_fr.tr | 81 +++++++++++++ extra/en-themes/mhw2_es.tr | 103 +++++++++++++++++ extra/en-themes/sky_it.themes | 256 ++++++++++++++++++++++++++++++++++++++++++ util.c | 38 +++++-- util.h | 9 ++ 11 files changed, 635 insertions(+), 53 deletions(-) create mode 100644 extra/en-themes/mhw1_fr.tr create mode 100644 extra/en-themes/mhw2_es.tr create mode 100644 extra/en-themes/sky_it.themes diff --git a/HISTORY b/HISTORY index fa0b59a..7ea07a2 100644 --- a/HISTORY +++ b/HISTORY @@ -39,6 +39,7 @@ Release 0.0.6pre: - Changed the logic of summary handling for SKY so that no SummaryAvailable bit is required, since it can not be located from the stream - Reformatted MHW1 themes - Added some new/missing SKY themes +- Added ability to translate themes. See README/Examples - Additional fixes logged at http://projects.vdr-developer.org/git/vdr-plugin-eepg.git/ diff --git a/README b/README index b898806..ea59f58 100644 --- a/README +++ b/README @@ -109,6 +109,11 @@ This is a workaround fix which does double conversion and depends on already know data for providers that send incorrect charset. The real solution is for Providers to follow the standards and not to do this in the first place. +The themes of the EPG events can be translated. For MHW a translation file is used, and for OTV the +theme file should be translated. +See example english translation files in: extra/en-themes/*.* +This files should be placed in eepg plugin config directory. + THANKS This code is based on: * Premiere plugin (C) 2005-2007 Stefan Huelswitt diff --git a/eepg.c b/eepg.c index ea5fd8c..a970479 100644 --- a/eepg.c +++ b/eepg.c @@ -49,7 +49,9 @@ #include #include +#include #include +#include #if defined(APIVERSNUM) && APIVERSNUM < 10401 @@ -416,7 +418,7 @@ static bool load_freesat_file (int tableid, const char *filename) return true; } -/** \brief Load an individual freesat data file +/** \brief Load an individual sky data file * * \param filename - Filename to load * \return Success of operation @@ -550,6 +552,75 @@ static bool load_sky_file (const char *filename) return true; } +#define THEME_TR ".tr" + +void load_theme_dictionaries (void) +{ + char Buffer[1024]; + char *Line; + FILE *File; + + DIR *dp = opendir(cSetupEEPG::getInstance()->getConfDir()); + struct dirent *dirp; + if(!dp) { + LogE (0, prep("Can't read configuration folder '%s'"), cSetupEEPG::getInstance()->getConfDir()); + return ; + } + + if (tableDict.size() > 0) + tableDict.clear(); + + + while ((dirp = readdir(dp)) != NULL) { + + string fname = dirp->d_name; // filename + if (dirp->d_type == DT_DIR || // if entry is a directory + fname.find(THEME_TR, (fname.length() - strlen(THEME_TR))) == string::npos){ + continue; + } + + fname = string(cSetupEEPG::getInstance()->getConfDir()) + "/" + fname; + + //Test if file is changed and reload + struct stat st; + if (stat(fname.c_str(), &st)) { + LogE(0, prep("Error obtaining stats for '%s' "), fname.c_str()); + continue; + } + + File = fopen (fname.c_str(), "r"); + if (!File) continue; + + memset (Buffer, 0, sizeof (Buffer)); + char origThemeName[256]; + char transThemeName[256]; + while ((Line = fgets (Buffer, sizeof (Buffer), File)) != NULL) { + Line = compactspace (skipspace (stripspace (Line))); + //Skip empty and commented lines + if (isempty (Line) || Line[0] == '#' || Line[0] == ';') continue; + if (sscanf (Line, "%[^=]=%[^\n]\n", origThemeName, transThemeName) == 2) { + + string origTh(compactspace (skipspace (stripspace (origThemeName)))); + string transTh(compactspace (skipspace (stripspace (transThemeName)))); + if (!tableDict.count(origTh) && !transTh.empty()) { + tableDict.insert(pair(string(origThemeName),string(transThemeName))); + LogD(4, prep("Original '%s' translation to '%s'."), origTh.c_str(), transTh.c_str()); + } + } //if scanf + } //while + fclose (File); + LogD(3, prep("Loaded %i translations from %s."), tableDict.size(), fname.c_str()); + } + closedir(dp); + + LogD(2, prep("Loaded %i translations."), tableDict.size()); + LogD(2, prep("Original <-> Translation")); + map::iterator it; + for ( it=tableDict.begin() ; it != tableDict.end(); it++ ) + LogD(2, prep("%s <-> %s"), (*it).first.c_str(), it->second.c_str()); + +} + /** \brief Decode an EPG string as necessary * * \param src - Possibly encoded string @@ -796,8 +867,8 @@ bool cFilterEEPG::GetThemesSKYBOX (void) //TODO can't we read this from the DVB LogE (0, prep("Error re-creating file '%s', %s"), FileName.c_str(), strerror (errno)); } else { for (int i = 0; i < 256; i++) { - if (Themes[nThemes]) { - fprintf (FileThemes, "0x%02x=%s\n", i, (char *) Themes[nThemes]); + if (Themes[i]) { + fprintf (FileThemes, "0x%02x=%s\n", i, (char *) Themes[i]); } else { fprintf (FileThemes, "0x%02x=\n", i); @@ -899,6 +970,7 @@ int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length) LogI(1, "|------|-%-26.26s-|-%-22.22s-|-----|-%-8.8s-|\n", "------------------------------", "-----------------------------", "--------------------"); int pName = ((nChannels * 8) + 121); //TODO double ... + LogD(1, prep("Length:%d pName:%d diff:%d"), Length, pName, Length - pName); for (int i = 0; i < nChannels; i++) { Channel = (sChannelMHW1 *) (Data + Off); sChannel *C = &sChannels[i]; @@ -983,6 +1055,7 @@ int cFilterEEPG::GetThemesMHW1 (const u_char * Data, int Length) theme = strreplace(theme,"DOC","DOCUMENTAIRE"); theme = strreplace(theme,"DOCUMENTAIRE.","DOCUMENTAIRE"); theme = strreplace(theme,"MAG","MAGAZINE"); + theme = strreplace(theme,"INFO-METEO","INFO/METEO"); //Remove category from genre. TODO Maybe they should be separated in the future theme = strreplace(theme,cat,""); theme = skipspace(theme); @@ -1282,23 +1355,28 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, if (SummText && ShTxtLen) { shText.assign(SummText,ShTxtLen); - + //LogD(0, prep("DEBUG: Title '%s', Subtitle '%s'"), Text, shText.c_str()); string tmpTitle(Text); if (Format == MHW2 && !shText.empty()) { size_t found = tmpTitle.find(" (HD)"); if (found != string::npos) tmpTitle.erase(found, 5); - found = shText.compare(0, tmpTitle.size() + 2, string(tmpTitle + ": ")); + //found = shText.compare(0, tmpTitle.size() + 2, string(tmpTitle + ": ")); if (shText.compare(0, tmpTitle.size() + 2, string(tmpTitle + ": "))==0) shText.erase(0, tmpTitle.size() + 2); + + //Remove Subtitle from title it is not pretty. + //int sumLen = strlen(SummText); + //if (sumLen > ShTxtLen) + // memmove(SummText,SummText + ShTxtLen + 1, sumLen - ShTxtLen); } //Do not use Subtitle if it is substring of Title if (tmpTitle.compare(0, shText.size(), shText) == 0) shText.clear(); - //The subtitle is wrong if contains '.' - if (Format == SKY_UK && !shText.empty() && shText.find('.') != string::npos) { + //The subtitle is wrong if contains '.' after possible initial '...' + if (Format == SKY_UK && !shText.empty() && shText.find('.',3) != string::npos) { shText.clear(); } @@ -1308,7 +1386,7 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, // the Description totally empty. So if the ShortText length exceeds // MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description // instead: - if (!shText.empty() && shText.size() > MAX_USEFUL_EPISODE_LENGTH) + if (Format != SKY_IT && Format != MHW2 && !shText.empty() && shText.size() > MAX_USEFUL_EPISODE_LENGTH) shText.clear(); } @@ -1353,10 +1431,11 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, } string desc = SummText; -// if (stripspace(category)) desc.append("\n").append(CATEGORY).append(tr(category)); -// if (stripspace(genre)) desc += '\n' + string(GENRE) + tr(genre); - if (stripspace(category)) desc.append("\n").append(CATEGORY).append(category); - if (stripspace(genre)) desc += '\n' + string(GENRE) + genre; + if (Format == MHW2 && ShTxtLen) { + desc.erase(0, ShTxtLen + 1); + } + if (stripspace(category)) desc.append("\n").append(CATEGORY).append(findThemeTr(category)); + if (stripspace(genre)) desc += '\n' + string(GENRE) + findThemeTr(genre); Event->SetDescription (desc.c_str()); free(theme); @@ -1367,7 +1446,7 @@ void cFilterEEPG::WriteToSchedule(tChannelID channelID, cSchedules* pSchedules, if (ThemeId) { char *theme; Asprintf (&theme, "0x%x", ThemeId); - LogD(0, prep("DEBUG: missing theme ID 0x%x"), ThemeId); + LogD(0, prep("DEBUG: missing theme ID 0x%x title:'%s'"), ThemeId, Event->Title()); desc += '\n' + string(GENRE) + theme; free(theme); } @@ -2428,7 +2507,11 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) S->Text[Len2] = '\0'; //end string with NULL character CleanString (S->Text); char * delim = strstr ( (char *)S->Text, STxtDelim ); - S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; + //S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; + if (Format == SKY_UK && !delim && strncmp((char *)S->Text,"...",3) == 0) + delim = strstr ( (char *)(S->Text+3), "." ); + int shLen = delim - (char *)S->Text; + S->ShortTextLength = delim == NULL || shLen > numeric_limits::max() ? 0 : shLen; LogI(4, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); p += Len1; nSummaries++; @@ -2624,7 +2707,8 @@ void cFilterEEPG::LoadIntoSchedule (void) i++; //move to next title, for this one no summary can be found } - if (SummIndex != -1 && isOTV){ + //Do not loop through summaries for OTV when sumaries and titles are in sync + if (SummIndex != -1 && isOTV && nSummaries <= nTitles){ j--; } @@ -3566,6 +3650,7 @@ bool cPluginEEPG::Start (void) CheckCreateFile("sky_uk.themes", SkyUkThemes); CheckCreateFile("freesat.t1", FreesatT1); CheckCreateFile("freesat.t2", FreesatT2); + load_theme_dictionaries(); sky_tables[0] = NULL; sky_tables[1] = NULL; diff --git a/eepg.h b/eepg.h index b553122..644f4a8 100644 --- a/eepg.h +++ b/eepg.h @@ -1239,10 +1239,10 @@ static const char *SkyItThemes[] = { "Sport - Golf", // 010 01111 "Sport - Nuoto", // 010 10000 "Sport - Wrestling", // 010 10001 - NULL, // 010 10010 + "Sport - Pallamano", // 010 10010 "Sport - Volley", // 010 10011 "Sport - Poker", // 010 10100 - NULL, // 010 10101 + "Sport - Vela", // 010 10101 "Sport - Sport Invernali", // 010 10110 NULL, // 010 10111 NULL, // 010 11000 @@ -1360,13 +1360,13 @@ static const char *SkyItThemes[] = { "Ragazzi e Musica - Magazine", // 110 01000 "Ragazzi e Musica - Giochi", // 110 01001 NULL, // 110 01010 - NULL, // 110 01011 + "Ragazzi e Musica - Musica da Camera", // 110 01011 NULL, // 110 01100 NULL, // 110 01101 NULL, // 110 01110 NULL, // 110 01111 NULL, // 110 10000 - NULL, // 110 10001 + "Ragazzi e Musica - Concerto", // 110 10001 NULL, // 110 10010 NULL, // 110 10011 "Ragazzi e Musica - Danza", // 110 10100 @@ -1385,7 +1385,7 @@ static const char *SkyItThemes[] = { "Altri Programmi - Educational", // 111 00001 "Altri Programmi - Regionale", // 111 00010 "Altri Programmi - Shopping", // 111 00011 - NULL, // 111 00100 + "Altri Programmi - Altri", // 111 00100 "Altri Programmi - Inizio e Fine Trasmissioni", // 111 00101 "Altri Programmi - Eventi Speciali", // 111 00110 "Altri Programmi - Film per Adulti", // 111 00111 diff --git a/epghandler.c b/epghandler.c index 328aa91..8302cdc 100644 --- a/epghandler.c +++ b/epghandler.c @@ -23,6 +23,7 @@ cEEpgHandler::cEEpgHandler() { modified = false; charsetFixer = new cCharsetFixer(); schedule = NULL; + searchDuplicates = true; } @@ -61,6 +62,21 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, } modified = false; + //VDR creates new event if the EitEvent StartTime is different than EEPG time so + //the EPG event has to be deleted but the data should be kept + const cEvent* ev = schedule->GetEvent(EitEvent->getEventId(),EitEvent->getStartTime()); + searchDuplicates = !ev; //if the event exist with a same start time, it is handled by SetShortText/SetDescription + if (!ev){ + ev = schedule->GetEvent(EitEvent->getEventId()); + // remove shifted duplicates with same ID + if (ev && ((ev->StartTime()>EitEvent->getStartTime() && ev->StartTime() < EitEvent->getStartTime()+EitEvent->getDuration()) + || (EitEvent->getStartTime() > ev->StartTime() && EitEvent->getStartTime() < ev->EndTime()))) { + LogD(0, prep("!!!Deleting Event id:%d title:%s start_time:%d new_start_time:%d duration:%d new_duration:%d"), + ev->EventID(), ev->Title(), ev->StartTime(), EitEvent->getStartTime(), ev->Duration(), EitEvent->getDuration()); + RemoveEvent((cEvent*)ev); + searchDuplicates = false; + } + } return false; // return true; @@ -71,31 +87,36 @@ bool cEEpgHandler::SetEventID(cEvent* Event, tEventID EventID) { return true; } -//VDR creates new event if the EitEvent StartTime is different than EEPG time so -//the EPG event has to be deleted but the data should be kept +void cEEpgHandler::RemoveEvent(cEvent* ev) +{ + if (ev->Description() && strcmp(ev->Description(), "") != 0) + origDescription = ev->Description(); + + if (ev->ShortText() && strcmp(ev->ShortText(), "") != 0) + origShortText = ev->ShortText(); + + LogD(4, prep("!!!Deleting Event id:%d title:%s start_time:%d duration:%d"), + ev->EventID(), ev->Title(), ev->StartTime(), ev->Duration()); + schedule->DelEvent((ev)); //The equivalents should be handled on adding equivalent event. +} + +//Find duplicate events by title / time +//Sometimes same events overlap and have different EventID void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) { - //Sometimes same events overlap and have different EventID - if (origDescription.empty() && origShortText.empty()) { - cEvent* eqEvent = NULL; - cEvent* ev = (cEvent*) Event->Next(); - if (ev && (ev->EventID() == Event->EventID() || (newTitle && strcasecmp(ev->Title(), newTitle) == 0)) - && Event->StartTime() <= ev->StartTime() && Event->EndTime() > ev->StartTime()) - eqEvent = ev; - if (!eqEvent && (ev = (cEvent*) Event->Prev()) != NULL - && (ev->EventID() == Event->EventID() || (newTitle && strcasecmp(ev->Title(), newTitle) == 0)) - && ev->StartTime() <= Event->StartTime() && ev->EndTime() > Event->StartTime()) - eqEvent = ev; - if (eqEvent) { - if (ev->Description() && strcmp(ev->Description(), "") != 0) - origDescription = ev->Description(); - if (ev->ShortText() && strcmp(ev->ShortText(), "") != 0) - origShortText = ev->ShortText(); + if (!newTitle || !searchDuplicates) return; + + for (cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { + //assume that events are already sorted. + if (ev->StartTime() > Event->EndTime()) break; + if (ev->Title() && strcasecmp(ev->Title(), newTitle) == 0 + && ((Event->StartTime() > ev->StartTime() && Event->StartTime() < ev->EndTime()) + || (ev->StartTime() > Event->StartTime() && ev->StartTime() < Event->EndTime()))){ LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%s; start_time o:%d n:%d; duration o:%d n:%d"), ev->EventID(), Event->EventID(), ev->Title(), newTitle, ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); - - schedule->DelEvent((cEvent*) eqEvent);//The equivalents should be handled on adding equivalent event. + RemoveEvent(ev); + break; } } } @@ -106,6 +127,7 @@ bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { const char* title = charsetFixer->FixCharset(Title); //Sometimes same events overlap and have different EventID + //Find/Remove duplicates with same title/time FindDuplicate(Event, title); if (!Event->Title() || (title && (!strcmp(Event->Title(),"") || (strcmp(Title,"") && strcmp(Event->Title(),title))))) { @@ -242,7 +264,7 @@ bool cEEpgHandler::SortSchedule(cSchedule* Schedule) { bool cEEpgHandler::FixEpgBugs(cEvent* Event) { - //TODO to see which channels have bugs - disable fixing with true + //to see which channels have bugs - disable fixing with true return false; } diff --git a/epghandler.h b/epghandler.h index c0c5f0a..4a08fcf 100644 --- a/epghandler.h +++ b/epghandler.h @@ -41,6 +41,10 @@ public: private: std::string ExtractAttribute(const char* attr); void FindDuplicate(cEvent* Event, const char* newTitle); + /* + * Extract the date from duplicate event and remove it + */ + void RemoveEvent(cEvent* ev); private: std::string origShortText; @@ -50,7 +54,7 @@ private: cSchedule* schedule; static const int _LONG_EVENT_HOURS = 10; bool modified; - + bool searchDuplicates; }; #endif /*APIVERSNUM > 10725*/ diff --git a/extra/en-themes/mhw1_fr.tr b/extra/en-themes/mhw1_fr.tr new file mode 100644 index 0000000..cef2cb4 --- /dev/null +++ b/extra/en-themes/mhw1_fr.tr @@ -0,0 +1,81 @@ +# +# Translation of MHW1 Fr themes into En +# Fromat: +# Original Key=Translated + +#. /Categories +DIVERTISSEMENT=Entertainment +DOCUMENTAIRE=Documentary +EVENEMENT=Event +FILM=Movie +INFO/METEO=News/Wather +JEUNESSE=Youth +MAGAZINE=Magazine +MUSIQUE=Music +SERIE=Series +SPORT=Sports + +#. /Genres +ACTION=Action +ANIMATION=Animation +ARTE=Art +ATHLETISME=Athletics +BASKETBALL=Basketball +CARRE ROSE= +CHARME= +CINEMA=Cinema +CLASSIC-CONTEMP=Classic-Contemp +CLIPS=Clips +COURSE HIPPIQUE=Horse Racing +COURT METRAGE=Short Film +CULTURE=Culture +CYCLISME=Cycling +DANSE=Dance +DE COMBAT=Combat +DE GLISSE=Gliding +DEBAT=Debate +DECOUVERTE=Discovery +DESSINS -ANIMES= +ECONOMIE=Economy +EDUCATION=Educational +EROTIQUE=Erotic +EVASION= +FOOTBALL=Football +FRISSON=Thriller +FUN=Fun +FUNK-SOUL=Funk / Soul +GOLF=Golf +GRAND PRIX F1=Formula 1 +HISTOIRE=History +HORREUR=Horror +INFO=News +INFORMATION=Information +JAZZ-BLUES=Jazz / Blues +JEU=Games +MECANIQUE=Mechanical +METEO=Weather +MODE=Fashion +MUSIQ. DU MONDE=World Music +NATURE=Nature +OPERA=Opera +PASSION=Passion +POLITIQUE=Politics +PORTRAIT=Portrait +RAP-GROOVE=Rap-Groove +RIRES=Laughter +ROCK-POP=Rock / Pop +RUGBY=Rugby +SC. & TECH=Science & Technology +SC. & TECH.=Science & Technology +SC.FICTION=Sci-Fi +SCIENCE FICTION=Sci-Fi +SERVICE=Service +SKI=Ski +SOCIETE=Society +SPECTACLE=Show +TECHNO-DANCE=Techno / Dance +TENDRESSE= +TENNIS=Tennis +THEATRE=Theatre +TV ACHAT=Teleshopping +VARIETES=Variety diff --git a/extra/en-themes/mhw2_es.tr b/extra/en-themes/mhw2_es.tr new file mode 100644 index 0000000..fe31a73 --- /dev/null +++ b/extra/en-themes/mhw2_es.tr @@ -0,0 +1,103 @@ +# +# Translation of MHW2 Es themes into En +# Fromat: +# Original Key=Translated + +#. /Categories +CINE=Movie +CULTURAL/EDUCAT.=Cultural/Educat. +DEPORTES=Sports +DOCUMENTALES=Documentary +ENTRETENIMIENTO=Entertainment +INFANTIL=Children +INFORMACIÓ=Information +MÚSIC=Music +OCIO Y AFICIONES=Leisure & Hobbies +OTROS=Other +SERIES=Series + +#. /Genres +ACCIÓN=Action +ACTUALIDAD=News +ADULTO=Adult +ANIMACIÓN=Animation +ARTE Y CULTURA=Art & Culture +ATLETISMO=Athletics +AVENTURAS=Adventure +BALONCESTO=Basketball +BALONMANO=Handball +BELLEZA=Beauty +BIOGRAFÍA=Biography +BRICOLAJE=DIY +CAZA Y PESCA=Hunting & Fishing +CIENCIA FICCIÓN=Sci-Fi +CIENCIA Y TECNOLOGÍA=Science & Technology +CLÁSICA=Classic +COCINA=Cooking +COMEDIA=Comedy +COMEDIA ROMÁNT.=Romantic Comedy +CONCIERTO=Concert +CONCURSO=Contest +CORAZÓN / SOCIEDAD= +CORTOMETRAJE=Short Film +DANCE / ELECTRÓNICA=Dance / Electornic +DANZA / BALLET=Dance / Ballet +DEBATE=Debate +DECORACIÓN=Decor +DEPORTE=Sport +DEPORTES ACUÁTICOS=Watersports +DEPORTES DE INVIERNO=Winter Sports +DIBUJOS ANIMADOS=Cartoons +DRAMA=Drama +ECONOMÍA=Economy +EDUCATIVO=Educational +ENTREVISTA=Interview +ESOTERISMO= +FOOTBALL=Football +FORMACIÓN=Training +FÚTBOL=Football +FÚTBOL AMERICANO=American Football +HISTORIA=History +HISTÓRICO=Historical +HUMOR=Humor +IDIOMAS=Languages +INFORMATIVO=Information +JAZZ / BLUES=Jazz / Blues +JUEGOS=Games +JUVENIL=Youth +LISTAS=Lists +LITERATURA=Literature +MAGACÍN=Magazine +MAGACÍN DEPORTIVO=Sports Magazine +MELODRAMA=Melodrama +METEOROLOGÍA=Weather +MINISERIE=Mini series +MODA=Fashion +MOTOR=Moto +MUSICAL=Musical +MÚSICA=Music +NATURALEZA=Nature +NOCHE=Nights +OESTE=Western +POLICÍACA=Detective +POLICÍACO=Detective +PREESCOLAR=Preschool +RELIGIÓN=Religious +REPORTAJE=Reportage +REVISTA CULTURAL=Culture Magazine +ROCK / POP=Rock / Pop +SALUD Y BIENESTAR=Health & Wellness +SOCIEDAD=Society +SUSPENSE=Thriller +TECNOLOGÍA=Technology +TELE REALIDAD=Reality TV +TELEFILME=Telefilm +TELENOVELA=Soap +TELEVENTA=Teleshopping +TENDENCIAS=Trends +TERROR=Horror +TOROS=Bulls +TURISMO=Travel +VIAJES / EXPEDICIONES=Travel / Expeditions +VIDEOCLIPS=Clips +ÓPERA=Opera \ No newline at end of file diff --git a/extra/en-themes/sky_it.themes b/extra/en-themes/sky_it.themes new file mode 100644 index 0000000..198c79a --- /dev/null +++ b/extra/en-themes/sky_it.themes @@ -0,0 +1,256 @@ +0x00=No Category +0x01= +0x02= +0x03= +0x04= +0x05= +0x06= +0x07= +0x08= +0x09= +0x0a= +0x0b= +0x0c= +0x0d= +0x0e= +0x0f= +0x10= +0x11= +0x12= +0x13= +0x14= +0x15= +0x16= +0x17= +0x18= +0x19= +0x1a= +0x1b= +0x1c= +0x1d= +0x1e= +0x1f= +0x20=Entertainment +0x21=Entertainment - Fiction +0x22=Entertainment - Sit Com +0x23=Entertainment - Show +0x24=Entertainment - Telefilm +0x25=Entertainment - Soap Opera +0x26=Entertainment - Telenovela +0x27=Entertainment - Sci-Fi +0x28=Entertainment - Animation +0x29=Entertainment - Detective +0x2a=Entertainment - Drama +0x2b=Entertainment - Romance +0x2c=Entertainment - Mini series +0x2d=Entertainment - Spectacle +0x2e=Entertainment - Quiz +0x2f=Entertainment - Talk Show +0x30=Entertainment - Variety +0x31=Entertainment - Festival +0x32=Entertainment - Teater +0x33=Entertainment - Game +0x34= +0x35= +0x36= +0x37= +0x38= +0x39= +0x3a= +0x3b= +0x3c= +0x3d= +0x3e= +0x3f= +0x40=Sports +0x41=Sports - Football +0x42=Sports - Tennis +0x43=Sports - Motor Sport +0x44=Sports - Other +0x45=Sports - Baseball +0x46=Sports - Cycling +0x47=Sports - Rugby +0x48=Sports - Basketball +0x49=Sports - Boxing +0x4a=Sports - Athletics +0x4b=Sports - American Football +0x4c=Sports - Ice Hockey +0x4d=Sports - Ski +0x4e=Sports - Equestrian +0x4f=Sports - Golf +0x50=Sports - Watersports +0x51=Sports - Wrestling +0x52=Sports - Handball +0x53=Sports - Volleyball +0x54=Sports - Poker +0x55=Sports - Sailing +0x56=Sports - Winter Sports +0x57= +0x58= +0x59= +0x5a= +0x5b= +0x5c= +0x5d= +0x5e= +0x5f= +0x60=Movie +0x61=Movie - Drama +0x62=Movie - Comedy +0x63=Movie - Romance +0x64=Movie - Action +0x65=Movie - Sci-Fi +0x66=Movie - Western +0x67=Movie - Comic +0x68=Movie - Fantasy +0x69=Movie - Adventure +0x6a=Movie - Crime +0x6b=Movie - War +0x6c=Movie - Horror +0x6d=Movie - Animation +0x6e=Movie - Thriller +0x6f=Movie - Musical +0x70=Movie - Short +0x71=Movie - Short film +0x72=Movie - Erotic +0x73= +0x74= +0x75= +0x76= +0x77= +0x78= +0x79= +0x7a= +0x7b= +0x7c= +0x7d= +0x7e= +0x7f= +0x80=World & Trends +0x81=World & Trends - Nature +0x82=World & Trends - Art & Culture +0x83=World & Trends - Lifestyle +0x84=World & Trends - Travel +0x85=World & Trends - Documentary +0x86=World & Trends - Society +0x87=World & Trends - Science +0x88=World & Trends - History +0x89=World & Trends - Sport +0x8a=World & Trends - Fishing +0x8b=World & Trends - People +0x8c=World & Trends - Cinema +0x8d=World & Trends - Music +0x8e=World & Trends - Hobby +0x8f=World & Trends - Hunting +0x90=World & Trends - Reportage +0x91=World & Trends - Magazine +0x92=World & Trends - Culture Magazine +0x93=World & Trends - Science Magazine +0x94=World & Trends - Politics +0x95=World & Trends - Cinema Magazine +0x96=World & Trends - Sport Magazine +0x97=World & Trends - Actuality +0x98=World & Trends - Fashion +0x99=World & Trends - Economy +0x9a=World & Trends - Hunting & Fishing Magazine +0x9b=World & Trends - Travel Magazine +0x9c=World & Trends - Nature Magazine +0x9d=World & Trends - Music Magazine +0x9e=World & Trends - Religion +0x9f=World & Trends - Teleshopping +0xa0=Information +0xa1=Information - News +0xa2=Information - Sport +0xa3=Information - Economy +0xa4= +0xa5=Information - Weather +0xa6= +0xa7= +0xa8= +0xa9= +0xaa= +0xab= +0xac= +0xad= +0xae= +0xaf= +0xb0= +0xb1= +0xb2= +0xb3= +0xb4= +0xb5= +0xb6= +0xb7= +0xb8= +0xb9= +0xba= +0xbb= +0xbc= +0xbd= +0xbe= +0xbf= +0xc0=Children & Music +0xc1=Children & Music - Kids +0xc2=Children & Music - Children +0xc3=Children & Music - Cartoons +0xc4=Children & Music - Music +0xc5=Children & Music - Animation Movie +0xc6=Children & Music - Movie +0xc7=Children & Music - Telefilm +0xc8=Children & Music - Magazine +0xc9=Children & Music - Games +0xca= +0xcb=Children & Music - Chamber Music +0xcc= +0xcd= +0xce= +0xcf= +0xd0= +0xd1=Children & Music - Concert +0xd2= +0xd3= +0xd4=Children & Music - Dance +0xd5=Children & Music - Videoclip +0xd6= +0xd7= +0xd8= +0xd9= +0xda= +0xdb= +0xdc= +0xdd= +0xde= +0xdf= +0xe0=Other +0xe1=Other - Educational +0xe2=Other - Regional +0xe3=Other - Shopping +0xe4=Other - Other +0xe5=Other - Start & End Transmission +0xe6=Other - Special Events +0xe7=Other - Adult Movie +0xe8= +0xe9= +0xea= +0xeb= +0xec= +0xed= +0xee= +0xef= +0xf0= +0xf1= +0xf2= +0xf3= +0xf4= +0xf5= +0xf6= +0xf7= +0xf8= +0xf9= +0xfa= +0xfb= +0xfc= +0xfd= +0xfe= +0xff= diff --git a/util.c b/util.c index e565b2e..f70c520 100644 --- a/util.c +++ b/util.c @@ -26,6 +26,7 @@ int YesterdayEpochUTC; struct hufftab *tables[2][128]; int table_size[2][128]; +map tableDict; EFormat Format; cEquivHandler* EquivHandler; @@ -207,11 +208,17 @@ void cAddEventThread::Action(void) (*it).second->Del(event, false); - cEvent *ev = (cEvent *) schedule->GetEventAround(event->StartTime()); - if (ev && (ev->EventID() == event->EventID() || (event->Title() && strcasecmp(ev->Title(), event->Title()) == 0)) - && event->StartTime() <= ev->StartTime() && event->EndTime() > ev->StartTime()){ - MergeEquivalents(event, ev); - schedule->DelEvent(ev); + for (cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { + if (ev->StartTime() > event->EndTime()) { + break; + } + if (ev && (ev->EventID() == event->EventID() || (event->Title() && strcasecmp(ev->Title(), event->Title()) == 0)) + && ((event->StartTime() >= ev->StartTime() && event->StartTime() < ev->EndTime()) + || (ev->StartTime() >= event->StartTime() && ev->StartTime() < event->EndTime()))){ + MergeEquivalents(event, ev); + schedule->DelEvent(ev); + break; + } } event = schedule->AddEvent(event); @@ -262,18 +269,18 @@ string ExtractAttributes(string text) { } - inline void cAddEventThread::MergeEquivalents(cEvent* dest, cEvent* src) { if (!dest->ShortText() || !strcmp(dest->ShortText(),"")) dest->SetShortText(src->ShortText()); //Handle the Category and Genre, and optionally future tags - if ((dest->Description() || strcmp(src->Description(),"")) && - (!dest->Description() || - (dest->Description() && strstr(src->Description(),dest->Description())) != 0 )) { + if (!src->Description() || !strcmp(src->Description(),"")) + return; + + if ((!dest->Description() || strstr(src->Description(),dest->Description()))) { dest->SetDescription(src->Description()); - } else if (src->Description() && !strcmp(src->Description(),"") && dest->Description()) { + } else if (dest->Description()) { string desc = dest->Description() ? dest->Description() : ""; desc += ExtractAttributes(desc); @@ -283,7 +290,6 @@ inline void cAddEventThread::MergeEquivalents(cEvent* dest, cEvent* src) } - static cAddEventThread AddEventThread; // --- @@ -509,4 +515,14 @@ void cCharsetFixer::InitCharsets(const cChannel* Channel) } +string findThemeTr(const char* text) +{ + map::iterator it; + string trans = text; + if ((it = tableDict.find(trans)) != tableDict.end()) + trans = it->second; + LogD(4, prep("original:%s translated:%s map size:%d"), text, trans.c_str(), tableDict.size()); + return trans; +} + } diff --git a/util.h b/util.h index bef2a3e..2a4cd51 100644 --- a/util.h +++ b/util.h @@ -10,6 +10,7 @@ #include #include #include +#include class cChannel; struct tChannelID; @@ -68,6 +69,12 @@ void CleanString(unsigned char *String); void decodeText2(const unsigned char *from, int len, char *buffer, int buffsize); char *freesat_huffman_decode(const unsigned char *src, size_t size); void sortSchedules(cSchedules * Schedules, tChannelID channelID); +/** + * Locate the translation of a given Theme (Category, Genre) string in the translation map + * @param the text to search + * @return found translation or the source text if not found. + */ +std::string findThemeTr(const char*); //struct sNode //{ @@ -95,6 +102,8 @@ struct hufftab extern struct hufftab *tables[2][128]; extern int table_size[2][128]; //static sNodeH* sky_tables[2]; +extern std::map tableDict; + class cCharsetFixer { -- cgit v1.2.3 From ec10b1df60b96477c8cb5e24d9833eb4bdb75f99 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 6 Jan 2014 20:42:30 +0100 Subject: fixed compile with VDR 2.1.3 --- eepg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eepg.c b/eepg.c index a970479..ac2f9fa 100644 --- a/eepg.c +++ b/eepg.c @@ -3553,7 +3553,7 @@ private: struct { cFilterEEPG *filter; cDevice *device; - } epg[MAXDVBDEVICES]; + } epg[MAXDEVICES]; void CheckCreateFile(const char* Name, const char *fileContent[]); @@ -3618,7 +3618,7 @@ bool cPluginEEPG::Start (void) #if APIVERSNUM < 10507 RegisterI18n (Phrases); #endif - for (int i = 0; i < MAXDVBDEVICES; i++) { + for (int i = 0; i < MAXDEVICES; i++) { cDevice *dev = cDevice::GetDevice (i); if (dev) { epg[i].device = dev; @@ -3684,7 +3684,7 @@ bool cPluginEEPG::Start (void) void cPluginEEPG::Stop (void) { - for (int i = 0; i < MAXDVBDEVICES; i++) { + for (int i = 0; i < MAXDEVICES; i++) { cDevice *dev = epg[i].device; if (dev) dev->Detach (epg[i].filter); -- cgit v1.2.3 From cbe347f60c34892382452580af39a55c550d9cb5 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Tue, 7 Jan 2014 19:18:51 +0100 Subject: Updated PKGCFG variable --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3b9c86f..bf209b6 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ VERSION := $(RELEASE)$(SUBREL) ### The directory environment: # Use package data if installed...otherwise assume we're under the VDR source directory: -PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc)) +PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr)) LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) -- cgit v1.2.3 From 6a6db913ac85b4144f3144ab50a7e6f89ef9640b Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 17 Mar 2014 09:07:13 +0100 Subject: Ipdated Makefile and skyuk shorttext extraction --- Makefile | 31 +++++++++++++++++++++++++++++-- eepg.c | 9 +++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index bf209b6..b07b767 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,28 @@ export CXXFLAGS = $(call PKGCFG,cxxflags) APIVERSION = $(call PKGCFG,apiversion) +# backward compatibility with VDR version < 1.7.34 +API1733 := $(shell if [ "$(APIVERSION)" \< "1.7.34" ]; then echo true; fi; ) + +ifdef API1733 + +VDRSRC = $(VDRDIR) +ifeq ($(strip $(VDRSRC)),) +VDRSRC := ../../.. +endif +LIBDIR = $(VDRSRC)/PLUGINS/lib + +ifndef NOCONFIG +CXXFLAGS = $(call PKGCFG,cflags) +CXXFLAGS += -fPIC +else +-include $(VDRSRC)/Make.global +-include $(VDRSRC)/Make.config +endif + +export CXXFLAGS +endif + ### Allow user defined options to overwrite defaults: -include $(PLGCFG) @@ -68,8 +90,9 @@ SOFILE = libvdr-$(PLUGIN).so ### Includes and Defines (add further entries here): -#INCLUDES += -I$(VDRDIR)/include -INCLUDES += +ifdef API1733 +INCLUDES += -I$(VDRDIR)/include +endif DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' @@ -79,7 +102,11 @@ OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o eit2.o ### The main target: +ifdef API1733 +all: libvdr-$(PLUGIN).so i18n +else all: $(SOFILE) i18n +endif ### Implicit rules: diff --git a/eepg.c b/eepg.c index ac2f9fa..10e966e 100644 --- a/eepg.c +++ b/eepg.c @@ -2508,8 +2508,13 @@ int cFilterEEPG::GetSummariesSKYBOX (const u_char * Data, int Length) CleanString (S->Text); char * delim = strstr ( (char *)S->Text, STxtDelim ); //S->ShortTextLength = delim == NULL ? 0 : delim - (char *)S->Text; - if (Format == SKY_UK && !delim && strncmp((char *)S->Text,"...",3) == 0) - delim = strstr ( (char *)(S->Text+3), "." ); + if (Format == SKY_UK && !delim && strncmp((char *)S->Text,"..",2) == 0) { + char * tdlm = strpbrk ( (char *)(S->Text+3), ".?!" ); + if (tdlm && tdlm[0] != '.') + tdlm++; + if (tdlm) + delim = tdlm; + } int shLen = delim - (char *)S->Text; S->ShortTextLength = delim == NULL || shLen > numeric_limits::max() ? 0 : shLen; LogI(4, prep("EventId %08x Summnr %d:%.30s."), S->EventId, nSummaries, S->Text); -- cgit v1.2.3 From 39ed518cc429c7576d18bad1e1babd2f5dada280 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 17 Mar 2014 09:09:26 +0100 Subject: test conv_to before deletion --- util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util.c b/util.c index f70c520..96a80fd 100644 --- a/util.c +++ b/util.c @@ -492,7 +492,8 @@ void cCharsetFixer::InitCharsets(const cChannel* Channel) if (!fixedCharset.empty()) { - delete conv_to; + if (conv_to) + delete conv_to; conv_to = new cCharSetConv(fixedCharset.c_str()); -- cgit v1.2.3 From 4e51e3a4c2b3006f8ce760ebcdc424b9c7a3eeb4 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 17 Mar 2014 09:12:20 +0100 Subject: add new theme --- eepg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eepg.h b/eepg.h index 644f4a8..9e640e7 100644 --- a/eepg.h +++ b/eepg.h @@ -1209,7 +1209,7 @@ static const char *SkyItThemes[] = { "Intrattenimento - Festival", // 001 10001 "Intrattenimento - Teatro", // 001 10010 "Intrattenimento - Gioco", // 001 10011 - NULL, // 001 10100 + "Intrattenimento - Manga", // 001 10100 NULL, // 001 10101 NULL, // 001 10110 NULL, // 001 10111 -- cgit v1.2.3 From 3c99a2588c6e3a994797fcf943a0b195914fb5c8 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Tue, 18 Mar 2014 09:11:30 +0100 Subject: try to decode freeview hd --- epghandler.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/epghandler.c b/epghandler.c index 8302cdc..37580bc 100644 --- a/epghandler.c +++ b/epghandler.c @@ -124,7 +124,9 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - const char* title = charsetFixer->FixCharset(Title); + char buffer[Utf8BufSize(256)]; + decodeText2((uchar*)Title, strlen(Title), buffer, sizeof(buffer)); + const char* title = charsetFixer->FixCharset(buffer); //Sometimes same events overlap and have different EventID //Find/Remove duplicates with same title/time @@ -148,7 +150,10 @@ bool cEEpgHandler::SetShortText(cEvent* Event, const char* ShortText) { origShortText.clear(); } - const char* shText = charsetFixer->FixCharset(ShortText); + char buffer[Utf8BufSize(256)]; + decodeText2((uchar*)ShortText, strlen(ShortText), buffer, sizeof(buffer)); + + const char* shText = charsetFixer->FixCharset(buffer); //if (!Event->ShortText() || ShortText && (!strcmp(Event->ShortText(),"") || (strcmp(ShortText,"") && strcmp(Event->ShortText(),ShortText)))) Event->SetShortText(shText); -- cgit v1.2.3 From 809d08939391b0f3db93b28cf59bc3da137ff006 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 24 Mar 2014 22:58:18 +0100 Subject: freeview hd try 2 --- epghandler.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/epghandler.c b/epghandler.c index 37580bc..bc068af 100644 --- a/epghandler.c +++ b/epghandler.c @@ -39,14 +39,18 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, //LogD(1, prep("HandleEitEvent")); //DISH NID 0x1001 to 0x100B BEV 0x100 and 0x101 int nid = schedule->ChannelID().Nid(); - if ((nid >= 0x1001 && nid <= 0x100B) || nid == 0x101 || nid == 0x100) { + if ((nid >= 0x1001 && nid <= 0x100B) || nid == 0x101 || nid == 0x100 || nid == 0x233A) { //Set the Format for Eit events so that the new lines are not erased with FixEpgBugs - if (Format != DISH_BEV) Format = DISH_BEV; + if (nid == 0x233A) Format = FREEVIEW; + else if (Format != DISH_BEV) Format = DISH_BEV; SI::cEIT2 eit2(Schedule); eit2.ProcessEitEvent(Schedule, EitEvent, TableID, Version); return true; - } + } + /*else if (nid == 0x233A) { + Format = FREEVIEW; + } */ //TODO Should it be added in setup? if (EitEvent->getDurationHour() > _LONG_EVENT_HOURS) { @@ -124,9 +128,9 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - char buffer[Utf8BufSize(256)]; - decodeText2((uchar*)Title, strlen(Title), buffer, sizeof(buffer)); - const char* title = charsetFixer->FixCharset(buffer); + //char buffer[Utf8BufSize(256)]; + //decodeText2((uchar*)Title, strlen(Title), buffer, sizeof(buffer)); + const char* title = charsetFixer->FixCharset(Title); //Sometimes same events overlap and have different EventID //Find/Remove duplicates with same title/time @@ -150,10 +154,13 @@ bool cEEpgHandler::SetShortText(cEvent* Event, const char* ShortText) { origShortText.clear(); } + const char* shText; char buffer[Utf8BufSize(256)]; - decodeText2((uchar*)ShortText, strlen(ShortText), buffer, sizeof(buffer)); - - const char* shText = charsetFixer->FixCharset(buffer); +/* if (ShortText && Format == FREEVIEW) { + decodeText2((uchar*)ShortText, strlen(ShortText), buffer, sizeof(buffer)); + shText = charsetFixer->FixCharset(buffer); + } else */ + shText = charsetFixer->FixCharset(ShortText); //if (!Event->ShortText() || ShortText && (!strcmp(Event->ShortText(),"") || (strcmp(ShortText,"") && strcmp(Event->ShortText(),ShortText)))) Event->SetShortText(shText); -- cgit v1.2.3 From 0223b8b98276b3f1c935325c9dcdf9b6484eb136 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 14 Apr 2014 09:58:04 +0200 Subject: fix wrong merge conflicts --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index 320a63e..b07b767 100644 --- a/Makefile +++ b/Makefile @@ -102,15 +102,11 @@ OBJS = $(PLUGIN).o dish.o epghandler.o setupeepg.o equivhandler.o util.o eit2.o ### The main target: -<<<<<<< HEAD ifdef API1733 all: libvdr-$(PLUGIN).so i18n else all: $(SOFILE) i18n endif -======= -all: $(SOFILE) ->>>>>>> master ### Implicit rules: -- cgit v1.2.3 From a65e2c09448b24c8e4d6c0e13fd9775ecdca3488 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 16 Apr 2014 18:23:38 +0200 Subject: remove commented lines --- epghandler.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/epghandler.c b/epghandler.c index 90c8434..a80600c 100644 --- a/epghandler.c +++ b/epghandler.c @@ -41,17 +41,14 @@ bool cEEpgHandler::HandleEitEvent(cSchedule* Schedule, int nid = schedule->ChannelID().Nid(); if ((nid >= 0x1001 && nid <= 0x100B) || nid == 0x101 || nid == 0x100 || nid == 0x233A) { //Set the Format for Eit events so that the new lines are not erased with FixEpgBugs - EFormat Format = DISH_BEV; + EFormat Format; if (nid == 0x233A) Format = FREEVIEW; else Format = DISH_BEV; SI::cEIT2 eit2(Schedule, Format); eit2.ProcessEitEvent(Schedule, EitEvent, TableID, Version); return true; - } - /*else if (nid == 0x233A) { - Format = FREEVIEW; - } */ + } //TODO Should it be added in setup? if (EitEvent->getDurationHour() > _LONG_EVENT_HOURS) { @@ -129,8 +126,6 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) bool cEEpgHandler::SetTitle(cEvent* Event, const char* Title) { LogD(3, prep("Event id:%d title:%s new title:%s"), Event->EventID(), Event->Title(), Title); - //char buffer[Utf8BufSize(256)]; - //decodeText2((uchar*)Title, strlen(Title), buffer, sizeof(buffer)); const char* title = charsetFixer->FixCharset(Title); //Sometimes same events overlap and have different EventID @@ -155,13 +150,7 @@ bool cEEpgHandler::SetShortText(cEvent* Event, const char* ShortText) { origShortText.clear(); } - const char* shText; - char buffer[Utf8BufSize(256)]; -/* if (ShortText && Format == FREEVIEW) { - decodeText2((uchar*)ShortText, strlen(ShortText), buffer, sizeof(buffer)); - shText = charsetFixer->FixCharset(buffer); - } else */ - shText = charsetFixer->FixCharset(ShortText); + const char* shText = charsetFixer->FixCharset(ShortText); //if (!Event->ShortText() || ShortText && (!strcmp(Event->ShortText(),"") || (strcmp(ShortText,"") && strcmp(Event->ShortText(),ShortText)))) Event->SetShortText(shText); -- cgit v1.2.3 From 98e560b5a1b357f95dc64742570529661d9a22cf Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 16 Apr 2014 18:29:39 +0200 Subject: Update documentation --- HISTORY | 1 + README | 2 ++ 2 files changed, 3 insertions(+) diff --git a/HISTORY b/HISTORY index 7ea07a2..e28cdd2 100644 --- a/HISTORY +++ b/HISTORY @@ -40,6 +40,7 @@ Release 0.0.6pre: - Reformatted MHW1 themes - Added some new/missing SKY themes - Added ability to translate themes. See README/Examples +- Added support for Freeview HD (DVB-T) - Additional fixes logged at http://projects.vdr-developer.org/git/vdr-plugin-eepg.git/ diff --git a/README b/README index b04c44f..c043a25 100644 --- a/README +++ b/README @@ -32,6 +32,7 @@ Currently the following EEPG formats are supported: * Sky Italy * Sky UK * Freesat +* Freeview * Premiere * NagraGuide (CanaalDigitaalNL, only in test) * NA Dish and BEV @@ -125,6 +126,7 @@ This code is based on: Thanks to mrgandalf, and the others who helped map NA eit. Thanks to VDR User for testing and providing makequiv.sh script for S72.7W channels. Thanks to cheesemonster for providing a patch to fix multipe device problems +Thanks to Tony Houghton and Stuart Morris for testing Freeview HD We wish to thank all authors for the great work they have been doing, decoding this EEPG data; this plugin tries to combine the best of all worlds. -- cgit v1.2.3 From d8d74bb9f4ed3ddc26f515efa538d6ea841a6895 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Wed, 16 Apr 2014 18:29:39 +0200 Subject: Update documentation. Fixes #692 --- HISTORY | 1 + README | 2 ++ 2 files changed, 3 insertions(+) diff --git a/HISTORY b/HISTORY index 7ea07a2..e28cdd2 100644 --- a/HISTORY +++ b/HISTORY @@ -40,6 +40,7 @@ Release 0.0.6pre: - Reformatted MHW1 themes - Added some new/missing SKY themes - Added ability to translate themes. See README/Examples +- Added support for Freeview HD (DVB-T) - Additional fixes logged at http://projects.vdr-developer.org/git/vdr-plugin-eepg.git/ diff --git a/README b/README index b04c44f..c043a25 100644 --- a/README +++ b/README @@ -32,6 +32,7 @@ Currently the following EEPG formats are supported: * Sky Italy * Sky UK * Freesat +* Freeview * Premiere * NagraGuide (CanaalDigitaalNL, only in test) * NA Dish and BEV @@ -125,6 +126,7 @@ This code is based on: Thanks to mrgandalf, and the others who helped map NA eit. Thanks to VDR User for testing and providing makequiv.sh script for S72.7W channels. Thanks to cheesemonster for providing a patch to fix multipe device problems +Thanks to Tony Houghton and Stuart Morris for testing Freeview HD We wish to thank all authors for the great work they have been doing, decoding this EEPG data; this plugin tries to combine the best of all worlds. -- cgit v1.2.3 From fd944ccd25762873a5235b44b23ff8cbc2147d98 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sun, 16 Nov 2014 19:46:58 +0100 Subject: add new theme --- eepg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eepg.h b/eepg.h index 9e640e7..6c84051 100644 --- a/eepg.h +++ b/eepg.h @@ -1363,7 +1363,7 @@ static const char *SkyItThemes[] = { "Ragazzi e Musica - Musica da Camera", // 110 01011 NULL, // 110 01100 NULL, // 110 01101 - NULL, // 110 01110 + "Ragazzi e Musica - Classica", // 110 01110 NULL, // 110 01111 NULL, // 110 10000 "Ragazzi e Musica - Concerto", // 110 10001 -- cgit v1.2.3 From bae08c5a8299861111afadde92b3fbce34e758e8 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sun, 15 Feb 2015 20:08:32 +0100 Subject: Implement fix for memory leak in case of broken Extended Event Descriptors for vdr 2.1.9+ --- eit2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eit2.c b/eit2.c index 4e813af..d5f928b 100644 --- a/eit2.c +++ b/eit2.c @@ -133,8 +133,12 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, UseExtendedEventDescriptor = true; } if (UseExtendedEventDescriptor) { +#if APIVERSNUM < 20109 ExtendedEventDescriptors->Add(eed); - d = NULL; // so that it is not deleted +#else + if (ExtendedEventDescriptors->Add(eed)) +#endif + d = NULL; // so that it is not deleted } if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber()) UseExtendedEventDescriptor = false; -- cgit v1.2.3 From 7f7ec60c3654f318fc4ec918a29b8b95c8c4a25e Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Fri, 17 Jun 2016 21:04:11 +0200 Subject: vdr 2.3.1 compatibility --- eepg.c | 70 +++++++++++++++++++++++++++++++++++++++++++--------------- eit2.c | 43 +++++++++++++++++++++++++++++++----- eit2.h | 5 ++--- epghandler.c | 4 ++-- equivhandler.c | 17 ++++++++++++-- util.c | 42 +++++++++++++++++++++++++---------- util.h | 2 +- 7 files changed, 139 insertions(+), 44 deletions(-) diff --git a/eepg.c b/eepg.c index f55f9ed..afab8bc 100644 --- a/eepg.c +++ b/eepg.c @@ -1001,7 +1001,7 @@ int cFilterEEPG::GetChannelsMHW (const u_char * Data, int Length) C->Tid = HILO16 (Channel->TransportId); C->Sid = HILO16 (Channel->ServiceId); tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); - cChannel *VC = GetChannelByID(channelID, true); + const cChannel *VC = GetChannelByID(channelID, true); bool IsFound = (VC); if(IsFound) { C->Src = VC->Source(); @@ -1515,8 +1515,12 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor unsigned short int CurrentYear = tmCurrent->tm_year; unsigned short int CurrentMonth = tmCurrent->tm_mon; //esyslog("EEPGDEBUG: CurrentMonthday=%i, TableIdExtension:%04x, MonthdayTitles=%i.",CurrentMonthday,TableIdExtension, MonthdayTitles); +#if APIVERSNUM >= 20300 + LOCK_SCHEDULES_WRITE; +#else cSchedulesLock SchedulesLock (true); - cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock); + cSchedules *Schedules = (cSchedules *) cSchedules::Schedules (SchedulesLock); +#endif do { //process each block of titles sTitleBlockNagraGuide *TB = (sTitleBlockNagraGuide *) p; int ChannelId = HILO16 (TB->ChannelId); @@ -1535,7 +1539,7 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor sChannel *C = &sChannels[ChannelSeq[ChannelId]]; //find channel //cSchedule *ps = NULL;//[MAX_EQUIVALENCES]; - //PrepareToWriteToSchedule (C, s, ps); + //PrepareToWriteToSchedule (C, Schedules, ps); for (int i = 0; i < NumberOfTitles; i++) { //process each title within block sTitleNagraGuide *Title = (sTitleNagraGuide *) p; @@ -1586,7 +1590,7 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor if (Themes[Title->ThemeId][0] == 0x00) //if detailed themeid is not known, get global themeid Title->ThemeId &= 0xf0; - WriteToSchedule (tChannelID (C->Src, C->Nid, C->Tid, C->Sid), s, EventId, StartTime, Title->Duration, Text, SummText, + WriteToSchedule (tChannelID (C->Src, C->Nid, C->Tid, C->Sid), Schedules, EventId, StartTime, Title->Duration, Text, SummText, Title->ThemeId, NAGRA_TABLE_ID, Version); if (Text != NULL) @@ -1625,7 +1629,7 @@ void cFilterEEPG::GetTitlesNagra (const u_char * Data, int Length, unsigned shor } //end for titles //FinishWriteToSchedule (C, s, ps); - sortSchedules(s, tChannelID (C->Src, C->Nid, C->Tid, C->Sid)); + sortSchedules(Schedules, tChannelID (C->Src, C->Nid, C->Tid, C->Sid)); p = next_p; } while (p < DataEnd); //end of TitleBlock } @@ -1748,7 +1752,7 @@ int cFilterEEPG::GetChannelsNagra (const u_char * Data, int Length) C->Tid = HILO16 (Channel->TransportId); C->Sid = HILO16 (Channel->ServiceId); tChannelID channelID = tChannelID(C->Src, C->Nid, C->Tid, C->Sid); - cChannel *VC = GetChannelByID(channelID, true); + const cChannel *VC = GetChannelByID(channelID, true); bool IsFound = (VC); if(IsFound) { strncpy((char*)(C->Name), VC->Name (), 64); @@ -2318,7 +2322,7 @@ int cFilterEEPG::GetChannelsSKYBOX (const u_char * Data, int Length) C->Sid = Sid; C->SkyNumber = SkyNumber; tChannelID channelID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); - cChannel *VC = Channels.GetByChannelID (channelID, true); + const cChannel *VC = GetChannelByID (channelID, false); bool IsFound = (VC); if (IsFound) strncpy ((char *) C->Name, VC->Name (), 64); @@ -2592,9 +2596,13 @@ void cFilterEEPG::LoadIntoSchedule (void) bool isOTV = Format == SKY_IT || Format == SKY_UK; { +#if APIVERSNUM >= 20300 + LOCK_SCHEDULES_WRITE; +#else cSchedulesLock SchedulesLock (true); - cSchedules *s = (cSchedules *) cSchedules::Schedules (SchedulesLock); - if (s) { + cSchedules *Schedules = (cSchedules *) cSchedules::Schedules (SchedulesLock); +#endif + if (Schedules) { while (i < nTitles) { S = Summaries[j]; @@ -2646,7 +2654,7 @@ void cFilterEEPG::LoadIntoSchedule (void) //channelids are sequentially numbered and sent in MHW1 and MHW2, but not in SKY, so we need to lookup the table index sChannel *C = &sChannels[ChannelSeq[ChannelId]]; //find channel //cSchedule *p;//[MAX_EQUIVALENCES]; - //PrepareToWriteToSchedule (C, s, p); + //PrepareToWriteToSchedule (C, Schedules, p); tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); char rating = 0x00; @@ -2661,12 +2669,12 @@ void cFilterEEPG::LoadIntoSchedule (void) // LogD (0, prep("EventId %08x Titlenr:%d,SummNr:%d,SummAv:%x,Un1:%x,Un2:%x,Un3:%x,Name:%s,STxtLn:%d,Summary:%s."), // T->EventId, i, j, T->SummaryAvailable, T->Unknown1, T->Unknown2, T->Unknown3, T->Text, S->ShortTextLength, S->Text); - WriteToSchedule (chanID, s, T->EventId, StartTime, T->Duration / 60, (char *) T->Text, + WriteToSchedule (chanID, Schedules, T->EventId, StartTime, T->Duration / 60, (char *) T->Text, (char *) S->Text, T->ThemeId, TableId, 0, rating, S->ShortTextLength); - sortSchedules(s, chanID); + sortSchedules(Schedules, chanID); //if (shortText != NULL) delete [] shortText; - //FinishWriteToSchedule (C, s, p); + //FinishWriteToSchedule (C, Schedules, p); //Replays--; //if ((S->NumReplays != 0) && (Replays > 0)) { //when replays are used, all summaries of the replays are stored consecutively; currently only CSAT //j++; //move to next summary @@ -2704,15 +2712,15 @@ void cFilterEEPG::LoadIntoSchedule (void) sChannel *C = &sChannels[ChannelSeq[T->ChannelId]]; //find channel //cSchedule *p;//[MAX_EQUIVALENCES]; tChannelID chanID = tChannelID (C->Src, C->Nid, C->Tid, C->Sid); - //PrepareToWriteToSchedule (C, s, p); + //PrepareToWriteToSchedule (C, Schedules, p); char rating = 0x00; if (!isOTV && T->Rating) { //TODO only works on OTV for now rating = T->Rating; } - WriteToSchedule (chanID, s, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text, + WriteToSchedule (chanID, Schedules, T->EventId, T->StartTime, T->Duration / 60, (char *) T->Text, NULL, T->ThemeId, DEFAULT_TABLE_ID, 0, rating, S->ShortTextLength); - //FinishWriteToSchedule (C, s, p); - sortSchedules(s, chanID); + //FinishWriteToSchedule (C, Schedules, p); + sortSchedules(Schedules, chanID); SummariesNotFound++; } @@ -2909,12 +2917,19 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const { //0x39 Viasat, 0x0300 Dish Network EEPG, 0x0441 Bell ExpressVU EEPG LogD(4, prep("Pid: 0x%02x Tid: %d Length: %d"), Pid, Tid, Length); +#if APIVERSNUM >= 20300 + LOCK_SCHEDULES_WRITE; +// cStateKey SchedulesStateKey; +// cSchedules *Schedules = cSchedules::GetSchedulesWrite(SchedulesStateKey, 10); +#else cSchedulesLock SchedulesLock(true, 10); cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); +#endif //Look for other satelite positions only if Dish/Bell ExpressVU for the moment hardcoded pid check if(Schedules) SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Format, Pid == EIT_PID); +#if APIVERSNUM < 20300 else//cEIT EIT (Schedules, Source (), Tid, Data); { // If we don't get a write lock, let's at least get a read lock, so @@ -2928,6 +2943,7 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const //cEIT EIT (Schedules, Source (), Tid, Data, true); } +#endif } void cFilterEEPG::Process (u_short Pid, u_char Tid, const u_char * Data, int Length) @@ -3295,8 +3311,12 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) SI::PremiereCIT cit(Data, false); if (cit.CheckCRCAndParse ()) { +#if APIVERSNUM >= 20300 + LOCK_SCHEDULES_WRITE; +#else cSchedulesLock SchedulesLock (true, 10); cSchedules *Schedules = (cSchedules *) cSchedules::Schedules (SchedulesLock); +#endif if (Schedules) { int now = time (0); int nCount = 0; @@ -3438,7 +3458,12 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) } } tChannelID channelID (Source (), nid, tid, sid); +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_READ; + const cChannel *channel = Channels->GetByChannelID (channelID, true); +#else cChannel *channel = Channels.GetByChannelID (channelID, true); +#endif if (!channel) continue; @@ -3543,7 +3568,11 @@ void cFilterEEPG::ProcessPremiere(const u_char *& Data) } if (Modified) { pSchedule->Sort (); +#if APIVERSNUM >= 20300 + pSchedule->SetModified(); +#else Schedules->SetModified (pSchedule); +#endif } delete pct; } @@ -3669,7 +3698,12 @@ bool cPluginEEPG::Start (void) tables[0][0] = NULL; //store all available sources, so when a channel is not found on current satellite, we can look for alternate sat positions. //perhaps this can be done smarter through existing VDR function??? - for (cChannel * Channel = Channels.First (); Channel; Channel = Channels.Next (Channel)) { +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_READ; + for (const cChannel * Channel = Channels->First(); Channel; Channel = Channels->Next(Channel)) { +#else + for (const cChannel * Channel = Channels.First (); Channel; Channel = Channels.Next (Channel)) { +#endif if (!Channel->GroupSep ()) { bool found = false; for (int i = 0; (i < NumberOfAvailableSources) && (!found); i++) diff --git a/eit2.c b/eit2.c index d5f928b..63f6187 100644 --- a/eit2.c +++ b/eit2.c @@ -76,14 +76,21 @@ cEvent* cEIT2::ProcessEitEvent(cSchedule* pSchedule,const SI::EIT::Event* EitEve pSchedule->AddEvent (newEvent); if (Tid == 0x4E) { // we trust only the present/following info on the actual TS if (EitEvent->getRunningStatus () >= SI::RunningStatusNotRunning) - pSchedule->SetRunningStatus (pEvent, EitEvent->getRunningStatus (), channel); + { +#if APIVERSNUM >= 20300 + pSchedule->SetRunningStatus (pEvent, EitEvent->getRunningStatus (), channel); +#else + cChannel* chan = Channels.GetByChannelID(channel->GetChannelID()); + pSchedule->SetRunningStatus (pEvent, EitEvent->getRunningStatus (), chan); +#endif + } } if (OnlyRunningStatus) return NULL; // do this before setting the version, so that the full update can be done later pEvent->SetVersion (versionNumber); ProcessEventDescriptors(ExternalData, channel->Source(), Tid, EitEvent, - pEvent, Schedules, channel); + pEvent, Schedules, channel->GetChannelID()); Modified = true; return pEvent; @@ -91,7 +98,7 @@ cEvent* cEIT2::ProcessEitEvent(cSchedule* pSchedule,const SI::EIT::Event* EitEve void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent, - cSchedules* Schedules, cChannel* channel) + cSchedules* Schedules, const tChannelID& channelId) { cEvent *rEvent = NULL; @@ -110,6 +117,13 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, cLinkChannels *LinkChannels = NULL; cComponents *Components = NULL; +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_WRITE; + if (!Channels) return; + cChannel *channel = Channels->GetByChannelID(channelId); +#else + cChannel *channel = Channels.GetByChannelID(channelId); +#endif DescriptorLoop dl = SiEitEvent->eventDescriptors; for (SI::Loop::Iterator it2; (d = dl.getNext(it2)); ) @@ -247,7 +261,11 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, char linkName[ld->privateData.getLength() + 1]; strn0cpy(linkName, (const char *) ld->privateData.getData(), sizeof(linkName)); // TODO is there a standard way to determine the character set of this string? +#if APIVERSNUM >= 20300 + cChannel *link = Channels->GetByChannelID(linkID); +#else cChannel *link = Channels.GetByChannelID(linkID); +#endif if (link != channel) { // only link to other channels, not the same one //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX if (link) { @@ -255,10 +273,15 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, link->SetName(linkName, "", ""); } else if (Setup.UpdateChannels >= 4) { - cChannel *transponder = channel; + const cChannel *transponder = channel; if (channel->Tid() != ld->getTransportStreamId()) +#if APIVERSNUM >= 20300 + transponder = Channels->GetByTransponderID(linkID); + link = Channels->NewChannel(transponder, linkName, "", "", ld->getOriginalNetworkId(), +#else transponder = Channels.GetByTransponderID(linkID); link = Channels.NewChannel(transponder, linkName, "", "", ld->getOriginalNetworkId(), +#endif ld->getTransportStreamId(), ld->getServiceId()); } if (link) { @@ -549,8 +572,16 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat //// if (Empty && Tid == 0x4E && getSectionNumber () == 0) - // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running - pSchedule->ClrRunningStatus (channel); + // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running + { +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_WRITE; + cChannel *chan = Channels->GetByChannelID(channel->GetChannelID()); +#else + cChannel *chan = Channels.GetByChannelID(channel->GetChannelID()); +#endif + pSchedule->ClrRunningStatus (chan); + } if (Tid == 0x4E) pSchedule->SetPresentSeen (); if (OnlyRunningStatus) { diff --git a/eit2.h b/eit2.h index 0cfd6e6..b9e6298 100644 --- a/eit2.h +++ b/eit2.h @@ -62,7 +62,7 @@ public: private: void ProcessEventDescriptors(bool ExternalData, int Source, u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent, - cSchedules* Schedules, cChannel* channel); + cSchedules* Schedules, const tChannelID& channelID); private: bool Empty; @@ -73,8 +73,7 @@ private: time_t SegmentEnd; cSchedules* Schedules; EFormat Format; - cChannel* channel; - + const cChannel* channel; }; } //end namespace SI diff --git a/epghandler.c b/epghandler.c index a80600c..1e2db9f 100644 --- a/epghandler.c +++ b/epghandler.c @@ -108,7 +108,7 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) { if (!newTitle || !searchDuplicates) return; - for (cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { + for (const cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { //assume that events are already sorted. if (ev->StartTime() > Event->EndTime()) break; if (ev->Title() && strcasecmp(ev->Title(), newTitle) == 0 @@ -117,7 +117,7 @@ void cEEpgHandler::FindDuplicate(cEvent* Event, const char* newTitle) LogD(0, prep("!!!Deleting Event id o:%d n:%d; title o:%s n:%s; start_time o:%d n:%d; duration o:%d n:%d"), ev->EventID(), Event->EventID(), ev->Title(), newTitle, ev->StartTime(), Event->StartTime(), ev->Duration(), Event->Duration()); - RemoveEvent(ev); + RemoveEvent((cEvent*)ev); break; } } diff --git a/equivhandler.c b/equivhandler.c index 745f513..75007ec 100644 --- a/equivhandler.c +++ b/equivhandler.c @@ -77,7 +77,12 @@ void cEquivHandler::loadEquivalentChannelMap (void) tChannelID OriginalChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); bool found = false; //int i = 0; +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_READ; + const cChannel *OriginalChannel = Channels->GetByChannelID(OriginalChID, false); +#else cChannel *OriginalChannel = Channels.GetByChannelID (OriginalChID, false); +#endif if (!OriginalChannel) { LogI(2, prep("Warning, not found EPG channel \'%s\' in channels.conf. Equivalence is assumed to be valid, but perhaps you should check the entry in the equivalents file"), origChanID); continue; @@ -89,7 +94,11 @@ void cEquivHandler::loadEquivalentChannelMap (void) rid = 0; } tChannelID EquivChID = tChannelID (cSource::FromString (source), nid, tid, sid, rid); +#if APIVERSNUM >= 20300 + const cChannel *EquivChannel = Channels->GetByChannelID(EquivChID, false); +#else cChannel *EquivChannel = Channels.GetByChannelID (EquivChID, false); +#endif if (!EquivChannel) { LogI(0, prep("Warning, not found equivalent channel \'%s\' in channels.conf"), equiChanID); continue; @@ -130,7 +139,7 @@ void cEquivHandler::updateEquivalent(cSchedules * Schedules, tChannelID channelI for (it=ret.first; it!=ret.second; ++it) { LogD(2, prep("equivalent channel exists")); tChannelID equChannelID (tChannelID::FromString((*it).second.c_str())); - cChannel *equChannel = GetChannelByID (equChannelID, false); + const cChannel *equChannel = GetChannelByID (equChannelID, false); if (equChannel) { LogD(2, prep("found Equivalent channel %s"), *equChannelID.ToString()); cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (equChannel, true); @@ -192,14 +201,18 @@ void cEquivHandler::sortEquivalents(tChannelID channelID, cSchedules* Schedules) { LogD(3, prep("equivalent channel exists")); tChannelID equChannelID(tChannelID::FromString((*it).second.c_str())); - cChannel* pChannel = GetChannelByID(equChannelID, false); + const cChannel* pChannel = GetChannelByID(equChannelID, false); if (pChannel) { LogD(2, prep("found Equivalent channel %s"), *equChannelID.ToString()); cSchedule* pSchedule = (cSchedule *) Schedules->GetSchedule(pChannel, true); pSchedule->Sort(); +#if APIVERSNUM >= 20300 + pSchedule->SetModified(); +#else Schedules->SetModified(pSchedule); +#endif } } } diff --git a/util.c b/util.c index 0373d1a..b41faf8 100644 --- a/util.c +++ b/util.c @@ -30,14 +30,23 @@ map tableDict; cEquivHandler* EquivHandler; -cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos) +const cChannel *GetChannelByID(const tChannelID & channelID, bool searchOtherPos) { - cChannel *VC = Channels.GetByChannelID(channelID, true); +#if APIVERSNUM >= 20300 + LOCK_CHANNELS_READ; + const cChannel *VC = Channels->GetByChannelID(channelID, true); +#else + const cChannel *VC = Channels.GetByChannelID(channelID, true); +#endif if(!VC && searchOtherPos){ //look on other satpositions for(int i = 0;i < NumberOfAvailableSources;i++){ - channelID = tChannelID(AvailableSources[i], channelID.Nid(), channelID.Tid(), channelID.Sid()); - VC = Channels.GetByChannelID(channelID, true); + tChannelID chID = tChannelID(AvailableSources[i], channelID.Nid(), channelID.Tid(), channelID.Sid()); +#if APIVERSNUM >= 20300 + VC = Channels->GetByChannelID(chID, true); +#else + VC = Channels.GetByChannelID(chID, true); +#endif if(VC){ //found this actually on satellite nextdoor... break; @@ -159,7 +168,7 @@ private: cTimeMs LastHandleEvent; std::map*,tChannelIDCompare> *map_list; // enum { INSERT_TIMEOUT_IN_MS = 10000 }; - void MergeEquivalents(cEvent* dest, cEvent* src); + void MergeEquivalents(cEvent* dest, const cEvent* src); protected: virtual void Action(void); public: @@ -189,14 +198,19 @@ void cAddEventThread::Action(void) while (Running() && !LastHandleEvent.TimedOut()) { std::map*, tChannelIDCompare>::iterator it; +#if APIVERSNUM >= 20300 + LOCK_SCHEDULES_WRITE; + cSchedules *schedules = Schedules; +#else cSchedulesLock SchedulesLock(true, 10); - cSchedules *schedules = (cSchedules *) cSchedules::Schedules(SchedulesLock); - Lock(); + cSchedules *schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); +#endif + Lock(); it = map_list->begin(); while (schedules && it != map_list->end()) { cSchedule *schedule = (cSchedule *) schedules->GetSchedule( - Channels.GetByChannelID((*it).first), true); + GetChannelByID((*it).first, false), true); while (((*it).second->First()) != NULL) { cEvent* event = (*it).second->First(); @@ -207,7 +221,7 @@ void cAddEventThread::Action(void) (*it).second->Del(event, false); - for (cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { + for (const cEvent *ev = schedule->Events()->First(); ev; ev = schedule->Events()->Next(ev)) { if (ev->StartTime() > event->EndTime()) { break; } @@ -215,7 +229,7 @@ void cAddEventThread::Action(void) && ((event->StartTime() >= ev->StartTime() && event->StartTime() < ev->EndTime()) || (ev->StartTime() >= event->StartTime() && ev->StartTime() < event->EndTime()))){ MergeEquivalents(event, ev); - schedule->DelEvent(ev); + schedule->DelEvent((cEvent*)ev); break; } } @@ -268,7 +282,7 @@ string ExtractAttributes(string text) { } -inline void cAddEventThread::MergeEquivalents(cEvent* dest, cEvent* src) +inline void cAddEventThread::MergeEquivalents(cEvent* dest, const cEvent* src) { if (!dest->ShortText() || !strcmp(dest->ShortText(),"")) dest->SetShortText(src->ShortText()); @@ -427,12 +441,16 @@ void sortSchedules(cSchedules * Schedules, tChannelID channelID){ LogD(3, prep("Start sortEquivalent %s"), *channelID.ToString()); - cChannel *pChannel = GetChannelByID (channelID, false); + const cChannel *pChannel = GetChannelByID (channelID, false); cSchedule *pSchedule; if (pChannel) { pSchedule = (cSchedule *) (Schedules->GetSchedule(pChannel, true)); pSchedule->Sort(); +#if APIVERSNUM >= 20300 + pSchedule->SetModified(); +#else Schedules->SetModified(pSchedule); +#endif } if (EquivHandler->getEquiChanMap().count(*channelID.ToString()) > 0) EquivHandler->sortEquivalents(channelID, Schedules); diff --git a/util.h b/util.h index b72aaa1..7573744 100644 --- a/util.h +++ b/util.h @@ -61,7 +61,7 @@ extern cEquivHandler* EquivHandler; void AddEvent(cEvent *event, tChannelID ChannelID); -cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos); +const cChannel *GetChannelByID(const tChannelID & channelID, bool searchOtherPos); time_t LocalTime2UTC(time_t t); time_t UTC2LocalTime(time_t t); void GetLocalTimeOffset(void); -- cgit v1.2.3 From 584d76601777973253c87580216a7f5b970bae44 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Mon, 12 Jun 2017 00:59:08 +0200 Subject: VDR 2.3.6 style Makefile --- Makefile | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b07b767..64ebe01 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,14 @@ # PLUGIN = eepg +# Output control +ifdef VERBOSE +Q = +else +Q = @ +endif +export Q + ### The version number of this plugin (taken from the main source file): RELEASE := $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') @@ -111,7 +119,8 @@ endif ### Implicit rules: %.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< + @echo CC $@ + $(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: @@ -131,17 +140,21 @@ I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLU I18Npot = $(PODIR)/$(PLUGIN).pot %.mo: %.po - msgfmt -c -o $@ $< + @echo MO $@ + $(Q)msgfmt -c -o $@ $< $(I18Npot): $(wildcard *.c) - xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` + @echo GT $@ + $(Q)xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='' -o $@ `ls $^` %.po: $(I18Npot) - msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< + @echo PO $@ + $(Q)msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $< @touch $@ $(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo - install -D -m644 $< $@ + @echo IN $@ + $(Q)install -D -m644 $< $@ .PHONY: i18n i18n: $(I18Nmo) $(I18Npot) @@ -151,7 +164,8 @@ install-i18n: $(I18Nmsgs) ### Targets: $(SOFILE): $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ + @echo LD $@ + $(Q)$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) -- cgit v1.2.3 From 7e30f7b7c80d41883ec9b0187dc9c47b6765a4d1 Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sat, 11 Aug 2018 14:27:23 +0200 Subject: fix wrong lock sequence thanks to Matthias Feistel --- README | 1 + eepg.c | 11 +++++++---- eit2.c | 6 ++---- eit2.h | 3 ++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/README b/README index c043a25..4e9dd9d 100644 --- a/README +++ b/README @@ -127,6 +127,7 @@ Thanks to mrgandalf, and the others who helped map NA eit. Thanks to VDR User for testing and providing makequiv.sh script for S72.7W channels. Thanks to cheesemonster for providing a patch to fix multipe device problems Thanks to Tony Houghton and Stuart Morris for testing Freeview HD +Thanks to Matthias Feistel for the wrong lock sequence fix We wish to thank all authors for the great work they have been doing, decoding this EEPG data; this plugin tries to combine the best of all worlds. diff --git a/eepg.c b/eepg.c index afab8bc..b829d10 100644 --- a/eepg.c +++ b/eepg.c @@ -2918,6 +2918,7 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const //0x39 Viasat, 0x0300 Dish Network EEPG, 0x0441 Bell ExpressVU EEPG LogD(4, prep("Pid: 0x%02x Tid: %d Length: %d"), Pid, Tid, Length); #if APIVERSNUM >= 20300 + LOCK_CHANNELS_WRITE; LOCK_SCHEDULES_WRITE; // cStateKey SchedulesStateKey; // cSchedules *Schedules = cSchedules::GetSchedulesWrite(SchedulesStateKey, 10); @@ -2926,8 +2927,8 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); #endif //Look for other satelite positions only if Dish/Bell ExpressVU for the moment hardcoded pid check - if(Schedules) - SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Format, Pid == EIT_PID); + if(Channels && Schedules) + SI::cEIT2 EIT(Channels, Schedules, Source(), Tid, Data, Format, Pid == EIT_PID); #if APIVERSNUM < 20300 else//cEIT EIT (Schedules, Source (), Tid, Data); @@ -2936,10 +2937,12 @@ void cFilterEEPG::ProccessContinuous(u_short Pid, u_char Tid, int Length, const // that we can set the running status and 'seen' timestamp (well, actually // with a read lock we shouldn't be doing that, but it's only integers that // get changed, so it should be ok) + cChannelsLock ChannelsLock; + cChannels *Channels = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); cSchedulesLock SchedulesLock; cSchedules *Schedules = (cSchedules*)(cSchedules::Schedules(SchedulesLock)); - if(Schedules) - SI::cEIT2 EIT(Schedules, Source(), Tid, Data, Format, Pid == EIT_PID, true); + if(Channels && Schedules) + SI::cEIT2 EIT(Channels, Schedules, Source(), Tid, Data, Format, Pid == EIT_PID, true); //cEIT EIT (Schedules, Source (), Tid, Data, true); } diff --git a/eit2.c b/eit2.c index 63f6187..a8b0561 100644 --- a/eit2.c +++ b/eit2.c @@ -118,8 +118,6 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, cComponents *Components = NULL; #if APIVERSNUM >= 20300 - LOCK_CHANNELS_WRITE; - if (!Channels) return; cChannel *channel = Channels->GetByChannelID(channelId); #else cChannel *channel = Channels.GetByChannelID(channelId); @@ -461,9 +459,10 @@ void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source, channel->SetLinkChannels (LinkChannels); } -cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, EFormat format, bool isEITPid, bool OnlyRunningStatus) +cEIT2::cEIT2 (cChannels* Channels, cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, EFormat format, bool isEITPid, bool OnlyRunningStatus) : SI::EIT (Data, false) , OnlyRunningStatus(OnlyRunningStatus) +, Channels(Channels) , Schedules(Schedules) , Format(format) { @@ -575,7 +574,6 @@ cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Dat // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running { #if APIVERSNUM >= 20300 - LOCK_CHANNELS_WRITE; cChannel *chan = Channels->GetByChannelID(channel->GetChannelID()); #else cChannel *chan = Channels.GetByChannelID(channel->GetChannelID()); diff --git a/eit2.h b/eit2.h index b9e6298..65d4b82 100644 --- a/eit2.h +++ b/eit2.h @@ -51,7 +51,7 @@ extern bool SystemCharacterTableIsSingleByte;*/ class cEIT2:public SI::EIT { public: - cEIT2(cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, + cEIT2(cChannels* Channels, cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, EFormat format, bool isEITPid = false, bool OnlyRunningStatus = false); cEIT2 (cSchedule * Schedule, EFormat format); @@ -71,6 +71,7 @@ private: bool OnlyRunningStatus; time_t SegmentStart; time_t SegmentEnd; + cChannels* Channels; cSchedules* Schedules; EFormat Format; const cChannel* channel; -- cgit v1.2.3 From ca0c9dda448ffe0cd71e85cbc5b1f9c10203e1ad Mon Sep 17 00:00:00 2001 From: Dimitar Petrovski Date: Sat, 11 Aug 2018 14:30:48 +0200 Subject: silence warnings --- eepg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eepg.c b/eepg.c index b829d10..b319a46 100644 --- a/eepg.c +++ b/eepg.c @@ -2645,7 +2645,7 @@ void cFilterEEPG::LoadIntoSchedule (void) } index++; - if ((StartTime + T->Duration) < too_old) { + if ((StartTime + (int)T->Duration) < too_old) { LogD(3, prep("Skipping old event '%s', start time:%s"), T->Text, ctime (&StartTime)); OldEvents++; continue; @@ -2699,7 +2699,7 @@ void cFilterEEPG::LoadIntoSchedule (void) // esyslog("EEPG Error: lost sync at title %d, summary %d.",i,j); } else if (j == (remembersummary - 1) || SummIndex !=-1) { //the last summary to be checked has failed also //esyslog ("EEPG Error: could not find summary for summary-available Title %d.", i); - if ((T->StartTime + T->Duration) < too_old) { + if ((T->StartTime + T->Duration) < (uint)too_old) { LogD(3, prep("Skipping old event '%s' without summary, start time:%s"), T->Text, ctime ((time_t*)&T->StartTime)); OldEvents++; } else { -- cgit v1.2.3