python-backpack 2.0.3__py3-none-any.whl → 2.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- backpack/cache.py +93 -93
- backpack/custom_errors.py +37 -37
- backpack/file_utils.py +140 -135
- backpack/folder_utils.py +105 -105
- backpack/json_metadata.py +135 -135
- backpack/json_user_settings.py +85 -85
- backpack/json_utils.py +53 -53
- backpack/logger.py +16 -16
- backpack/patterns.py +28 -28
- backpack/strings.py +123 -123
- backpack/test_utils.py +48 -48
- backpack/version.py +25 -23
- {python_backpack-2.0.3.dist-info → python_backpack-2.0.5.dist-info}/METADATA +2 -2
- python_backpack-2.0.5.dist-info/RECORD +17 -0
- {python_backpack-2.0.3.dist-info → python_backpack-2.0.5.dist-info}/WHEEL +1 -1
- {python_backpack-2.0.3.dist-info → python_backpack-2.0.5.dist-info}/licenses/LICENSE +674 -674
- python_backpack-2.0.3.dist-info/RECORD +0 -17
backpack/folder_utils.py
CHANGED
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
# ----------------------------------------------------------------------------------------
|
|
2
|
-
# Python-Backpack - Folder Utilities
|
|
3
|
-
# Maximiliano Rocamora / maxirocamora@gmail.com
|
|
4
|
-
# https://github.com/MaxRocamora/python-backpack
|
|
5
|
-
# ----------------------------------------------------------------------------------------
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import shutil
|
|
9
|
-
import subprocess
|
|
10
|
-
from collections.abc import Sequence
|
|
11
|
-
|
|
12
|
-
from backpack.logger import get_logger
|
|
13
|
-
|
|
14
|
-
log = get_logger('Python Backpack - FolderUtils')
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def browse_folder(folder: str | None) -> bool:
|
|
18
|
-
"""Open windows explorer on folder.
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
folder: (string path) folder to open
|
|
22
|
-
"""
|
|
23
|
-
if folder and os.path.isdir(folder):
|
|
24
|
-
try:
|
|
25
|
-
subprocess.Popen(['explorer', os.path.abspath(folder)])
|
|
26
|
-
return True
|
|
27
|
-
except OSError as error:
|
|
28
|
-
log.warning(f'Unable to open folder {folder}')
|
|
29
|
-
log.error(str(error))
|
|
30
|
-
return False
|
|
31
|
-
|
|
32
|
-
log.warning(f'Unable to open folder {folder}')
|
|
33
|
-
return False
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def create_folders(
|
|
37
|
-
folders: Sequence[str],
|
|
38
|
-
force_empty: bool = False,
|
|
39
|
-
verbose: bool = False,
|
|
40
|
-
) -> None:
|
|
41
|
-
"""Creates multiple folders on disc.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
folders (list): folder list
|
|
45
|
-
force_empty (bool, optional): forces clearing folder content. Defaults to False.
|
|
46
|
-
verbose (bool, optional):shows log. Defaults to False.
|
|
47
|
-
"""
|
|
48
|
-
for folder in folders:
|
|
49
|
-
create_folder(folder, force_empty=force_empty, verbose=verbose)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def create_folder(path: str, force_empty: bool = False, verbose: bool = True) -> bool:
|
|
53
|
-
"""Creates a folder.
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
path (str): folder path
|
|
57
|
-
force_empty (bool, optional): forces clearing folder content. Defaults to False.
|
|
58
|
-
verbose (bool, optional): show log. Defaults to True.
|
|
59
|
-
"""
|
|
60
|
-
abspath = os.path.abspath(path)
|
|
61
|
-
if verbose:
|
|
62
|
-
log.info(f'Creating Folder {abspath}')
|
|
63
|
-
|
|
64
|
-
try:
|
|
65
|
-
if not os.path.exists(abspath):
|
|
66
|
-
os.makedirs(f'{abspath}/')
|
|
67
|
-
elif force_empty:
|
|
68
|
-
remove_files_in_dir(abspath)
|
|
69
|
-
except OSError as e:
|
|
70
|
-
log.warning(f'Unable to create folder: {path}')
|
|
71
|
-
log.error(str(e))
|
|
72
|
-
|
|
73
|
-
return True
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def remove_files_in_dir(path: str) -> None:
|
|
77
|
-
"""Clears all content in given directory."""
|
|
78
|
-
for root, dirs, files in os.walk(path):
|
|
79
|
-
for f in files:
|
|
80
|
-
os.unlink(os.path.join(root, f))
|
|
81
|
-
for d in dirs:
|
|
82
|
-
shutil.rmtree(os.path.join(root, d))
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def recursive_dir_copy(source_path: str, target_path: str) -> None:
|
|
86
|
-
"""Copy all files src dir to dest dir, including sub-directories.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
source_path (str): source path
|
|
90
|
-
target_path (str): destination path
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
create_folder(source_path)
|
|
94
|
-
create_folder(target_path)
|
|
95
|
-
|
|
96
|
-
for item in os.listdir(source_path):
|
|
97
|
-
file_path = os.path.join(source_path, item)
|
|
98
|
-
|
|
99
|
-
# if item is a file, copy it
|
|
100
|
-
if os.path.isfile(file_path):
|
|
101
|
-
shutil.copy(file_path, target_path)
|
|
102
|
-
# else if item is a folder, recurse
|
|
103
|
-
elif os.path.isdir(file_path):
|
|
104
|
-
new_dest = os.path.join(target_path, item)
|
|
105
|
-
recursive_dir_copy(file_path, new_dest)
|
|
1
|
+
# ----------------------------------------------------------------------------------------
|
|
2
|
+
# Python-Backpack - Folder Utilities
|
|
3
|
+
# Maximiliano Rocamora / maxirocamora@gmail.com
|
|
4
|
+
# https://github.com/MaxRocamora/python-backpack
|
|
5
|
+
# ----------------------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
from collections.abc import Sequence
|
|
11
|
+
|
|
12
|
+
from backpack.logger import get_logger
|
|
13
|
+
|
|
14
|
+
log = get_logger('Python Backpack - FolderUtils')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def browse_folder(folder: str | None) -> bool:
|
|
18
|
+
"""Open windows explorer on folder.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
folder: (string path) folder to open
|
|
22
|
+
"""
|
|
23
|
+
if folder and os.path.isdir(folder):
|
|
24
|
+
try:
|
|
25
|
+
subprocess.Popen(['explorer', os.path.abspath(folder)])
|
|
26
|
+
return True
|
|
27
|
+
except OSError as error:
|
|
28
|
+
log.warning(f'Unable to open folder {folder}')
|
|
29
|
+
log.error(str(error))
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
log.warning(f'Unable to open folder {folder}')
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_folders(
|
|
37
|
+
folders: Sequence[str],
|
|
38
|
+
force_empty: bool = False,
|
|
39
|
+
verbose: bool = False,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""Creates multiple folders on disc.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
folders (list): folder list
|
|
45
|
+
force_empty (bool, optional): forces clearing folder content. Defaults to False.
|
|
46
|
+
verbose (bool, optional):shows log. Defaults to False.
|
|
47
|
+
"""
|
|
48
|
+
for folder in folders:
|
|
49
|
+
create_folder(folder, force_empty=force_empty, verbose=verbose)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def create_folder(path: str, force_empty: bool = False, verbose: bool = True) -> bool:
|
|
53
|
+
"""Creates a folder.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
path (str): folder path
|
|
57
|
+
force_empty (bool, optional): forces clearing folder content. Defaults to False.
|
|
58
|
+
verbose (bool, optional): show log. Defaults to True.
|
|
59
|
+
"""
|
|
60
|
+
abspath = os.path.abspath(path)
|
|
61
|
+
if verbose:
|
|
62
|
+
log.info(f'Creating Folder {abspath}')
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
if not os.path.exists(abspath):
|
|
66
|
+
os.makedirs(f'{abspath}/')
|
|
67
|
+
elif force_empty:
|
|
68
|
+
remove_files_in_dir(abspath)
|
|
69
|
+
except OSError as e:
|
|
70
|
+
log.warning(f'Unable to create folder: {path}')
|
|
71
|
+
log.error(str(e))
|
|
72
|
+
|
|
73
|
+
return True
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def remove_files_in_dir(path: str) -> None:
|
|
77
|
+
"""Clears all content in given directory."""
|
|
78
|
+
for root, dirs, files in os.walk(path):
|
|
79
|
+
for f in files:
|
|
80
|
+
os.unlink(os.path.join(root, f))
|
|
81
|
+
for d in dirs:
|
|
82
|
+
shutil.rmtree(os.path.join(root, d))
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def recursive_dir_copy(source_path: str, target_path: str) -> None:
|
|
86
|
+
"""Copy all files src dir to dest dir, including sub-directories.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
source_path (str): source path
|
|
90
|
+
target_path (str): destination path
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
create_folder(source_path)
|
|
94
|
+
create_folder(target_path)
|
|
95
|
+
|
|
96
|
+
for item in os.listdir(source_path):
|
|
97
|
+
file_path = os.path.join(source_path, item)
|
|
98
|
+
|
|
99
|
+
# if item is a file, copy it
|
|
100
|
+
if os.path.isfile(file_path):
|
|
101
|
+
shutil.copy(file_path, target_path)
|
|
102
|
+
# else if item is a folder, recurse
|
|
103
|
+
elif os.path.isdir(file_path):
|
|
104
|
+
new_dest = os.path.join(target_path, item)
|
|
105
|
+
recursive_dir_copy(file_path, new_dest)
|
backpack/json_metadata.py
CHANGED
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
# ----------------------------------------------------------------------------------------
|
|
2
|
-
# Python-Backpack - JsonMetadata
|
|
3
|
-
# Maximiliano Rocamora / maxirocamora@gmail.com
|
|
4
|
-
# https://github.com/MaxRocamora/python-backpack
|
|
5
|
-
# ----------------------------------------------------------------------------------------
|
|
6
|
-
import getpass
|
|
7
|
-
import inspect
|
|
8
|
-
import os
|
|
9
|
-
import platform
|
|
10
|
-
import sys
|
|
11
|
-
import time
|
|
12
|
-
from datetime import datetime
|
|
13
|
-
from typing import Any
|
|
14
|
-
|
|
15
|
-
from backpack.json_utils import json_load, json_save
|
|
16
|
-
from backpack.version import version
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class JsonMetaFile:
|
|
20
|
-
PREFIX = 'MD_'
|
|
21
|
-
|
|
22
|
-
def __init__(self, name: str, path: str) -> None:
|
|
23
|
-
"""saves/load a class/dict as a json metadata file.
|
|
24
|
-
|
|
25
|
-
Args:
|
|
26
|
-
name (str): name of the file/class
|
|
27
|
-
path (str, optional): filepath. Defaults to None.
|
|
28
|
-
"""
|
|
29
|
-
self._name = name
|
|
30
|
-
self._path = path
|
|
31
|
-
self._data = {'_about': {'package': 'python-backpack', 'version': self.version}}
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def name(self) -> str:
|
|
35
|
-
"""Name of this metadata class."""
|
|
36
|
-
return self._name
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def version(self) -> str:
|
|
40
|
-
"""Version of this metadata class."""
|
|
41
|
-
return version
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def filename(self) -> str:
|
|
45
|
-
"""Returns default filename with prefix and extension."""
|
|
46
|
-
return self.PREFIX + self.name + '.json'
|
|
47
|
-
|
|
48
|
-
@property
|
|
49
|
-
def filepath(self) -> str:
|
|
50
|
-
"""Full json metadata filepath."""
|
|
51
|
-
return os.path.join(self.path, self.filename)
|
|
52
|
-
|
|
53
|
-
@property
|
|
54
|
-
def path(self) -> str:
|
|
55
|
-
"""Base path location of metadata json file."""
|
|
56
|
-
return self._path
|
|
57
|
-
|
|
58
|
-
def has_file(self) -> bool:
|
|
59
|
-
"""Returns true if file exists."""
|
|
60
|
-
return os.path.exists(self.filepath)
|
|
61
|
-
|
|
62
|
-
# ------------------------------------------------------------------------------------
|
|
63
|
-
# LOAD/INSERT/REMOVE/SAVE
|
|
64
|
-
# ------------------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
def load(self) -> None:
|
|
67
|
-
"""Loads metadata from disk."""
|
|
68
|
-
self._data = json_load(self.filepath) if self.has_file() else {}
|
|
69
|
-
|
|
70
|
-
def insert(self, key: str, value: Any) -> None:
|
|
71
|
-
"""Inserts value into metadata."""
|
|
72
|
-
self._data[key] = value
|
|
73
|
-
|
|
74
|
-
def remove(self, key: str) -> None:
|
|
75
|
-
"""Remove key from metadata."""
|
|
76
|
-
if key in self._data.keys():
|
|
77
|
-
del self._data[key]
|
|
78
|
-
|
|
79
|
-
def save(self) -> None:
|
|
80
|
-
"""Save current metadata into json file."""
|
|
81
|
-
if not os.path.exists(self.path):
|
|
82
|
-
os.makedirs(self.path)
|
|
83
|
-
|
|
84
|
-
self._data['system'] = self._system_data()
|
|
85
|
-
json_save(self._data, self.filepath)
|
|
86
|
-
|
|
87
|
-
# ------------------------------------------------------------------------------------
|
|
88
|
-
# CLASS MODE METHODS
|
|
89
|
-
# ------------------------------------------------------------------------------------
|
|
90
|
-
|
|
91
|
-
def load_as_class(self) -> type:
|
|
92
|
-
"""Returns the metadata dict as a class obj."""
|
|
93
|
-
metadata_class = type(self.name, (), self._data)
|
|
94
|
-
return metadata_class
|
|
95
|
-
|
|
96
|
-
def insert_class(self, _class: type) -> None:
|
|
97
|
-
"""Load all attributes from a given class into this class metadata."""
|
|
98
|
-
attributes = {}
|
|
99
|
-
for name in dir(_class):
|
|
100
|
-
value = getattr(_class, name)
|
|
101
|
-
if not name.startswith('__') and not (
|
|
102
|
-
inspect.isroutine(value) or inspect.isdatadescriptor(value)
|
|
103
|
-
):
|
|
104
|
-
attributes[name] = value
|
|
105
|
-
|
|
106
|
-
self._data = attributes
|
|
107
|
-
|
|
108
|
-
# ------------------------------------------------------------------------------------
|
|
109
|
-
# SYSTEM METADATA OS/USER/TIME
|
|
110
|
-
# ------------------------------------------------------------------------------------
|
|
111
|
-
|
|
112
|
-
def _system_data(self) -> dict:
|
|
113
|
-
"""Add system metadata to the default data before save."""
|
|
114
|
-
return {
|
|
115
|
-
'name': self.name,
|
|
116
|
-
'app': os.path.basename(sys.executable),
|
|
117
|
-
'PC': str(platform.node()),
|
|
118
|
-
'python_version': sys.version,
|
|
119
|
-
'User': getpass.getuser(),
|
|
120
|
-
'time': self._current_time_metadata(),
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
def _current_time_metadata(self) -> dict:
|
|
124
|
-
"""Get export time info."""
|
|
125
|
-
ftime = time.strftime('%Y,%b,%d,%j,%H:%M', time.localtime())
|
|
126
|
-
times = ftime.split(',')
|
|
127
|
-
td = {
|
|
128
|
-
'year': times[0],
|
|
129
|
-
'month': times[1],
|
|
130
|
-
'day': times[2],
|
|
131
|
-
'year_day': times[3],
|
|
132
|
-
'time': times[4],
|
|
133
|
-
'save_time': datetime.now().ctime(),
|
|
134
|
-
}
|
|
135
|
-
return td
|
|
1
|
+
# ----------------------------------------------------------------------------------------
|
|
2
|
+
# Python-Backpack - JsonMetadata
|
|
3
|
+
# Maximiliano Rocamora / maxirocamora@gmail.com
|
|
4
|
+
# https://github.com/MaxRocamora/python-backpack
|
|
5
|
+
# ----------------------------------------------------------------------------------------
|
|
6
|
+
import getpass
|
|
7
|
+
import inspect
|
|
8
|
+
import os
|
|
9
|
+
import platform
|
|
10
|
+
import sys
|
|
11
|
+
import time
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from backpack.json_utils import json_load, json_save
|
|
16
|
+
from backpack.version import version
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class JsonMetaFile:
|
|
20
|
+
PREFIX = 'MD_'
|
|
21
|
+
|
|
22
|
+
def __init__(self, name: str, path: str) -> None:
|
|
23
|
+
"""saves/load a class/dict as a json metadata file.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
name (str): name of the file/class
|
|
27
|
+
path (str, optional): filepath. Defaults to None.
|
|
28
|
+
"""
|
|
29
|
+
self._name = name
|
|
30
|
+
self._path = path
|
|
31
|
+
self._data = {'_about': {'package': 'python-backpack', 'version': self.version}}
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def name(self) -> str:
|
|
35
|
+
"""Name of this metadata class."""
|
|
36
|
+
return self._name
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def version(self) -> str:
|
|
40
|
+
"""Version of this metadata class."""
|
|
41
|
+
return version
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def filename(self) -> str:
|
|
45
|
+
"""Returns default filename with prefix and extension."""
|
|
46
|
+
return self.PREFIX + self.name + '.json'
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def filepath(self) -> str:
|
|
50
|
+
"""Full json metadata filepath."""
|
|
51
|
+
return os.path.join(self.path, self.filename)
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def path(self) -> str:
|
|
55
|
+
"""Base path location of metadata json file."""
|
|
56
|
+
return self._path
|
|
57
|
+
|
|
58
|
+
def has_file(self) -> bool:
|
|
59
|
+
"""Returns true if file exists."""
|
|
60
|
+
return os.path.exists(self.filepath)
|
|
61
|
+
|
|
62
|
+
# ------------------------------------------------------------------------------------
|
|
63
|
+
# LOAD/INSERT/REMOVE/SAVE
|
|
64
|
+
# ------------------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
def load(self) -> None:
|
|
67
|
+
"""Loads metadata from disk."""
|
|
68
|
+
self._data = json_load(self.filepath) if self.has_file() else {}
|
|
69
|
+
|
|
70
|
+
def insert(self, key: str, value: Any) -> None:
|
|
71
|
+
"""Inserts value into metadata."""
|
|
72
|
+
self._data[key] = value
|
|
73
|
+
|
|
74
|
+
def remove(self, key: str) -> None:
|
|
75
|
+
"""Remove key from metadata."""
|
|
76
|
+
if key in self._data.keys():
|
|
77
|
+
del self._data[key]
|
|
78
|
+
|
|
79
|
+
def save(self) -> None:
|
|
80
|
+
"""Save current metadata into json file."""
|
|
81
|
+
if not os.path.exists(self.path):
|
|
82
|
+
os.makedirs(self.path)
|
|
83
|
+
|
|
84
|
+
self._data['system'] = self._system_data()
|
|
85
|
+
json_save(self._data, self.filepath)
|
|
86
|
+
|
|
87
|
+
# ------------------------------------------------------------------------------------
|
|
88
|
+
# CLASS MODE METHODS
|
|
89
|
+
# ------------------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
def load_as_class(self) -> type:
|
|
92
|
+
"""Returns the metadata dict as a class obj."""
|
|
93
|
+
metadata_class = type(self.name, (), self._data)
|
|
94
|
+
return metadata_class
|
|
95
|
+
|
|
96
|
+
def insert_class(self, _class: type) -> None:
|
|
97
|
+
"""Load all attributes from a given class into this class metadata."""
|
|
98
|
+
attributes = {}
|
|
99
|
+
for name in dir(_class):
|
|
100
|
+
value = getattr(_class, name)
|
|
101
|
+
if not name.startswith('__') and not (
|
|
102
|
+
inspect.isroutine(value) or inspect.isdatadescriptor(value)
|
|
103
|
+
):
|
|
104
|
+
attributes[name] = value
|
|
105
|
+
|
|
106
|
+
self._data = attributes
|
|
107
|
+
|
|
108
|
+
# ------------------------------------------------------------------------------------
|
|
109
|
+
# SYSTEM METADATA OS/USER/TIME
|
|
110
|
+
# ------------------------------------------------------------------------------------
|
|
111
|
+
|
|
112
|
+
def _system_data(self) -> dict:
|
|
113
|
+
"""Add system metadata to the default data before save."""
|
|
114
|
+
return {
|
|
115
|
+
'name': self.name,
|
|
116
|
+
'app': os.path.basename(sys.executable),
|
|
117
|
+
'PC': str(platform.node()),
|
|
118
|
+
'python_version': sys.version,
|
|
119
|
+
'User': getpass.getuser(),
|
|
120
|
+
'time': self._current_time_metadata(),
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
def _current_time_metadata(self) -> dict:
|
|
124
|
+
"""Get export time info."""
|
|
125
|
+
ftime = time.strftime('%Y,%b,%d,%j,%H:%M', time.localtime())
|
|
126
|
+
times = ftime.split(',')
|
|
127
|
+
td = {
|
|
128
|
+
'year': times[0],
|
|
129
|
+
'month': times[1],
|
|
130
|
+
'day': times[2],
|
|
131
|
+
'year_day': times[3],
|
|
132
|
+
'time': times[4],
|
|
133
|
+
'save_time': datetime.now().ctime(),
|
|
134
|
+
}
|
|
135
|
+
return td
|
backpack/json_user_settings.py
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
# ----------------------------------------------------------------------------------------
|
|
2
|
-
# Json Settings Class
|
|
3
|
-
# This class handle load/save json files on win/linux local user folder
|
|
4
|
-
|
|
5
|
-
"""Usage.
|
|
6
|
-
|
|
7
|
-
us = JsonUserSettings('my_app')
|
|
8
|
-
us.save(someDict)
|
|
9
|
-
data = us.load()
|
|
10
|
-
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
# ----------------------------------------------------------------------------------------
|
|
14
|
-
import os
|
|
15
|
-
|
|
16
|
-
from backpack.json_utils import json_load, json_save
|
|
17
|
-
from backpack.logger import get_logger
|
|
18
|
-
|
|
19
|
-
log = get_logger('Python Backpack - UserSettings')
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class JsonUserSettings:
|
|
23
|
-
def __init__(self, folder: str, name: str) -> None:
|
|
24
|
-
"""Manages saving/loading json file on local user folder.
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
folder (str): name of sub folder inside user path. Defaults to 'json_settings'.
|
|
28
|
-
name (str): name used for the json file. Defaults to 'user_data'.
|
|
29
|
-
"""
|
|
30
|
-
self.filename = name
|
|
31
|
-
self.folder = folder
|
|
32
|
-
self._user_data = {}
|
|
33
|
-
self._verify_path()
|
|
34
|
-
|
|
35
|
-
@property
|
|
36
|
-
def filepath(self) -> str:
|
|
37
|
-
"""Returns user filepath."""
|
|
38
|
-
path = os.path.join(self.os_user_folder, self.folder, f'{self.filename}.json')
|
|
39
|
-
return os.path.abspath(path)
|
|
40
|
-
|
|
41
|
-
@property
|
|
42
|
-
def os_user_folder(self) -> str:
|
|
43
|
-
"""Returns os users home directory."""
|
|
44
|
-
return os.path.expanduser('~')
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def user_data(self) -> dict:
|
|
48
|
-
"""Override this property to modify saving dict."""
|
|
49
|
-
return self._user_data
|
|
50
|
-
|
|
51
|
-
@user_data.setter
|
|
52
|
-
def user_data(self, v: dict) -> None:
|
|
53
|
-
self._user_data = v
|
|
54
|
-
|
|
55
|
-
def _verify_path(self) -> bool:
|
|
56
|
-
"""Checks for target directory or make it."""
|
|
57
|
-
path = os.path.dirname(self.filepath)
|
|
58
|
-
if not os.path.exists(path):
|
|
59
|
-
os.makedirs(path)
|
|
60
|
-
|
|
61
|
-
return True
|
|
62
|
-
|
|
63
|
-
def save_settings(self, data: dict | None = None) -> bool:
|
|
64
|
-
"""Saves a dictionary into a json file (os user path).
|
|
65
|
-
|
|
66
|
-
Args:
|
|
67
|
-
data (dict): info dictionary to save, if not provided,
|
|
68
|
-
saves instead local self.user_data property
|
|
69
|
-
Returns:
|
|
70
|
-
bool: True if the file was saved, otherwise False.
|
|
71
|
-
"""
|
|
72
|
-
if data is None:
|
|
73
|
-
data = self.user_data
|
|
74
|
-
|
|
75
|
-
r = json_save(data, self.filepath)
|
|
76
|
-
if r:
|
|
77
|
-
log.info('json settings file saved! [%s]', self.filepath)
|
|
78
|
-
return r
|
|
79
|
-
|
|
80
|
-
def load_settings(self) -> dict | bool:
|
|
81
|
-
"""Load json file from path and returns its contents."""
|
|
82
|
-
try:
|
|
83
|
-
return json_load(self.filepath)
|
|
84
|
-
except OSError:
|
|
85
|
-
return False
|
|
1
|
+
# ----------------------------------------------------------------------------------------
|
|
2
|
+
# Json Settings Class
|
|
3
|
+
# This class handle load/save json files on win/linux local user folder
|
|
4
|
+
|
|
5
|
+
"""Usage.
|
|
6
|
+
|
|
7
|
+
us = JsonUserSettings('my_app')
|
|
8
|
+
us.save(someDict)
|
|
9
|
+
data = us.load()
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# ----------------------------------------------------------------------------------------
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
from backpack.json_utils import json_load, json_save
|
|
17
|
+
from backpack.logger import get_logger
|
|
18
|
+
|
|
19
|
+
log = get_logger('Python Backpack - UserSettings')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class JsonUserSettings:
|
|
23
|
+
def __init__(self, folder: str, name: str) -> None:
|
|
24
|
+
"""Manages saving/loading json file on local user folder.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
folder (str): name of sub folder inside user path. Defaults to 'json_settings'.
|
|
28
|
+
name (str): name used for the json file. Defaults to 'user_data'.
|
|
29
|
+
"""
|
|
30
|
+
self.filename = name
|
|
31
|
+
self.folder = folder
|
|
32
|
+
self._user_data = {}
|
|
33
|
+
self._verify_path()
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def filepath(self) -> str:
|
|
37
|
+
"""Returns user filepath."""
|
|
38
|
+
path = os.path.join(self.os_user_folder, self.folder, f'{self.filename}.json')
|
|
39
|
+
return os.path.abspath(path)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def os_user_folder(self) -> str:
|
|
43
|
+
"""Returns os users home directory."""
|
|
44
|
+
return os.path.expanduser('~')
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def user_data(self) -> dict:
|
|
48
|
+
"""Override this property to modify saving dict."""
|
|
49
|
+
return self._user_data
|
|
50
|
+
|
|
51
|
+
@user_data.setter
|
|
52
|
+
def user_data(self, v: dict) -> None:
|
|
53
|
+
self._user_data = v
|
|
54
|
+
|
|
55
|
+
def _verify_path(self) -> bool:
|
|
56
|
+
"""Checks for target directory or make it."""
|
|
57
|
+
path = os.path.dirname(self.filepath)
|
|
58
|
+
if not os.path.exists(path):
|
|
59
|
+
os.makedirs(path)
|
|
60
|
+
|
|
61
|
+
return True
|
|
62
|
+
|
|
63
|
+
def save_settings(self, data: dict | None = None) -> bool:
|
|
64
|
+
"""Saves a dictionary into a json file (os user path).
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
data (dict): info dictionary to save, if not provided,
|
|
68
|
+
saves instead local self.user_data property
|
|
69
|
+
Returns:
|
|
70
|
+
bool: True if the file was saved, otherwise False.
|
|
71
|
+
"""
|
|
72
|
+
if data is None:
|
|
73
|
+
data = self.user_data
|
|
74
|
+
|
|
75
|
+
r = json_save(data, self.filepath)
|
|
76
|
+
if r:
|
|
77
|
+
log.info('json settings file saved! [%s]', self.filepath)
|
|
78
|
+
return r
|
|
79
|
+
|
|
80
|
+
def load_settings(self) -> dict | bool:
|
|
81
|
+
"""Load json file from path and returns its contents."""
|
|
82
|
+
try:
|
|
83
|
+
return json_load(self.filepath)
|
|
84
|
+
except OSError:
|
|
85
|
+
return False
|