]> git.rmz.io Git - dotfiles.git/commitdiff
Merge branch 'flexget'
authorSamir Benmendil <samir.benmendil@gmail.com>
Wed, 7 Jan 2015 02:49:21 +0000 (02:49 +0000)
committerSamir Benmendil <samir.benmendil@gmail.com>
Wed, 7 Jan 2015 02:49:21 +0000 (02:49 +0000)
flexget/.gitignore
flexget/config.yml
flexget/plugins/my_exists_movie.py [new file with mode: 0644]

index 9625a7507edfcab9d06c0c11dd9c88308a91c37b..3d4e12431a0d5b89ae187fc8bd2a14ec830550a8 100644 (file)
@@ -1,4 +1,7 @@
 db-config.sqlite
+test-config.sqlite
 flexget.log*
 received/
 temp/
+private.yml
+.config-lock
index e306cf9c5bc34ac4ae0a9f540b66970f74653842..40b5b2659dff3792ad22b6030094a21884059353 100644 (file)
-email:
+secrets: private.yml
+
+email: # {{{1
   from: flexget@tardis
   to: ramsi@localhost
 
-presets:
-  tv:
+templates: # {{{1
+  torrents: # {{{2
+    inputs:
+      - rss: { url: 'https://ezrss.it/feed/', silent: yes }
+      - rss: { url: 'http://publichd.se/rss.php', silent: yes }
+      - rss: { url: 'http://rss.bt-chat.com/?group=3', silent: yes }
+      - rss: { url: 'http://kickass.to/tv/?rss=1', silent: yes }
+      - rss: { url: 'http://showrss.info/feeds/all.rss', silent: yes }
+      # - rss: { url: 'http://www.torlock.com/television/rss.xml', silent: yes }
+      # - rss: { url: 'http://torrentz.eu/feed_verified?q=tv', silent: yes }
+      # - rss: { url: 'http://rss.thepiratebay.org/208', silent: yes }
+
+    transmission:
+      host: localhost
+      port: 9091
+      path: /mnt/Skaro/torrents/done
+      ratio: 0.0
+
+  usenet: # {{{2
+    sabnzbd:
+      key: '{{secrets.sabnzbd.key}}'
+      url: '{{secrets.sabnzbd.url}}'
+
+  usenet_paused: # {{{2
+    sabnzbd:
+      key: '{{secrets.sabnzbd.key}}'
+      url: '{{secrets.sabnzbd.url}}'
+      priority: -2
+
+  usenet-movies: # {{{2
+    template: usenet
+    set:
+      category: 'to check'
+    inputs:
+      - rss: { url: 'https://www.usenet-crawler.com/rss?t=2040&dl=1&num=100{{secrets.crawler.api}}', silent: yes } # Movies HD
+
+  usenet-tv: # {{{2
+    template: usenet
+    inputs:
+      - rss: { url: 'https://www.usenet-crawler.com/rss?t=5030&dl=1&num=100{{secrets.crawler.api}}', silent: yes } # TV SD
+      - rss: { url: 'https://www.usenet-crawler.com/rss?t=5040&dl=1&num=100{{secrets.crawler.api}}', silent: yes } # TV HD
+
+  filters: # {{{2
     content_filter:
+      require:
+        - '*.mkv'
+        - '*.mp4'
       reject:
+        - 'filename.mkv'
         - '*.rar'
         - '*.r0*'
         - '*.wmv'
+        - '*.exe'
+    regexp:
+      reject:
+        - \b3-?D\b:       {from: title}
+        - \btrailer\b:    {from: title} # I've gotten a few trailers that matched as movies. VERY annoying
+        - \bR5\b:         {from: title} # The following are poor quality types that somehow got through the quality
+        - \bWEBSCR\b:     {from: title} # features usually due to the title including a keyword like "720p" as well
+        - \bscreener\b:   {from: title}
+        - \bTS\b:         {from: title}
+        - \bCam\b:        {from: title}
+        - '{C_P}':        {from: title} # The following are groups with poor quality releases
+        - TrTd TeaM:      {from: title}
+        - \[TNTVillage\]: {from: title}
+        - \[facepalm\]:   {from: title}
+        - \bASAP\b:       {from: title}
+        - \b Go\):        {from: title} # filter those misplaced french only movies
 
