Ticket #12436: eitfixup-greek.2.diff

File eitfixup-greek.2.diff, 34.2 KB (added by yiannividalis@…, 5 years ago)

update after e7a20aa

Line 
1diff --git a/mythtv/libs/libmythtv/eitfixup.cpp b/mythtv/libs/libmythtv/eitfixup.cpp
2old mode 100644
3new mode 100755
4index 49484c1..b88295e
5--- a/mythtv/libs/libmythtv/eitfixup.cpp
6+++ b/mythtv/libs/libmythtv/eitfixup.cpp
7@@ -187,7 +187,51 @@ EITFixUp::EITFixUp()
8       m_AUFreeviewY("(.*) \\(([12][0-9][0-9][0-9])\\)$"),
9       m_AUFreeviewYC("(.*) \\(([12][0-9][0-9][0-9])\\) \\((.+)\\)$"),
10       m_AUFreeviewSYC("(.*) \\((.+)\\) \\(([12][0-9][0-9][0-9])\\) \\((.+)\\)$"),
11-      m_HTML("</?EM>", Qt::CaseInsensitive)
12+      m_HTML("</?EM>", Qt::CaseInsensitive),
13+      m_grReplay("\\([ΕE]\\)"),
14+      m_grDescriptionFinale("\\s*΀ελευταίο\\sΕπεισόΎιο\\.\\s*"),
15+      m_grActors("(?:[Ππ]α[ιί]ζουΜ:|[ΜΌ]ε τους:|ΠρωταγωΜιστο[υύ]Îœ:|ΠρωταγωΜιστε[ιί]:?)(?:\\s+στο ρόλο(?: του| της)?\\s(?:\\w+\\s[οη]\\s))?([-\\w\\s']+(?:,[-\\w\\s']+)*)(?:κ\\.[αά])?(?:\\W?)"),
16+      // cap(1) actors, just names
17+      m_grFixnofullstopActors("(\\w\\s(ΠαίζουΜ:|ΠρωταγωΜ))"),
18+      m_grFixnofullstopDirectors("((\\w\\s(ΣκηΜοΞ[εέ]))"),
19+      m_grPeopleSeparator("(,\\s+)"),
20+      m_grDirector("(?:ΣκηΜοΞεσία: |ΣκηΜοΞέτης: )(\\w+\\s\\w+\\s?)(?:\\W?)"),
21+      m_grPres("(?:Παρουσ[ιί]αση:(?:\\b)*|Παρουσι[αά]ζ(?:ουΜ|ει)(?::|\\sο|\\sη)|Με τ(?:οΜ |ηΜ )(?:[\\s|:|ο|η])*(?:\\b)*)([-\\w\\s]+(?:,[-\\w\\s]+)*)(?:\\W?)"),
22+      m_grYear("(?:\\W?)(?:\\s?παραγωγ[ηή]ς|\\s?-|,)\\s*([1-2]{1}[0-9]{3})(?:-\\d{1,4})?",Qt::CaseInsensitive),
23+      m_grCountry("(?:\\W|\\b)(?:(ελληΜ|τουρκ|αΌερικ[αά]Îœ|γαλλ|αγγλ|βρεττ?αΜ|γερΌαΜ|ρωσσ?|ιταλ|ελβετ|σουηΎ|ισπαΜ|πορτογαλ|ΌεΟικ[αά]Îœ|κιΜ[εέ]ζικ|ιαπωΜ|καΜαΎ|βραζιλι[αά]Îœ)(ικ[ηή][ςσ]))",Qt::CaseInsensitive),
24+      m_grlongEp("\\b(?:Επ.|επεισ[οό]Ύιο:?)\\s*(\\d+)(?:\\W?)",Qt::CaseInsensitive),
25+      m_grSeason("(?:-\\s)?\\b((\\D{1,2})(?:')?|(\\d{1,2})(?:ος|ου)?)(?:\\sκ[υύ]κλο(?:[σς]|υ)){1}\\s?",Qt::CaseInsensitive),
26+      m_grRealTitleinDescription("(?:^\\()([\\w\\s\\d\\D-]+)(?:\\))(?:\\s*)"),
27+      // cap1 = real title
28+      // cap0 = real title in parentheses.
29+      m_grRealTitleinTitle("(?:\\()([\\w\\s\\d\\D-]+)(?:\\))(?:\\s*$)*"),
30+      // cap1 = real title
31+      // cap0 = real title in parentheses.
32+      m_grNotPreviouslyShown("(?:\\b[Α1]['η]?\\s*(?:τηλεοπτικ[ηή]\\s*)?(?:Όετ[αά]Ύοση|προβολ[ηή]))(?:\\W?)"),
33+      // Try to exctract Greek categories from keywords in description.
34+      m_grEpisodeAsSubtitle("(?:^Επεισ[οό]Ύιο:\\s?)([\\w\\s-,']+)\\.(?:\\s)?"),
35+      m_grCategFood("(?:\\W)?(?:εκποΌπ[ηή]\\W)?(ΓαστροΜοΌ[ιί]α[σς]?|Όαγειρικ[ηή][σς]?|chef|συΜταγ[εέηή]|Ύιατροφ|wine|ÎŒ[αά]γειρα[σς]?)(?:\\W)?",Qt::CaseInsensitive),
36+      m_grCategDrama("(?:\\W)?(κοιΜωΜικ[ηήό]|ΎραΌατικ[ηή]|Ύρ[αά]Όα)(?:\\W)(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
37+      m_grCategComedy("(?:\\W)?(κωΌικ[ηήοό]|χιουΌοριστικ[ηήοό]|κωΌωΎ[ιί]α)(?:\\W)(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
38+      m_grCategChildren("(?:\\W)?(παιΎικ[ηήοό]|κιΜο[υύ]ÎŒ[εέ]Îœ(ωΜ|α)\\sσχ[εέ]ÎŽ[ιί](ωΜ|α))(?:\\W)(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
39+      m_grCategMystery("(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?(?:\\W)?(Όυστηρ[ιί]ου)(?:\\W)?",Qt::CaseInsensitive),
40+      m_grCategFantasy("(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?(?:\\W)?(φαΜτασ[ιί]ας)(?:\\W)?",Qt::CaseInsensitive),
41+      m_grCategHistory("(?:\\W)?(ιστορικ[ηήοό])(?:\\W)?(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
42+      m_grCategTeleMag("(?:\\W)?(εΜηΌερωτικ[ηή]|ψυχαγωγικ[ηή]|τηλεπεριοΎικ[οό]|Όαγκαζ[ιί]Μο)(?:\\W)?(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
43+      m_grCategTeleShop("(?:\\W)?(οΎηγ[οό][σς]?\\sαγορ[ωώ]Îœ|τηλεπ[ωώ]λ[ηή]σ|τηλεαγορ|τηλεΌ[αά]ρκετ|telemarket)(?:\\W)?(?:(?:εκποΌπ[ηή]|σειρ[αά]|ταιΜ[ιί]α)\\W)?",Qt::CaseInsensitive),
44+      m_grCategGameShow("(?:\\W)?(τηλεπαιχΜ[ιί]Ύι|quiz)(?:\\W)?",Qt::CaseInsensitive),
45+      m_grCategDocumentary("(?:\\W)?(Μτοκ[ιυ]ΌαΜτ[εέ]ρ)(?:\\W)?",Qt::CaseInsensitive),
46+      m_grCategBiography("(?:\\W)?(βιογραφ[ιί]α|βιογραφικ[οό][σς]?)(?:\\W)?",Qt::CaseInsensitive),
47+      m_grCategNews("(?:\\W)?(Ύελτ[ιί]ο\\W?|ειΎ[ηή]σε(ι[σς]|ωΜ))(?:\\W)?",Qt::CaseInsensitive),
48+      m_grCategSports("(?:\\W)?(champion|αΞλητικ[αάοόηή]|πρωτ[αά]ΞληΌα|ποΎ[οό]σφαιρο(ου)?|κολ[υύ]Όβηση|πατιΜ[αά]ζ|formula|Όπ[αά]σκετ|β[οό]λε[ιϊ])(?:\\W)?",Qt::CaseInsensitive),
49+      m_grCategMusic("(?:\\W)?(Όουσικ[οόηή]|eurovision|τραγο[υύ]Ύι)(?:\\W)?",Qt::CaseInsensitive),
50+      m_grCategReality("(?:\\W)?(ρι[αά]λιτι|reality)(?:\\W)?",Qt::CaseInsensitive),
51+      m_grCategReligion("(?:\\W)?(Ξρησκε[ιί]α|Ξρησκευτικ|Μα[οό][σς]?|Ξε[ιί]α λειτουργ[ιί]α)(?:\\W)?",Qt::CaseInsensitive),
52+      m_grCategCulture("(?:\\W)?(τ[εέ]χΜ(η|ε[σς])|πολιτισΌ)(?:\\W)?",Qt::CaseInsensitive),
53+      m_grCategNature("(?:\\W)?(φ[υύ]ση|περιβ[αά]λλο|κατασκευ|επιστ[ηή]ÎŒ(?!οΜικ[ηή]ς φαΜτασ[ιί]ας))(?:\\W)?",Qt::CaseInsensitive),
54+      m_grCategSciFi("(?:\\W)?(επιστ(.|ηΌοΜικ[ηή]ς)\\s?φαΜτασ[ιί]ας)(?:\\W)?",Qt::CaseInsensitive),
55+      m_grCategHealth("(?:\\W)?(υγε[ιί]α|υγειιΜ|ιατρικ|Ύιατροφ)(?:\\W)?",Qt::CaseInsensitive),
56+      m_grCategSpecial("(?:\\W)?(αφι[εέ]ρωΌα)(?:\\W)?",Qt::CaseInsensitive)
57 {
58 }
59 
60@@ -271,6 +315,15 @@ void EITFixUp::Fix(DBEventEIT &event) const
61     if (kFixCategory & event.fixup)
62         FixCategory(event);
63 
64+    if (kFixGreekSubtitle & event.fixup)
65+        FixGreekSubtitle(event);
66+
67+    if (kFixGreekEIT & event.fixup)
68+        FixGreekEIT(event);
69+
70+    if (kFixGreekCategories & event.fixup)
71+        FixGreekCategories(event);
72+
73     if (event.fixup)
74     {
75         if (!event.title.isEmpty())
76@@ -2336,3 +2389,408 @@ void EITFixUp::FixStripHTML(DBEventEIT &event) const
77     LOG(VB_EIT, LOG_INFO, QString("Applying html strip to %1").arg(event.title));
78     event.title.remove(m_HTML);
79 }
80+
81+// Moves the subtitle field into the description since it's just used
82+// as more description field. All the sort-out will happen in the description
83+// field. Also, sometimes the description is just a repeat of the title. If so,
84+// we remove it.
85+void EITFixUp::FixGreekSubtitle(DBEventEIT &event) const
86+{
87+    if (event.title == event.description)
88+    {
89+        event.description = QString("");
90+    }
91+    if (!event.subtitle.isEmpty())
92+    {
93+        if (event.subtitle.trimmed().right(1) != ".'" )
94+            event.subtitle = event.subtitle.trimmed() + ".";
95+        event.description = event.subtitle.trimmed() + QString(" ") + event.description;
96+        event.subtitle = QString("");
97+    }
98+}
99+
100+void EITFixUp::FixGreekEIT(DBEventEIT &event) const
101+{
102+    //Live show
103+    int position;
104+    QRegExp tmpRegEx;
105+    position = event.title.indexOf("(Ζ)");
106+    if (position != -1)
107+    {
108+        event.title = event.title.replace("(Ζ)", "");
109+        event.description.prepend("ΖωΜταΜή ΜετάΎοση. ");
110+    }
111+
112+    // Greek not previously Shown
113+    position = event.title.indexOf(m_grNotPreviouslyShown);
114+    if (position != -1)
115+    {
116+        event.previouslyshown = false;
117+        event.title = event.title.replace(m_grNotPreviouslyShown.cap(0), "");
118+    }
119+
120+    // Greek Replay (Ε)
121+    // it might look redundant compared to previous check but at least it helps
122+    // remove the (Ε) From the title.
123+    tmpRegEx = m_grReplay;
124+    if (event.title.indexOf(tmpRegEx) !=  -1)
125+    {
126+        event.previouslyshown = true;
127+        event.title = event.title.replace(tmpRegEx, "");
128+    }
129+
130+    tmpRegEx = m_grFixnofullstopActors;
131+    position = event.description.indexOf(tmpRegEx);
132+    if (position != -1)
133+    {
134+        event.description.insert(position + 1, ".");
135+    }
136+
137+    // If they forgot the "." at the end of the sentence before the actors/directors begin, let's insert it.
138+    tmpRegEx = m_grFixnofullstopDirectors;
139+    position = event.description.indexOf(tmpRegEx);
140+    if (position != -1)
141+    {
142+        event.description.insert(position + 1, ".");
143+    }
144+
145+    // Find actors and director in description
146+    // I am looking for actors first and then for directors/presenters because
147+    // sometimes punctuation is missing and the "ΠαίζουΜ:" label is mistaken
148+    // for a director's/presenter's surname (directors/presenters are shown
149+    // before actors in the description field.). So removing the text after
150+    // adding the actors AND THEN looking for dir/pres helps to clear things up.
151+    tmpRegEx = m_grActors;
152+    position = event.description.indexOf(tmpRegEx);
153+    if (position != -1)
154+    {
155+        QString tmpActorsString = tmpRegEx.cap(1);
156+        const QStringList actors =
157+            tmpActorsString.split(m_grPeopleSeparator, QString::SkipEmptyParts);
158+        QStringList::const_iterator it = actors.begin();
159+        for (; it != actors.end(); ++it)
160+        {
161+            tmpActorsString = it->split(":").last().trimmed().
162+                    remove(QRegExp("\\.$"));
163+            if (tmpActorsString != "")
164+                event.AddPerson(DBPerson::kActor, tmpActorsString);
165+        }
166+        event.description.replace(tmpRegEx.cap(0), "");
167+    }
168+    // Director
169+    tmpRegEx = m_grDirector;
170+    position = event.description.indexOf(tmpRegEx);
171+    if (position != -1)
172+    {
173+        QString tmpDirectorsString = tmpRegEx.cap(1);
174+        const QStringList directors =
175+            tmpDirectorsString.split(m_grPeopleSeparator, QString::SkipEmptyParts);
176+        QStringList::const_iterator it = directors.begin();
177+        for (; it != directors.end(); ++it)
178+        {
179+            tmpDirectorsString = it->split(":").last().trimmed().
180+                    remove(QRegExp("\\.$"));
181+            if (tmpDirectorsString != "")
182+            {
183+                event.AddPerson(DBPerson::kDirector, tmpDirectorsString);
184+            }
185+        }
186+        event.description.replace(tmpRegEx.cap(0), "");
187+    }
188+
189+/*
190+
191+    tmpRegEx = m_grDirector;
192+    position = event.description.indexOf(tmpRegEx);
193+    if (position != -1)
194+    {
195+        // director is captured in cap(1).Due to sometimes miswritten data in
196+        // eit, e.g no fullstop present(!)
197+        QString tmpDirectorsString = tmpRegEx.cap(1);
198+        // look for actors in director string (lack of fullstop, etc)
199+        tmpRegEx = m_grActors;
200+        int actposition = tmpDirectorsString.indexOf(tmpRegEx);
201+        if (actposition != -1)
202+        {
203+            tmpDirectorsString = tmpDirectorsString.replace(tmpRegEx,"");
204+        }
205+        const QStringList directors =
206+            tmpDirectorsString.split(m_grPeopleSeparator, QString::SkipEmptyParts);
207+        QStringList::const_iterator it = directors.begin();
208+        for (; it != directors.end(); ++it)
209+        {
210+            tmpDirectorsString = it->split(":").last().trimmed().
211+                    remove(QRegExp("\\.$"));
212+            if (tmpDirectorsString != "")
213+                event.AddPerson(DBPerson::kDirector, tmpDirectorsString);
214+
215+        }
216+        event.description.replace(tmpRegEx.cap(0), "");
217+       // directorPresent = true;
218+    }
219+*/
220+    //Try to find presenter
221+    tmpRegEx = m_grPres;
222+    position = event.description.indexOf(tmpRegEx);
223+    if (position != -1)
224+    {
225+        QString tmpPresentersString = tmpRegEx.cap(1);
226+        const QStringList presenters =
227+            tmpPresentersString.split(m_grPeopleSeparator, QString::SkipEmptyParts);
228+        QStringList::const_iterator it = presenters.begin();
229+        for (; it != presenters.end(); ++it)
230+        {
231+            tmpPresentersString = it->split(":").last().trimmed().
232+                    remove(QRegExp("\\.$"));
233+            if (tmpPresentersString != "")
234+            {
235+                event.AddPerson(DBPerson::kPresenter, tmpPresentersString);
236+            }
237+        }
238+        event.description.replace(tmpRegEx.cap(0), "");
239+    }
240+
241+    //find year e.g Παραγωγής 1966 ή Ν΀ΟΚΙΜΑΝ΀ΕΡ - 1998 Κατάλληλο για όλους
242+    // Used in Private channels (not 'secret', just not owned by Government!)
243+    tmpRegEx = m_grYear;
244+    position = event.description.indexOf(tmpRegEx);
245+    if (position != -1)
246+    {
247+        bool ok;
248+        uint y = tmpRegEx.cap(1).toUInt(&ok);
249+        if (ok)
250+            event.originalairdate = QDate(y, 1, 1);
251+            event.description.replace(tmpRegEx, "");
252+    }
253+    // Remove white spaces
254+    event.description = event.description.trimmed();
255+    event.title       = event.title.trimmed();
256+    event.subtitle    = event.subtitle.trimmed();
257+
258+    //find country of origin and remove it from description.
259+    tmpRegEx = m_grCountry;
260+    position = event.description.indexOf(tmpRegEx);
261+    if (position != -1)
262+    {
263+        event.description.replace(tmpRegEx, "");
264+    }
265+
266+    // Work out the season and episode numbers (if any)
267+    // Matching pattern "Επεισ[όο]Ύιο:?|Επ 3 από 14|3/14" etc
268+    bool    series  = false;
269+    int position1;
270+    int position2;
271+    QRegExp tmpSeries = m_grSeason;
272+    // cap(2) is the season for ΑΒΓΔ
273+    // cap(3) is the season for 1234
274+    if ((position1 = tmpSeries.indexIn(event.title)) != -1
275+            || (position2 = tmpSeries.indexIn(event.description)) != -1)
276+    {
277+        if (!tmpSeries.cap(2).isEmpty()) // we found a letter representing a number
278+        {
279+            //sometimes Nat. TV writes numbers as letters, i.e Α=1, Β=2, Γ=3, etc
280+            //must convert them to numbers.
281+            int tmpinteger = tmpSeries.cap(2).toUInt();
282+            if (tmpinteger < 1)
283+            {
284+                if (tmpSeries.cap(2) == "Σ΀") // 6, don't ask!
285+                    event.season = 6;
286+                else
287+                {
288+                    QString LettToNumber = "0ΑΒΓΔΕ6ΖΗΘΙΚΛΜΝ";
289+                    tmpinteger = LettToNumber.indexOf(tmpSeries.cap(2));
290+                    if (tmpinteger != -1)
291+                        event.season = tmpinteger;
292+                }
293+            }
294+        }
295+        else if (!tmpSeries.cap(3).isEmpty()) //number
296+        {
297+            event.season = tmpSeries.cap(3).toUInt();
298+        }
299+        series = true;
300+        if (position1 != -1)
301+            event.title.replace(tmpSeries.cap(0),"");
302+        if (position2 != -1)
303+            event.description.replace(tmpSeries.cap(0),"");
304+    }
305+
306+    QRegExp tmpEpisode = m_grlongEp;
307+    //tmpEpisode.setMinimal(true);
308+    // cap(1) is the Episode No.
309+    if ((position1 = tmpEpisode.indexIn(event.title)) != -1
310+            || (position2 = tmpEpisode.indexIn(event.description)) != -1)
311+    {
312+        if (!tmpEpisode.cap(1).isEmpty())
313+        {
314+            event.episode = tmpEpisode.cap(1).toUInt();
315+            series = true;
316+            if (position1 != -1)
317+                event.title.replace(tmpEpisode.cap(0),"");
318+            if (position2 != -1)
319+                event.description.replace(tmpEpisode.cap(0),"");
320+            // Sometimes description omits Season if it's 1. We fix this
321+            if (0 == event.season)
322+                event.season = 1;
323+        }
324+    }
325+
326+    // Sometimes the real (mostly English) title of a movie or series is
327+    // enclosed in parentheses in the event title, subtitle or description.
328+    // Since the subtitle has been moved to the description field by
329+    // EITFixUp::FixGreekSubtitle, I will search for it only in the description.
330+    // It will replace the translated one to get better chances of metadata
331+    // retrieval. The old title will be moved in the description.
332+    QRegExp tmptitle = m_grRealTitleinDescription;
333+    tmptitle.setMinimal(true);
334+    position = event.description.indexOf(tmptitle);
335+    if (position != -1)
336+    {
337+        event.description = event.description.replace(tmptitle, "");
338+        if (QString(tmptitle.cap(0)) != event.title.trimmed())
339+        {
340+            event.description = "(" + event.title.trimmed() + "). " + event.description;
341+        }
342+        event.title = tmptitle.cap(1);
343+        // Remove the real title from the description
344+    }
345+    else // search in title
346+    {
347+        tmptitle = m_grRealTitleinTitle;
348+        position = event.title.indexOf(tmptitle);
349+        if (position != -1) // found in title instead
350+        {
351+            event.title.replace(tmptitle.cap(0),"");
352+            QString tmpTranslTitle = event.title;
353+            //QString tmpTranslTitle = event.title.replace(tmptitle.cap(0),"");
354+            event.title = tmptitle.cap(1);
355+            event.description = "(" + tmpTranslTitle.trimmed() + "). " + event.description;
356+        }
357+    }
358+
359+    // Description field: "^Episode: Lion in the cage. (Description follows)"
360+    tmpRegEx = m_grEpisodeAsSubtitle;
361+    position = event.description.indexOf(tmpRegEx);
362+    if (position != -1)
363+    {
364+        event.subtitle = tmpRegEx.cap(1).trimmed();
365+        event.description.replace(tmpRegEx, "");
366+    }
367+    QRegExp m_grMovie("\\bταιΜ[ιί]α\\b",Qt::CaseInsensitive);
368+    bool isMovie = (event.description.indexOf(m_grMovie) !=-1) ;
369+    if (isMovie)
370+    {
371+        event.categoryType = ProgramInfo::kCategoryMovie;
372+    }
373+    else if (series)
374+    {
375+        event.categoryType = ProgramInfo::kCategorySeries;
376+    }
377+    // just for luck, retrim fields.
378+    event.description = event.description.trimmed();
379+    event.title       = event.title.trimmed();
380+    event.subtitle    = event.subtitle.trimmed();
381+
382+// Μα σβήσω τα κοΌΌάτια που Ï€ÎµÏÎ¹ÏƒÏƒÎµÏÎ¿Ï…Îœ από τηΜ περιγραφή πχ παραγωγής χχχχ
383+}
384+
385+void EITFixUp::FixGreekCategories(DBEventEIT &event) const
386+{
387+    if (event.description.indexOf(m_grCategComedy) != -1)
388+    {
389+        event.category = "ΚωΌωΎία";
390+    }
391+    else if (event.description.indexOf(m_grCategTeleMag) != -1)
392+    {
393+        event.category = "΀ηλεπεριοΎικό";
394+    }
395+    else if (event.description.indexOf(m_grCategNature) != -1)
396+    {
397+        event.category = "ΕπιστήΌη/Ίύση";
398+    }
399+    else if (event.description.indexOf(m_grCategHealth) != -1)
400+    {
401+        event.category = "Υγεία";
402+    }
403+    else if (event.description.indexOf(m_grCategReality) != -1)
404+    {
405+        event.category = "Ριάλιτι";
406+    }
407+    else if (event.description.indexOf(m_grCategDrama) != -1)
408+    {
409+        event.category = "ΚοιΜωΜικό";
410+    }
411+    else if (event.description.indexOf(m_grCategChildren) != -1)
412+    {
413+        event.category = "ΠαιΎικό";
414+    }
415+    else if (event.description.indexOf(m_grCategSciFi) != -1)
416+    {
417+        event.category = "Επιστ.ΊαΜτασίας";
418+    }
419+    else if ((event.description.indexOf(m_grCategFantasy) != -1)
420+             && (event.description.indexOf(m_grCategMystery) != -1))
421+    {
422+        event.category = "ΊαΜτασίας/Μυστηρίου";
423+    }
424+    else if (event.description.indexOf(m_grCategMystery) != -1)
425+    {
426+        event.category = "Μυστηρίου";
427+    }
428+    else if (event.description.indexOf(m_grCategFantasy) != -1)
429+    {
430+        event.category = "ΊαΜτασίας";
431+    }
432+    else if (event.description.indexOf(m_grCategHistory) != -1)
433+    {
434+        event.category = "Ιστορικό";
435+    }
436+    else if (event.description.indexOf(m_grCategTeleShop) != -1
437+            || event.title.indexOf(m_grCategTeleShop) != -1)
438+    {
439+        event.category = "΀ηλεπωλήσεις";
440+    }
441+    else if (event.description.indexOf(m_grCategFood) != -1)
442+    {
443+        event.category = "ΓαστροΜοΌία";
444+    }
445+    else if (event.description.indexOf(m_grCategGameShow) != -1
446+             || event.title.indexOf(m_grCategGameShow) != -1)
447+    {
448+        event.category = "΀ηλεπαιχΜίΎι";
449+    }
450+    else if (event.description.indexOf(m_grCategBiography) != -1)
451+    {
452+        event.category = "Βιογραφία";
453+    }
454+    else if (event.title.indexOf(m_grCategNews) != -1)
455+    {
456+        event.category = "ΕιΎήσεις";
457+    }
458+    else if (event.description.indexOf(m_grCategSports) != -1)
459+    {
460+        event.category = "ΑΞλητικά";
461+    }
462+    else if (event.description.indexOf(m_grCategMusic) != -1
463+            || event.title.indexOf(m_grCategMusic) != -1)
464+    {
465+        event.category = "Μουσική";
466+    }
467+    else if (event.description.indexOf(m_grCategDocumentary) != -1)
468+    {
469+        event.category = "ΝτοκιΌαΜτέρ";
470+    }
471+    else if (event.description.indexOf(m_grCategReligion) != -1)
472+    {
473+        event.category = "Θρησκεία";
474+    }
475+    else if (event.description.indexOf(m_grCategCulture) != -1)
476+    {
477+        event.category = "΀έχΜες/ΠολιτισΌός";
478+    }
479+    else if (event.description.indexOf(m_grCategSpecial) != -1)
480+    {
481+        event.category = "ΑφιέρωΌα";
482+    }
483+
484+}
485diff --git a/mythtv/libs/libmythtv/eitfixup.h b/mythtv/libs/libmythtv/eitfixup.h
486old mode 100644
487new mode 100755
488index 5071956..6091329
489--- a/mythtv/libs/libmythtv/eitfixup.h
490+++ b/mythtv/libs/libmythtv/eitfixup.h
491@@ -64,6 +64,11 @@ class EITFixUp
492         kEFixForceISO8859_2  = 1 << 23,
493         kEFixForceISO8859_9  = 1 << 24,
494         kEFixForceISO8859_15 = 1 << 25,
495+        kEFixForceISO8859_7  = 1 << 26,
496+
497+        kFixGreekSubtitle    = 1 << 27,
498+        kFixGreekEIT         = 1 << 28,
499+        kFixGreekCategories  = 1 << 29,
500     };
501 
502     EITFixUp();
503@@ -106,6 +111,9 @@ class EITFixUp
504     void FixNRK_DVBT(DBEventEIT &event) const;      // Norwegian NRK DVB-T
505     void FixDK(DBEventEIT &event) const;            // Danish YouSee DVB-C
506     void FixStripHTML(DBEventEIT &event) const;     // Strip HTML tags
507+    void FixGreekSubtitle(DBEventEIT &event) const; // Greek Nat TV fix
508+    void FixGreekEIT(DBEventEIT &event) const;
509+    void FixGreekCategories(DBEventEIT &event) const; // Greek categories from descr.
510 
511     static QString AddDVBEITAuthority(uint chanid, const QString &id);
512 
513@@ -240,6 +248,45 @@ class EITFixUp
514     const QRegExp m_AUFreeviewYC;//year, cast
515     const QRegExp m_AUFreeviewSYC;//subtitle, year, cast
516     const QRegExp m_HTML;
517+    const QRegExp m_grReplay; //Greek rerun
518+    const QRegExp m_grDescriptionFinale; //Greek last m_grEpisode
519+    const QRegExp m_grActors; //Greek actors
520+    const QRegExp m_grFixnofullstopActors; //bad punctuation makes the "ΠαίζουΜ:" and the actors' names part of the directors...
521+    const QRegExp m_grFixnofullstopDirectors; //bad punctuation makes the "ΣκηΜοΞ...:" and the previous sentence.
522+    const QRegExp m_grPeopleSeparator; // The comma that separates the actors.
523+    const QRegExp m_grDirector;
524+    const QRegExp m_grPres; // Greek Presenters for shows
525+    const QRegExp m_grYear; // Greek release year.
526+    const QRegExp m_grCountry; // Greek event country of origin.
527+    const QRegExp m_grlongEp; // Greek Episode
528+    const QRegExp m_grSeason; // Greek Season
529+    const QRegExp m_grSeries;
530+    const QRegExp m_grRealTitleinDescription; // The original title is often in the descr in parenthesis.
531+    const QRegExp m_grRealTitleinTitle; // The original title is often in the title in parenthesis.
532+    const QRegExp m_grNotPreviouslyShown; // Not previously shown on TV
533+    const QRegExp m_grEpisodeAsSubtitle; // Description field: "^Episode: Lion in the cage. (Description follows)"
534+    const QRegExp m_grCategFood; // Greek category food
535+    const QRegExp m_grCategDrama; // Greek category social/drama
536+    const QRegExp m_grCategComedy; // Greek category comedy
537+    const QRegExp m_grCategChildren; // Greek category for children / cartoons
538+    const QRegExp m_grCategMystery; // Greek category for mystery
539+    const QRegExp m_grCategFantasy; // Greek category for fantasy
540+    const QRegExp m_grCategHistory; //Greek category for historical movie/series
541+    const QRegExp m_grCategTeleMag; //Greek category for Telemagazine show
542+    const QRegExp m_grCategTeleShop; //Greek category for teleshopping
543+    const QRegExp m_grCategGameShow; //Greek category for game show
544+    const QRegExp m_grCategDocumentary; // Greek category for Documentaries
545+    const QRegExp m_grCategBiography; // Greek category for biography
546+    const QRegExp m_grCategNews; // Greek category for News
547+    const QRegExp m_grCategSports; // Greek category for Sports
548+    const QRegExp m_grCategMusic; // Greek category for Music
549+    const QRegExp m_grCategReality; // Greek category for reality shows
550+    const QRegExp m_grCategReligion; //Greek category for religion
551+    const QRegExp m_grCategCulture; //Greek category for Arts/Culture
552+    const QRegExp m_grCategNature; //Greek category for Nature/Science
553+    const QRegExp m_grCategSciFi;  // Greek category for Science Fiction
554+    const QRegExp m_grCategHealth; //Greek category for Health
555+    const QRegExp m_grCategSpecial; //Greek category for specials.
556 };
557 
558 #endif // EITFIXUP_H
559diff --git a/mythtv/libs/libmythtv/eithelper.cpp b/mythtv/libs/libmythtv/eithelper.cpp
560old mode 100644
561new mode 100755
562index 7e80a1d..7af0285
563--- a/mythtv/libs/libmythtv/eithelper.cpp
564+++ b/mythtv/libs/libmythtv/eithelper.cpp
565@@ -253,6 +253,7 @@ static void parse_dvb_event_descriptors(desc_list_t list, uint fix,
566     // from EN 300 468, Appendix A.2 - Selection of character table
567     unsigned char enc_1[3]  = { 0x10, 0x00, 0x01 };
568     unsigned char enc_2[3]  = { 0x10, 0x00, 0x02 };
569+    unsigned char enc_7[3]  = { 0x10, 0x00, 0x07 }; // Latin/Greek Alphabet
570     unsigned char enc_9[3]  = { 0x10, 0x00, 0x09 }; // could use { 0x05 } instead
571     unsigned char enc_15[3] = { 0x10, 0x00, 0x0f }; // could use { 0x0B } instead
572     int enc_len = 0;
573@@ -283,13 +284,21 @@ static void parse_dvb_event_descriptors(desc_list_t list, uint fix,
574     }
575 
576     // Is this broken DVB provider in Western Europe?
577-    // Use an encoding override of ISO 8859-15 (Latin6)
578+    // Use an encoding override of ISO 8859-15 (Latin9)
579     if (fix & EITFixUp::kEFixForceISO8859_15)
580     {
581         enc = enc_15;
582         enc_len = sizeof(enc_15);
583     }
584 
585+    // Is this broken DVB provider in Greece?
586+    // Use an encoding override of ISO 8859-7 (Latin/Greek)
587+    if (fix & EITFixUp::kEFixForceISO8859_7)
588+    {
589+        enc = enc_7;
590+        enc_len = sizeof(enc_7);
591+    }
592+
593     if (bestShortEvent)
594     {
595         ShortEventDescriptor sed(bestShortEvent);
596@@ -576,6 +585,32 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
597                 }
598                 category_type = content.GetMythCategory(0);
599             }
600+            else if (EITFixUp::kFixGreekEIT & fix)//Greek
601+            {
602+                ContentDescriptor content(content_data);
603+                switch (content.Nibble2(0))
604+                {
605+                    case 0x01:
606+                        category = "΀αιΜία";       // confirmed
607+                        break;
608+                    case 0x02:
609+                        category = "ΕΜηΌερωτικό";  // confirmed
610+                        break;
611+                    case 0x04:
612+                        category = "ΑΞλητικό";     // confirmed
613+                        break;
614+                    case 0x05:
615+                        category = "ΠαιΎικό";      // confirmed
616+                        break;
617+                    case 0x09:
618+                        category = "ΝτοκιΌαΜτέρ";  // confirmed
619+                        break;
620+                    default:
621+                        category = "";
622+                        break;
623+                }
624+                category_type = content.GetMythCategory(2);
625+            }
626             else
627             {
628                 ContentDescriptor content(content_data);
629@@ -1326,6 +1361,19 @@ static void init_fixup(QMap<uint64_t,uint> &fix)
630     // DVB-C T-Kábel Hungary
631     // FIXME this should be more specific. Is the encoding really wrong for all services?
632     fix[  100 << 16] = EITFixUp::kEFixForceISO8859_2;
633+    // Greece
634+    // Pelion Transmitter
635+    // transport_id<<32 | netword_id<<16 | service_id
636+    fix[  100LL << 32 |  8492LL << 16 ] = // Ant1,Alpha,Art,10E
637+    fix[  102LL << 32 |  8492LL << 16 ] = // Mega,Star,SKAI,M.tv
638+    fix[  320LL << 32 |  8492LL << 16 ] = // Astra,Thessalia,TRT,TV10,ZEYS
639+        EITFixUp::kFixGreekEIT |
640+        EITFixUp::kFixGreekCategories;
641+    fix[    2LL << 32 |  8492LL << 16 ] = // N1,Nplus,NHD,Vouli
642+        EITFixUp::kEFixForceISO8859_7 |   // it is encoded in cp-1253
643+        EITFixUp::kFixGreekSubtitle |     // Subtitle has too much info and is
644+        EITFixUp::kFixGreekEIT |              // cut in db. Will move to descr.
645+        EITFixUp::kFixGreekCategories;
646 }
647 
648 /** \fn EITHelper::RescheduleRecordings(void)
649diff --git a/mythtv/themes/default/categories.xml b/mythtv/themes/default/categories.xml
650old mode 100644
651new mode 100755
652index f098171..77def9f
653--- a/mythtv/themes/default/categories.xml
654+++ b/mythtv/themes/default/categories.xml
655@@ -474,4 +474,69 @@
656   <catcolor category="Weather" color="DarkOrange3"></catcolor>
657   <catcolor category="Wrestling" color="DarkCyan"></catcolor>
658 
659+  <!-- Categories introduced by Greek DVB-T channels -->
660+  <catcolor category="ΕΜηΌερωτικό" color="DarkOrange3"></catcolor>
661+  <catcolor category="΀αιΜία" color="Blue"></catcolor>
662+  <catcolor category="ΑΞλητικά" color="DarkCyan"></catcolor>
663+  <catcolor category="ΠοΎόσφαιρο" color="DarkCyan"></catcolor>
664+  <catcolor category="ΠαιΎικό" color="MediumSlateBlue"></catcolor>
665+  <catcolor category="ΝτοκιΌαΜτέρ" color="goldenrod"></catcolor>
666+  <catcolor category="ΕκπαιΎευτικό" color="CornflowerBlue"></catcolor>
667+  <catcolor category="Για ΕΜήλικες" color="thistle3"></catcolor>
668+  <catcolor category="Μιούζικαλ" color="turquoise3"></catcolor>
669+  <catcolor category="΀ηλεπεριοΎικό" color="DarkOrange3"></catcolor>
670+  <catcolor category="Ριάλιτι" color="sienna"></catcolor>
671+  <catcolor category="ΓαστροΜοΌία" color="tan3"></catcolor>
672+  <catcolor category="Ιατρικό" color="goldenrod"></catcolor>
673+  <catcolor category="Μυστηρίου" color="SlateGrey"></catcolor>
674+  <catcolor category="ΑστυΜοΌικό/Μυστηρίου" color="SlateGrey"></catcolor>
675+  <catcolor category="Μουσική" color="DarkRed"></catcolor>
676+  <catcolor category="Μουσικό αφιέρωΌα" color="#aa0000"></catcolor>
677+  <catcolor category="ΔραΌατικό" color="rosybrown3"></catcolor>
678+  <catcolor category="ΚοιΜωΜικό" color="rosybrown3"></catcolor>
679+  <catcolor category="Κλασσικό" color="grey62"></catcolor>
680+  <catcolor category="ΑστυΜοΌικό" color="MediumVioletRed"></catcolor>
681+  <catcolor category="ΑστυΜοΌικό ΔράΌα" color="MediumVioletRed"></catcolor>
682+  <catcolor category="Συζήτηση" color="MediumTurquoise"></catcolor>
683+  <catcolor category="Ζωα" color="ForestGreen"></catcolor>
684+  <catcolor category="ΓουέστερΜ" color="#bbbb00"></catcolor>
685+  <catcolor category="ΠολεΌικό" color="#dddd00"></catcolor>
686+  <catcolor category="ΑφιέρωΌα" color="#ee0000"></catcolor>
687+  <catcolor category="ΚωΌωΎία" color="DarkOrchid"></catcolor>
688+  <catcolor category="ΚωΌωΎία-ΎράΌα" color="#880099"></catcolor>
689+  <catcolor category="ΑισΞηΌατική κοΌεΜτί" color="#bbaa00"></catcolor>
690+  <catcolor category="ΚωΌική σειρά" color="#880088"></catcolor>
691+  <catcolor category="Ζωα" color="#00ff44"></catcolor>
692+  <catcolor category="Ίύση" color="#33ff99"></catcolor>
693+  <catcolor category="ΕπιστήΌη/Ίύση" color="#33ff99"></catcolor>
694+  <catcolor category="Επιστ.ΊαΜτασίας" color="#DD00DD"></catcolor>
695+  <catcolor category="ΊαΜτασίας/Επιστ.ΊαΜτασίας" color="DarkBlue"></catcolor>
696+  <catcolor category="ΊαΜτασίας" color="#996666"></catcolor>
697+  <catcolor category="ΊαΜτασίας/Μυστηρίου" color="#996666"></catcolor>
698+  <catcolor category="΀ρόΌου" color="firebrick3"></catcolor>
699+  <catcolor category="ΑγωΜίας" color="firebrick3"></catcolor>
700+  <catcolor category="Περιπέτεια" color="maroon"></catcolor>
701+  <catcolor category="ΑισΞηΌατικό" color="#ff9999"></catcolor>
702+  <catcolor category="ΓαστροΜοΌία/΀αΟίΎια" color="#aa00aa"></catcolor>
703+  <catcolor category="΀ουρισΌός/΀αΟίΎια" color="#aa00aa"></catcolor>
704+  <catcolor category="Υγεία" color="#00ffaa"></catcolor>
705+  <catcolor category="Σπίτι/ΊτιάΟτο ΌόΜος σου" color="Red"></catcolor>
706+  <catcolor category="Σπιτικές Βελτιώσεις" color="#00cc00"></catcolor>
707+  <catcolor category="ΊτιάΟτο ΌόΜος σου" color="#00aa00"></catcolor>
708+  <catcolor category="Σπίτι/κηπουρική" color="#00ee00"></catcolor>
709+  <catcolor category="ΠαιχΜίΎι" color="orchid"></catcolor>
710+  <catcolor category="ΑΜΞολογία" color="DarkOrchid"></catcolor>
711+  <catcolor category="ΚιΜ.ΣχέΎια" color="#3333aa"></catcolor>
712+  <catcolor category="΀ηλεπαιχΜίΎι" color="orchid"></catcolor>
713+  <catcolor category="ΓυΌΜαστική" color="#00dd99"></catcolor>
714+  <catcolor category="ΕΌπόριο/ΟικοΜοΌία" color="DarkOrange3"></catcolor>
715+  <catcolor category="ΑυτοκίΜητο" color="#a8bde8"></catcolor>
716+  <catcolor category="Βιογραφία" color="#e9ecf3"></catcolor>
717+  <catcolor category="ΜόΎα" color="#a8cdea"></catcolor>
718+  <catcolor category="ΣαπουΜόπερα" color="DarkOrchid"></catcolor>
719+  <catcolor category="Ιστορικό" color="DarkOrange1"></catcolor>
720+  <catcolor category="΀ηλεπωλήσεις" color="#222200"></catcolor>
721+  <catcolor category="ΕιΎήσεις" color="DarkOrange3"></catcolor>
722+  <catcolor category="Θρησκεία" color="goldenrod"></catcolor>
723+  <catcolor category="΀έχΜες/ΠολιτισΌός" color="goldenrod"></catcolor>
724 </categorycolors>