summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Lehtimäki <matti.lehtimaki@gmail.com>2012-05-04 00:20:23 +0300
committerMatti Lehtimäki <matti.lehtimaki@gmail.com>2012-05-04 00:20:23 +0300
commit8877487555503d3615a4b17f9a9809fec2e28944 (patch)
tree42b7ecf8ce45923217d9403475d9c83e6ed4bd7d
parent5fb133a99f38083a421dc0a33acb58a1fa674876 (diff)
downloadvdr-plugin-epgfixer-8877487555503d3615a4b17f9a9809fec2e28944.tar.gz
vdr-plugin-epgfixer-8877487555503d3615a4b17f9a9809fec2e28944.tar.bz2
Fix last commit.
-rw-r--r--HISTORY4
-rw-r--r--Makefile2
-rw-r--r--README21
-rw-r--r--charset.c2
-rw-r--r--charset.h2
-rw-r--r--config.c2
-rw-r--r--config.h1
-rw-r--r--epgfixer.c19
-rw-r--r--epgfixer/charset.conf2
-rw-r--r--epghandler.c163
-rw-r--r--epghandler.h4
-rw-r--r--po/fi_FI.po18
-rw-r--r--regexp.c299
-rw-r--r--regexp.h55
-rw-r--r--setup_menu.c287
15 files changed, 407 insertions, 474 deletions
diff --git a/HISTORY b/HISTORY
index fa2e55e..68ad7a6 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,5 +1,9 @@
VDR Plugin 'epgfixer' Revision History
--------------------------------------
+2012-xx-xx: Version 0.0.6
+
+- Support for character set conversion for selected channels.
+- Support for stripping HTML entities.
2012-04-13: Version 0.0.5
diff --git a/Makefile b/Makefile
index 4bdbdf6..868b76d 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o config.o epghandler.o setup_menu.o regexp.o
+OBJS = $(PLUGIN).o charset.o config.o epghandler.o regexp.o setup_menu.o tools.o
ifeq ($(REGEXLIB), pcre)
LIBS += $(shell pcre-config --libs-posix)
diff --git a/README b/README
index d7e8c11..9521d28 100644
--- a/README
+++ b/README
@@ -25,16 +25,17 @@ Requirements:
Usage:
+General syntax of configuration files:
+- Lines beginning with # are regarded as comments.
+- Lines beginning with ! are regarded as disabled lines.
+- Channel_list is optional comma separated list of channels for which the line
+ is used. If no list of channels is given the line is used for all channels.
+- Channel_list can contain either channel IDs (e.g. S19.2E-1-1089-12003-0) or
+ numbers but not both.
+
All regular expressions are placed to VDRPLUGINCONFDIR/epgfixer/regexp.conf.
Syntax of regexp.conf line is "Channel_list:Parsed_epg_field=Regexp" with:
-- Lines beginning with # are regarded as comments.
-- Lines beginning with ! are regarded as disabled regular expressions.
-- Channel_list is optional comma separated list of channels for which the
- regular expression is used. If no list of channels is given the regular
- expression is used for all channels.
-- Channel_list for a regular expression can contain either channel IDs
- (e.g. S19.2E-1-1089-12003-0) or numbers but not both.
- Parsed_epg_field is the EPG field for which the regular expression is applied
with available field names title, shorttext and description.
- Regular expressions use named backreferences with either title, shorttext,
@@ -44,6 +45,12 @@ Syntax of regexp.conf line is "Channel_list:Parsed_epg_field=Regexp" with:
content of the target EPG field, respectively.
- Several regular expressions may be applied to same field.
+All character set conversions are placed to
+VDRPLUGINCONFDIR/epgfixer/charset.conf.
+
+Syntax of charset.conf line is "Channel_list=OriginalCharSet" with:
+- OriginalCharSet is a name of a character set (e.g. iso8859-1).
+
Examples of regexp.conf:
# Example of disabled regexp:
diff --git a/charset.c b/charset.c
index 0e77ed4..889fb8c 100644
--- a/charset.c
+++ b/charset.c
@@ -1,5 +1,5 @@
/*
- * regexp.c: Regular expression list
+ * charset.c: Character set list item
*
* See the README file for copyright information and how to reach the author.
*
diff --git a/charset.h b/charset.h
index fd021df..9a3cf2b 100644
--- a/charset.h
+++ b/charset.h
@@ -1,5 +1,5 @@
/*
- * regexp.h: Regular expression list
+ * charset.h: Character set list item
*
* See the README file for copyright information and how to reach the author.
*
diff --git a/config.c b/config.c
index 2be9d26..e746c24 100644
--- a/config.c
+++ b/config.c
@@ -22,6 +22,7 @@ cEpgfixerSetup::cEpgfixerSetup()
equalshorttextanddescription = 0;
nobackticks = 0;
components = 0;
+ striphtml = 0;
}
cString cEpgfixerSetup::m_ProcessedArgs;
@@ -59,6 +60,7 @@ bool cEpgfixerSetup::SetupParse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "PreventEqualShortTextAndDescription")) equalshorttextanddescription = atoi(Value);
else if (!strcasecmp(Name, "ReplaceBackticksWithSingleQuotes")) nobackticks = atoi(Value);
else if (!strcasecmp(Name, "FixStreamComponentDescriptions")) components = atoi(Value);
+ else if (!strcasecmp(Name, "StripHTMLentities")) striphtml = atoi(Value);
else
return false;
diff --git a/config.h b/config.h
index d9efe76..283237f 100644
--- a/config.h
+++ b/config.h
@@ -22,6 +22,7 @@ public:
int equalshorttextanddescription;
int nobackticks;
int components;
+ int striphtml;
cEpgfixerSetup();
bool SetupParse(const char *Name, const char *Value);
diff --git a/epgfixer.c b/epgfixer.c
index 9d3dc80..a9e3720 100644
--- a/epgfixer.c
+++ b/epgfixer.c
@@ -7,6 +7,7 @@
#include <vdr/plugin.h>
#include <vdr/i18n.h>
+#include "charset.h"
#include "regexp.h"
#include "setup_menu.h"
#include "epghandler.h"
@@ -71,8 +72,10 @@ bool cPluginEpgfixer::ProcessArgs(int argc, char *argv[])
bool cPluginEpgfixer::Initialize(void)
{
// Initialize any background activities the plugin shall perform.
- EpgfixerRegexps.SetRegexpConfigFile(AddDirectory(cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), "regexp.conf")); // allowed only via main thread!);
- EpgfixerRegexps.ReloadRegexps();
+ EpgfixerRegexps.SetConfigFile(AddDirectory(cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), "regexp.conf")); // allowed only via main thread!);
+ EpgfixerRegexps.ReloadConfigFile();
+ EpgfixerCharSets.SetConfigFile(AddDirectory(cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), "charset.conf")); // allowed only via main thread!);
+ EpgfixerCharSets.ReloadConfigFile();
return new cEpgfixerEpgHandler();
}
@@ -144,6 +147,8 @@ const char **cPluginEpgfixer::SVDRPHelpPages(void)
static const char *HelpPages[] = {
"RLRE\n"
" Reload regexp.conf.",
+ "RLCH\n"
+ " Reload charset.conf.",
NULL
};
return HelpPages;
@@ -152,13 +157,21 @@ const char **cPluginEpgfixer::SVDRPHelpPages(void)
cString cPluginEpgfixer::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
{
if (strcasecmp(Command, "RLRE") == 0) {
- if (EpgfixerRegexps.ReloadRegexps()) {
+ if (EpgfixerRegexps.ReloadConfigFile()) {
return cString("Reloaded regexp.conf");
} else {
ReplyCode = 554; // Requested action failed
return cString("Reloading regexp.conf failed");
}
}
+ else if (strcasecmp(Command, "RLCH") == 0) {
+ if (EpgfixerCharSets.ReloadConfigFile()) {
+ return cString("Reloaded charset.conf");
+ } else {
+ ReplyCode = 554; // Requested action failed
+ return cString("Reloading charset.conf failed");
+ }
+ }
return NULL;
}
diff --git a/epgfixer/charset.conf b/epgfixer/charset.conf
index 98cd247..bd84ae6 100644
--- a/epgfixer/charset.conf
+++ b/epgfixer/charset.conf
@@ -1,3 +1,3 @@
-#C onvert character set of channels 1, 2 and 3 from iso8859-1 to character set
+# Convert character set of channels 1, 2 and 3 from iso8859-1 to character set
# used by VDR
1,2,3=iso8859-1
diff --git a/epghandler.c b/epghandler.c
index ab837a0..c9db409 100644
--- a/epghandler.c
+++ b/epghandler.c
@@ -7,15 +7,11 @@
#include "epghandler.h"
#include "config.h"
+#include "charset.h"
+#include "regexp.h"
#include <vdr/tools.h>
#include <string.h>
-#ifdef HAVE_PCREPOSIX
-#include <pcre.h>
-#endif
-
-typedef enum { ATITLE,PTITLE,TITLE,ASHORTTEXT,PSHORTTEXT,SHORTTEXT,ADESCRIPTION,PDESCRIPTION,DESCRIPTION,RATING } backrefs;
-const char *strBackrefs[] = { "atitle","ptitle","title","ashorttext","pshorttext","shorttext","adescription","pdescription","description","rating" };
void cEpgfixerEpgHandler::FixOriginalEpgBugs(cEvent *event)
{
@@ -237,135 +233,66 @@ void cEpgfixerEpgHandler::FixOriginalEpgBugs(cEvent *event)
}
}
-bool cEpgfixerEpgHandler::ApplyRegexp(cRegexp *regexp, cEvent *Event, const char *input)
+bool cEpgfixerEpgHandler::FixBugs(cEvent *Event)
{
- bool active = true;
- if (regexp->NumChannels() > 0) {
- bool found = false;
- int i = 0;
- while (i < regexp->NumChannels() && !found) {
- if (Channels.GetByChannelID(Event->ChannelID())->Number() == regexp->GetChannelNum(i))
- found = true;
- if (regexp->GetChannelID(i) && strcmp(*(Event->ChannelID().ToString()), regexp->GetChannelID(i)) == 0)
- found = true;
- i++;
- }
- if (!found)
- active = false;
- }
- if (active && regexp->Enabled() && regexp->GetRe()) {
- const char *string;
- int ovector[20];
- int rc;
- rc = pcre_exec(regexp->GetRe(), regexp->GetSd(), input, strlen(input), 0, 0, ovector, 20);
- if (rc > 0) {
- int i = 0;
- while (i < 10) {
- if (pcre_get_named_substring(regexp->GetRe(), input, ovector, rc, strBackrefs[i], &string) != PCRE_ERROR_NOSUBSTRING) {
- char *tempstring = 0;
- switch (i) {
- case TITLE:
- Event->SetTitle(string);
- break;
- case ATITLE:
- tempstring = (char *)malloc(strlen(Event->Title())+strlen(string)+1);
- strcpy(tempstring, Event->Title());
- strcat(tempstring, string);
- Event->SetTitle(tempstring);
- break;
- case PTITLE:
- tempstring = (char *)malloc(strlen(Event->Title())+strlen(string)+1);
- strcpy(tempstring, string);
- strcat(tempstring, Event->Title());
- Event->SetTitle(tempstring);
- break;
- case SHORTTEXT:
- Event->SetShortText(string);
- break;
- case ASHORTTEXT:
- tempstring = (char *)malloc(strlen(Event->ShortText())+strlen(string)+1);
- strcpy(tempstring, Event->ShortText());
- strcat(tempstring, string);
- Event->SetShortText(tempstring);
- break;
- case PSHORTTEXT:
- tempstring = (char *)malloc(strlen(Event->ShortText())+strlen(string)+1);
- strcpy(tempstring, string);
- strcat(tempstring, Event->ShortText());
- Event->SetShortText(tempstring);
- break;
- case DESCRIPTION:
- Event->SetDescription(string);
- break;
- case ADESCRIPTION:
- tempstring = (char *)malloc(strlen(Event->Description())+strlen(string)+1);
- strcpy(tempstring, Event->Description());
- strcat(tempstring, string);
- Event->SetDescription(tempstring);
- break;
- case PDESCRIPTION:
- tempstring = (char *)malloc(strlen(Event->Description())+strlen(string)+1);
- strcpy(tempstring, string);
- strcat(tempstring, Event->Description());
- Event->SetDescription(tempstring);
- break;
- case RATING:
- Event->SetParentalRating(atoi(string));
- break;
- default:
- break;
- }
- pcre_free_substring(string);
- free(tempstring);
- }
- i++;
+ int res = false;
+ cRegexp *regex = (cRegexp *)EpgfixerRegexps.First();
+ while (regex) {
+ if (regex->Enabled()) {
+ int ret = regex->Apply(Event);
+ if (ret && !res)
+ res = true;
}
- return true;
+ regex = (cRegexp *)regex->Next();
}
- }
- return false;
+ return res;
}
-bool cEpgfixerEpgHandler::FixBugs(cEvent *Event)
+bool cEpgfixerEpgHandler::FixCharSets(cEvent *Event)
{
int res = false;
- char *tmpstring;
- cRegexp *regex = (cRegexp *)EpgfixerRegexps.regexps->First();
- while (regex) {
- if (regex->Enabled()) {
- switch (regex->GetSource()) {
- case REGEXP_TITLE:
- tmpstring = strdup(Event->Title());
- break;
- case REGEXP_SHORTTEXT:
- if (Event->ShortText())
- tmpstring = strdup(Event->ShortText());
- else
- tmpstring = strdup("");
- break;
- case REGEXP_DESCRIPTION:
- if (Event->Description())
- tmpstring = strdup(Event->Description());
- else
- tmpstring = strdup("");
- break;
- default:
- tmpstring = strdup("");
- break;
- }
- int ret = ApplyRegexp(regex, Event, tmpstring);
+ cCharSet *charset = (cCharSet *)EpgfixerCharSets.First();
+ while (charset) {
+ if (charset->Enabled()) {
+ int ret = charset->ConvertCharSet(Event);
if (ret && !res)
res = true;
- free(tmpstring);
}
- regex = (cRegexp *)regex->Next();
+ charset = (cCharSet *)charset->Next();
}
return res;
}
+void cEpgfixerEpgHandler::StripHTML(cEvent *Event)
+{
+ if (EpgfixerSetup.striphtml) {
+ char *tmpstring;
+ if (Event->Title())
+ tmpstring = strdup(Event->Title());
+ else
+ tmpstring = strdup("");
+ Event->SetTitle(striphtml(tmpstring));
+ free(tmpstring);
+ if (Event->ShortText())
+ tmpstring = strdup(Event->ShortText());
+ else
+ tmpstring = strdup("");
+ Event->SetShortText(striphtml(tmpstring));
+ free(tmpstring);
+ if (Event->Description())
+ tmpstring = strdup(Event->Description());
+ else
+ tmpstring = strdup("");
+ Event->SetDescription(striphtml(tmpstring));
+ free(tmpstring);
+ }
+}
+
bool cEpgfixerEpgHandler::FixEpgBugs(cEvent *Event)
{
FixOriginalEpgBugs(Event);
+ FixCharSets(Event);
+ StripHTML(Event);
FixBugs(Event);
return false;
}
diff --git a/epghandler.h b/epghandler.h
index 8971f20..cc38378 100644
--- a/epghandler.h
+++ b/epghandler.h
@@ -9,14 +9,14 @@
#define __EPGFIXER_EPGHANDLER_H
#include <vdr/epg.h>
-#include "regexp.h"
class cEpgfixerEpgHandler : public cEpgHandler
{
private:
- bool ApplyRegexp(cRegexp *regexp, cEvent *Event, const char *input);
void FixOriginalEpgBugs(cEvent *event);
+ bool FixCharSets(cEvent *Event);
bool FixBugs(cEvent *Event);
+ void StripHTML(cEvent *Event);
public:
cEpgfixerEpgHandler(void) {};
virtual bool FixEpgBugs(cEvent *Event);
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 963dd15..770b25c 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-epgfixer 0.0.3\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2012-03-25 14:46+0300\n"
-"PO-Revision-Date: 2012-03-25 15:20+0300\n"
+"POT-Creation-Date: 2012-05-03 21:34+0300\n"
+"PO-Revision-Date: 2012-05-03 22:20+0300\n"
"Last-Translator: Matti Lehtimäki <matti.lehtimaki@gmail.com>\n"
"Language-Team: Finnish <vdr@linuxtv.org>\n"
"MIME-Version: 1.0\n"
@@ -31,6 +31,12 @@ msgstr "Poista"
msgid "Cancel"
msgstr "Peru"
+msgid "Regular expressions"
+msgstr "Säännölliset lausekkeet"
+
+msgid "Character set conversions"
+msgstr "Merkistömuunnokset"
+
msgid "Remove quotes from ShortText"
msgstr "Poista lainaukset lyhyestä kuvauksesta"
@@ -58,11 +64,11 @@ msgstr "Korvaa gravis heittomerkillä"
msgid "Fix stream component descriptions"
msgstr "Korjaa lähetekomponenttien kuvaukset"
-msgid "Regular expressions"
-msgstr "Säännölliset lausekkeet"
+msgid "Strip HTML entities"
+msgstr "Poista HTML-merkit"
-msgid "Reload regexp.conf"
-msgstr "Lataa uudelleen regexp.conf"
+msgid "Reload files"
+msgstr "Lataa uudelleen tiedostot"
msgid "Clear EPG data"
msgstr "Tyhjennä EPG tiedot"
diff --git a/regexp.c b/regexp.c
index 0b64ca9..e20de16 100644
--- a/regexp.c
+++ b/regexp.c
@@ -1,5 +1,5 @@
/*
- * regexp.c: Regular expression list
+ * regexp.c: Regular expression list item
*
* See the README file for copyright information and how to reach the author.
*
@@ -9,78 +9,74 @@
#include <unistd.h>
/* Global instance */
-cEpgfixerRegexps EpgfixerRegexps;
+cEpgfixerList<cRegexp> EpgfixerRegexps;
const char *strSources[] = { "title","shorttext","description","undefined" };
+typedef enum { ATITLE,PTITLE,TITLE,ASHORTTEXT,PSHORTTEXT,SHORTTEXT,ADESCRIPTION,PDESCRIPTION,DESCRIPTION,RATING } backrefs;
+const char *strBackrefs[] = { "atitle","ptitle","title","ashorttext","pshorttext","shorttext","adescription","pdescription","description","rating" };
+
cRegexp::cRegexp()
{
- enabled = false;
regexp = NULL;
- string = NULL;
source = REGEXP_UNDEFINED;
re = NULL;
sd = NULL;
- numchannels = 0;
- channels_num = NULL;
- channels_str = NULL;
}
cRegexp::~cRegexp(void)
{
Free();
-}
-
-void cRegexp::Free(void)
-{
- free(channels_num);
- if (channels_str) {
- int i = 0;
- while (i < numchannels) {
- free(channels_str[i]);
- i++;
- }
- }
- free(channels_str);
free(regexp);
- free(string);
- channels_num = NULL;
- channels_str = NULL;
regexp = NULL;
- string = NULL;
FreeCompiled();
}
-int cRegexp::GetChannelNum(int index)
-{
- if (channels_num && index >= 0 && index < numchannels)
- return channels_num[index];
- else
- return -1;
-}
-
-const char *cRegexp::GetChannelID(int index)
+void cRegexp::Compile()
{
- if (channels_str && index >= 0 && index < numchannels)
- return channels_str[index];
- else
- return NULL;
+ FreeCompiled();
+ const char *error;
+ int erroffset;
+ re = pcre_compile(regexp, 0, &error, &erroffset, NULL);
+ if (error) {
+ esyslog("PCRE compile error: %s at offset %i", error, erroffset);
+ enabled = false;
+ }
+ else {
+ sd = pcre_study(re, 0, (const char **)&error);
+ if (error)
+ esyslog("PCRE study error: %s", error);
+ }
}
-void cRegexp::ToggleEnabled(void)
+void cRegexp::FreeCompiled()
{
- enabled = enabled ? 0 : 1;
+ if (re) {
+ pcre_free(re);
+ re = NULL;
+ }
+ if (sd) {
+#ifdef PCRE_CONFIG_JIT
+ pcre_free_study(sd);
+#else
+ pcre_free(sd);
+#endif
+ sd = NULL;
+ }
}
-void cRegexp::SetFromString(char *s, bool Enabled, bool Precompile)
+void cRegexp::SetFromString(char *s, bool Enabled)
{
Free();
- string = strdup(s);
enabled = Enabled;
- bool precompile = Precompile;
+ if (s[0] == '!')
+ string = strdup(s+1);
+ else
+ string = strdup(s);
+ bool compile = true;
if (s[0] == '!' || s[0] == '#') {
enabled = false;
- precompile = false;
+ compile = false;
}
char *p = (s[0] == '#') ? s : strchr(s, '=');
if (p) {
@@ -95,31 +91,7 @@ void cRegexp::SetFromString(char *s, bool Enabled, bool Precompile)
if (f) {
*f = 0;
field = f+1;
- char *c = chanfield;
- numchannels = 0;
- while (c) {
- numchannels++;
- c = strchr(c+1, ',');
- }
- if (numchannels > 0) {
- c = chanfield;
- // Use channel numbers
- if (atoi(chanfield))
- channels_num = (int *)malloc(sizeof(int)*numchannels);
- else// use channel IDs
- channels_str = (char **)malloc(sizeof(char *)*numchannels);
- int i = 0;
- char *pc = strtok(c, ",");
- while (i < numchannels) {
- // Use channel numbers
- if (atoi(chanfield))
- channels_num[i] = atoi(pc);
- else// use channel IDs
- channels_str[i] = strdup(pc);
- pc = strtok(NULL, ",");
- i++;
- }
- }
+ numchannels = loadChannelsFromString(chanfield, &channels_num, &channels_str);
}
if (strcmp(field, "title") == 0)
source = REGEXP_TITLE;
@@ -127,93 +99,136 @@ void cRegexp::SetFromString(char *s, bool Enabled, bool Precompile)
source = REGEXP_SHORTTEXT;
if (strcmp(field, "description") == 0)
source = REGEXP_DESCRIPTION;
- if (precompile)
+ if (compile)
Compile();
}
}
}
-void cRegexp::FreeCompiled()
+bool cRegexp::Apply(cEvent *Event)
{
- if (re) {
- pcre_free(re);
- re = NULL;
+ bool active = true;
+ if (numchannels > 0) {
+ bool found = false;
+ int i = 0;
+ while (i < numchannels && !found) {
+ if (Channels.GetByChannelID(Event->ChannelID())->Number() == GetChannelNum(i))
+ found = true;
+ if (GetChannelID(i) && strcmp(*(Event->ChannelID().ToString()), GetChannelID(i)) == 0)
+ found = true;
+ i++;
+ }
+ if (!found)
+ active = false;
}
- if (sd) {
-#ifdef PCRE_CONFIG_JIT
- pcre_free_study(sd);
-#else
- pcre_free(sd);
-#endif
- sd = NULL;
+ if (active && enabled && re) {
+ char *tmpstring;
+ switch (source) {
+ case REGEXP_TITLE:
+ tmpstring = strdup(Event->Title());
+ break;
+ case REGEXP_SHORTTEXT:
+ if (Event->ShortText())
+ tmpstring = strdup(Event->ShortText());
+ else
+ tmpstring = strdup("");
+ break;
+ case REGEXP_DESCRIPTION:
+ if (Event->Description())
+ tmpstring = strdup(Event->Description());
+ else
+ tmpstring = strdup("");
+ break;
+ default:
+ tmpstring = strdup("");
+ break;
+ }
+ const char *string;
+ int ovector[20];
+ int rc;
+ rc = pcre_exec(re, sd, tmpstring, strlen(tmpstring), 0, 0, ovector, 20);
+ if (rc > 0) {
+ int i = 0;
+ while (i < 10) {
+ if (pcre_get_named_substring(re, tmpstring, ovector, rc, strBackrefs[i], &string) != PCRE_ERROR_NOSUBSTRING) {
+ char *tempstring = 0;
+ switch (i) {
+ case TITLE:
+ Event->SetTitle(string);
+ break;
+ case ATITLE:
+ tempstring = (char *)malloc(strlen(Event->Title())+strlen(string)+1);
+ strcpy(tempstring, Event->Title());
+ strcat(tempstring, string);
+ Event->SetTitle(tempstring);
+ break;
+ case PTITLE:
+ tempstring = (char *)malloc(strlen(Event->Title())+strlen(string)+1);
+ strcpy(tempstring, string);
+ strcat(tempstring, Event->Title());
+ Event->SetTitle(tempstring);
+ break;
+ case SHORTTEXT:
+ Event->SetShortText(string);
+ break;
+ case ASHORTTEXT:
+ tempstring = (char *)malloc(strlen(Event->ShortText())+strlen(string)+1);
+ strcpy(tempstring, Event->ShortText());
+ strcat(tempstring, string);
+ Event->SetShortText(tempstring);
+ break;
+ case PSHORTTEXT:
+ tempstring = (char *)malloc(strlen(Event->ShortText())+strlen(string)+1);
+ strcpy(tempstring, string);
+ strcat(tempstring, Event->ShortText());
+ Event->SetShortText(tempstring);
+ break;
+ case DESCRIPTION:
+ Event->SetDescription(string);
+ break;
+ case ADESCRIPTION:
+ tempstring = (char *)malloc(strlen(Event->Description())+strlen(string)+1);
+ strcpy(tempstring, Event->Description());
+ strcat(tempstring, string);
+ Event->SetDescription(tempstring);
+ break;
+ case PDESCRIPTION:
+ tempstring = (char *)malloc(strlen(Event->Description())+strlen(string)+1);
+ strcpy(tempstring, string);
+ strcat(tempstring, Event->Description());
+ Event->SetDescription(tempstring);
+ break;
+ case RATING:
+ Event->SetParentalRating(atoi(string));
+ break;
+ default:
+ break;
+ }
+ pcre_free_substring(string);
+ free(tempstring);
+ }
+ i++;
+ }
+ free(tmpstring);
+ return true;
+ }
+ free(tmpstring);
}
+ return false;
}
-void cRegexp::Compile()
+void cRegexp::PrintConfigLineToFile(FILE *f)
{
- FreeCompiled();
- const char *error;
- int erroffset;
- re = pcre_compile(regexp, 0, &error, &erroffset, NULL);
- if (error) {
- esyslog("PCRE compile error: %s at offset %i", error, erroffset);
- enabled = false;
- }
- else {
- sd = pcre_study(re, 0, (const char **)&error);
- if (error)
- esyslog("PCRE study error: %s", error);
+ if (f) {
+ if (source == REGEXP_UNDEFINED)
+ fprintf(f, "%s\n", string);
+ else
+ fprintf(f, "%s%s\n", enabled ? "" : "!", string);
}
}
-cEpgfixerRegexps::cEpgfixerRegexps()
-{
- fileName = NULL;
- regexps = new cRegexpList();
-}
-
-cEpgfixerRegexps::~cEpgfixerRegexps()
-{
- free(fileName);
- delete regexps;
-}
-
-void cEpgfixerRegexps::SetRegexpConfigFile(const char *FileName)
-{
- fileName = strdup(FileName);
-}
-
-const char *cEpgfixerRegexps::RegexpConfigFile()
-{
- return fileName;
-}
-
-bool cEpgfixerRegexps::ReloadRegexps(bool AllowComments, bool Precompile)
-{
- regexps->Clear();
- return LoadRegexps(fileName, AllowComments, Precompile);
-}
-
-bool cEpgfixerRegexps::LoadRegexps(const char *FileName, bool AllowComments, bool Precompile)
+void cRegexp::ToggleEnabled(void)
{
- bool result = false;
- if (FileName && access(FileName, F_OK) == 0) {
- FILE *f = fopen(FileName, "r");
- if (f) {
- char *s;
- cReadLine ReadLine;
- while ((s = ReadLine.Read(f)) != NULL) {
- if (!isempty(s)) {
- regexps->Add(new cRegexp());
- regexps->Last()->SetFromString(s, true, Precompile);
- }
- }
- fclose(f);
- }
- else {
- LOG_ERROR_STR(FileName);
- result = false;
- }
- }
- return result;
+ if (source != REGEXP_UNDEFINED)
+ enabled = enabled ? 0 : 1;
}
diff --git a/regexp.h b/regexp.h
index 57d69ba..3016c4c 100644
--- a/regexp.h
+++ b/regexp.h
@@ -1,5 +1,5 @@
/*
- * regexp.h: Regular expression list
+ * regexp.h: Regular expression list item
*
* See the README file for copyright information and how to reach the author.
*
@@ -8,68 +8,37 @@
#ifndef _REGEXP_H_
#define _REGEXP_H_
+#include "tools.h"
+#include <vdr/epg.h>
#include <vdr/tools.h>
+#include <stdio.h>
#ifdef HAVE_PCREPOSIX
#include <pcre.h>
#endif
typedef enum { REGEXP_TITLE,REGEXP_SHORTTEXT,REGEXP_DESCRIPTION,REGEXP_UNDEFINED } sources;
-extern const char *strSources[];
-class cRegexp : public cListObject
+class cRegexp : public cListItem
{
private:
- bool enabled;
char *regexp;
- char *string;
- int *channels_num;
- char **channels_str;
- int numchannels;
int source;
pcre *re;
pcre_extra *sd;
- void Free();
+ void Compile();
+ void FreeCompiled();
public:
cRegexp();
- cRegexp(int Source, const char *Regex, bool Enabled, bool Precompile);
virtual ~cRegexp();
- void SetFromString(char *string, bool Enabled, bool Precompile);
- const char *GetString() { return string; }
- void Compile();
- void FreeCompiled();
- bool Enabled(void) { return enabled; }
+ bool Apply(cEvent *Event);
+ void SetFromString(char *string, bool Enabled);
+ int GetSource() { return source; };
void ToggleEnabled(void);
- int NumChannels() { return numchannels; }
- int GetChannelNum(int index);
- const char *GetChannelID(int index);
- int GetSource(void) { return source; }
- pcre *GetRe(void) { return re; }
- pcre_extra *GetSd(void) { return sd; }
-};
-
-class cRegexpList : public cList<cRegexp>
-{
-public:
- void Clear(void) { cList<cRegexp>::Clear(); }
- cRegexpList(void) {}
-};
-
-class cEpgfixerRegexps
-{
-private:
- bool LoadRegexps(const char *FileName = NULL, bool AllowComments = true, bool Precompile = true);
- char *fileName;
-public:
- cRegexpList *regexps;
- cEpgfixerRegexps();
- ~cEpgfixerRegexps();
- void SetRegexpConfigFile(const char *FileName);
- const char *RegexpConfigFile();
- bool ReloadRegexps(bool AllowComments = true, bool Precompile = true);
+ virtual void PrintConfigLineToFile(FILE *f);
};
// Global instance
-extern cEpgfixerRegexps EpgfixerRegexps;
+extern cEpgfixerList<cRegexp> EpgfixerRegexps;
#endif //_REGEXP_H_
diff --git a/setup_menu.c b/setup_menu.c
index eb8032d..a90030d 100644
--- a/setup_menu.c
+++ b/setup_menu.c
@@ -8,164 +8,147 @@
#include "setup_menu.h"
#include <vdr/config.h>
#include <vdr/i18n.h>
+#include "tools.h"
+#include "charset.h"
#include "regexp.h"
-//--- cMenuSetupRegexp ------------------------------------------------------
+//--- cMenuSetupConfigEditor ------------------------------------------------------
#define MAXREGEXPLENGTH 512
const char *RegexpChars =
- " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=.,*%$^<>~:;\\/?!()[]{}#";
+ " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789%~\\/?!()[]{}<>$^*.,:;-=#";
-class cMenuSetupRegexp : public cMenuSetupPage
+template<class T> class cMenuSetupConfigEditor : public cMenuSetupPage
{
private:
+ cEpgfixerList<T> *list;
const char *fileName;
char **lines;
char **numlines;
- void LoadRegexpArray();
- void FreeRegexpArray();
- void Save();
+ virtual void LoadListToArray(void)
+ {
+ lines = (char **)malloc(sizeof(char *)*(list->Count()));
+ int i = 0;
+ T *item = (T *)list->First();
+ while (item) {
+ lines[i] = (char *)malloc(sizeof(char)*MAXREGEXPLENGTH);
+ snprintf(lines[i], MAXREGEXPLENGTH, "%s", item->GetString());
+ item = (T *)item->Next();
+ i++;
+ }
+ }
+ void FreeArray()
+ {
+ int i = 0;
+ while (i < list->Count()) {
+ free(lines[i]);
+ i++;
+ }
+ free(lines);
+ }
+ void Save()
+ {
+ // Store regular expressions to config file
+ if (fileName && access(fileName, F_OK) == 0) {
+ FILE *f = fopen(fileName, "w");
+ if (f) {
+ T *item = (T *)list->First();
+ while (item) {
+ item->PrintConfigLineToFile(f);
+ item = (T *)item->Next();
+ }
+ fclose(f);
+ }
+ }
+ }
protected:
- virtual void Store(void);
- void Set(void);
+ virtual void Store(void)
+ {
+ // Store regular expressions back to list
+ int i = 0;
+ T *item = (T *)list->First();
+ while (i < list->Count()) {
+ item->SetFromString(lines[i], item->Enabled());
+ item = (T *)item->Next();
+ i++;
+ }
+ }
+ void Set(void)
+ {
+ Clear();
+ int i = 0;
+ T *item = (T *)list->First();
+ while (i < list->Count()) {
+ Add(new cMenuEditStrItem(item->Enabled() ? "+" : "-", lines[i], MAXREGEXPLENGTH, RegexpChars));
+ item = (T *)item->Next();
+ i++;
+ }
+ SetHelp(tr("Toggle state"), tr("Add"), tr("Delete"), tr("Cancel"));
+ Display();
+ }
public:
- cMenuSetupRegexp(void);
- ~cMenuSetupRegexp(void);
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-void cMenuSetupRegexp::LoadRegexpArray()
-{
- lines = (char **)malloc(sizeof(char *)*(EpgfixerRegexps.regexps->Count()));
- int i = 0;
- cRegexp *regex = (cRegexp *)EpgfixerRegexps.regexps->First();
- while (regex) {
- lines[i] = (char *)malloc(sizeof(char)*MAXREGEXPLENGTH);
- snprintf(lines[i], MAXREGEXPLENGTH, "%s", regex->GetString());
- regex = (cRegexp *)regex->Next();
- i++;
- }
-}
-
-cMenuSetupRegexp::cMenuSetupRegexp(void)
-{
- cEitFilter::SetDisableUntil(time(NULL) + 1000);
- SetCols(2);
- fileName = EpgfixerRegexps.RegexpConfigFile();
- LoadRegexpArray();
- Set();
-}
-
-void cMenuSetupRegexp::FreeRegexpArray(void)
-{
- int i = 0;
- while (i < EpgfixerRegexps.regexps->Count()) {
- free(lines[i]);
- i++;
- }
- free(lines);
-}
-
-cMenuSetupRegexp::~cMenuSetupRegexp(void)
-{
- FreeRegexpArray();
- cEitFilter::SetDisableUntil(time(NULL) + 5);
-}
-
-void cMenuSetupRegexp::Set(void)
-{
- Clear();
- int i = 0;
- cRegexp *regex = (cRegexp *)EpgfixerRegexps.regexps->First();
- while (i < EpgfixerRegexps.regexps->Count()) {
- Add(new cMenuEditStrItem(regex->Enabled() ? "+" : "-", lines[i], MAXREGEXPLENGTH, RegexpChars));
- regex = (cRegexp *)regex->Next();
- i++;
- }
- SetHelp(tr("Toggle state"), tr("Add"), tr("Delete"), tr("Cancel"));
- Display();
-}
-
-void cMenuSetupRegexp::Store(void)
-{
- // Store regular expressions back to list
- int i = 0;
- cRegexp *regex = (cRegexp *)EpgfixerRegexps.regexps->First();
- while (i < EpgfixerRegexps.regexps->Count()) {
- regex->SetFromString(lines[i], regex->Enabled(), true);
- regex = (cRegexp *)regex->Next();
- i++;
- }
-}
-
-void cMenuSetupRegexp::Save(void)
-{
- // Store regular expressions to regxep.conf
- if (fileName && access(fileName, F_OK) == 0) {
- FILE *f = fopen(fileName, "w");
- if (f) {
- cRegexp *regex = (cRegexp *)EpgfixerRegexps.regexps->First();
- while (regex) {
- if (regex->GetSource() == REGEXP_UNDEFINED)
- fprintf(f, "%s\n", regex->GetString());
- else
- fprintf(f, "%s%s\n", regex->Enabled() ? "" : "!", regex->GetString());
- regex = (cRegexp *)regex->Next();
- }
- fclose(f);
- }
- }
-}
-
-eOSState cMenuSetupRegexp::ProcessKey(eKeys Key)
-{
- eOSState state = cOsdMenu::ProcessKey(Key);
-
- if (state == osUnknown) {
- switch (Key) {
- case kRed:
- if (EpgfixerRegexps.regexps->Get(Current())->GetSource() != REGEXP_UNDEFINED) {
- EpgfixerRegexps.regexps->Get(Current())->ToggleEnabled();
- Set();
- Display();
- }
- state = osContinue;
- break;
- case kGreen:
- Store();
- FreeRegexpArray();
- EpgfixerRegexps.regexps->Add(new cRegexp());
- LoadRegexpArray();
- Set();
- Display();
- state = osContinue;
- break;
- case kYellow:
- Store();
- FreeRegexpArray();
- EpgfixerRegexps.regexps->Del(EpgfixerRegexps.regexps->Get(Current()),true);
- LoadRegexpArray();
- Set();
- Display();
- state = osContinue;
- break;
- case kBlue:
- EpgfixerRegexps.ReloadRegexps();
- state = osBack;
- break;
- case kOk:
- Store();
- Save();
- EpgfixerRegexps.ReloadRegexps();
- state = osBack;
- break;
- default:
- break;
+ cMenuSetupConfigEditor(cEpgfixerList<T> *l)
+ {
+ list = l;
+ cEitFilter::SetDisableUntil(time(NULL) + 1000);
+ SetCols(2);
+ fileName = list->GetConfigFile();
+ LoadListToArray();
+ Set();
+ }
+ ~cMenuSetupConfigEditor(void)
+ {
+ FreeArray();
+ cEitFilter::SetDisableUntil(time(NULL) + 5);
+ }
+ virtual eOSState ProcessKey(eKeys Key)
+ {
+ eOSState state = cOsdMenu::ProcessKey(Key);
+
+ if (state == osUnknown) {
+ switch (Key) {
+ case kRed:
+ list->Get(Current())->ToggleEnabled();
+ Set();
+ Display();
+ state = osContinue;
+ break;
+ case kGreen:
+ Store();
+ FreeArray();
+ list->Add(new T());
+ LoadListToArray();
+ Set();
+ Display();
+ state = osContinue;
+ break;
+ case kYellow:
+ Store();
+ FreeArray();
+ list->Del(list->Get(Current()),true);
+ LoadListToArray();
+ Set();
+ Display();
+ state = osContinue;
+ break;
+ case kBlue:
+ list->ReloadConfigFile();
+ state = osBack;
+ break;
+ case kOk:
+ Store();
+ Save();
+ list->ReloadConfigFile();
+ state = osBack;
+ break;
+ default:
+ break;
+ }
}
- }
- return state;
-}
+ return state;
+ }
+};
//--- cMenuSetupEpgfixer ------------------------------------------------------
@@ -178,6 +161,8 @@ cMenuSetupEpgfixer::cMenuSetupEpgfixer(void)
void cMenuSetupEpgfixer::Set(void)
{
Clear();
+ Add(new cOsdItem(tr("Regular expressions"), osUser1));
+ Add(new cOsdItem(tr("Character set conversions"), osUser2));
Add(new cMenuEditBoolItem(tr("Remove quotes from ShortText"),
&newconfig.quotedshorttext));
@@ -197,8 +182,9 @@ void cMenuSetupEpgfixer::Set(void)
&newconfig.nobackticks));
Add(new cMenuEditBoolItem(tr("Fix stream component descriptions"),
&newconfig.components));
- Add(new cOsdItem(tr("Regular expressions"), osUser1));
- SetHelp(tr("Reload regexp.conf"),NULL,NULL, tr("Clear EPG data"));
+ Add(new cMenuEditBoolItem(tr("Strip HTML entities"),
+ &newconfig.striphtml));
+ SetHelp(tr("Reload files"),NULL,NULL, tr("Clear EPG data"));
Display();
}
@@ -215,6 +201,7 @@ void cMenuSetupEpgfixer::Store(void)
SetupStore("PreventEqualShortTextAndDescription", EpgfixerSetup.equalshorttextanddescription);
SetupStore("ReplaceBackticksWithSingleQuotes", EpgfixerSetup.nobackticks);
SetupStore("FixStreamComponentDescriptions", EpgfixerSetup.components);
+ SetupStore("StripHTMLentities", EpgfixerSetup.striphtml);
Setup.Save();
}
@@ -226,14 +213,14 @@ eOSState cMenuSetupEpgfixer::ProcessKey(eKeys Key)
if (state == osUnknown) {
switch (Key) {
case kRed:
- EpgfixerRegexps.ReloadRegexps();
+ EpgfixerRegexps.ReloadConfigFile();
+ EpgfixerCharSets.ReloadConfigFile();
state = osContinue;
break;
case kBlue:
cEitFilter::SetDisableUntil(time(NULL) + 10);
- if (cSchedules::ClearAll()) {
+ if (cSchedules::ClearAll())
cEitFilter::SetDisableUntil(time(NULL) + 10);
- }
state = osContinue;
break;
default:
@@ -241,6 +228,8 @@ eOSState cMenuSetupEpgfixer::ProcessKey(eKeys Key)
}
}
else if (state == osUser1)
- return AddSubMenu(new cMenuSetupRegexp());
+ return AddSubMenu(new cMenuSetupConfigEditor<cRegexp>(&EpgfixerRegexps));
+ else if (state == osUser2)
+ return AddSubMenu(new cMenuSetupConfigEditor<cCharSet>(&EpgfixerCharSets));
return state;
}