-    exists_series:
-      - "/mnt/Skaro/Series"
-
+  tv: # {{{2
     series:
-      settings:
-        normal:
-          timeframe: 12 hours
-          target: 1080p webdl
-          quality: 480p+
-          upgrade: yes
-
       normal:
         - 8 out of 10 cats
         - american dad
-        - breaking bad
+        - archer 2009
         - boardwalk empire
+        - breaking bad
+        - broadchurch
         - burn notice
         - chuck
+        - community
         - dexter
-        - doctor who
+        - doctor who 2005
         - downton abbey
         - eureka
         - family guy
+        - foyle's war
         - futurama
         - game of thrones
-        - house
+        - homeland
         - how i met your mother
+        - last week tonight with john oliver
+        - master of sex
         - my little pony
-        - qi
+        - mythbusters
+        - qi (xl)
         - ray donovan
         - red dwarf
         - sherlock
+        - suits
         - the big bang theory
+        - the blacklist
         - the cleveland show
         - the walking dead
         - two and a half men
-        - weeds
+        - the wire:
+            quality: 720p+
 
-    transmission:
-      host: localhost
-      port: 9091
-      path: /mnt/Skaro/Torrents.flex
-      removewhendone: yes
-      ratio: 0.0
+  movies: # {{{2
+    imdb:
+      min_score: 7.5
+      min_votes: 50000
+    imdb_required: on
+    my_exists_movie:
+      path:
+        - '/mnt/Skaro/Movies'
+      allow_different_qualities: better
+      type: files
+    seen_movies: strict
+
+tasks: # {{{1
+  tv-shows: # {{{2
+    series:
+      settings:
+        normal:
+          timeframe: 12 hours
+          target: 1080p webdl
+          quality: 480p+
+          upgrade: yes
 
-tasks:
-  tv-shows:
     priority: 1
-    inputs:
-      - rss: { url: 'https://ezrss.it/feed/', silent: yes }
-      - rss: { url: 'http://publichd.se/rss.php', silent: yes }
-      - rss: { url: 'http://rss.bt-chat.com/?group=3', silent: yes }
-      - rss: { url: 'http://kickass.to/tv/?rss=1', silent: yes }
-      - rss: { url: 'http://showrss.info/feeds/all.rss', silent: yes }
-#      - rss: { url: 'http://www.torlock.com/television/rss.xml', silent: yes }
-#      - rss: { url: 'http://torrentz.eu/feed_verified?q=tv', silent: yes }
-#      - rss: { url: 'http://rss.thepiratebay.org/208', silent: yes }
-    preset: tv
+    template:
+      - tv
+      - filters
+      - usenet-tv
+    exists_series:
+      path: '/mnt/Skaro/Series/{{tvdb_series_name}}'
+      allow_different_qualities: better
+    content_size:
+      min:  100
+      max: 6000
+      strict: yes
 
+  movies-1080p: # {{{2
+    priority: 1
+    template:
+      - movies
+      - filters
+      - usenet-movies
+    quality: 1080p webdl+
+    content_size:
+      min:  3000
+      max: 15000
+      strict: yes
 
-  move-episodes:
+  movies-720p: # {{{2
+    priority: 2
+    template:
+      - movies
+      - filters
+      - usenet-movies
+    quality: 720p hdrip+
+    delay: 7 days
+    content_size:
+      min:  1000
+      max: 10000
+      strict: yes
+
+  move-tv: # {{{2
     priority: 2
     thetvdb_lookup: yes
     metainfo_series: yes
-    accept_all: yes
-    # only reject files that have been seen by this task
     seen: local
+    disable_builtins: [retry_failed]
+    all_series:
+      parse_only: yes
+    accept_all: yes
 
     find:
-      path: /mnt/Skaro/Torrents.flex
+      path:
+        - /mnt/Skaro/usenet/done
+        - /mnt/Skaro/torrents/done
       recursive: yes
-      regexp: '.*\.(avi|mkv|mp4|mpg|divx)$'
+      regexp: '.*\.(avi|mkv|mp4|mpg|divx|webm)$'
 
     regexp:
       reject:
