Repository: Flexget/Flexget

Issue:
Rejecting episode because detected as season pack 
I have recently encountered an issue where an episode is being rejected because it is detected as a season pack.  It does accept it if season_packs is enabled, however the metadata will be incorrect.  For sanity purposes, I have also tested with Flexget version 2.10.24, prior to introduction of Season packs support - Phase 1 #1710, and the episode is accepted as expected. 

I'm not sure why this is being detected as a season pack, nor do I believe the fault lies in the detection system.  It would seem to me that once it is determined as an episode, it should not go through the season pack detection, but I'm not sure that's correct either.  

since it does work normally in 2.10.24... It occurs to me that since the introduction of season pack support, anything detected as a season pack is either accepted or rejected.  There is not an option to disable the season pack parser from running or to configure Flexget to not make decisions about season packs.  Personally, I see no reason to explicitly reject the season packs verses leaving them undecided.

### Expected behavior:
Should be accepted as episode

### Actual behavior:
Entry initially determines episode number properly, however it is later detected as a season pack and subsequently is rejected 

### Steps to reproduce:
Use provided config and example [input](https://www.pastiebin.com/59dfc9f16ad82)

#### Config:
```
tasks:
  test1:
    rss: /home/test/input.rss
    all_series:
      target: 720p
```
- example input: https://www.pastiebin.com/59dfc9f16ad82
  
#### Log:
```
2017-10-12 15:42 TRACE    entry         test1           ENTRY SET: description = u'Show Name:Mr. Robot; Show Title: eps3.0_power-saver-mode.h (720p .mkv HDTV); Season: 3; **Episode: 01**; Filename: Mr.Robot.S03E01.720p.HDTV.x264-AVS.mkv'
2017-10-12 15:42 DEBUG    parser_internal test1           Parsing result: <SeriesParser(data=Mr. Robot - 3x01 - eps3.0_power-saver-mode.h (720p .mkv HDTV),name=Mr Robot,id=S3,season=3,**season_pack=True,episode=None**,quality=720p hdtv,proper=0,status=OK)> (in 21.011 ms)
2017-10-12 15:42 VERBOSE  task          test1           REJECTED: `Mr. Robot - 3x01 - eps3.0_power-saver-mode.h (720p .mkv HDTV)` by series plugin because season pack support is turned off
```
- Link to full trace log: https://www.pastiebin.com/59dfc6bc238bf

### Additional information:

- FlexGet version: 2.10.98
- Python version: 2.7.13
- Installation method: pip
- Using daemon (yes/no): no
- OS and version: Debian Stretch
- Link to crash log: no crash





Discussion:
I think it trips the regexp because of the `s3.` part in the episode title. Probably just need to tweak the regexp a bit 
that makes sense, the episode names of this show are quite unusual.  I'm not very strong with regexp 

any thoughts on my comment regarding the changes introduced by the default handling of the season_packs plugin? 

Resolving patch:
diff --git a/flexget/utils/titles/series.py b/flexget/utils/titles/series.py
--- a/flexget/utils/titles/series.py
+++ b/flexget/utils/titles/series.py
@@ -317,41 +317,40 @@ def parse(self, data=None, field=None, quality=None):
                 log.debug('-> no luck with date_regexps')
 
         if self.identified_by in ['ep', 'auto'] and not self.valid:
-            season_pack_match = self.parse_season_packs(data_stripped)
-            # If a title looks like a special, give it precendance over season pack
-            if season_pack_match and not self.special:
+            ep_match = self.parse_episode(data_stripped)
+            if ep_match:
+                # strict_name
                 if self.strict_name:
-                    if season_pack_match['match'].start() > 1:
+                    if ep_match['match'].start() > 1:
                         return
-                self.season = season_pack_match['season']
-                self.season_pack = True
-                self.id = 'S%s' % season_pack_match['season']
+
+                if ep_match['end_episode'] and ep_match['end_episode'] > ep_match['episode'] + 2:
+                    # This is a pack of too many episodes, ignore it.
+                    log.debug('Series pack contains too many episodes (%d). Rejecting',
+                              ep_match['end_episode'] - ep_match['episode'])
+                    return
+
+                self.season = ep_match['season']
+                self.episode = ep_match['episode']
+                if ep_match['end_episode']:
+                    self.episodes = (ep_match['end_episode'] - ep_match['episode']) + 1
+                else:
+                    self.episodes = 1
                 self.id_type = 'ep'
                 self.valid = True
+                if not (self.special and self.prefer_specials):
+                    return
             else:
-                ep_match = self.parse_episode(data_stripped)
-                if ep_match:
-                    # strict_name
-                    if self.strict_name:
-                        if ep_match['match'].start() > 1:
-                            return
-
-                    if ep_match['end_episode'] and ep_match['end_episode'] > ep_match['episode'] + 2:
-                        # This is a pack of too many episodes, ignore it.
-                        log.debug('Series pack contains too many episodes (%d). Rejecting',
-                                  ep_match['end_episode'] - ep_match['episode'])
+                season_pack_match = self.parse_season_packs(data_stripped)
+                # If a title looks like a special, give it precedence over season pack
+                if season_pack_match and not self.special:
+                    if self.strict_name and season_pack_match['match'].start() > 1:
                         return
-
-                    self.season = ep_match['season']
-                    self.episode = ep_match['episode']
-                    if ep_match['end_episode']:
-                        self.episodes = (ep_match['end_episode'] - ep_match['episode']) + 1
-                    else:
-                        self.episodes = 1
+                    self.season = season_pack_match['season']
+                    self.season_pack = True
+                    self.id = 'S%s' % season_pack_match['season']
                     self.id_type = 'ep'
                     self.valid = True
-                    if not (self.special and self.prefer_specials):
-                        return
                 else:
                     log.debug('-> no luck with ep_regexps')
 
@@ -577,13 +576,13 @@ def parse_season_packs(self, data):
                 if len(matches) == 1:
                     # Single season full pack, no parts etc
                     season = int(matches[0])
+                    return {
+                        'season': season,
+                        'match': match
+                    }
                 elif len(matches) == 2:
                     # TODO support other formats of season packs: 1xall, s01-PART1, etc.
                     pass
-                return {
-                    'season': season,
-                    'match': match
-                }
 
     def roman_to_int(self, roman):
         """Converts roman numerals up to 39 to integers"""


Test patch:
diff --git a/flexget/tests/test_seriesparser.py b/flexget/tests/test_seriesparser.py
--- a/flexget/tests/test_seriesparser.py
+++ b/flexget/tests/test_seriesparser.py
@@ -607,3 +607,12 @@ def test_long_season(self, parse):
         assert s.episode == 14
         assert s.quality.name == '720p hdtv h264 aac'
         assert not s.proper, 'detected proper'
+
+    def test_episode_with_season_pack_match_is_not_season_pack(self, parse):
+        """SeriesParser: Github issue #1986, s\d{1} parses as invalid season"""
+        s = parse(name='The Show', data='The.Show.S01E01.eps3.0.some.title.720p.x264-NOGRP')
+        assert s.valid
+        assert not s.season_pack
+        assert s.season == 1
+        assert s.episode == 1
+