flexget.plugins.filter.thetvdb
Covered: 77 lines
Missed: 93 lines
Skipped 61 lines
Percent: 45 %
  1
import logging
  2
from flexget.plugin import register_plugin, priority, get_plugin_by_name, PluginError
  3
from flexget.utils.log import log_once
  5
log = logging.getLogger('thetvdb')
  8
class FilterTvdb(object):
  9
    """
 10
        This plugin allows filtering based on thetvdb series rating,
 11
        episode rating, status, genres, runtime, content-rating,
 12
        languages, directors, writers, network, guest stars, episode
 13
        rating, and actors
 15
        series info:
 16
            series_rating
 17
            series_status (Continuing or Ended)
 18
            series_runtime (show runtime in minutes)
 19
            series_content_rating
 20
            series_genres
 21
            series_network
 22
            series_actors
 23
            series_language (en, fr, etc.)
 24
          episode info: (if episode is found)
 25
            ep_director
 26
            ep_writer
 27
            ep_rating
 28
            ep_guest_stars
 29
            ep_air_date
 31
        Configuration:
 33
        Note: All parameters are optional. Some are mutually exclusive.
 35
        min_series_rating: <num>
 36
        min_episode_rating: <num>
 37
        min_episode_air_year: <num>
 38
        max_episode_air_year: <num>
 39
        min_episode_runtime: <num>
 40
        max_episode_runtime: <num>
 43
        reject_content_rating:
 44
            - TV-MA
 46
        accept_content_rating:
 47
            - TV-PG
 50
        accept_network:
 51
            - NBC
 53
        reject_network:
 54
            - ABC
 57
        reject_genres:
 58
            - drama
 59
            - romance
 62
        reject_status:
 63
            - Ended
 66
        reject_languages:
 67
            - fr
 69
        accept_languages:
 70
            - en
 74
        accept_actors:
 75
            - Heidi Klum
 76
            - Bruce Willis
 78
        reject_actors:
 79
            - Cher
 80
            - Tamala Jones
 83
        accept_writers:
 84
            - Andrew W. Marlowe
 86
        reject_writers:
 87
            - Barry Schindel
 90
        accept_directors:
 91
            - Rob Bowman
 93
        reject_directors:
 94
            - John Terlesky
 95
    """
 97
    def validator(self):
 98
        """Validate given configuration"""
 99
        from flexget import validator
100
        thetvdb = validator.factory('dict')
101
        thetvdb.accept('number', key='min_series_rating')
102
        thetvdb.accept('number', key='min_episode_rating')
103
        thetvdb.accept('integer', key='min_episode_air_year')
104
        thetvdb.accept('integer', key='max_episode_air_year')
105
        thetvdb.accept('number', key='min_episode_runtime')
106
        thetvdb.accept('number', key='max_episode_runtime')
107
        thetvdb.accept('list', key='reject_content_rating').accept('text')
108
        thetvdb.accept('list', key='accept_content_rating').accept('text')
109
        thetvdb.accept('list', key='accept_network').accept('text')
110
        thetvdb.accept('list', key='reject_network').accept('text')
111
        thetvdb.accept('list', key='reject_genres').accept('text')
112
        thetvdb.accept('list', key='reject_status').accept('text')
113
        thetvdb.accept('list', key='reject_languages').accept('text')
114
        thetvdb.accept('list', key='accept_languages').accept('text')
115
        thetvdb.accept('list', key='accept_actors').accept('text')
116
        thetvdb.accept('list', key='reject_actors').accept('text')
117
        thetvdb.accept('list', key='accept_writers').accept('text')
118
        thetvdb.accept('list', key='reject_writers').accept('text')
119
        thetvdb.accept('list', key='accept_directors').accept('text')
120
        thetvdb.accept('list', key='reject_directors').accept('text')
121
        return thetvdb
123
    def is_in_set(self, config, configkey, entryitem,):
124
        '''
125
        this takes the config object, config key (to a list), and entry
126
        item so it can return True if the object matches,
127
        (be that a subset of the list, or if the entry item is contained
128
        within the config object list) or false if it does not.
129
        '''