@@ -89,21 +195,65 @@ tasks:
 
     move:
       to: "/mnt/Skaro/Series/{{tvdb_series_name}}/{% if tvdb_season == 0 %}Specials{% else %}Season {{tvdb_season}}{% endif %}/"
-      filename: "{{tvdb_season}}x{{tvdb_episode|pad(2)}} {{tvdb_ep_name|replace('/','-')}} ({{tvdb_ep_air_date|formatdate('%Y')}}){{'{'}}{{quality|replace(' ','}{')}}{{'}'}}[en]{{location|pathext}}"
+      filename: "{{tvdb_season}}x{{tvdb_episode|pad(2)}} {{tvdb_ep_name|replace('/','-')}} ({{tvdb_ep_air_date|formatdate('%Y')}}){{'{'}}{{quality|replace(' ','}{')}}{{'}'}}[en]"
+      clean_source: 100   # removes dir if < [N] MB
 
-  move-movies:
+  move-movies: # {{{2
     priority: 3
-    tmdb_lookup: yes
+    imdb_lookup: yes
     accept_all: yes
     seen: local
+    disable_builtins: [retry_failed]
 
     find:
-      path: /mnt/Skaro/Torrents.flex
+      path:
+        - /mnt/Skaro/usenet/done
+        - /mnt/Skaro/torrents/done
       recursive: yes
       regexp: '.*\.(mkv|avi|mp4)$'
 
     move:
       to: "/mnt/Skaro/Movies"
-      filename: "{{tmdb_name}} ({{tmdb_year}}){{'{'}}{{quality|replace(' ','}{')}}{{'}'}}[en]{{location|pathext}}"
+      filename: "{{imdb_name}} ({{imdb_year}}){{'{'}}{{quality|replace(' ','}{')}}{{'}'}}[en]"
+      clean_source: 100   # removes dir if < [N] MB
+
+  seed-tv-db: # {{{2
+    manual: yes
+    find:
+      path: '/mnt/Skaro/Series'
+      regexp: '.*\.(avi|mkv|mp4|webm)$'
+      recursive: yes
+    require_field:
+      - series_name
+    manipulate:
+      - title:
+          from: location
+          replace:
+            regexp: '.*/([^/]+)/[^/]+/(\d+)x(\d+)([^/]*)\.[^.]+$'
+            format: '\1 S\2E\3\4'
+      - title:
+          replace:
+            regexp: '\[.*\]'
+            format: ''
+      - title:
+          replace:
+            regexp: '[\(\)\{\}]'
+            format: ' '
+    all_series: yes
+    assume_quality: 480p
+    # template: tv
+    # configure_series:
+    #   from:
+    #     listdir:
+    #       - /mnt/Skaro/Series
+    # series:
+    #   settings:
+    #     normal:
+    #       target: 480p
+
+schedules: # {{{1
+  - tasks: '*'
+    interval:
+      hours: 1
 
 # vim: sts=2 ts=2 sw=2 et
