flexget.plugins.input.find
Covered: 42 lines
Missed: 31 lines
Skipped 22 lines
Percent: 57 %
 1
import logging
 2
import os
 3
import re
 4
import sys
 5
from flexget.entry import Entry
 6
from flexget.plugin import register_plugin
 7
from flexget.utils.cached_input import cached
 9
log = logging.getLogger('find')
12
class InputFind(object):
13
    """
14
        Uses local path content as an input, recurses through directories and creates entries for files that match mask.
16
        You can specify either the mask key, in shell file matching format, (see python fnmatch module,) or regexp key.
18
        Example:
20
        find:
21
          path: /storage/movies/
22
          mask: *.avi
24
        Example:
26
        find:
27
          path:
28
            - /storage/movies/
29
            - /storage/tv/
30
          regexp: .*\.(avi|mkv)$
31
    """
33
    def validator(self):
34
        from flexget import validator
35
        root = validator.factory('dict')
36
        root.accept('path', key='path', required=True)
37
        root.accept('list', key='path').accept('path')
38
        root.accept('text', key='mask')
39
        root.accept('regexp', key='regexp')
40
        root.accept('boolean', key='recursive')
41
        return root
43
    def prepare_config(self, config):
44
        from fnmatch import translate
46
        if isinstance(config['path'], basestring):
47
            config['path'] = [config['path']]
48
        config.setdefault('recursive', False)
50
        if config.get('mask'):
51
            config['regexp'] = translate(config['mask'])
53
        if not config.get('regexp'):
54
            config['regexp'] = '.'
56
    @cached('find')
57
    def on_feed_input(self, feed, config):
58
        self.prepare_config(config)
59
        entries = []
60
        match = re.compile(config['regexp'], re.IGNORECASE).match
62
        fs_encoding = sys.getfilesystemencoding() or 'utf-8'
63
        for path in config['path']:
64
            log.debug('scanning %s' % path)
66
            path = path.encode(fs_encoding)
67
            path = os.path.expanduser(path)
68
            for item in os.walk(path):
69
                log.debug('item: %s' % str(item))
70
                for name in item[2]:
72
                    if match(name) is None:
73
                        continue
74
                    e = Entry()
75
                    try:
77
                        e['title'] = name.decode(fs_encoding)
78
                    except UnicodeDecodeError:
79
                        log.warning('Filename `%r` in `%s` encoding broken?' %
80
                                    (name.decode('utf-8', 'replace'), item[0]))
81
                        continue
82
                    filepath = os.path.join(item[0], name).decode(fs_encoding)
83
                    e['location'] = filepath
85
                    if not filepath.startswith('/'):
86
                        filepath = '/' + filepath
87
                    e['url'] = 'file://%s' % (filepath)
88
                    entries.append(e)
90
                if not config['recursive']:
91
                    break
92
        return entries
94
register_plugin(InputFind, 'find', api_ver=2)