Repository: pymedusa/Medusa

Issue:
Guessit parser problems - Allowed languages
**Medusa (please complete the following information):**
 - Branch: develop https://github.com/pymedusa/Medusa/commit/a1c7ab36b00c469aaba113fd84776e42fb01949f


Sometimes guessit fails to parse spanish releases.
For example:
```
u'Cuerpo de Elite  - Temporada 1 [HDTV 720p][Cap.113][AC3 5.1 Español Castellano]\\CuerpoDeElite720p_113_descargas2020.mkv'
MatchesDict([('title', u'Cuerpo'), ('season', 1), ('source', u'HDTV'), ('screen_size', u'720p'), ('episode', 13), ('audio_codec', u'AC3'), ('audio_channels', u'5.1'), ('release_group', u'Espa\xf1ol'), ('language', <Language [ca]>), ('container', u'mkv'), ('mimetype', u'video/x-matroska'), ('type', u'episode')])
```
```
u'Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201_213][AC3 5.1 Castellano]\\Por Trece Razones 2x04 [www.descargas2020].mkv'
MatchesDict([('language', [<Language [pt]>, <Language [ca]>]), ('title', u'Trece Razones'), ('season', 2), ('source', u'HDTV'), ('screen_size', u'720p'), ('episode', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]), ('audio_codec', u'AC3'), ('audio_channels', u'5.1'), ('release_group', u'www.descargas2020'), ('container', u'mkv'), ('mimetype', u'video/x-matroska'), ('type', u'episode')])
```
The problem has to do with the allowed languages. "de", "en", "por", etc. are words in spanish.
If I remove the allowed languages from the guessit call, everything is correct:
```
u'Cuerpo de Elite  - Temporada 1 [HDTV 720p][Cap.113][AC3 5.1 Español Castellano]\\CuerpoDeElite720p_113_descargas2020.mkv'
MatchesDict([('title', u'Cuerpo de Elite'), ('season', 1), ('source', u'HDTV'), ('screen_size', u'720p'), ('episode', 13), ('audio_codec', u'AC3'), ('audio_channels', u'5.1'), ('release_group', u'Espa\xf1ol Castellano'), ('episode_title', u'descargas2020'), ('container', u'mkv'), ('mimetype', u'video/x-matroska'), ('type', u'episode')])
```
```
u'Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201_213][AC3 5.1 Castellano]\\Por Trece Razones 2x04 [www.descargas2020].mkv'
MatchesDict([('title', u'Por Trece Razones'), ('season', 2), ('source', u'HDTV'), ('screen_size', u'720p'), ('episode', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]), ('audio_codec', u'AC3'), ('audio_channels', u'5.1'), ('release_group', u'Castellano'), ('container', u'mkv'), ('mimetype', u'video/x-matroska'), ('type', u'episode')]) 
```

So, what is the point of passing allowed languages to the guessit call? Could there be some option to remove it?






Discussion:
It's not that easy. Removing the languages will cause many other releases, that currently parse correctly, to fail. I will try to find a workaround for the next version. 

Resolving patch:
diff --git a/medusa/name_parser/rules/rules.py b/medusa/name_parser/rules/rules.py
--- a/medusa/name_parser/rules/rules.py
+++ b/medusa/name_parser/rules/rules.py
@@ -1107,6 +1107,111 @@ def when(self, matches, context):
                     return to_remove, to_append
 
 
