# Path: ranger/core/loader.py
# class Loadable(object):
#     paused = False
#     progressbar_supported = False
# 
#     def __init__(self, gen, descr):
#         self.load_generator = gen
#         self.description = descr
#         self.percent = 0
# 
#     def get_description(self):
#         return self.description
# 
#     def pause(self):
#         self.paused = True
# 
#     def unpause(self):
#         try:
#             del self.paused
#         except AttributeError:
#             pass
# 
#     def destroy(self):
#         pass
# 
# Path: ranger/container/file.py
# class File(FileSystemObject):
#     is_file = True
#     preview_data = None
#     preview_known = False
#     preview_loading = False
#     _firstbytes = None
# 
#     @property
#     def firstbytes(self):
#         if self._firstbytes is not None:
#             return self._firstbytes
#         try:
#             with open(self.path, 'rb') as fobj:
#                 self._firstbytes = set(fobj.read(N_FIRST_BYTES))
#         # IOError for Python2, OSError for Python3
#         except (IOError, OSError):
#             return None
#         return self._firstbytes
# 
#     def is_binary(self):
#         if self.firstbytes and CONTROL_CHARACTERS & self.firstbytes:
#             return True
#         return False
# 
#     def has_preview(self):  # pylint: disable=too-many-return-statements
#         if not self.fm.settings.preview_files:
#             return False
#         if self.is_socket or self.is_fifo or self.is_device:
#             return False
#         if not self.accessible:
#             return False
#         if self.fm.settings.preview_max_size and \
#                 self.size > self.fm.settings.preview_max_size:
#             return False
#         if self.fm.settings.preview_script and \
#                 self.fm.settings.use_preview_script:
#             return True
#         if self.container:
#             return False
#         if PREVIEW_WHITELIST.search(self.basename):
#             return True
#         if PREVIEW_BLACKLIST.search(self.basename):
#             return False
#         if self.path == '/dev/core' or self.path == '/proc/kcore':
#             return False
#         if self.is_binary():
#             return False
#         return True
# 
#     def get_preview_source(self, width, height):
#         return self.fm.get_preview(self, width, height)
# 
#     def is_image_preview(self):
#         try:
#             return self.fm.previews[self.realpath]['imagepreview']
#         except KeyError:
#             return False
# 
#     def __eq__(self, other):
#         return isinstance(other, File) and self.path == other.path
# 
#     def __neq__(self, other):
#         return not self.__eq__(other)
# 
#     def __hash__(self):
#         return hash(self.path)
# 
# Path: ranger/container/settings.py
# class LocalSettings(object):  # pylint: disable=too-few-public-methods
# 
#     def __init__(self, path, parent):
#         self.__dict__['_parent'] = parent
#         self.__dict__['_path'] = path
# 
#     def __setattr__(self, name, value):
#         if name.startswith('_'):
#             self.__dict__[name] = value
#         else:
#             self._parent.set(name, value, self._path)
# 
#     def __getattr__(self, name):
#         if name.startswith('_'):
#             return self.__dict__[name]
#         if name.startswith('signal_'):
#             return getattr(self._parent, name)
#         return self._parent.get(name, self._path)
# 
#     def __iter__(self):
#         for setting in self._parent._settings:  # pylint: disable=protected-access
#             yield setting
# 
#     __getitem__ = __getattr__
#     __setitem__ = __setattr__


import locale
import os.path
import random
import re
from os import stat as os_stat, lstat as os_lstat
from collections import deque
from time import time
from ranger.container.fsobject import BAD_INFO, FileSystemObject
from ranger.core.loader import Loadable
from ranger.ext.mount_path import mount_path
from ranger.container.file import File
from ranger.ext.accumulator import Accumulator
from ranger.ext.lazy_property import lazy_property
from ranger.ext.human_readable import human_readable
from ranger.container.settings import LocalSettings
from ranger.ext.vcs import Vcs


def walklevel(some_dir, level):
    some_dir = some_dir.rstrip(os.path.sep)
    followlinks = level > 0
    assert os.path.isdir(some_dir)
    num_sep = some_dir.count(os.path.sep)
    for root, dirs, files in os.walk(some_dir, followlinks=followlinks):
        yield root, dirs, files
        num_sep_this = root.count(os.path.sep)
        if level != -1 and num_sep + level <= num_sep_this:
            del dirs[:]


def mtimelevel(path, level):
    mtime = os.stat(path).st_mtime
    for dirpath, dirnames, _ in walklevel(path, level):
        dirlist = [os.path.join("/", dirpath, d) for d in dirnames
                   if level == -1 or dirpath.count(os.path.sep) - path.count(os.path.sep) <= level]
        mtime = max(mtime, max([-1] + [os.stat(d).st_mtime for d in dirlist]))
    return mtime


class InodeFilterConstants(object):  # pylint: disable=too-few-public-methods
    DIRS = 'd'
    FILES = 'f'
    LINKS = 'l'


