1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-06 10:12:59 +00:00
Files
dotdrop/dotdrop/ftree.py
2025-05-20 21:56:27 +02:00

81 lines
2.6 KiB
Python

"""
author: deadc0de6 (https://github.com/deadc0de6)
Copyright (c) 2024, deadc0de6
filesystem tree for directories
"""
import os
# local imports
from dotdrop.utils import must_ignore, dir_empty
from dotdrop.logger import Logger
class FTreeDir:
"""
directory tree for comparison
"""
def __init__(self, path, ignores=None,
debug=False):
self.path = path
self.ignores = ignores
self.debug = debug
self.entries = []
self.log = Logger(debug=self.debug)
if os.path.exists(path) and os.path.isdir(path):
self._walk()
def _walk(self):
"""
index directory
ignore empty directory
test for ignore pattern
"""
for root, dirs, files in os.walk(self.path, followlinks=True):
for file in files:
fpath = os.path.join(root, file)
if must_ignore([fpath], ignores=self.ignores,
debug=self.debug, strict=True):
self.log.dbg(f'ignoring file {fpath}')
continue
self.log.dbg(f'added file to list of {self.path}: {fpath}')
self.entries.append(fpath)
for dname in dirs:
dpath = os.path.join(root, dname)
if dir_empty(dpath):
# ignore empty directory
self.log.dbg(f'ignoring empty dir {dpath}')
continue
# appending "/" allows to ensure pattern
# like "*/dir/*" will match the content of the directory
# but also the directory itself
dpath += os.path.sep
if must_ignore([dpath], ignores=self.ignores,
debug=self.debug, strict=True):
self.log.dbg(f'ignoring dir {dpath}')
continue
self.log.dbg(f'added dir to list of {self.path}: {dpath}')
self.entries.append(dpath)
def get_entries(self):
"""return all entries"""
return self.entries
def compare(self, other):
"""
compare two trees and returns
- left_only (only in self)
- right_only (only in other)
- in_both (in both)
the relative path are returned
"""
left = [os.path.relpath(entry, self.path) for entry in self.entries]
right = [os.path.relpath(entry, other.path) for entry in other.entries]
left_only = set(left) - set(right)
right_only = set(right) - set(left)
in_both = set(left) & set(right)
return list(left_only), list(right_only), list(in_both)