summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY1
-rw-r--r--README5
-rw-r--r--eepg.c115
-rw-r--r--eepg.h10
-rw-r--r--epghandler.c64
-rw-r--r--epghandler.h6
-rw-r--r--extra/en-themes/mhw1_fr.tr81
-rw-r--r--extra/en-themes/mhw2_es.tr103
-rw-r--r--extra/en-themes/sky_it.themes256
-rw-r--r--util.c38
-rw-r--r--util.h9
11 files changed, 635 insertions, 53 deletions
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 <s.huelswitt@gmx.de>
diff --git a/eepg.c b/eepg.c
index ea5fd8c..a970479 100644
--- a/eepg.c
+++ b/eepg.c
@@ -49,7 +49,9 @@
#include <map>
#include <string>
+#include <limits>
#include <stdarg.h>
+#include <dirent.h>
#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,string>(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<string,string>::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<u_char>::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<string,string> 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<string,string>::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 <time.h>
#include <stdlib.h>
#include <string>
+#include <map>
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<std::string,std::string> tableDict;
+
class cCharsetFixer
{