halib 0.2.30__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.
- halib/__init__.py +94 -0
- halib/common/__init__.py +0 -0
- halib/common/common.py +326 -0
- halib/common/rich_color.py +285 -0
- halib/common.py +151 -0
- halib/csvfile.py +48 -0
- halib/cuda.py +39 -0
- halib/dataset.py +209 -0
- halib/exp/__init__.py +0 -0
- halib/exp/core/__init__.py +0 -0
- halib/exp/core/base_config.py +167 -0
- halib/exp/core/base_exp.py +147 -0
- halib/exp/core/param_gen.py +170 -0
- halib/exp/core/wandb_op.py +117 -0
- halib/exp/data/__init__.py +0 -0
- halib/exp/data/dataclass_util.py +41 -0
- halib/exp/data/dataset.py +208 -0
- halib/exp/data/torchloader.py +165 -0
- halib/exp/perf/__init__.py +0 -0
- halib/exp/perf/flop_calc.py +190 -0
- halib/exp/perf/gpu_mon.py +58 -0
- halib/exp/perf/perfcalc.py +470 -0
- halib/exp/perf/perfmetrics.py +137 -0
- halib/exp/perf/perftb.py +778 -0
- halib/exp/perf/profiler.py +507 -0
- halib/exp/viz/__init__.py +0 -0
- halib/exp/viz/plot.py +754 -0
- halib/filesys.py +117 -0
- halib/filetype/__init__.py +0 -0
- halib/filetype/csvfile.py +192 -0
- halib/filetype/ipynb.py +61 -0
- halib/filetype/jsonfile.py +19 -0
- halib/filetype/textfile.py +12 -0
- halib/filetype/videofile.py +266 -0
- halib/filetype/yamlfile.py +87 -0
- halib/gdrive.py +179 -0
- halib/gdrive_mkdir.py +41 -0
- halib/gdrive_test.py +37 -0
- halib/jsonfile.py +22 -0
- halib/listop.py +13 -0
- halib/online/__init__.py +0 -0
- halib/online/gdrive.py +229 -0
- halib/online/gdrive_mkdir.py +53 -0
- halib/online/gdrive_test.py +50 -0
- halib/online/projectmake.py +131 -0
- halib/online/tele_noti.py +165 -0
- halib/plot.py +301 -0
- halib/projectmake.py +115 -0
- halib/research/__init__.py +0 -0
- halib/research/base_config.py +100 -0
- halib/research/base_exp.py +157 -0
- halib/research/benchquery.py +131 -0
- halib/research/core/__init__.py +0 -0
- halib/research/core/base_config.py +144 -0
- halib/research/core/base_exp.py +157 -0
- halib/research/core/param_gen.py +108 -0
- halib/research/core/wandb_op.py +117 -0
- halib/research/data/__init__.py +0 -0
- halib/research/data/dataclass_util.py +41 -0
- halib/research/data/dataset.py +208 -0
- halib/research/data/torchloader.py +165 -0
- halib/research/dataset.py +208 -0
- halib/research/flop_csv.py +34 -0
- halib/research/flops.py +156 -0
- halib/research/metrics.py +137 -0
- halib/research/mics.py +74 -0
- halib/research/params_gen.py +108 -0
- halib/research/perf/__init__.py +0 -0
- halib/research/perf/flop_calc.py +190 -0
- halib/research/perf/gpu_mon.py +58 -0
- halib/research/perf/perfcalc.py +363 -0
- halib/research/perf/perfmetrics.py +137 -0
- halib/research/perf/perftb.py +778 -0
- halib/research/perf/profiler.py +301 -0
- halib/research/perfcalc.py +361 -0
- halib/research/perftb.py +780 -0
- halib/research/plot.py +758 -0
- halib/research/profiler.py +300 -0
- halib/research/torchloader.py +162 -0
- halib/research/viz/__init__.py +0 -0
- halib/research/viz/plot.py +754 -0
- halib/research/wandb_op.py +116 -0
- halib/rich_color.py +285 -0
- halib/sys/__init__.py +0 -0
- halib/sys/cmd.py +8 -0
- halib/sys/filesys.py +124 -0
- halib/system/__init__.py +0 -0
- halib/system/_list_pc.csv +6 -0
- halib/system/cmd.py +8 -0
- halib/system/filesys.py +164 -0
- halib/system/path.py +106 -0
- halib/tele_noti.py +166 -0
- halib/textfile.py +13 -0
- halib/torchloader.py +162 -0
- halib/utils/__init__.py +0 -0
- halib/utils/dataclass_util.py +40 -0
- halib/utils/dict.py +317 -0
- halib/utils/dict_op.py +9 -0
- halib/utils/gpu_mon.py +58 -0
- halib/utils/list.py +17 -0
- halib/utils/listop.py +13 -0
- halib/utils/slack.py +86 -0
- halib/utils/tele_noti.py +166 -0
- halib/utils/video.py +82 -0
- halib/videofile.py +139 -0
- halib-0.2.30.dist-info/METADATA +237 -0
- halib-0.2.30.dist-info/RECORD +110 -0
- halib-0.2.30.dist-info/WHEEL +5 -0
- halib-0.2.30.dist-info/licenses/LICENSE.txt +17 -0
- halib-0.2.30.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
from rich.pretty import pprint
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import argparse
|
|
6
|
+
import wandb
|
|
7
|
+
from tqdm import tqdm
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
def sync_runs(outdir):
|
|
12
|
+
outdir = os.path.abspath(outdir)
|
|
13
|
+
assert os.path.exists(outdir), f"Output directory {outdir} does not exist."
|
|
14
|
+
sub_dirs = [name for name in os.listdir(outdir) if os.path.isdir(os.path.join(outdir, name))]
|
|
15
|
+
assert len(sub_dirs) > 0, f"No subdirectories found in {outdir}."
|
|
16
|
+
console.rule("Parent Directory")
|
|
17
|
+
console.print(f"[yellow]{outdir}[/yellow]")
|
|
18
|
+
|
|
19
|
+
exp_dirs = [os.path.join(outdir, sub_dir) for sub_dir in sub_dirs]
|
|
20
|
+
wandb_dirs = []
|
|
21
|
+
for exp_dir in exp_dirs:
|
|
22
|
+
wandb_dirs.extend(glob.glob(f"{exp_dir}/wandb/*run-*"))
|
|
23
|
+
if len(wandb_dirs) == 0:
|
|
24
|
+
console.print(f"No wandb runs found in {outdir}.")
|
|
25
|
+
return
|
|
26
|
+
else:
|
|
27
|
+
console.print(f"Found [bold]{len(wandb_dirs)}[/bold] wandb runs in {outdir}.")
|
|
28
|
+
for i, wandb_dir in enumerate(wandb_dirs):
|
|
29
|
+
console.rule(f"Syncing wandb run {i + 1}/{len(wandb_dirs)}")
|
|
30
|
+
console.print(f"Syncing: {wandb_dir}")
|
|
31
|
+
process = subprocess.Popen(
|
|
32
|
+
["wandb", "sync", wandb_dir],
|
|
33
|
+
stdout=subprocess.PIPE,
|
|
34
|
+
stderr=subprocess.STDOUT,
|
|
35
|
+
text=True,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
for line in process.stdout:
|
|
39
|
+
console.print(line.strip())
|
|
40
|
+
if " ERROR Error while calling W&B API" in line:
|
|
41
|
+
break
|
|
42
|
+
process.stdout.close()
|
|
43
|
+
process.wait()
|
|
44
|
+
if process.returncode != 0:
|
|
45
|
+
console.print(f"[red]Error syncing {wandb_dir}. Return code: {process.returncode}[/red]")
|
|
46
|
+
else:
|
|
47
|
+
console.print(f"Successfully synced {wandb_dir}.")
|
|
48
|
+
|
|
49
|
+
def delete_runs(project, pattern=None):
|
|
50
|
+
console.rule("Delete W&B Runs")
|
|
51
|
+
confirm_msg = f"Are you sure you want to delete all runs in"
|
|
52
|
+
confirm_msg += f" \n\tproject: [red]{project}[/red]"
|
|
53
|
+
if pattern:
|
|
54
|
+
confirm_msg += f"\n\tpattern: [blue]{pattern}[/blue]"
|
|
55
|
+
|
|
56
|
+
console.print(confirm_msg)
|
|
57
|
+
confirmation = input(f"This action cannot be undone. [y/N]: ").strip().lower()
|
|
58
|
+
if confirmation != "y":
|
|
59
|
+
print("Cancelled.")
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
print("Confirmed. Proceeding...")
|
|
63
|
+
api = wandb.Api()
|
|
64
|
+
runs = api.runs(project)
|
|
65
|
+
|
|
66
|
+
deleted = 0
|
|
67
|
+
console.rule("Deleting W&B Runs")
|
|
68
|
+
if len(runs) == 0:
|
|
69
|
+
print("No runs found in the project.")
|
|
70
|
+
return
|
|
71
|
+
for run in tqdm(runs):
|
|
72
|
+
if pattern is None or pattern in run.name:
|
|
73
|
+
run.delete()
|
|
74
|
+
console.print(f"Deleted run: [red]{run.name}[/red]")
|
|
75
|
+
deleted += 1
|
|
76
|
+
|
|
77
|
+
console.print(f"Total runs deleted: {deleted}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def valid_argument(args):
|
|
81
|
+
if args.op == "sync":
|
|
82
|
+
assert os.path.exists(args.outdir), f"Output directory {args.outdir} does not exist."
|
|
83
|
+
elif args.op == "delete":
|
|
84
|
+
assert isinstance(args.project, str) and len(args.project.strip()) > 0, "Project name must be a non-empty string."
|
|
85
|
+
else:
|
|
86
|
+
raise ValueError(f"Unknown operation: {args.op}")
|
|
87
|
+
|
|
88
|
+
def parse_args():
|
|
89
|
+
parser = argparse.ArgumentParser(description="Operations on W&B runs")
|
|
90
|
+
parser.add_argument("-op", "--op", type=str, help="Operation to perform", default="sync", choices=["delete", "sync"])
|
|
91
|
+
parser.add_argument("-prj", "--project", type=str, default="fire-paper2-2025", help="W&B project name")
|
|
92
|
+
parser.add_argument("-outdir", "--outdir", type=str, help="arg1 description", default="./zout/train")
|
|
93
|
+
parser.add_argument("-pt", "--pattern",
|
|
94
|
+
type=str,
|
|
95
|
+
default=None,
|
|
96
|
+
help="Run name pattern to match for deletion",
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return parser.parse_args()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def main():
|
|
103
|
+
args = parse_args()
|
|
104
|
+
# Validate arguments, stop if invalid
|
|
105
|
+
valid_argument(args)
|
|
106
|
+
|
|
107
|
+
op = args.op
|
|
108
|
+
if op == "sync":
|
|
109
|
+
sync_runs(args.outdir)
|
|
110
|
+
elif op == "delete":
|
|
111
|
+
delete_runs(args.project, args.pattern)
|
|
112
|
+
else:
|
|
113
|
+
raise ValueError(f"Unknown operation: {op}")
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
main()
|
halib/rich_color.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.pretty import pprint
|
|
3
|
+
from rich.table import Table
|
|
4
|
+
from rich.text import Text
|
|
5
|
+
from rich.panel import Panel
|
|
6
|
+
|
|
7
|
+
# List of colors
|
|
8
|
+
# ! https://rich.readthedocs.io/en/stable/appendix/colors.html
|
|
9
|
+
all_colors = [
|
|
10
|
+
"black",
|
|
11
|
+
"red",
|
|
12
|
+
"green",
|
|
13
|
+
"yellow",
|
|
14
|
+
"blue",
|
|
15
|
+
"magenta",
|
|
16
|
+
"cyan",
|
|
17
|
+
"white",
|
|
18
|
+
"bright_black",
|
|
19
|
+
"bright_red",
|
|
20
|
+
"bright_green",
|
|
21
|
+
"bright_yellow",
|
|
22
|
+
"bright_blue",
|
|
23
|
+
"bright_magenta",
|
|
24
|
+
"bright_cyan",
|
|
25
|
+
"bright_white",
|
|
26
|
+
"grey0",
|
|
27
|
+
"navy_blue",
|
|
28
|
+
"dark_blue",
|
|
29
|
+
"blue3",
|
|
30
|
+
"blue1",
|
|
31
|
+
"dark_green",
|
|
32
|
+
"deep_sky_blue4",
|
|
33
|
+
"dodger_blue3",
|
|
34
|
+
"dodger_blue2",
|
|
35
|
+
"green4",
|
|
36
|
+
"spring_green4",
|
|
37
|
+
"turquoise4",
|
|
38
|
+
"deep_sky_blue3",
|
|
39
|
+
"dodger_blue1",
|
|
40
|
+
"dark_cyan",
|
|
41
|
+
"light_sea_green",
|
|
42
|
+
"deep_sky_blue2",
|
|
43
|
+
"deep_sky_blue1",
|
|
44
|
+
"green3",
|
|
45
|
+
"spring_green3",
|
|
46
|
+
"cyan3",
|
|
47
|
+
"dark_turquoise",
|
|
48
|
+
"turquoise2",
|
|
49
|
+
"green1",
|
|
50
|
+
"spring_green2",
|
|
51
|
+
"spring_green1",
|
|
52
|
+
"medium_spring_green",
|
|
53
|
+
"cyan2",
|
|
54
|
+
"cyan1",
|
|
55
|
+
"purple4",
|
|
56
|
+
"purple3",
|
|
57
|
+
"blue_violet",
|
|
58
|
+
"grey37",
|
|
59
|
+
"medium_purple4",
|
|
60
|
+
"slate_blue3",
|
|
61
|
+
"royal_blue1",
|
|
62
|
+
"chartreuse4",
|
|
63
|
+
"pale_turquoise4",
|
|
64
|
+
"steel_blue",
|
|
65
|
+
"steel_blue3",
|
|
66
|
+
"cornflower_blue",
|
|
67
|
+
"dark_sea_green4",
|
|
68
|
+
"cadet_blue",
|
|
69
|
+
"sky_blue3",
|
|
70
|
+
"chartreuse3",
|
|
71
|
+
"sea_green3",
|
|
72
|
+
"aquamarine3",
|
|
73
|
+
"medium_turquoise",
|
|
74
|
+
"steel_blue1",
|
|
75
|
+
"sea_green2",
|
|
76
|
+
"sea_green1",
|
|
77
|
+
"dark_slate_gray2",
|
|
78
|
+
"dark_red",
|
|
79
|
+
"dark_magenta",
|
|
80
|
+
"orange4",
|
|
81
|
+
"light_pink4",
|
|
82
|
+
"plum4",
|
|
83
|
+
"medium_purple3",
|
|
84
|
+
"slate_blue1",
|
|
85
|
+
"wheat4",
|
|
86
|
+
"grey53",
|
|
87
|
+
"light_slate_grey",
|
|
88
|
+
"medium_purple",
|
|
89
|
+
"light_slate_blue",
|
|
90
|
+
"yellow4",
|
|
91
|
+
"dark_sea_green",
|
|
92
|
+
"light_sky_blue3",
|
|
93
|
+
"sky_blue2",
|
|
94
|
+
"chartreuse2",
|
|
95
|
+
"pale_green3",
|
|
96
|
+
"dark_slate_gray3",
|
|
97
|
+
"sky_blue1",
|
|
98
|
+
"chartreuse1",
|
|
99
|
+
"light_green",
|
|
100
|
+
"aquamarine1",
|
|
101
|
+
"dark_slate_gray1",
|
|
102
|
+
"deep_pink4",
|
|
103
|
+
"medium_violet_red",
|
|
104
|
+
"dark_violet",
|
|
105
|
+
"purple",
|
|
106
|
+
"medium_orchid3",
|
|
107
|
+
"medium_orchid",
|
|
108
|
+
"dark_goldenrod",
|
|
109
|
+
"rosy_brown",
|
|
110
|
+
"grey63",
|
|
111
|
+
"medium_purple2",
|
|
112
|
+
"medium_purple1",
|
|
113
|
+
"dark_khaki",
|
|
114
|
+
"navajo_white3",
|
|
115
|
+
"grey69",
|
|
116
|
+
"light_steel_blue3",
|
|
117
|
+
"light_steel_blue",
|
|
118
|
+
"dark_olive_green3",
|
|
119
|
+
"dark_sea_green3",
|
|
120
|
+
"light_cyan3",
|
|
121
|
+
"light_sky_blue1",
|
|
122
|
+
"green_yellow",
|
|
123
|
+
"dark_olive_green2",
|
|
124
|
+
"pale_green1",
|
|
125
|
+
"dark_sea_green2",
|
|
126
|
+
"pale_turquoise1",
|
|
127
|
+
"red3",
|
|
128
|
+
"deep_pink3",
|
|
129
|
+
"magenta3",
|
|
130
|
+
"dark_orange3",
|
|
131
|
+
"indian_red",
|
|
132
|
+
"hot_pink3",
|
|
133
|
+
"hot_pink2",
|
|
134
|
+
"orchid",
|
|
135
|
+
"orange3",
|
|
136
|
+
"light_salmon3",
|
|
137
|
+
"light_pink3",
|
|
138
|
+
"pink3",
|
|
139
|
+
"plum3",
|
|
140
|
+
"violet",
|
|
141
|
+
"gold3",
|
|
142
|
+
"light_goldenrod3",
|
|
143
|
+
"tan",
|
|
144
|
+
"misty_rose3",
|
|
145
|
+
"thistle3",
|
|
146
|
+
"plum2",
|
|
147
|
+
"yellow3",
|
|
148
|
+
"khaki3",
|
|
149
|
+
"light_yellow3",
|
|
150
|
+
"grey84",
|
|
151
|
+
"light_steel_blue1",
|
|
152
|
+
"yellow2",
|
|
153
|
+
"dark_olive_green1",
|
|
154
|
+
"dark_sea_green1",
|
|
155
|
+
"honeydew2",
|
|
156
|
+
"light_cyan1",
|
|
157
|
+
"red1",
|
|
158
|
+
"deep_pink2",
|
|
159
|
+
"deep_pink1",
|
|
160
|
+
"magenta2",
|
|
161
|
+
"magenta1",
|
|
162
|
+
"orange_red1",
|
|
163
|
+
"indian_red1",
|
|
164
|
+
"hot_pink",
|
|
165
|
+
"medium_orchid1",
|
|
166
|
+
"dark_orange",
|
|
167
|
+
"salmon1",
|
|
168
|
+
"light_coral",
|
|
169
|
+
"pale_violet_red1",
|
|
170
|
+
"orchid2",
|
|
171
|
+
"orchid1",
|
|
172
|
+
"orange1",
|
|
173
|
+
"sandy_brown",
|
|
174
|
+
"light_salmon1",
|
|
175
|
+
"light_pink1",
|
|
176
|
+
"pink1",
|
|
177
|
+
"plum1",
|
|
178
|
+
"gold1",
|
|
179
|
+
"light_goldenrod2",
|
|
180
|
+
"navajo_white1",
|
|
181
|
+
"misty_rose1",
|
|
182
|
+
"thistle1",
|
|
183
|
+
"yellow1",
|
|
184
|
+
"light_goldenrod1",
|
|
185
|
+
"khaki1",
|
|
186
|
+
"wheat1",
|
|
187
|
+
"cornsilk1",
|
|
188
|
+
"grey100",
|
|
189
|
+
"grey3",
|
|
190
|
+
"grey7",
|
|
191
|
+
"grey11",
|
|
192
|
+
"grey15",
|
|
193
|
+
"grey19",
|
|
194
|
+
"grey23",
|
|
195
|
+
"grey27",
|
|
196
|
+
"grey30",
|
|
197
|
+
"grey35",
|
|
198
|
+
"grey39",
|
|
199
|
+
"grey42",
|
|
200
|
+
"grey46",
|
|
201
|
+
"grey50",
|
|
202
|
+
"grey54",
|
|
203
|
+
"grey58",
|
|
204
|
+
"grey62",
|
|
205
|
+
"grey66",
|
|
206
|
+
"grey70",
|
|
207
|
+
"grey74",
|
|
208
|
+
"grey78",
|
|
209
|
+
"grey82",
|
|
210
|
+
"grey85",
|
|
211
|
+
"grey89",
|
|
212
|
+
"grey93",
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
basic_colors = [
|
|
216
|
+
"black",
|
|
217
|
+
"red",
|
|
218
|
+
"green",
|
|
219
|
+
"yellow",
|
|
220
|
+
"blue",
|
|
221
|
+
"magenta",
|
|
222
|
+
"cyan",
|
|
223
|
+
"white",
|
|
224
|
+
"bright_black",
|
|
225
|
+
"bright_red",
|
|
226
|
+
"bright_green",
|
|
227
|
+
"bright_yellow",
|
|
228
|
+
"bright_blue",
|
|
229
|
+
"bright_magenta",
|
|
230
|
+
"bright_cyan",
|
|
231
|
+
"bright_white",
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
def rcolor_all_str():
|
|
235
|
+
pprint(all_colors)
|
|
236
|
+
|
|
237
|
+
def rcolor_basic_str():
|
|
238
|
+
pprint(basic_colors)
|
|
239
|
+
|
|
240
|
+
def rcolor_str(in_str, color="white"):
|
|
241
|
+
assert color in all_colors, f"color must be one of {all_colors}"
|
|
242
|
+
return f"[{color}]{in_str}[/{color}]"
|
|
243
|
+
|
|
244
|
+
def rcolor_palette(color_list):
|
|
245
|
+
# make sure all colors are valid (in all_colors)
|
|
246
|
+
for color in color_list:
|
|
247
|
+
assert (
|
|
248
|
+
color in all_colors
|
|
249
|
+
), f"color must be a valid color. call <rcolor_all_str()> or <rcolor_palette_all()> to see all valid colors"
|
|
250
|
+
# Initialize console
|
|
251
|
+
console = Console()
|
|
252
|
+
|
|
253
|
+
# Create a table with horizontal lines and six columns
|
|
254
|
+
table = Table(show_header=True, header_style="bold magenta", show_lines=True)
|
|
255
|
+
|
|
256
|
+
# Define the columns
|
|
257
|
+
table.add_column("Color Name 1", style="bold")
|
|
258
|
+
table.add_column("Sample 1", style="bold")
|
|
259
|
+
table.add_column("Color Name 2", style="bold")
|
|
260
|
+
table.add_column("Sample 2", style="bold")
|
|
261
|
+
table.add_column("Color Name 3", style="bold")
|
|
262
|
+
table.add_column("Sample 3", style="bold")
|
|
263
|
+
|
|
264
|
+
# Adjust the number of rows needed for the table
|
|
265
|
+
num_colors = len(color_list)
|
|
266
|
+
num_rows = (num_colors + 2) // 3 # Ceiling division to ensure all colors fit
|
|
267
|
+
|
|
268
|
+
# Add rows to the table
|
|
269
|
+
for i in range(num_rows):
|
|
270
|
+
color1 = color_list[i * 3] if i * 3 < num_colors else ""
|
|
271
|
+
color2 = color_list[i * 3 + 1] if i * 3 + 1 < num_colors else ""
|
|
272
|
+
color3 = color_list[i * 3 + 2] if i * 3 + 2 < num_colors else ""
|
|
273
|
+
filled_rect1 = Text(" " * 10, style=f"on {color1}") if color1 else ""
|
|
274
|
+
filled_rect2 = Text(" " * 10, style=f"on {color2}") if color2 else ""
|
|
275
|
+
filled_rect3 = Text(" " * 10, style=f"on {color3}") if color3 else ""
|
|
276
|
+
table.add_row(color1, filled_rect1, color2, filled_rect2, color3, filled_rect3)
|
|
277
|
+
|
|
278
|
+
# Print the table
|
|
279
|
+
console.print(table)
|
|
280
|
+
|
|
281
|
+
def rcolor_palette_basic():
|
|
282
|
+
rcolor_palette(basic_colors)
|
|
283
|
+
|
|
284
|
+
def rcolor_palette_all():
|
|
285
|
+
rcolor_palette(all_colors)
|
halib/sys/__init__.py
ADDED
|
File without changes
|
halib/sys/cmd.py
ADDED
halib/sys/filesys.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from distutils.dir_util import copy_tree
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def is_exist(path):
|
|
8
|
+
return os.path.exists(path)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_directory(path):
|
|
12
|
+
return os.path.isdir(path)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_current_dir():
|
|
16
|
+
return os.getcwd()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def change_current_dir(new_dir):
|
|
20
|
+
if is_directory(new_dir):
|
|
21
|
+
os.chdir(new_dir)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_dir_name(directory):
|
|
25
|
+
return os.path.basename(os.path.normpath(directory))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_parent_dir(directory, return_full_path=False):
|
|
29
|
+
if not return_full_path:
|
|
30
|
+
return os.path.basename(os.path.dirname(directory))
|
|
31
|
+
else:
|
|
32
|
+
return os.path.dirname(directory)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def make_dir(directory):
|
|
36
|
+
if not os.path.exists(directory):
|
|
37
|
+
os.makedirs(directory)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def copy_dir(src_dir, dst_dir, dirs_exist_ok=True, ignore_patterns=None):
|
|
41
|
+
shutil.copytree(
|
|
42
|
+
src_dir, dst_dir, dirs_exist_ok=dirs_exist_ok, ignore=ignore_patterns
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def delete_dir(directory):
|
|
47
|
+
shutil.rmtree(directory)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def list_dirs(directory):
|
|
51
|
+
folders = list(
|
|
52
|
+
filter(
|
|
53
|
+
lambda x: os.path.isdir(os.path.join(directory, x)), os.listdir(directory)
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
return folders
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def list_files(directory):
|
|
60
|
+
files = list(
|
|
61
|
+
filter(
|
|
62
|
+
lambda x: os.path.isfile(os.path.join(directory, x)), os.listdir(directory)
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
return files
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def filter_files_by_extension(directory, ext, recursive=True):
|
|
69
|
+
if is_directory(directory):
|
|
70
|
+
result_files = []
|
|
71
|
+
if isinstance(ext, list):
|
|
72
|
+
ext_list = ext
|
|
73
|
+
else:
|
|
74
|
+
ext_list = [ext]
|
|
75
|
+
if not recursive:
|
|
76
|
+
filter_pattern = f"{directory}/*"
|
|
77
|
+
else:
|
|
78
|
+
filter_pattern = f"{directory}/**/*"
|
|
79
|
+
|
|
80
|
+
for ext_item in ext_list:
|
|
81
|
+
ext_filter = f"{filter_pattern}.{ext_item}"
|
|
82
|
+
files = glob.glob(filter_pattern, recursive=True)
|
|
83
|
+
files = [f for f in files if is_file(f) and f.endswith(ext_item)]
|
|
84
|
+
result_files.extend(files)
|
|
85
|
+
return result_files
|
|
86
|
+
else:
|
|
87
|
+
raise OSError("Directory not exists")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def is_file(path):
|
|
91
|
+
return os.path.isfile(path)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_file_name(file_path, split_file_ext=False):
|
|
95
|
+
if is_file(file_path):
|
|
96
|
+
if split_file_ext:
|
|
97
|
+
filename, file_extension = os.path.splitext(os.path.basename(file_path))
|
|
98
|
+
return filename, file_extension
|
|
99
|
+
else:
|
|
100
|
+
return os.path.basename(file_path)
|
|
101
|
+
else:
|
|
102
|
+
raise OSError("Not a file")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_absolute_path(file_path):
|
|
106
|
+
return os.path.abspath(file_path)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# dest can be a directory
|
|
110
|
+
def copy_file(source, dest):
|
|
111
|
+
shutil.copy2(source, dest)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def delete_file(path):
|
|
115
|
+
if is_file(path):
|
|
116
|
+
os.remove(path)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def rename_dir_or_file(old, new):
|
|
120
|
+
os.renames(old, new)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def move_dir_or_file(source, destination):
|
|
124
|
+
shutil.move(source, destination)
|
halib/system/__init__.py
ADDED
|
File without changes
|