Ticket #12436: eitfixup-greek-2015-04-25.diff

File eitfixup-greek-2015-04-25.diff, 35.3 KB (added by Yianni Vidalis <yiannividalis@…>, 9 years ago)

v2

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