+class FixWordAsLanguage(Rule):
+    """Fix word getting parsed as language with multiple fileparts.
+
+    e.g.: Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201][AC3 5.1 Castellano]/Por Trece Razones 2x01 [des202].mkv
+
+    without the rule:
+        GuessIt found: {
+            "language": [
+                "Portuguese",
+                "Catalan"
+            ],
+            "title": "Trece Razones",
+            "season": 2,
+            "source": "HDTV",
+            "screen_size": "720p",
+            "episode": 1,
+            "audio_codec": "Dolby Digital",
+            "audio_channels": "5.1",
+            "release_group": "des202",
+            "container": "mkv",
+            "mimetype": "video/x-matroska",
+            "type": "episode"
+        }
+
+    with the rule:
+        GuessIt found: {
+            "language": "Catalan",
+            "title": "Por Trece Razones",
+            "season": 2,
+            "source": "HDTV",
+            "screen_size": "720p",
+            "episode": 1,
+            "audio_codec": "Dolby Digital",
+            "audio_channels": "5.1",
+            "release_group": "des202",
+            "container": "mkv",
+            "mimetype": "video/x-matroska",
+            "type": "episode"
+        }
+    """
+
+    priority = POST_PROCESS
+    consequence = [RemoveMatch, AppendMatch]
+
+    def when(self, matches, context):
+        """Evaluate the rule.
+
+        :param matches:
+        :type matches: rebulk.match.Matches
+        :param context:
+        :type context: dict
+        :return:
+        """
+        languages = matches.named('language')
+        if not languages:
+            return
+
+        fileparts = matches.markers.named('path')
+        parts_len = len(fileparts)
+        if parts_len < 2:
+            return
+
+        titles = matches.named('title')
+        first_title = titles[0]
+        last_title = titles[-1]
+
+        # Always use the first langauge
+        first_language = languages[0]
+        for language in languages[1:]:
+            if language.start < first_language.start:
+                first_language = language
+
+        lang_start = first_language.start
+        lang_end = first_language.end
+
+        start = end = None
+        # Language is before titles
+        if lang_end == first_title.start:
+            start = lang_start
+            end = last_title.end
+        # Language is after titles
+        elif last_title.end == lang_start:
+            start = first_title.start
+            end = lang_end
+        # Language is between titles
+        elif len(titles) > 1:
+            lang_code = last_title.value.split()[0].lower()
+            if lang_code in context.get('allowed_languages', []):
+                start = first_title.start
+                end = last_title.end
+
+        if start is not None:
+            second_filepart = fileparts[parts_len - 2]
+            rel_start = start - second_filepart.start
+            rel_end = end - second_filepart.end
+
+            new_title = second_filepart.value[rel_start:rel_end]
+            titles[0].value = cleanup(new_title)
+
+            to_append = titles[0]
+            to_remove = first_language
+
+            return to_remove, to_append
+
+
 class FixMultipleSources(Rule):
     """Fix multiple sources.
 
@@ -1498,6 +1603,7 @@ def rules():
         CreateAliasWithCountryOrYear,
         ReleaseGroupPostProcessor,
         FixParentFolderReplacingTitle,
+        FixWordAsLanguage,
         FixMultipleSources,
         FixMultipleReleaseGroups,
         AudioCodecStandardizer,


Test patch:
diff --git a/tests/test_guessit.yml b/tests/test_guessit.yml
--- a/tests/test_guessit.yml
+++ b/tests/test_guessit.yml
@@ -4319,3 +4319,30 @@
   container: mkv
   mimetype: video/x-matroska
   type: episode
+
+? Cuerpo de Elite  - Temporada 1 [HDTV 720p][Cap.113][AC3 5.1 Esp Castellano]\CuerpoDeElite720p_113_desca202.mkv
+: title: Cuerpo de Elite
+  season: 1
+  episode: 13
+  screen_size: 720p
+  source: HDTV
+  audio_codec: AC3
+  audio_channels: '5.1'
+  language: ca
+  container: mkv
+  mimetype: video/x-matroska
+  type: episode
+
+? Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201][AC3 5.1 Castellano]\Por Trece Razones 2x01 [desca202].mkv
+: title: Por Trece Razones
+  season: 2
+  episode: 1
+  screen_size: 720p
+  source: HDTV
+  audio_codec: AC3
+  audio_channels: '5.1'
+  language: [ca, pt]
+  release_group: desca202
+  container: mkv
+  mimetype: video/x-matroska
+  type: episode