MainShortcuts2 2.0.0__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.
- MainShortcuts2/__init__.py +9 -0
- MainShortcuts2/_module_info.py +2 -0
- MainShortcuts2/cfg.py +125 -0
- MainShortcuts2/core.py +142 -0
- MainShortcuts2/dict.py +45 -0
- MainShortcuts2/dir.py +102 -0
- MainShortcuts2/file.py +92 -0
- MainShortcuts2/json.py +90 -0
- MainShortcuts2/list.py +84 -0
- MainShortcuts2/path.py +306 -0
- MainShortcuts2/proc.py +30 -0
- MainShortcuts2/str.py +48 -0
- MainShortcuts2/term.py +93 -0
- MainShortcuts2/utils.py +295 -0
- MainShortcuts2/win.py +39 -0
- mainshortcuts2-2.0.0.dist-info/METADATA +79 -0
- mainshortcuts2-2.0.0.dist-info/RECORD +19 -0
- mainshortcuts2-2.0.0.dist-info/WHEEL +4 -0
- mainshortcuts2-2.0.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Упрощение и сокращение вашего кода благодаря этой библиотеке
|
|
2
|
+
Разработчик: MainPlay TG
|
|
3
|
+
https://t.me/MainPlayCh"""
|
|
4
|
+
__all__ = ["ms", "MS2"]
|
|
5
|
+
__scripts__ = ["ms2-import_example"]
|
|
6
|
+
from ._module_info import version as __version__
|
|
7
|
+
# 2.0.0
|
|
8
|
+
from .core import MS2
|
|
9
|
+
ms = MS2()
|
MainShortcuts2/cfg.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from .core import MS2
|
|
3
|
+
from .path import PATH_TYPES, path2str
|
|
4
|
+
from typing import *
|
|
5
|
+
ms: MS2 = None
|
|
6
|
+
# 2.0.0
|
|
7
|
+
types = ["json", "json5", "pickle", "toml"]
|
|
8
|
+
ext2type = {
|
|
9
|
+
"json": "json",
|
|
10
|
+
"json5": "json5",
|
|
11
|
+
"pickle": "pickle",
|
|
12
|
+
"pkl": "pickle",
|
|
13
|
+
"toml": "toml",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _check_type(path: str, type: Union[str, None]):
|
|
18
|
+
type = type.lower()
|
|
19
|
+
if not type is None:
|
|
20
|
+
if not type in types:
|
|
21
|
+
raise Exception("Type %r not supported" % type)
|
|
22
|
+
return type
|
|
23
|
+
_, ext = os.path.splitext(path).lower()
|
|
24
|
+
if ext in ext2type:
|
|
25
|
+
return ext2type[ext]
|
|
26
|
+
raise Exception("Cannot determine type by extension %r" % ext)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _load_type(cfg):
|
|
30
|
+
path: str = cfg.path
|
|
31
|
+
type: str = cfg.type
|
|
32
|
+
if type == "json":
|
|
33
|
+
def load(**kw):
|
|
34
|
+
kw["like_json5"] = False
|
|
35
|
+
kw["path"] = path
|
|
36
|
+
return ms.json.read(**kw)
|
|
37
|
+
|
|
38
|
+
def save(**kw):
|
|
39
|
+
kw["data"] = cfg.data
|
|
40
|
+
kw["path"] = path
|
|
41
|
+
return ms.json.write(**kw)
|
|
42
|
+
if type == "json5":
|
|
43
|
+
def load(**kw):
|
|
44
|
+
kw["like_json5"] = True
|
|
45
|
+
kw["path"] = path
|
|
46
|
+
return ms.json.read(**kw)
|
|
47
|
+
|
|
48
|
+
def save(**kw):
|
|
49
|
+
kw["data"] = cfg.data
|
|
50
|
+
kw["path"] = path
|
|
51
|
+
return ms.json.write(**kw)
|
|
52
|
+
if type == "pickle":
|
|
53
|
+
import pickle
|
|
54
|
+
|
|
55
|
+
def load(**kw):
|
|
56
|
+
with open(path, "rb") as f:
|
|
57
|
+
kw["file"] = f
|
|
58
|
+
return pickle.load(**kw)
|
|
59
|
+
|
|
60
|
+
def save(**kw):
|
|
61
|
+
buf = pickle.dumps(**kw)
|
|
62
|
+
with open(path, "wb") as f:
|
|
63
|
+
return f.write(buf)
|
|
64
|
+
if type == "toml":
|
|
65
|
+
import toml
|
|
66
|
+
|
|
67
|
+
def load(encoding="utf-8", **kw):
|
|
68
|
+
with open(path, "r", encoding=encoding) as f:
|
|
69
|
+
kw["f"] = f
|
|
70
|
+
return toml.load(**kw)
|
|
71
|
+
|
|
72
|
+
def save(encoding="utf-8", **kw):
|
|
73
|
+
kw["o"] = cfg.data
|
|
74
|
+
buf = toml.dumps(**kw)
|
|
75
|
+
with open(path, "w", encoding=encoding) as f:
|
|
76
|
+
return f.write(buf)
|
|
77
|
+
return load, save
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class cfg:
|
|
81
|
+
# 2.0.0
|
|
82
|
+
def __init__(self, path: PATH_TYPES, data: dict = None, default: dict = None, type=None):
|
|
83
|
+
self.data = {} if data is None else data
|
|
84
|
+
self.default = {} if default is None else default
|
|
85
|
+
self.path = path2str(path, True)
|
|
86
|
+
self.type = _check_type(path, type)
|
|
87
|
+
self._load_func, self._save_func = _load_type(self)
|
|
88
|
+
|
|
89
|
+
def load(self, **kw):
|
|
90
|
+
self.data = self._load_func(**kw)
|
|
91
|
+
read = load
|
|
92
|
+
|
|
93
|
+
def save(self, **kw) -> int:
|
|
94
|
+
return self._save_func(**kw)
|
|
95
|
+
write = save
|
|
96
|
+
|
|
97
|
+
def fill_defaults(self):
|
|
98
|
+
for i in self.default:
|
|
99
|
+
if not i in self:
|
|
100
|
+
self[i] = self.default[i]
|
|
101
|
+
|
|
102
|
+
def dload(self, **kw):
|
|
103
|
+
self.load(**kw)
|
|
104
|
+
self.fill_defaults()
|
|
105
|
+
|
|
106
|
+
def __contains__(self, k):
|
|
107
|
+
return k in self.data
|
|
108
|
+
|
|
109
|
+
def __delitem__(self, k):
|
|
110
|
+
del self.data[k]
|
|
111
|
+
|
|
112
|
+
def __getitem__(self, k):
|
|
113
|
+
return self.data[k]
|
|
114
|
+
|
|
115
|
+
def __setitem__(self, k, v):
|
|
116
|
+
self.data[k] = v
|
|
117
|
+
|
|
118
|
+
def items(self):
|
|
119
|
+
return self.data.items()
|
|
120
|
+
|
|
121
|
+
def keys(self):
|
|
122
|
+
return self.data.keys()
|
|
123
|
+
|
|
124
|
+
def values(self):
|
|
125
|
+
return self.data.values()
|
MainShortcuts2/core.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from logging import Logger
|
|
4
|
+
# 2.0.0
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NoLogger:
|
|
8
|
+
def __init__(*a, **b):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
def __getattr__(self, k):
|
|
12
|
+
return lambda *a, **b: None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MS2:
|
|
16
|
+
def __init__(self, *,
|
|
17
|
+
__file__: str = None,
|
|
18
|
+
__name__: str = None,
|
|
19
|
+
logger: Logger = None,
|
|
20
|
+
**kw):
|
|
21
|
+
self._cfg = None
|
|
22
|
+
self._dict = None
|
|
23
|
+
self._dir = None
|
|
24
|
+
self._file = None
|
|
25
|
+
self._json = None
|
|
26
|
+
self._list = None
|
|
27
|
+
self._path = None
|
|
28
|
+
self._proc = None
|
|
29
|
+
self._str = None
|
|
30
|
+
self._term = None
|
|
31
|
+
self._utils = None
|
|
32
|
+
self._win = None
|
|
33
|
+
self.encoding = "utf-8"
|
|
34
|
+
self.env = os.environ
|
|
35
|
+
self.log: Logger = NoLogger() if logger is None else logger
|
|
36
|
+
self.prog_file = __file__
|
|
37
|
+
self.prog_name = __name__
|
|
38
|
+
self.reload()
|
|
39
|
+
|
|
40
|
+
def reload(self):
|
|
41
|
+
self.args = sys.argv
|
|
42
|
+
self.import_code = "from MainShortcuts2 import ms\nms.prog_file,ms.prog_name=__file__,__name__\nms.reload()"
|
|
43
|
+
self.imported = self.prog_name != "__main__"
|
|
44
|
+
self.pid = os.getpid()
|
|
45
|
+
self.prog_dir = os.path.dirname(self.prog_file)
|
|
46
|
+
self.running = self.prog_name == "__main__"
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def cfg(self):
|
|
50
|
+
if self._cfg is None:
|
|
51
|
+
from .cfg import cfg
|
|
52
|
+
self._cfg = cfg
|
|
53
|
+
self._cfg.ms = self
|
|
54
|
+
return self._cfg
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def dict(self):
|
|
58
|
+
if self._dict is None:
|
|
59
|
+
from . import dict
|
|
60
|
+
self._dict = dict
|
|
61
|
+
self._dict.ms = self
|
|
62
|
+
return self._dict
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def dir(self):
|
|
66
|
+
if self._dir is None:
|
|
67
|
+
from . import dir
|
|
68
|
+
self._dir = dir
|
|
69
|
+
self._dir.ms = self
|
|
70
|
+
return self._dir
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def file(self):
|
|
74
|
+
if self._file is None:
|
|
75
|
+
from . import file
|
|
76
|
+
self._file = file
|
|
77
|
+
self._file.ms = self
|
|
78
|
+
return self._file
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def json(self):
|
|
82
|
+
if self._json is None:
|
|
83
|
+
from . import json
|
|
84
|
+
self._json = json
|
|
85
|
+
self._json.ms = self
|
|
86
|
+
return self._json
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def list(self):
|
|
90
|
+
if self._list is None:
|
|
91
|
+
from . import list
|
|
92
|
+
self._list = list
|
|
93
|
+
self._list.ms = self
|
|
94
|
+
return self._list
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def path(self):
|
|
98
|
+
if self._path is None:
|
|
99
|
+
from . import path
|
|
100
|
+
self._path = path
|
|
101
|
+
self._path.ms = self
|
|
102
|
+
return self._path
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def proc(self):
|
|
106
|
+
if self._proc is None:
|
|
107
|
+
from . import proc
|
|
108
|
+
self._proc = proc
|
|
109
|
+
self._proc.ms = self
|
|
110
|
+
return self._proc
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def str(self):
|
|
114
|
+
if self._str is None:
|
|
115
|
+
from . import str
|
|
116
|
+
self._str = str
|
|
117
|
+
self._str.ms = self
|
|
118
|
+
return self._str
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def term(self):
|
|
122
|
+
if self._term is None:
|
|
123
|
+
from . import term
|
|
124
|
+
self._term = term
|
|
125
|
+
self._term.ms = self
|
|
126
|
+
return self._term
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def utils(self):
|
|
130
|
+
if self._utils is None:
|
|
131
|
+
from . import utils
|
|
132
|
+
self._utils = utils
|
|
133
|
+
self._utils.ms = self
|
|
134
|
+
return self._utils
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def win(self):
|
|
138
|
+
if self._win is None:
|
|
139
|
+
from . import win
|
|
140
|
+
self._win = win
|
|
141
|
+
self._win.ms = self
|
|
142
|
+
return self._win
|
MainShortcuts2/dict.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from .core import MS2
|
|
2
|
+
from typing import *
|
|
3
|
+
ms: MS2 = None
|
|
4
|
+
# 2.0.0
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def merge(old: dict, new: dict) -> dict:
|
|
8
|
+
"""Рекурсиво объединить словари"""
|
|
9
|
+
out = old.copy()
|
|
10
|
+
for k, v in new.items():
|
|
11
|
+
if k in out:
|
|
12
|
+
if type(out[k]) == dict and type(v) == dict:
|
|
13
|
+
out[k] = merge(out[k], v)
|
|
14
|
+
else:
|
|
15
|
+
out[k] = v
|
|
16
|
+
else:
|
|
17
|
+
out[k] = v
|
|
18
|
+
return out
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def reverse(d: dict) -> dict:
|
|
22
|
+
"""Развернуть порядок ключей"""
|
|
23
|
+
keys = list(d.keys())[::-1]
|
|
24
|
+
r = {}
|
|
25
|
+
for k in keys:
|
|
26
|
+
r[k] = d[k]
|
|
27
|
+
return r
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def sort(d: dict, *, key: None = None, reverse: bool = False) -> dict:
|
|
31
|
+
"""Сортировать порядок ключей"""
|
|
32
|
+
keys = list(d.keys)
|
|
33
|
+
keys.sort(key=key, reverse=reverse)
|
|
34
|
+
r = {}
|
|
35
|
+
for k in keys:
|
|
36
|
+
r[k] = d[k]
|
|
37
|
+
return r
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def swap(d: dict) -> dict:
|
|
41
|
+
"""Вывернуть словарь (повторяющиеся значения будут перезаписаны)"""
|
|
42
|
+
r = {}
|
|
43
|
+
for k, v in d.items():
|
|
44
|
+
r[v] = k
|
|
45
|
+
return r
|
MainShortcuts2/dir.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from .core import MS2
|
|
3
|
+
from .path import Path, PATH_TYPES, path2str
|
|
4
|
+
from typing import *
|
|
5
|
+
ms: MS2 = None
|
|
6
|
+
# 2.0.0
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NotADirError(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _check(path, **kw) -> str:
|
|
14
|
+
kw["path"] = path
|
|
15
|
+
path = path2str(**kw)
|
|
16
|
+
if os.path.exists(path):
|
|
17
|
+
if not os.path.isdir(path):
|
|
18
|
+
raise NotADirError(path)
|
|
19
|
+
return path
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create(path: PATH_TYPES, force: bool = True, **kw):
|
|
23
|
+
path = path2str(path)
|
|
24
|
+
if os.path.isdir(path):
|
|
25
|
+
return
|
|
26
|
+
if force:
|
|
27
|
+
if os.path.isfile(path):
|
|
28
|
+
ms.path.delete(path)
|
|
29
|
+
kw["name"] = _check(path)
|
|
30
|
+
os.makedirs(**kw)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _list_filter(path: Path, *, exts: Iterable[str], func: Callable[[Path], bool], links: bool, type: str):
|
|
34
|
+
if not exts is None:
|
|
35
|
+
if not path.ext in exts:
|
|
36
|
+
return False
|
|
37
|
+
if not func is None:
|
|
38
|
+
if not func(path):
|
|
39
|
+
return False
|
|
40
|
+
if not links is None:
|
|
41
|
+
if os.path.islink(path.path) != links:
|
|
42
|
+
return False
|
|
43
|
+
if not type is None:
|
|
44
|
+
if path.type != type:
|
|
45
|
+
return False
|
|
46
|
+
return True
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def list(path: PATH_TYPES = ".", *, exts: Iterable[str] = None, func: Callable[[Path], bool] = None, links: bool = None, type: str = None) -> list[Path]:
|
|
50
|
+
r = []
|
|
51
|
+
kw = {}
|
|
52
|
+
kw["exts"] = list(exts)
|
|
53
|
+
kw["func"] = func
|
|
54
|
+
kw["links"] = bool(links)
|
|
55
|
+
kw["type"] = type
|
|
56
|
+
for i in os.listdir(_check(path)):
|
|
57
|
+
i = Path(i)
|
|
58
|
+
if _list_filter(i, **kw):
|
|
59
|
+
r.append(i)
|
|
60
|
+
return i
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def copy(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
64
|
+
kw["dest"] = dest
|
|
65
|
+
kw["path"] = _check(path)
|
|
66
|
+
return ms.path.copy(**kw)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def delete(path: PATH_TYPES, **kw):
|
|
70
|
+
kw["path"] = _check(path)
|
|
71
|
+
return ms.path.delete(**kw)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def in_dir(path: str, dir: str, **kw) -> bool:
|
|
75
|
+
kw["dir"] = dir
|
|
76
|
+
kw["path"] = _check(path)
|
|
77
|
+
return ms.path.in_dir(**kw)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def link(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
81
|
+
kw["dest"] = dest
|
|
82
|
+
kw["path"] = _check(path)
|
|
83
|
+
return ms.path.link(**kw)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def move(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
87
|
+
kw["dest"] = dest
|
|
88
|
+
kw["path"] = _check(path)
|
|
89
|
+
return ms.path.move(**kw)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def rename(path: PATH_TYPES, name: PATH_TYPES, **kw):
|
|
93
|
+
kw["name"] = name
|
|
94
|
+
kw["path"] = _check(path)
|
|
95
|
+
return ms.path.rename(**kw)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
cp = copy
|
|
99
|
+
ln = link
|
|
100
|
+
mv = move
|
|
101
|
+
rm = delete
|
|
102
|
+
rn = rename
|
MainShortcuts2/file.py
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import builtins
|
|
2
|
+
import os
|
|
3
|
+
from .core import MS2
|
|
4
|
+
from .path import PATH_TYPES, path2str
|
|
5
|
+
from typing import *
|
|
6
|
+
ms: MS2 = None
|
|
7
|
+
# 2.0.0
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NotAFileError(Exception):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _check(path, **kw) -> str:
|
|
15
|
+
kw["path"] = path
|
|
16
|
+
path = path2str(**kw)
|
|
17
|
+
if os.path.exists(path):
|
|
18
|
+
if not os.path.isfile(path):
|
|
19
|
+
raise NotAFileError(path)
|
|
20
|
+
return path
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def read(path: PATH_TYPES, encoding: str = None, **kw) -> str:
|
|
24
|
+
kw["encoding"] = ms.encoding if encoding is None else encoding
|
|
25
|
+
kw["file"] = _check(path)
|
|
26
|
+
kw["mode"] = "r"
|
|
27
|
+
with builtins.open(**kw) as f:
|
|
28
|
+
return f.read()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def write(path: PATH_TYPES, data: str, encoding: str = None, **kw) -> int:
|
|
32
|
+
kw["encoding"] = ms.encoding if encoding is None else encoding
|
|
33
|
+
kw["file"] = _check(path)
|
|
34
|
+
kw["mode"] = "w"
|
|
35
|
+
with builtins.open(**kw) as f:
|
|
36
|
+
return f.write(data)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def load(path: PATH_TYPES, **kw) -> bytes:
|
|
40
|
+
kw["file"] = _check(path)
|
|
41
|
+
kw["mode"] = "rb"
|
|
42
|
+
with builtins.open(**kw) as f:
|
|
43
|
+
return f.read()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def save(path: PATH_TYPES, data: bytes, **kw) -> int:
|
|
47
|
+
kw["file"] = _check(path)
|
|
48
|
+
kw["mode"] = "wb"
|
|
49
|
+
with builtins.open(**kw) as f:
|
|
50
|
+
return f.write(data)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def copy(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
54
|
+
kw["dest"] = dest
|
|
55
|
+
kw["path"] = _check(path)
|
|
56
|
+
return ms.path.copy(**kw)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def delete(path: PATH_TYPES, **kw):
|
|
60
|
+
kw["path"] = _check(path)
|
|
61
|
+
return ms.path.delete(**kw)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def in_dir(path: str, dir: str, **kw) -> bool:
|
|
65
|
+
kw["dir"] = dir
|
|
66
|
+
kw["path"] = _check(path)
|
|
67
|
+
return ms.path.in_dir(**kw)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def link(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
71
|
+
kw["dest"] = dest
|
|
72
|
+
kw["path"] = _check(path)
|
|
73
|
+
return ms.path.link(**kw)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def move(path: PATH_TYPES, dest: PATH_TYPES, **kw):
|
|
77
|
+
kw["dest"] = dest
|
|
78
|
+
kw["path"] = _check(path)
|
|
79
|
+
return ms.path.move(**kw)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def rename(path: PATH_TYPES, name: PATH_TYPES, **kw):
|
|
83
|
+
kw["name"] = name
|
|
84
|
+
kw["path"] = _check(path)
|
|
85
|
+
return ms.path.rename(**kw)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
cp = copy
|
|
89
|
+
ln = link
|
|
90
|
+
mv = move
|
|
91
|
+
rm = delete
|
|
92
|
+
rn = rename
|
MainShortcuts2/json.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import builtins
|
|
3
|
+
from .core import MS2
|
|
4
|
+
from .path import PATH_TYPES
|
|
5
|
+
from typing import *
|
|
6
|
+
try:
|
|
7
|
+
import json5
|
|
8
|
+
except Exception:
|
|
9
|
+
json5 = None
|
|
10
|
+
ms: MS2 = None
|
|
11
|
+
# 2.0.0
|
|
12
|
+
JSON_TYPES = Union[bool, dict, float, int, list, None, str]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def decode(text: str, *, like_json5: bool = False, **kw) -> JSON_TYPES:
|
|
16
|
+
kw["s"] = text
|
|
17
|
+
if like_json5:
|
|
18
|
+
if not json5 is None:
|
|
19
|
+
return json5.loads(**kw)
|
|
20
|
+
return json.loads(**kw)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def encode(data: JSON_TYPES, mode: str = "c", **kw):
|
|
24
|
+
kw["obj"] = data
|
|
25
|
+
mode = mode.lower()
|
|
26
|
+
if "force" in kw:
|
|
27
|
+
del kw["force"]
|
|
28
|
+
if "sort" in kw:
|
|
29
|
+
kw["sort_keys"] = kw.pop("sort")
|
|
30
|
+
if mode in ["c", "compress", "min", "zip"]: # Сжатый
|
|
31
|
+
kw["indent"] = None
|
|
32
|
+
kw["separators"] = [",", ":"]
|
|
33
|
+
if mode in ["p", "pretty", "max", "print"]: # Развёрнутый
|
|
34
|
+
if not "indent" in kw:
|
|
35
|
+
kw["indent"] = 2
|
|
36
|
+
kw["separators"] = None
|
|
37
|
+
if mode in ["mp", "mp_tg", "mainplay", "mainplay_tg"]: # Стиль MainPlay TG
|
|
38
|
+
kw["indent"] = 2
|
|
39
|
+
kw["separators"] = [",", ":"]
|
|
40
|
+
return json.dumps(**kw)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def print(data: JSON_TYPES, mode: str = "p", **kw):
|
|
44
|
+
pr_kw = {}
|
|
45
|
+
for i in ["end", "file", "flush", "sep"]:
|
|
46
|
+
if i in kw:
|
|
47
|
+
pr_kw[i] = kw.pop(i)
|
|
48
|
+
kw["data"] = data
|
|
49
|
+
kw["mode"] = mode
|
|
50
|
+
builtins.print(encode(**kw), **pr_kw)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def read(path: PATH_TYPES, **kw) -> JSON_TYPES:
|
|
54
|
+
f_kw = {}
|
|
55
|
+
if "encoding" in kw:
|
|
56
|
+
f_kw["encoding"] = kw.pop("encoding")
|
|
57
|
+
f_kw["path"] = path
|
|
58
|
+
kw["text"] = ms.file.read(**f_kw)
|
|
59
|
+
return decode(**kw)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def rebuild(text: str, **kw) -> str:
|
|
63
|
+
de_kw = {}
|
|
64
|
+
if "like_json5" in kw:
|
|
65
|
+
de_kw["like_json5"] = kw.pop("like_json5")
|
|
66
|
+
de_kw["text"] = text
|
|
67
|
+
kw["data"] = decode(**de_kw)
|
|
68
|
+
return encode(**kw)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def rewrite(path: PATH_TYPES, **kw) -> int:
|
|
72
|
+
de_kw = {}
|
|
73
|
+
if "encoding" in kw:
|
|
74
|
+
de_kw["encoding"] = kw["encoding"]
|
|
75
|
+
if "like_json5" in kw:
|
|
76
|
+
de_kw["like_json5"] = kw.pop("like_json5")
|
|
77
|
+
de_kw["path"] = path
|
|
78
|
+
kw["path"] = path
|
|
79
|
+
kw["text"] = read(**de_kw)
|
|
80
|
+
return write(**kw)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def write(path: PATH_TYPES, data: JSON_TYPES, **kw) -> int:
|
|
84
|
+
f_kw = {}
|
|
85
|
+
for i in ["encoding", "force"]:
|
|
86
|
+
if i in kw:
|
|
87
|
+
f_kw[i] = kw.pop(i)
|
|
88
|
+
f_kw["path"] = path
|
|
89
|
+
f_kw["text"] = encode(**kw)
|
|
90
|
+
return ms.file.write(**f_kw)
|
MainShortcuts2/list.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from .core import MS2
|
|
3
|
+
from typing import *
|
|
4
|
+
ms: MS2 = None
|
|
5
|
+
# 2.0.0
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def filter(a: list, whitelist: list = None, blacklist: list = [], regex: str = False, begin: str = None, end: str = None):
|
|
9
|
+
"""Фильтровать список
|
|
10
|
+
whitelist - удалить всё, чего нет в этом списке
|
|
11
|
+
blacklist - удалить всё, что есть в этом списке
|
|
12
|
+
regex - сортировка с регулярным выражением (строки)"""
|
|
13
|
+
a = list(a)
|
|
14
|
+
if whitelist == None:
|
|
15
|
+
whitelist = a
|
|
16
|
+
if type(whitelist) == str:
|
|
17
|
+
whitelist = [whitelist]
|
|
18
|
+
if type(blacklist) == str:
|
|
19
|
+
blacklist = [blacklist]
|
|
20
|
+
b = []
|
|
21
|
+
for i in a:
|
|
22
|
+
add = True
|
|
23
|
+
if begin != None:
|
|
24
|
+
if str(i).startswith(str(begin)):
|
|
25
|
+
add = True
|
|
26
|
+
else:
|
|
27
|
+
add = False
|
|
28
|
+
if end != None and add:
|
|
29
|
+
if str(i).endswith(str(end)):
|
|
30
|
+
add = True
|
|
31
|
+
else:
|
|
32
|
+
add = False
|
|
33
|
+
if regex and add:
|
|
34
|
+
reW = False
|
|
35
|
+
for i2 in whitelist:
|
|
36
|
+
if re.match(str(i2), str(i)) != None:
|
|
37
|
+
reW = True
|
|
38
|
+
break
|
|
39
|
+
reB = False
|
|
40
|
+
for i2 in blacklist:
|
|
41
|
+
if re.match(str(i2), str(i)) != None:
|
|
42
|
+
reB = True
|
|
43
|
+
break
|
|
44
|
+
if reW and not reB:
|
|
45
|
+
add = True
|
|
46
|
+
else:
|
|
47
|
+
add = False
|
|
48
|
+
if add and not regex:
|
|
49
|
+
if (i in whitelist) and (not i in blacklist):
|
|
50
|
+
add = True
|
|
51
|
+
else:
|
|
52
|
+
add = False
|
|
53
|
+
if add:
|
|
54
|
+
b.append(i)
|
|
55
|
+
return b
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def rm_duplicates(a: list, trim: bool = False, case: bool = False, func=lambda i: i):
|
|
59
|
+
"""Удалить дублирующиеся элементы
|
|
60
|
+
trim - True: использовать strip()
|
|
61
|
+
l: использовать lstrip()
|
|
62
|
+
r: использовать rstrip()
|
|
63
|
+
case - lower/upper/capitalize
|
|
64
|
+
func - обработать каждый элемент этой функцией"""
|
|
65
|
+
b = []
|
|
66
|
+
trim = str(trim).lower()
|
|
67
|
+
case = str(case).lower()
|
|
68
|
+
for i in a:
|
|
69
|
+
if trim in ["true", "lr", "rl", "all"]:
|
|
70
|
+
i = i.strip()
|
|
71
|
+
elif trim in ["l", "left"]:
|
|
72
|
+
i = i.lstrip()
|
|
73
|
+
elif trim in ["r", "right"]:
|
|
74
|
+
i = i.rstrip()
|
|
75
|
+
if case in ["l", "lower", "low"]:
|
|
76
|
+
i = i.lower()
|
|
77
|
+
elif case in ["u", "upper", "up"]:
|
|
78
|
+
i = i.upper()
|
|
79
|
+
elif case in ["capitalize", "cap"]:
|
|
80
|
+
i = i.capitalize()
|
|
81
|
+
i = func(i)
|
|
82
|
+
if not i in b:
|
|
83
|
+
b.append(i)
|
|
84
|
+
return b
|