# 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

        self.__log.debug("Ensuring local target directory exists: %s" % 
                         (path_to))

        try:
            mkdir(path_to)
        except OSError:
            already_exists = True
            self.__log.debug("Local target already exists.")
        else:
            already_exists = False
            self.__log.debug("Local target created.")

        from_tuple = self.__get_remote_files(path_from)
        to_tuple = self.__get_local_files(path_to)
        delta_tuple = self.__get_deltas(from_tuple, to_tuple, log_files)

        context = (from_tuple, path_from, path_to, delta_tuple)
        ops = self.__get_local_ops()

        return self.__fix_deltas_at_target(context, ops)

    def mirror_to_remote_no_recursion(self, path_from, path_to, 
                                      log_files=False):

        self.__log.debug("Ensuring remote target directory exists: %s" % 
                         (path_to))

        try:
            self.__sftp_session.mkdir(path_to)

# 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


        self.__log.debug("Ensuring local target directory exists: %s" % 
                         (path_to))

        try:
            mkdir(path_to)
        except OSError:
            already_exists = True
            self.__log.debug("Local target already exists.")
        else:
            already_exists = False
            self.__log.debug("Local target created.")

        from_tuple = self.__get_remote_files(path_from)
        to_tuple = self.__get_local_files(path_to)
        delta_tuple = self.__get_deltas(from_tuple, to_tuple, log_files)

        context = (from_tuple, path_from, path_to, delta_tuple)
        ops = self.__get_local_ops()

        return self.__fix_deltas_at_target(context, ops)

    def mirror_to_remote_no_recursion(self, path_from, path_to, 
                                      log_files=False):

        self.__log.debug("Ensuring remote target directory exists: %s" % 
                         (path_to))

        try:
            self.__sftp_session.mkdir(path_to)

        except SftpAlreadyExistsError: