Repository: pymedusa/Medusa

Issue:
Guessit error
Hi,

During Medusa scheduled process for scanning new release, the following exception has occurred for 2 days now :
```
2019-01-12 00:58:27 ERROR    SEARCHQUEUE-DAILY-SEARCH :: [NZBHydra2] :: [918cfe7] DailySearchQueueItem Exception, error: An internal error has occured in guessit.
===================== Guessit Exception Report =====================
version=3.0.3
string=Dakar.2019.uitzending.RTL7.dd.11/1.etappe.5
options={'allowed_languages': ['de', 'en', 'es', 'ca', 'cs', 'fr', 'he', 'hi', 'hu', 'it', 'ja', 'ko', 'nl', 'pl', 'pt', 'ro', 'ru', 'sv', 'te', 'uk', 'mul', 'und', 'jp'], 'expected_group': ['TV2LAX9', 'DHD', '20-40', 'E7'], 'expected_title': ['OSS 117', 'The 100'], 'allowed_countries': ['au', 'us', 'gb'], 'advanced_config': {'website': {'prefixes': ['from'], 'safe_tlds': ['com', 'org', 'net'], 'safe_prefixes': ['co', 'com', 'org', 'net'], 'safe_subdomains': ['www']}, 'container': {'info': ['nfo'], 'nzb': ['nzb'], 'subtitles': ['srt', 'idx', 'sub', 'ssa', 'ass'], 'videos': ['3g2', '3gp', '3gp2', 'asf', 'avi', 'divx', 'flv', 'mk3d', 'm4v', 'mk2', 'mka', 'mkv', 'mov', 'mp4', 'mp4a', 'mpeg', 'mpg', 'ogg', 'ogm', 'ogv', 'qt', 'ra', 'ram', 'rm', 'ts', 'wav', 'webm', 'wma', 'wmv', 'iso', 'vob'], 'torrent': ['torrent']}, 'language': {'language_prefixes': ['true'], 'subtitle_prefixes': ['st', 'v', 'vost', 'subforced', 'fansub', 'hardsub', 'legenda', 'legendas', 'legendado', 'subtitulado', 'soft', 'subtitles'], 'subtitle_affixes': ['sub', 'subs', 'esub', 'esubs', 'subbed', 'custom subbed', 'custom subs', 'custom sub', 'customsubbed', 'customsubs', 'customsub', 'soft subtitles', 'soft subs'], 'language_affixes': ['dublado', 'dubbed', 'dub'], 'synonyms': {'fra': ['fran\xc3\xa7ais', 'vf', 'vff', 'vfi', 'vfq'], 'ell': ['gr', 'greek'], 'jpn': ['jp'], 'por_BR': ['po', 'pb', 'pob', 'ptbr', 'br', 'brazilian'], 'hrv': ['scr'], 'swe': ['se'], 'ukr': ['ua'], 'cat': ['catal\xc3\xa0', 'castellano', 'espanol castellano', 'espa\xc3\xb1ol castellano'], 'ces': ['cz'], 'spa': ['esp', 'espa\xc3\xb1ol', 'espanol'], 'mul': ['multi', 'dl'], 'deu_CH': ['swissgerman', 'swiss german'], 'nld_BE': ['flemish'], 'zho': ['cn']}, 'weak_affixes': ['v', 'audio', 'true'], 'subtitle_suffixes': ['subforced', 'fansub', 'hardsub'], 'language_suffixes': ['audio']}, 'common_words': ['de', 'it'], 'screen_size': {'frame_rates': ['23.976', '24', '25', '30', '48', '50', '60', '120'], 'max_ar': 1.8979999999999999, 'min_ar': 1.333, 'progressive': ['360', '480', '576', '900', '1080', '368', '720', '1440', '2160', '4320'], 'interlaced': ['360', '480', '576', '900', '1080']}, 'episodes': {'season_markers': ['s'], 'range_separators': ['-', '~', 'to', 'a'], 'episode_max_range': 100, 'episode_markers': ['xe', 'ex', 'ep', 'e', 'x'], 'season_max_range': 100, 'disc_markers': ['d'], 'season_words': ['season', 'saison', 'seizoen', 'seasons', 'saisons', 'tem', 'temp', 'temporada', 'temporadas', 'stagione'], 'max_range_gap': 1, 'discrete_separators': ['+', '&', 'and', 'et'], 'season_ep_markers': ['x'], 'of_words': ['of', 'sur'], 'all_words': ['All'], 'episode_words': ['episode', 'episodes', 'eps', 'ep', 'episodio', 'episodios', 'capitulo', 'capitulos']}, 'part': {'prefixes': ['pt', 'part']}, 'groups': {'starting': '([{', 'ending': ')]}'}, 'country': {'synonyms': {'BR': ['brazilian', 'bra'], 'CA': ['qu\xc3\xa9bec', 'quebec', 'qc'], 'MX': ['Latinoam\xc3\xa9rica', 'latin america'], 'ES': ['espa\xc3\xb1a'], 'GB': ['UK']}}, 'release_group': {'forbidden_names': ['rip', 'by', 'for', 'par', 'pour', 'bonus'], 'ignored_seps': '[]{}()'}}, 'episode_prefer_number': False, 'type': 'episode', 'implicit': True}
--------------------------------------------------------------------
Traceback (most recent call last):
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/guessit/api.py", line 197, in guessit
    matches = self.rebulk.matches(string, options)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rebulk.py", line 288, in matches
    self._execute_rules(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rebulk.py", line 319, in _execute_rules
    rules.execute_all_rules(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rules.py", line 316, in execute_all_rules
    when_response = execute_rule(rule, matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rules.py", line 337, in execute_rule
    when_response = rule.when(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/name_parser/rules/rules.py", line 1098, in when
    if season and not second_part.endswith(season[-1].initiator.value):
TypeError: endswith first arg must be str, unicode, or tuple, not int
--------------------------------------------------------------------
Please report at https://github.com/guessit-io/guessit/issues.
====================================================================
Traceback (most recent call last):
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/search/queue.py", line 263, in run
    found_results = search_for_needed_episodes(self.scheduler_start_time, force=self.force)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/search/core.py", line 524, in search_for_needed_episodes
    cur_provider.cache.update_cache(scheduler_start_time)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/tv/cache.py", line 234, in update_cache
    result = self._parse_item(item)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/tv/cache.py", line 313, in _parse_item
    leechers, size, pubdate)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/tv/cache.py", line 383, in add_cache_entry
    parse_result = parsed_result or NameParser().parse(name)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/name_parser/parser.py", line 367, in parse
    result = self._parse_string(name)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/name_parser/parser.py", line 275, in _parse_string
    guess = guessit.guessit(name, dict(show_type=self.show_type))
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/name_parser/guessit_parser.py", line 80, in guessit
    result = default_api.guessit(name, options=final_options)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/guessit/api.py", line 209, in guessit
    raise GuessitException(string, options)
GuessitException: An internal error has occured in guessit.
===================== Guessit Exception Report =====================
version=3.0.3
string=Dakar.2019.uitzending.RTL7.dd.11/1.etappe.5
options={'allowed_languages': ['de', 'en', 'es', 'ca', 'cs', 'fr', 'he', 'hi', 'hu', 'it', 'ja', 'ko', 'nl', 'pl', 'pt', 'ro', 'ru', 'sv', 'te', 'uk', 'mul', 'und', 'jp'], 'expected_group': ['TV2LAX9', 'DHD', '20-40', 'E7'], 'expected_title': ['OSS 117', 'The 100'], 'allowed_countries': ['au', 'us', 'gb'], 'advanced_config': {'website': {'prefixes': ['from'], 'safe_tlds': ['com', 'org', 'net'], 'safe_prefixes': ['co', 'com', 'org', 'net'], 'safe_subdomains': ['www']}, 'container': {'info': ['nfo'], 'nzb': ['nzb'], 'subtitles': ['srt', 'idx', 'sub', 'ssa', 'ass'], 'videos': ['3g2', '3gp', '3gp2', 'asf', 'avi', 'divx', 'flv', 'mk3d', 'm4v', 'mk2', 'mka', 'mkv', 'mov', 'mp4', 'mp4a', 'mpeg', 'mpg', 'ogg', 'ogm', 'ogv', 'qt', 'ra', 'ram', 'rm', 'ts', 'wav', 'webm', 'wma', 'wmv', 'iso', 'vob'], 'torrent': ['torrent']}, 'language': {'language_prefixes': ['true'], 'subtitle_prefixes': ['st', 'v', 'vost', 'subforced', 'fansub', 'hardsub', 'legenda', 'legendas', 'legendado', 'subtitulado', 'soft', 'subtitles'], 'subtitle_affixes': ['sub', 'subs', 'esub', 'esubs', 'subbed', 'custom subbed', 'custom subs', 'custom sub', 'customsubbed', 'customsubs', 'customsub', 'soft subtitles', 'soft subs'], 'language_affixes': ['dublado', 'dubbed', 'dub'], 'synonyms': {'fra': ['fran\xc3\xa7ais', 'vf', 'vff', 'vfi', 'vfq'], 'ell': ['gr', 'greek'], 'jpn': ['jp'], 'por_BR': ['po', 'pb', 'pob', 'ptbr', 'br', 'brazilian'], 'hrv': ['scr'], 'swe': ['se'], 'ukr': ['ua'], 'cat': ['catal\xc3\xa0', 'castellano', 'espanol castellano', 'espa\xc3\xb1ol castellano'], 'ces': ['cz'], 'spa': ['esp', 'espa\xc3\xb1ol', 'espanol'], 'mul': ['multi', 'dl'], 'deu_CH': ['swissgerman', 'swiss german'], 'nld_BE': ['flemish'], 'zho': ['cn']}, 'weak_affixes': ['v', 'audio', 'true'], 'subtitle_suffixes': ['subforced', 'fansub', 'hardsub'], 'language_suffixes': ['audio']}, 'common_words': ['de', 'it'], 'screen_size': {'frame_rates': ['23.976', '24', '25', '30', '48', '50', '60', '120'], 'max_ar': 1.8979999999999999, 'min_ar': 1.333, 'progressive': ['360', '480', '576', '900', '1080', '368', '720', '1440', '2160', '4320'], 'interlaced': ['360', '480', '576', '900', '1080']}, 'episodes': {'season_markers': ['s'], 'range_separators': ['-', '~', 'to', 'a'], 'episode_max_range': 100, 'episode_markers': ['xe', 'ex', 'ep', 'e', 'x'], 'season_max_range': 100, 'disc_markers': ['d'], 'season_words': ['season', 'saison', 'seizoen', 'seasons', 'saisons', 'tem', 'temp', 'temporada', 'temporadas', 'stagione'], 'max_range_gap': 1, 'discrete_separators': ['+', '&', 'and', 'et'], 'season_ep_markers': ['x'], 'of_words': ['of', 'sur'], 'all_words': ['All'], 'episode_words': ['episode', 'episodes', 'eps', 'ep', 'episodio', 'episodios', 'capitulo', 'capitulos']}, 'part': {'prefixes': ['pt', 'part']}, 'groups': {'starting': '([{', 'ending': ')]}'}, 'country': {'synonyms': {'BR': ['brazilian', 'bra'], 'CA': ['qu\xc3\xa9bec', 'quebec', 'qc'], 'MX': ['Latinoam\xc3\xa9rica', 'latin america'], 'ES': ['espa\xc3\xb1a'], 'GB': ['UK']}}, 'release_group': {'forbidden_names': ['rip', 'by', 'for', 'par', 'pour', 'bonus'], 'ignored_seps': '[]{}()'}}, 'episode_prefer_number': False, 'type': 'episode', 'implicit': True}
--------------------------------------------------------------------
Traceback (most recent call last):
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/guessit/api.py", line 197, in guessit
    matches = self.rebulk.matches(string, options)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rebulk.py", line 288, in matches
    self._execute_rules(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rebulk.py", line 319, in _execute_rules
    rules.execute_all_rules(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rules.py", line 316, in execute_all_rules
    when_response = execute_rule(rule, matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/ext/rebulk/rules.py", line 337, in execute_rule
    when_response = rule.when(matches, context)
  File "/volume1/@appstore/sickbeard-custom/var/SickBeard/medusa/name_parser/rules/rules.py", line 1098, in when
    if season and not second_part.endswith(season[-1].initiator.value):
TypeError: endswith first arg must be str, unicode, or tuple, not int
--------------------------------------------------------------------
Please report at https://github.com/guessit-io/guessit/issues.
====================================================================
```

I've reported this to Guessit team (https://github.com/guessit-io/guessit/issues/586), who told me to report here, as it seems related to Medusa rules



Discussion:

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
@@ -1095,7 +1095,7 @@ def when(self, matches, context):
 
                 if second_part.startswith(title[0].value):
                     season = matches.named('season')
-                    if season and not second_part.endswith(season[-1].initiator.value):
+                    if season and not second_part.endswith(str(season[-1].initiator.value)):
                         episode_title[0].name = 'title'
                         to_append = episode_title
                         to_remove = title


Test patch: