add ignore_hidden_files and fix '.' and './' will cause problems in path/name
This commit is contained in:
@@ -1,15 +1,18 @@
|
|||||||
dest: /path/to/store/backup/files # The programs will store database and backup files in this location
|
dest: /path/to/store/backup/files # The programs will store database and backup files in this location
|
||||||
remove_old_files: true # Optional. Default value: true. Remove unneeded backup files which already deleted in source tree when backuping files.
|
remove_old_files: true # Optional. Default value: true. Remove unneeded backup files which already deleted in source tree when backuping files.
|
||||||
|
ignore_hidden_files: true # Optional. Default value: true. Whether to ignore files which its name starts with ".". Only effect folder which type is "path".
|
||||||
programs:
|
programs:
|
||||||
- name: Your program name # This name is used to identify different application.
|
- name: Your program name # This name is used to identify different application.
|
||||||
base: /path/to/save/path # Must be absoulte path.
|
base: /path/to/save/path # Must be absoulte path.
|
||||||
remove_old_files: true # Optional.
|
remove_old_files: true # Optional.
|
||||||
|
ignore_hidden_files: true # Optional.
|
||||||
files:
|
files:
|
||||||
- BGI.gdb # path to a file/folder. All subfolders will include if it is a folder. Must be relative path.
|
- BGI.gdb # path to a file/folder. All subfolders will include if it is a folder. Must be relative path.
|
||||||
- type: path
|
- type: path
|
||||||
path: folder # path to a file/folder. All subfolders will include if it is a folder. Must be relative path if name not found.
|
path: folder # path to a file/folder. All subfolders will include if it is a folder. Must be relative path if name not found.
|
||||||
name: folder2 # optional. path to the backup files. Shoule be a relative path
|
name: folder2 # optional. path to the backup files. Shoule be a relative path
|
||||||
remove_old_files: true # Optional.
|
remove_old_files: true # Optional.
|
||||||
|
ignore_hidden_files: true # Optional.
|
||||||
- type: leveldb # module plyvel is needed to support this type. This will store leveldb database to a single file database (sqlite3)
|
- type: leveldb # module plyvel is needed to support this type. This will store leveldb database to a single file database (sqlite3)
|
||||||
path: leveldb # path to leveldb. Must be relative path.
|
path: leveldb # path to leveldb. Must be relative path.
|
||||||
name: dest # optional. path to the backup files. Shoule be a relative path
|
name: dest # optional. path to the backup files. Shoule be a relative path
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ except ImportError:
|
|||||||
|
|
||||||
|
|
||||||
class BasicOption:
|
class BasicOption:
|
||||||
|
'''Basic options which is included in config, program and files.'''
|
||||||
_remove_old_files = None
|
_remove_old_files = None
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
@@ -45,6 +46,43 @@ class BasicOption:
|
|||||||
del v
|
del v
|
||||||
|
|
||||||
|
|
||||||
|
class NFBasicOption:
|
||||||
|
"""Basic options which is included in config, program."""
|
||||||
|
_ignore_hidden_files = None
|
||||||
|
|
||||||
|
def __init__(self, cfg=None, prog=None):
|
||||||
|
self._cfg = cfg
|
||||||
|
self._prog = prog
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def ignore_hidden_files(self) -> bool:
|
||||||
|
if self._ignore_hidden_files is not None:
|
||||||
|
return self._ignore_hidden_files
|
||||||
|
prog = getattr(self, "_prog", None)
|
||||||
|
if prog is not None:
|
||||||
|
if prog._ignore_hidden_files is not None:
|
||||||
|
return prog._ignore_hidden_files
|
||||||
|
cfg = getattr(self, "_cfg", None)
|
||||||
|
if cfg is not None:
|
||||||
|
if cfg._ignore_hidden_files is not None:
|
||||||
|
return cfg._ignore_hidden_files
|
||||||
|
return True
|
||||||
|
|
||||||
|
def parse_all_nf(self, data=None):
|
||||||
|
self.parse_ignore_hidden_files(data)
|
||||||
|
|
||||||
|
def parse_ignore_hidden_files(self, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = getattr(self, 'data')
|
||||||
|
if 'ignore_hidden_files' in data:
|
||||||
|
v = data['ignore_hidden_files']
|
||||||
|
if isinstance(v, bool):
|
||||||
|
self._ignore_hidden_files = v
|
||||||
|
else:
|
||||||
|
raise TypeError('ignore_hidden_files option must be a bool.')
|
||||||
|
del v
|
||||||
|
|
||||||
|
|
||||||
def namedtuple_bo(typename, field_names):
|
def namedtuple_bo(typename, field_names):
|
||||||
a = namedtuple(typename, field_names)
|
a = namedtuple(typename, field_names)
|
||||||
return type(typename, (a, BasicOption), {})
|
return type(typename, (a, BasicOption), {})
|
||||||
@@ -55,12 +93,13 @@ ConfigLeveldb = namedtuple_bo('ConfigLeveldb', ['name', 'full_path', 'domains'])
|
|||||||
ConfigResult = Union[ConfigNormalFile, ConfigLeveldb]
|
ConfigResult = Union[ConfigNormalFile, ConfigLeveldb]
|
||||||
|
|
||||||
|
|
||||||
class Program(BasicOption):
|
class Program(BasicOption, NFBasicOption):
|
||||||
def __init__(self, data: dict, cfg):
|
def __init__(self, data: dict, cfg):
|
||||||
self.data = data
|
self.data = data
|
||||||
self._files = None
|
self._files = None
|
||||||
self._cfg = cfg
|
self._cfg = cfg
|
||||||
self.parse_all()
|
self.parse_all()
|
||||||
|
self.parse_all_nf()
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def base(self) -> str:
|
def base(self) -> str:
|
||||||
@@ -94,9 +133,13 @@ class Program(BasicOption):
|
|||||||
raise ValueError('Absolute path must need a name.')
|
raise ValueError('Absolute path must need a name.')
|
||||||
bp = join(b, i)
|
bp = join(b, i)
|
||||||
if isfile(bp):
|
if isfile(bp):
|
||||||
r.append(ConfigNormalFile(i, bp))
|
tname = relpath(join(b, i), b)
|
||||||
|
r.append(ConfigNormalFile(tname, bp))
|
||||||
|
del tname
|
||||||
elif isdir(bp):
|
elif isdir(bp):
|
||||||
ll = listdirs(bp)
|
top = NFBasicOption(self._cfg, self)
|
||||||
|
ll = listdirs(bp, top.ignore_hidden_files)
|
||||||
|
del top
|
||||||
for ii in ll:
|
for ii in ll:
|
||||||
r.append(ConfigNormalFile(relpath(ii, b), ii))
|
r.append(ConfigNormalFile(relpath(ii, b), ii))
|
||||||
elif isinstance(i, dict):
|
elif isinstance(i, dict):
|
||||||
@@ -114,13 +157,20 @@ class Program(BasicOption):
|
|||||||
if i['name'] != '':
|
if i['name'] != '':
|
||||||
name = i['name']
|
name = i['name']
|
||||||
if isfile(bp):
|
if isfile(bp):
|
||||||
tmp = ConfigNormalFile(name, bp)
|
tname = relpath(join(b, name), b)
|
||||||
|
tmp = ConfigNormalFile(tname, bp)
|
||||||
|
del tname
|
||||||
tmp.parse_all(i)
|
tmp.parse_all(i)
|
||||||
r.append(tmp)
|
r.append(tmp)
|
||||||
elif isdir(bp):
|
elif isdir(bp):
|
||||||
ll = listdirs(bp)
|
top = NFBasicOption(self._cfg, self)
|
||||||
|
top.parse_ignore_hidden_files(i)
|
||||||
|
ll = listdirs(bp, top.ignore_hidden_files)
|
||||||
|
del top
|
||||||
for ii in ll:
|
for ii in ll:
|
||||||
tmp = ConfigNormalFile(join(name, relpath(ii, bp)), ii) # noqa: E501
|
tname = relpath(join(b, join(name, relpath(ii, bp))), b) # noqa: E501
|
||||||
|
tmp = ConfigNormalFile(tname, ii)
|
||||||
|
del tname
|
||||||
tmp.parse_all(i)
|
tmp.parse_all(i)
|
||||||
r.append(tmp)
|
r.append(tmp)
|
||||||
elif t == 'leveldb':
|
elif t == 'leveldb':
|
||||||
@@ -143,10 +193,13 @@ class Program(BasicOption):
|
|||||||
dms.append(ii.encode())
|
dms.append(ii.encode())
|
||||||
if len(dms) == 0:
|
if len(dms) == 0:
|
||||||
dms = None
|
dms = None
|
||||||
tmp = ConfigLeveldb(n, p, dms)
|
tname = relpath(join(b, n), b)
|
||||||
|
tmp = ConfigLeveldb(tname, p, dms)
|
||||||
|
del tname
|
||||||
tmp.parse_all(i)
|
tmp.parse_all(i)
|
||||||
r.append(tmp)
|
r.append(tmp)
|
||||||
for i in r:
|
for i in r:
|
||||||
|
i._cfg = self._cfg
|
||||||
i._prog = self
|
i._prog = self
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@@ -158,7 +211,7 @@ class Program(BasicOption):
|
|||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
class Config(BasicOption):
|
class Config(BasicOption, NFBasicOption):
|
||||||
dest = ''
|
dest = ''
|
||||||
progs = []
|
progs = []
|
||||||
progs_name = []
|
progs_name = []
|
||||||
@@ -176,6 +229,7 @@ class Config(BasicOption):
|
|||||||
if 'programs' not in t:
|
if 'programs' not in t:
|
||||||
raise ValueError("No programs found.")
|
raise ValueError("No programs found.")
|
||||||
self.parse_all(t)
|
self.parse_all(t)
|
||||||
|
self.parse_all_nf(t)
|
||||||
progs = t['programs']
|
progs = t['programs']
|
||||||
if not isinstance(progs, list):
|
if not isinstance(progs, list):
|
||||||
raise ValueError("programs should be list.")
|
raise ValueError("programs should be list.")
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ def copy_file(loc: str, dest: str, name: str, prog: str):
|
|||||||
print(f'{prog}: Copyed {loc}({name}) -> {r}')
|
print(f'{prog}: Copyed {loc}({name}) -> {r}')
|
||||||
|
|
||||||
|
|
||||||
def listdirs(loc: str):
|
def listdirs(loc: str, ignore_hidden_files: bool = True):
|
||||||
bl = listdir(loc)
|
bl = listdir(loc)
|
||||||
r = []
|
r = []
|
||||||
for i in bl:
|
for i in bl:
|
||||||
if i.startswith('.'):
|
if i.startswith('.'):
|
||||||
continue
|
if ignore_hidden_files or i == '.' or i == '..':
|
||||||
|
continue
|
||||||
p = join(loc, i)
|
p = join(loc, i)
|
||||||
if isfile(p):
|
if isfile(p):
|
||||||
r.append(p)
|
r.append(p)
|
||||||
|
|||||||
Reference in New Issue
Block a user