diff --git a/flexget/plugins/my_exists_movie.py b/flexget/plugins/my_exists_movie.py
new file mode 100644 (file)
index 0000000..92d6e12
--- /dev/null
@@ -0,0 +1,156 @@
+from __future__ import unicode_literals, division, absolute_import
+import os
+import re
+import logging
+
+from flexget import plugin
+from flexget.event import event
+from flexget.config_schema import one_or_more
+from flexget.plugin import get_plugin_by_name
+from flexget.utils.tools import TimedDict
+
+log = logging.getLogger('my_exists_movie')
+
+
+class FilterExistsMovie(object):
+    """
+    Reject existing movies.
+
+    Example::
+
+      exists_movie: /storage/movies/
+    """
+
+    schema = {
+        'anyOf': [
+            one_or_more({'type': 'string', 'format': 'path'}),
+            {
+                'type': 'object',
+                'properties': {
+                    'path': one_or_more({'type': 'string', 'format': 'path'}),
+                    'allow_different_qualities': {'enum': ['better', True, False], 'default': False},
+                    'type': {'enum': ['files', 'dirs'], 'default': 'files'}
+                },
+                'required': ['path'],
+                'additionalProperties': False
+            }
+        ]
+    }
+
+    def __init__(self):
+        self.cache = TimedDict(cache_time='1 hour')
+
+    def prepare_config(self, config):
+        # if config is not a dict, assign value to 'path' key
+        if not isinstance(config, dict):
+            config = {'path': config}
+        # if only a single path is passed turn it into a 1 element list
+        if isinstance(config['path'], basestring):
+            config['path'] = [config['path']]
+        return config
+
+    @plugin.priority(-1)
+    def on_task_filter(self, task, config):
+        # if not task.accepted:
+        #     log.debug('nothing accepted, aborting')
+        #     return
+
+        config = self.prepare_config(config)
+        imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance
+
+        incompatible_files = 0
+        incompatible_entries = 0
+        count_entries = 0
+        count_files = 0
+
+        # list of imdb ids gathered from paths / cache
+        qualities = {}
+
+        for folder in config['path']:
+            folder = os.path.expanduser(folder)
+            # see if this path has already been scanned
+            if folder in self.cache:
+                log.verbose('Using cached scan for %s ...' % folder)
+                qualities.update(self.cache[folder])
+                continue
+
+            path_ids = {}
+
+            if not os.path.isdir(folder):
+                log.critical('Path %s does not exist' % folder)
+                continue
+
+            log.verbose('Scanning path %s ...' % folder)
+
+            # Help debugging by removing a lot of noise
+            #logging.getLogger('movieparser').setLevel(logging.WARNING)
+            #logging.getLogger('imdb_lookup').setLevel(logging.WARNING)
+
+            # scan through
+            for root, dirs, files in os.walk(folder):
+                for item in eval(config['type']):
+                    log.debug("item: %s" % item)
+                    pattern = re.compile(".*\.(avi|mkv|mp4|mpg|webm)")
+                    if not re.search(pattern, item):
+                        continue
+                    count_files += 1
+
+                    movie = get_plugin_by_name('parsing').instance.parse_movie(item)
+
+                    try:
+                        imdb_id = imdb_lookup.imdb_id_lookup(movie_title=movie.name,
+                                                            raw_title=item,
+                                                            session=task.session)
+                        if imdb_id in path_ids:
+                            log.trace('duplicate %s' % item)
+                            continue
+                        if imdb_id is not None:
+                            log.trace('adding: %s' % imdb_id)
+                            path_ids[imdb_id] = movie.quality
+                    except plugin.PluginError as e:
+                        log.trace('%s lookup failed (%s)' % (item, e.value))
+                        incompatible_files += 1
+
+            # store to cache and extend to found list
+            self.cache[folder] = path_ids
+            qualities.update(path_ids)
+
+        log.debug('qualities: %s' % qualities)
+
+        log.debug('-- Start filtering entries ----------------------------------')
+
+        # do actual filtering
+        for entry in task.accepted:
+            count_entries += 1
+            if not entry.get('imdb_id', eval_lazy=False):
+                try:
+                    imdb_lookup.lookup(entry)
+                except plugin.PluginError as e:
+                    log.trace('entry %s imdb failed (%s)' % (entry['title'], e.value))
+                    incompatible_entries += 1
+                    continue
+
+            entry.trace("msg")
+            # actual filtering
+            if entry['imdb_id'] in qualities:
+                if config.get('allow_different_qualities') == 'better':
+                    if entry['quality'] > qualities[entry['imdb_id']]:
+                        log.trace('better quality')
+                        continue
+                elif config.get('allow_different_qualities'):
+                    if entry['quality'] != qualities[entry['imdb_id']]:
+                        log.trace('wrong quality')
+                        continue
+
+                entry.reject('movie exists')
+
+        if incompatible_files or incompatible_entries:
+            log.verbose('There were some incompatible items. %s of %s entries '
+                        'and %s of %s directories could not be verified.' %
+                (incompatible_entries, count_entries, incompatible_files, count_dirs))
+
+        log.debug('-- Finished filtering entries -------------------------------')
+
+@event('plugin.register')
+def register_plugin():
+    plugin.register(FilterExistsMovie, 'my_exists_movie', groups=['exists'], api_ver=2)