1# -*- coding: utf-8 -*-
2from __future__ import unicode_literals
3
4import os
5import sys
6from collections import OrderedDict
7
8from six import PY2, string_types, text_type
9
10from . import VIDEO_EXTENSIONS
11
12
13def recurse_paths(paths):
14    """Return a file system encoded list of videofiles.
15
16    :param paths:
17    :type paths: string or list
18    :return:
19    :rtype: list
20    """
21    enc_paths = []
22
23    if isinstance(paths, (string_types, text_type)):
24        paths = [p.strip() for p in paths.split(',')] if ',' in paths else paths.split()
25
26    encoding = sys.getfilesystemencoding()
27    for path in paths:
28        if os.path.isfile(path):
29            enc_paths.append(path.decode(encoding) if PY2 else path)
30        if os.path.isdir(path):
31            for root, directories, filenames in os.walk(path):
32                for filename in filenames:
33                    if os.path.splitext(filename)[1] in VIDEO_EXTENSIONS:
34                        if PY2 and os.name == 'nt':
35                            fullpath = os.path.join(root, filename.decode(encoding))
36                        else:
37                            fullpath = os.path.join(root, filename).decode(encoding)
38                        enc_paths.append(fullpath)
39
40    # Lets remove any dupes since mediainfo is rather slow.
41    seen = set()
42    seen_add = seen.add
43    return [f for f in enc_paths if not (f in seen or seen_add(f))]
44
45
46def todict(obj, classkey=None):
47    """Transform an object to dict."""
48    if isinstance(obj, string_types):
49        return obj
50    elif isinstance(obj, dict):
51        data = {}
52        for (k, v) in obj.items():
53            data[k] = todict(v, classkey)
54        return data
55    elif hasattr(obj, '_ast'):
56        return todict(obj._ast())
57    elif hasattr(obj, '__iter__'):
58        return [todict(v, classkey) for v in obj]
59    elif hasattr(obj, '__dict__'):
60        values = [(key, todict(value, classkey))
61                  for key, value in obj.__dict__.items() if not callable(value) and not key.startswith('_')]
62        data = OrderedDict([(k, v) for k, v in values if v is not None])
63        if classkey is not None and hasattr(obj, '__class__'):
64            data[classkey] = obj.__class__.__name__
65        return data
66    return obj
67
68
69def detect_os():
70    """Detect os family: windows, macos or unix."""
71    if os.name in ('nt', 'dos', 'os2', 'ce'):
72        return 'windows'
73    if sys.platform == 'darwin':
74        return 'macos'
75
76    return 'unix'
77
78
79def define_candidate(locations, names, os_family=None, suggested_path=None):
80    """Generate candidate list for the given parameters."""
81    os_family = os_family or detect_os()
82    for location in (suggested_path, ) + locations[os_family]:
83        if not location:
84            continue
85
86        if location == '__PATH__':
87            for name in names[os_family]:
88                yield name
89        elif os.path.isfile(location):
90            yield location
91        elif os.path.isdir(location):
92            for name in names[os_family]:
93                cmd = os.path.join(location, name)
94                if os.path.isfile(cmd):
95                    yield cmd
96