flexget.utils.titles.movie
Covered: 74 lines
Missed: 1 lines
Skipped 42 lines
Percent: 98 %
  1
import logging
  2
import re
  3
from flexget.utils.titles.parser import TitleParser
  4
from flexget.utils import qualities
  6
log = logging.getLogger('movieparser')
  9
def diff_pos(string1, string2):
 10
    """Returns first position where string1 and string2 differ."""
 11
    for (count, c) in enumerate(string1):
 12
        if len(string2) <= count:
 13
            return count
 14
        if string2[count] != c:
 15
            return count
 18
class MovieParser(TitleParser):
 20
    def __init__(self):
 21
        self.data = None
 22
        self.reset()
 23
        TitleParser.__init__(self)
 25
    def reset(self):
 27
        self.name = None
 28
        self.year = None
 29
        self.quality = qualities.UNKNOWN
 30
        self.proper_count = 0
 32
    def __str__(self):
 33
        return "<MovieParser(name=%s,year=%s,quality=%s)>" % (self.name, self.year, self.quality)
 35
    def parse(self, data=None):
 36
        """Parse movie name. Populates name, year, quality and proper_count attributes"""
 39
        self.reset()
 41
        if data is None:
 42
            data = self.data
 44
        for char in '[]()_,.':
 45
            data = data.replace(char, ' ')
 48
        if data.find(' ') == -1:
 49
            data = data.replace('-', ' ')
 52
        self.remove_words(data, self.remove)
 54
        data = self.strip_spaces(data)
 57
        parts = data.split(' ')
 58
        year = None
 59
        cut_part = 256
 60
        for part_pos, part in enumerate(parts):
 61
            cut = False
 63
            if part_pos < 1:
 64
                continue
 66
            if part.isdigit():
 67
                num = int(part)
 68
                if 1930 < num < 2050:
 69
                    year = part
 70
                    cut = True
 72
            if len(part) > 3 and part.isupper() and part.isalpha() and part_pos > 0:
 73
                cut = True
 75
            if part.lower() in self.cutoffs:
 76
                cut = True
 78
            if part.lower() in self.propers:
 79
                self.proper_count += 1
 80
                cut = True
 82
            if cut and parts.index(part) < cut_part:
 83
                cut_part = part_pos
 85
        if cut_part != 256:
 86
            log.debug('parts: %s, cut is: %s' % (parts, parts[cut_part]))
 89
        abs_cut = len(' '.join(parts[:cut_part]))
 91
        log.debug('after parts check, cut data would be: `%s` abs_cut: %i' % (data[:abs_cut], abs_cut))
 94
        quality, remaining = qualities.quality_match(data)
 95
        if quality:
 96
            self.quality = quality
100
            dp = diff_pos(data, remaining)
101
            if dp is not None:
102
                log.debug('quality start: %s' % dp)
103
                if dp < abs_cut:
104
                    log.debug('quality cut is even shorter')
105
                    abs_cut = dp
108
        data = data[:abs_cut].strip()
109
        log.debug('data cut to `%s` - this will be the name' % data)
112
        self.name = data
114
        if year:
115
            if year.isdigit():
116
                self.year = int(year)