132
        if configkey in config:
133
            configlist = config[configkey]
134
            if isinstance(entryitem, list):
135
                for item in entryitem:
136
                    if item in configlist:
137
                        return True
138
            else:
139
                if entryitem in configlist:
140
                    return True
141
        return False
143
    @priority(126)
144
    def on_feed_filter(self, feed):
145
        config = feed.config['thetvdb']
147
        lookup = get_plugin_by_name('thetvdb_lookup').instance.lookup
150
        for entry in feed.entries:
151
            force_accept = False
153
            try:
154
                lookup(feed, entry)
155
            except PluginError, e:
156
                log.error('Skipping %s because of an error: %s' % (entry['title'], e.value))
157
                continue
160
            reasons = []
161
            if 'min_series_rating' in config:
162
                if entry['series_rating'] < config['min_series_rating']:
163
                    reasons.append('series_rating (%s < %s)' % (entry['series_rating'], config['min_series_rating']))
164
            if 'min_episode_rating' in config:
165
                if entry['ep_rating'] < config['min_episode_rating']:
166
                    reasons.append('ep_rating (%s < %s)' % (entry['ep_rating'], config['min_episode_rating']))
167
            if 'min_episode_air_year' in config:
168
                if entry['ep_air_date'].strftime("%Y") < config['min_episode_air_year']:
169
                    reasons.append('ep_air_date (%s < %s)' % (entry['ep_air_date'].strftime("%Y"), config['min_episode_air_year']))
170
            if 'max_episode_air_year' in config:
171
                if entry['ep_air_date'].strftime("%Y") > config['max_episode_air_year']:
172
                    reasons.append('ep_air_date (%s < %s)' % (entry['ep_air_date'].strftime("%Y"), config['max_episode_air_year']))
174
            if self.is_in_set(config, 'reject_content_rating', entry['series_content_rating']):
175
                reasons.append('reject_content_rating')
177
            if not self.is_in_set(config, 'accept_content_rating', entry['series_content_rating']):
178
                reasons.append('accept_content_rating')
180
            if self.is_in_set(config, 'reject_network', entry['series_network']):
181
                reasons.append('reject_network')
183
            if not self.is_in_set(config, 'accept_network', entry['series_network']):
184
                reasons.append('accept_network')
186
            if self.is_in_set(config, 'reject_genres', entry['series_genres']):
187
                reasons.append('reject_genres')
189
            if self.is_in_set(config, 'reject_status', entry['series_status']):
190
                reasons.append('reject_status')
192
            if self.is_in_set(config, 'reject_languages', entry['series_language']):
193
                reasons.append('reject_languages')
195
            if not self.is_in_set(config, 'accept_languages', entry['series_language']):
196
                reasons.append('accept_languages')
199
            if self.is_in_set(config, 'accept_actors', entry['series_actors'] + entry['ep_guest_stars']):
200
                force_accept = True
202
            if self.is_in_set(config, 'reject_actors', entry['series_actors'] + entry['ep_guest_stars']):
203
                reasons.append('reject_genres')
206
            if self.is_in_set(config, 'accept_writers', entry['ep_writer']):
207
                force_accept = True
209
            if self.is_in_set(config, 'reject_writers', entry['ep_writer']):
210
                reasons.append('reject_writers')
213
            if self.is_in_set(config, 'accept_directors', entry['ep_director']):
214
                force_accept = True
216
            if self.is_in_set(config, 'reject_directors', entry['ep_director']):
217
                reasons.append('reject_directors')
219
            if reasons and not force_accept:
220
                msg = 'Skipping %s because of rule(s) %s' % \
221
                    (entry.get('series_name_thetvdb', None) or entry['title'], ', '.join(reasons))
222
                if feed.manager.options.debug:
223
                    log.debug(msg)
224
                else:
225
                    log_once(msg, log)
226
            else:
227
                log.debug('Accepting %s' % (entry))
228
                feed.accept(entry)
230
register_plugin(FilterTvdb, 'thetvdb')