# Path: pysecure/config.py
# MAX_MIRROR_LISTING_CHUNK_SIZE = 5
# 
# Path: pysecure/utility.py
# def local_recurse(path, dir_cb, listing_cb, max_listing_size=0, 
#                   max_depth=None):
# 
#     def get_flags_from_attr(attr):
#         return (stat_is_regular(attr), 
#                 stat_is_symlink(attr), 
#                 stat_is_special(attr))
# 
#     q = deque([(path, 0)])
#     while q:
#         (path, current_depth) = q.popleft()
# 
#         entries = listdir(path)
#         collected = []
# 
#         def push_entry(entry):
#             collected.append(entry)
#             if max_listing_size > 0 and \
#                max_listing_size <= len(collected):
#                 listing_cb(path, collected)
#                 del collected[:]
# 
#         def push_entry_with_filepath(file_path, name, is_link):
#             attr = lstat(file_path) if is_link else stat(file_path)
#             entry = (name, 
#                      int(attr.st_mtime), 
#                      attr.st_size, 
#                      get_flags_from_attr(attr))
# 
#             push_entry(entry)
# 
#         for name in entries:
#             file_path = ('%s/%s' % (path, name))
# #            print("ENTRY: %s" % (file_path))
# 
#             if islink(file_path):
#                 if listing_cb is not None:
#                     push_entry_with_filepath(file_path, name, True)
#             elif isdir(file_path):
#                 if name == '.' or name == '..':
#                     continue
# 
#                 if dir_cb is not None:
#                     dir_cb(path, file_path, name)
# 
#                 new_depth = current_depth + 1
#                 
#                 if max_depth is not None and max_depth >= new_depth:
#                     q.append((file_path, new_depth))
#             elif isfile(file_path):
#                 if listing_cb is not None:
#                     push_entry_with_filepath(file_path, name, False)
# 
#         if listing_cb is not None and max_listing_size == 0 or \
#            len(collected) > 0:
#             listing_cb(path, collected)
# 
# def stringify(s):
#     if issubclass(s.__class__, (bytes, bytearray)):
#         return s.decode('ascii')
#     else:
#         return s
# 
# Path: pysecure/exceptions.py
# class SftpAlreadyExistsError(SftpError):
#     pass


import logging
from datetime import datetime
from os import mkdir, unlink, symlink
from collections import deque
from shutil import rmtree
from time import mktime
from pysecure.config import MAX_MIRROR_LISTING_CHUNK_SIZE
from pysecure.utility import local_recurse, stringify
from pysecure.exceptions import SftpAlreadyExistsError
            full_from = ('%s/%s' % (path_from, path)) if path else path_from
            full_to = ('%s/%s' % (path_to, path)) if path else path_to

            subdirs = handler(full_from, full_to, log_files)
            for subdir in subdirs:
                q.append(('%s/%s' % (path, subdir)) if path else subdir)

    def __get_local_files(self, path):
        self.__log.debug("Checking local files.")

        local_dirs = set()
        def local_dir_cb(parent_path, full_path, filename):
            local_dirs.add(filename)
        
        local_entities = set()
        local_files = set()
        local_attributes = {}
        def local_listing_cb(parent_path, listing):
            for entry in listing:
                (filename, mtime, size, flags) = entry

                entity = (filename, mtime, size, flags[1])
                local_entities.add(entity)
                local_files.add(filename)
                local_attributes[filename] = (datetime.fromtimestamp(mtime), 
                                              flags)

        local_recurse(path, 
                      local_dir_cb, 
                      local_listing_cb, 

# Path: pysecure/config.py
# MAX_MIRROR_LISTING_CHUNK_SIZE = 5
# 
# Path: pysecure/utility.py
# def local_recurse(path, dir_cb, listing_cb, max_listing_size=0, 
#                   max_depth=None):
# 
#     def get_flags_from_attr(attr):
#         return (stat_is_regular(attr), 
#                 stat_is_symlink(attr), 
#                 stat_is_special(attr))
# 
#     q = deque([(path, 0)])
#     while q:
#         (path, current_depth) = q.popleft()
# 
#         entries = listdir(path)
#         collected = []
# 
#         def push_entry(entry):
#             collected.append(entry)
#             if max_listing_size > 0 and \
#                max_listing_size <= len(collected):
#                 listing_cb(path, collected)
#                 del collected[:]
# 
#         def push_entry_with_filepath(file_path, name, is_link):
#             attr = lstat(file_path) if is_link else stat(file_path)
#             entry = (name, 
#                      int(attr.st_mtime), 
#                      attr.st_size, 
#                      get_flags_from_attr(attr))
# 
#             push_entry(entry)
# 
#         for name in entries:
#             file_path = ('%s/%s' % (path, name))
# #            print("ENTRY: %s" % (file_path))
# 
#             if islink(file_path):
#                 if listing_cb is not None:
#                     push_entry_with_filepath(file_path, name, True)
#             elif isdir(file_path):
#                 if name == '.' or name == '..':
#                     continue
# 
#                 if dir_cb is not None:
#                     dir_cb(path, file_path, name)
# 
#                 new_depth = current_depth + 1
#                 
#                 if max_depth is not None and max_depth >= new_depth:
#                     q.append((file_path, new_depth))
#             elif isfile(file_path):
#                 if listing_cb is not None:
#                     push_entry_with_filepath(file_path, name, False)
# 
#         if listing_cb is not None and max_listing_size == 0 or \
#            len(collected) > 0:
#             listing_cb(path, collected)
# 
# def stringify(s):
#     if issubclass(s.__class__, (bytes, bytearray)):
#         return s.decode('ascii')
#     else:
#         return s
# 
# Path: pysecure/exceptions.py
# class SftpAlreadyExistsError(SftpError):
#     pass


# Path: pysecure/sftp_mirror.py
import logging
from datetime import datetime
from os import mkdir, unlink, symlink
from collections import deque
from shutil import rmtree
from time import mktime
from pysecure.config import MAX_MIRROR_LISTING_CHUNK_SIZE
from pysecure.utility import local_recurse, stringify
from pysecure.exceptions import SftpAlreadyExistsError

            full_from = ('%s/%s' % (path_from, path)) if path else path_from
            full_to = ('%s/%s' % (path_to, path)) if path else path_to

            subdirs = handler(full_from, full_to, log_files)
            for subdir in subdirs:
                q.append(('%s/%s' % (path, subdir)) if path else subdir)

    def __get_local_files(self, path):
        self.__log.debug("Checking local files.")

        local_dirs = set()
        def local_dir_cb(parent_path, full_path, filename):
            local_dirs.add(filename)
        
        local_entities = set()
        local_files = set()
        local_attributes = {}
        def local_listing_cb(parent_path, listing):
            for entry in listing:
                (filename, mtime, size, flags) = entry

                entity = (filename, mtime, size, flags[1])
                local_entities.add(entity)
                local_files.add(filename)
                local_attributes[filename] = (datetime.fromtimestamp(mtime), 
                                              flags)

        local_recurse(path, 
                      local_dir_cb, 
                      local_listing_cb, 

                      MAX_MIRROR_LISTING_CHUNK_SIZE, 