class Directory(  # pylint: disable=too-many-instance-attributes,too-many-public-methods

# Path: ranger/core/loader.py
# class Loadable(object):
#     paused = False
#     progressbar_supported = False
# 
#     def __init__(self, gen, descr):
#         self.load_generator = gen
#         self.description = descr
#         self.percent = 0
# 
#     def get_description(self):
#         return self.description
# 
#     def pause(self):
#         self.paused = True
# 
#     def unpause(self):
#         try:
#             del self.paused
#         except AttributeError:
#             pass
# 
#     def destroy(self):
#         pass
# 
# Path: ranger/container/file.py
# class File(FileSystemObject):
#     is_file = True
#     preview_data = None
#     preview_known = False
#     preview_loading = False
#     _firstbytes = None
# 
#     @property
#     def firstbytes(self):
#         if self._firstbytes is not None:
#             return self._firstbytes
#         try:
#             with open(self.path, 'rb') as fobj:
#                 self._firstbytes = set(fobj.read(N_FIRST_BYTES))
#         # IOError for Python2, OSError for Python3
#         except (IOError, OSError):
#             return None
#         return self._firstbytes
# 
#     def is_binary(self):
#         if self.firstbytes and CONTROL_CHARACTERS & self.firstbytes:
#             return True
#         return False
# 
#     def has_preview(self):  # pylint: disable=too-many-return-statements
#         if not self.fm.settings.preview_files:
#             return False
#         if self.is_socket or self.is_fifo or self.is_device:
#             return False
#         if not self.accessible:
#             return False
#         if self.fm.settings.preview_max_size and \
#                 self.size > self.fm.settings.preview_max_size:
#             return False
#         if self.fm.settings.preview_script and \
#                 self.fm.settings.use_preview_script:
#             return True
#         if self.container:
#             return False
#         if PREVIEW_WHITELIST.search(self.basename):
#             return True
#         if PREVIEW_BLACKLIST.search(self.basename):
#             return False
#         if self.path == '/dev/core' or self.path == '/proc/kcore':
#             return False
#         if self.is_binary():
#             return False
#         return True
# 
#     def get_preview_source(self, width, height):
#         return self.fm.get_preview(self, width, height)
# 
#     def is_image_preview(self):
#         try:
#             return self.fm.previews[self.realpath]['imagepreview']
#         except KeyError:
#             return False
# 
#     def __eq__(self, other):
#         return isinstance(other, File) and self.path == other.path
# 
#     def __neq__(self, other):
#         return not self.__eq__(other)
# 
#     def __hash__(self):
#         return hash(self.path)
# 
# Path: ranger/container/settings.py
# class LocalSettings(object):  # pylint: disable=too-few-public-methods
# 
#     def __init__(self, path, parent):
#         self.__dict__['_parent'] = parent
#         self.__dict__['_path'] = path
# 
#     def __setattr__(self, name, value):
#         if name.startswith('_'):
#             self.__dict__[name] = value
#         else:
#             self._parent.set(name, value, self._path)
# 
#     def __getattr__(self, name):
#         if name.startswith('_'):
#             return self.__dict__[name]
#         if name.startswith('signal_'):
#             return getattr(self._parent, name)
#         return self._parent.get(name, self._path)
# 
#     def __iter__(self):
#         for setting in self._parent._settings:  # pylint: disable=protected-access
#             yield setting
# 
#     __getitem__ = __getattr__
#     __setitem__ = __setattr__


# Path: ranger/container/directory.py
import locale
import os.path
import random
import re
from os import stat as os_stat, lstat as os_lstat
from collections import deque
from time import time
from ranger.container.fsobject import BAD_INFO, FileSystemObject
from ranger.core.loader import Loadable
from ranger.ext.mount_path import mount_path
from ranger.container.file import File
from ranger.ext.accumulator import Accumulator
from ranger.ext.lazy_property import lazy_property
from ranger.ext.human_readable import human_readable
from ranger.container.settings import LocalSettings
from ranger.ext.vcs import Vcs



def walklevel(some_dir, level):
    some_dir = some_dir.rstrip(os.path.sep)
    followlinks = level > 0
    assert os.path.isdir(some_dir)
    num_sep = some_dir.count(os.path.sep)
    for root, dirs, files in os.walk(some_dir, followlinks=followlinks):
        yield root, dirs, files
        num_sep_this = root.count(os.path.sep)
        if level != -1 and num_sep + level <= num_sep_this:
            del dirs[:]


def mtimelevel(path, level):
    mtime = os.stat(path).st_mtime
    for dirpath, dirnames, _ in walklevel(path, level):
        dirlist = [os.path.join("/", dirpath, d) for d in dirnames
                   if level == -1 or dirpath.count(os.path.sep) - path.count(os.path.sep) <= level]
        mtime = max(mtime, max([-1] + [os.stat(d).st_mtime for d in dirlist]))
    return mtime


class InodeFilterConstants(object):  # pylint: disable=too-few-public-methods
    DIRS = 'd'
    FILES = 'f'
    LINKS = 'l'


class Directory(  # pylint: disable=too-many-instance-attributes,too-many-public-methods

        FileSystemObject, Accumulator, Loadable):