oafuncs 0.0.97.11__py3-none-any.whl → 0.0.97.12__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.
- oafuncs/_script/cprogressbar.py +150 -0
- oafuncs/oa_data.py +22 -1
- oafuncs/oa_down/hycom_3hourly.py +23 -6
- oafuncs/oa_down/idm.py +9 -4
- {oafuncs-0.0.97.11.dist-info → oafuncs-0.0.97.12.dist-info}/METADATA +1 -1
- {oafuncs-0.0.97.11.dist-info → oafuncs-0.0.97.12.dist-info}/RECORD +9 -8
- {oafuncs-0.0.97.11.dist-info → oafuncs-0.0.97.12.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.97.11.dist-info → oafuncs-0.0.97.12.dist-info}/licenses/LICENSE.txt +0 -0
- {oafuncs-0.0.97.11.dist-info → oafuncs-0.0.97.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
# progressbar.py
|
2
|
+
import sys
|
3
|
+
import shutil
|
4
|
+
import time
|
5
|
+
import warnings
|
6
|
+
from typing import Iterable, Any, List, Union
|
7
|
+
import numpy as np
|
8
|
+
|
9
|
+
try:
|
10
|
+
from matplotlib.colors import LinearSegmentedColormap, to_rgb, to_hex
|
11
|
+
from matplotlib.cm import get_cmap
|
12
|
+
except ImportError:
|
13
|
+
raise ImportError("This module requires matplotlib. Install with: pip install matplotlib")
|
14
|
+
|
15
|
+
|
16
|
+
class ColorProgressBar:
|
17
|
+
def __init__(self, iterable: Iterable, prefix: str = "", color: Any = "cyan", cmap: Union[str, List[str]] = None, update_interval: float = 0.1, bar_length: int = None):
|
18
|
+
self.iterable = iterable
|
19
|
+
self.prefix = prefix
|
20
|
+
self.base_color = color
|
21
|
+
self.cmap = cmap
|
22
|
+
self.update_interval = update_interval
|
23
|
+
self.bar_length = bar_length
|
24
|
+
|
25
|
+
self._start_time = None
|
26
|
+
self._last_update = 0
|
27
|
+
self._count = len(iterable) if hasattr(iterable, "__len__") else None
|
28
|
+
self._file = sys.stdout
|
29
|
+
self._gradient_colors = self._generate_gradient() if cmap else None
|
30
|
+
|
31
|
+
def _generate_gradient(self) -> List[str]:
|
32
|
+
"""生成渐变色列表(修复内置colormap支持)"""
|
33
|
+
try:
|
34
|
+
if isinstance(self.cmap, list):
|
35
|
+
cmap = LinearSegmentedColormap.from_list("custom_cmap", self.cmap)
|
36
|
+
else:
|
37
|
+
# 正确获取Matplotlib内置colormap
|
38
|
+
cmap = get_cmap(self.cmap)
|
39
|
+
|
40
|
+
return [to_hex(cmap(i)) for i in np.linspace(0, 1, self._count)]
|
41
|
+
except Exception as e:
|
42
|
+
warnings.warn(f"Colormap generation failed: {str(e)}")
|
43
|
+
return None
|
44
|
+
|
45
|
+
def _hex_to_ansi(self, hex_color: str) -> str:
|
46
|
+
"""将颜色转换为ANSI真彩色代码"""
|
47
|
+
try:
|
48
|
+
rgb = [int(x * 255) for x in to_rgb(hex_color)]
|
49
|
+
return f"\033[38;2;{rgb[0]};{rgb[1]};{rgb[2]}m"
|
50
|
+
except ValueError as e:
|
51
|
+
warnings.warn(f"Invalid color value: {e}, falling back to cyan")
|
52
|
+
return "\033[96m"
|
53
|
+
|
54
|
+
def _resolve_color(self, index: int) -> str:
|
55
|
+
"""解析当前应使用的颜色"""
|
56
|
+
if self._gradient_colors and index < len(self._gradient_colors):
|
57
|
+
try:
|
58
|
+
return self._hex_to_ansi(self._gradient_colors[index])
|
59
|
+
except IndexError:
|
60
|
+
pass
|
61
|
+
|
62
|
+
return self._process_color_value(self.base_color)
|
63
|
+
|
64
|
+
def _process_color_value(self, color: Any) -> str:
|
65
|
+
"""处理颜色输入格式"""
|
66
|
+
preset_map = {
|
67
|
+
"red": "\033[91m",
|
68
|
+
"green": "\033[92m",
|
69
|
+
"yellow": "\033[93m",
|
70
|
+
"cyan": "\033[96m",
|
71
|
+
}
|
72
|
+
|
73
|
+
if color in preset_map:
|
74
|
+
return preset_map[color]
|
75
|
+
|
76
|
+
try:
|
77
|
+
hex_color = to_hex(color)
|
78
|
+
return self._hex_to_ansi(hex_color)
|
79
|
+
except (ValueError, TypeError) as e:
|
80
|
+
warnings.warn(f"Color parsing failed: {e}, using cyan")
|
81
|
+
return preset_map["cyan"]
|
82
|
+
|
83
|
+
def _format_bar(self, progress: float, width: int) -> str:
|
84
|
+
"""格式化进度条显示"""
|
85
|
+
filled = "▊"
|
86
|
+
empty = " "
|
87
|
+
max_width = width - 50
|
88
|
+
filled_length = int(round(max_width * progress))
|
89
|
+
return filled * filled_length + empty * (max_width - filled_length)
|
90
|
+
|
91
|
+
def _calculate_speed(self, index: int, elapsed: float) -> tuple:
|
92
|
+
"""计算速率和剩余时间"""
|
93
|
+
if index == 0 or elapsed < 1e-6:
|
94
|
+
return 0.0, 0.0
|
95
|
+
|
96
|
+
rate = index / elapsed
|
97
|
+
remaining = (self._count - index) / rate if self._count else 0
|
98
|
+
return rate, remaining
|
99
|
+
|
100
|
+
def __iter__(self):
|
101
|
+
self._start_time = time.time()
|
102
|
+
self._last_update = self._start_time
|
103
|
+
reset_code = "\033[0m"
|
104
|
+
|
105
|
+
for i, item in enumerate(self.iterable):
|
106
|
+
now = time.time()
|
107
|
+
elapsed = now - self._start_time
|
108
|
+
yield item
|
109
|
+
|
110
|
+
if (now - self._last_update) < self.update_interval and i + 1 != self._count:
|
111
|
+
continue
|
112
|
+
|
113
|
+
term_width = self.bar_length or shutil.get_terminal_size().columns
|
114
|
+
progress = (i + 1) / self._count if self._count else 0
|
115
|
+
|
116
|
+
current_color = self._resolve_color(i) if self._gradient_colors else self._resolve_color(0)
|
117
|
+
|
118
|
+
bar = self._format_bar(progress, term_width)
|
119
|
+
rate, remaining = self._calculate_speed(i + 1, elapsed)
|
120
|
+
|
121
|
+
count_info = f"{i + 1}/{self._count}" if self._count else str(i + 1)
|
122
|
+
percent = f"{progress:.1%}" if self._count else ""
|
123
|
+
rate_info = f"{rate:.1f}it/s" if rate else ""
|
124
|
+
time_info = f"ETA: {remaining:.1f}s" if self._count else f"Elapsed: {elapsed:.1f}s"
|
125
|
+
|
126
|
+
line = (f"\r{self.prefix}{current_color}[{bar}]{reset_code} {count_info} {percent} [{time_info} | {rate_info}]").ljust(term_width)
|
127
|
+
|
128
|
+
self._file.write(line)
|
129
|
+
self._file.flush()
|
130
|
+
self._last_update = now
|
131
|
+
|
132
|
+
self._file.write("\n")
|
133
|
+
self._file.flush()
|
134
|
+
|
135
|
+
@classmethod
|
136
|
+
def gradient_color(cls, colors: List[str], n: int) -> List[str]:
|
137
|
+
"""生成渐变色列表"""
|
138
|
+
cmap = LinearSegmentedColormap.from_list("gradient", colors)
|
139
|
+
return [to_hex(cmap(i)) for i in np.linspace(0, 1, n)]
|
140
|
+
|
141
|
+
|
142
|
+
# 验证示例
|
143
|
+
if __name__ == "__main__":
|
144
|
+
# 正确使用内置colormap
|
145
|
+
for _ in ColorProgressBar(range(100), cmap="viridis", prefix="Viridis: "):
|
146
|
+
time.sleep(0.05)
|
147
|
+
|
148
|
+
# 使用自定义渐变色
|
149
|
+
for _ in ColorProgressBar(range(50), cmap=["#FF0000", "#0000FF"], prefix="Custom: "):
|
150
|
+
time.sleep(0.1)
|
oafuncs/oa_data.py
CHANGED
@@ -22,8 +22,9 @@ import salem
|
|
22
22
|
import xarray as xr
|
23
23
|
from scipy.interpolate import griddata
|
24
24
|
from scipy.interpolate import interp1d
|
25
|
+
from typing import Iterable
|
25
26
|
|
26
|
-
__all__ = ["interp_along_dim", "interp_2d", "ensure_list", "mask_shapefile"]
|
27
|
+
__all__ = ["interp_along_dim", "interp_2d", "ensure_list", "mask_shapefile", "pbar"]
|
27
28
|
|
28
29
|
|
29
30
|
def ensure_list(input_data):
|
@@ -254,6 +255,26 @@ def mask_shapefile(data: np.ndarray, lons: np.ndarray, lats: np.ndarray, shapefi
|
|
254
255
|
return None
|
255
256
|
|
256
257
|
|
258
|
+
def pbar(iterable: Iterable, prefix: str = "", color: str = "cyan", cmap: str = None, **kwargs) -> Iterable:
|
259
|
+
"""
|
260
|
+
快速创建进度条的封装函数
|
261
|
+
:param iterable: 可迭代对象
|
262
|
+
:param prefix: 进度条前缀
|
263
|
+
:param color: 基础颜色
|
264
|
+
:param cmap: 渐变色名称
|
265
|
+
:param kwargs: 其他ColorProgressBar支持的参数
|
266
|
+
|
267
|
+
example:
|
268
|
+
from oafuncs.oa_data import pbar
|
269
|
+
from time import sleep
|
270
|
+
for i in pbar(range(100), prefix="Processing", color="green", cmap="viridis"):
|
271
|
+
sleep(0.1)
|
272
|
+
"""
|
273
|
+
from ._script.cprogressbar import ColorProgressBar # 从progressbar.py导入类
|
274
|
+
|
275
|
+
return ColorProgressBar(iterable=iterable, prefix=prefix, color=color, cmap=cmap, **kwargs)
|
276
|
+
|
277
|
+
|
257
278
|
if __name__ == "__main__":
|
258
279
|
pass
|
259
280
|
""" import time
|
oafuncs/oa_down/hycom_3hourly.py
CHANGED
@@ -900,7 +900,7 @@ def _get_submit_url_var(var, depth, level_num, lon_min, lon_max, lat_min, lat_ma
|
|
900
900
|
|
901
901
|
|
902
902
|
def _prepare_url_to_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, download_time="2024083100", download_time_end=None, depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None, check=False):
|
903
|
-
print("[bold #ecdbfe]-" *
|
903
|
+
print("[bold #ecdbfe]-" * mark_len)
|
904
904
|
download_time = str(download_time)
|
905
905
|
if download_time_end is not None:
|
906
906
|
download_time_end = str(download_time_end)
|
@@ -1181,30 +1181,47 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
|
|
1181
1181
|
|
1182
1182
|
global match_time
|
1183
1183
|
match_time = fill_time
|
1184
|
+
|
1185
|
+
global mark_len
|
1186
|
+
mark_len = 150
|
1184
1187
|
|
1185
1188
|
_download_hourly_func(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check, ftimes, int(interval_hour))
|
1186
1189
|
|
1187
1190
|
if idm_engine is not None:
|
1191
|
+
print("[bold #ecdbfe]*" * mark_len)
|
1192
|
+
print("[bold #3dfc40]All files have been submitted to IDM for downloading")
|
1193
|
+
print("[bold #ecdbfe]*" * mark_len)
|
1188
1194
|
if idm_download_list:
|
1195
|
+
file_download_time = 60 # 预设下载时间为1分钟
|
1189
1196
|
for f in idm_download_list:
|
1197
|
+
file_download_start_time = time.time()
|
1190
1198
|
wait_success = 0
|
1191
1199
|
success = False
|
1192
1200
|
while not success:
|
1193
1201
|
if check_nc(f):
|
1194
1202
|
count_dict["success"] += 1
|
1195
1203
|
success = True
|
1204
|
+
print(f"[bold #3dfc40]File [bold #dfff73]{f} [#3dfc40]has been downloaded successfully")
|
1205
|
+
file_download_end_time = time.time()
|
1206
|
+
file_download_time = file_download_end_time - file_download_start_time
|
1207
|
+
file_download_time = int(file_download_time)
|
1208
|
+
print(f"[bold #3dfc40]Time: {file_download_time} seconds")
|
1209
|
+
file_download_time = max(60, file_download_time) # 预设下载时间为1分钟起步
|
1196
1210
|
else:
|
1197
1211
|
wait_success += 1
|
1198
|
-
|
1199
|
-
|
1212
|
+
print(f"[bold #ffe5c0]Waiting {file_download_time} seconds to check the file {f}...")
|
1213
|
+
time.sleep(file_download_time)
|
1214
|
+
if wait_success >= 10:
|
1200
1215
|
success = True
|
1201
1216
|
# print(f'{f} download failed')
|
1217
|
+
print(f'[bold #ffe5c0]Waiting for more than 10 times, skipping the file {f}...')
|
1202
1218
|
count_dict["fail"] += 1
|
1219
|
+
print('[bold #ecdbfe]-' * mark_len)
|
1203
1220
|
|
1204
1221
|
count_dict["total"] = count_dict["success"] + count_dict["fail"] + count_dict["skip"] + count_dict["no_data"]
|
1205
|
-
print("[bold #ecdbfe]
|
1222
|
+
print("[bold #ecdbfe]=" * mark_len)
|
1206
1223
|
print(f"[bold #ff80ab]Total: {count_dict['total']}\nSuccess: {count_dict['success']}\nFail: {count_dict['fail']}\nSkip: {count_dict['skip']}\nNo data: {count_dict['no_data']}")
|
1207
|
-
print("[bold #ecdbfe]
|
1224
|
+
print("[bold #ecdbfe]=" * mark_len)
|
1208
1225
|
if count_dict["fail"] > 0:
|
1209
1226
|
print("[bold #be5528]Please try again to download the failed data later")
|
1210
1227
|
if count_dict["no_data"] > 0:
|
@@ -1214,7 +1231,7 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
|
|
1214
1231
|
print(f"[bold #f90000]These are {count_dict['no_data']} data that do not exist in any dataset and version")
|
1215
1232
|
for no_data in count_dict["no_data_list"]:
|
1216
1233
|
print(f"[bold #d81b60]{no_data}")
|
1217
|
-
print("[bold #ecdbfe]
|
1234
|
+
print("[bold #ecdbfe]=" * mark_len)
|
1218
1235
|
|
1219
1236
|
|
1220
1237
|
def how_to_use():
|
oafuncs/oa_down/idm.py
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
# coding=utf-8
|
3
3
|
"""
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
|
-
Date: 2025-
|
5
|
+
Date: 2025-03-27 16:51:26
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2025-01
|
7
|
+
LastEditTime: 2025-04-01 16:09:03
|
8
8
|
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\idm.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
@@ -16,7 +16,6 @@ Python Version: 3.12
|
|
16
16
|
import datetime
|
17
17
|
import os
|
18
18
|
from subprocess import call
|
19
|
-
|
20
19
|
from rich import print
|
21
20
|
|
22
21
|
__all__ = ["downloader"]
|
@@ -46,5 +45,11 @@ def downloader(task_url, folder_path, file_name, idm_engine=r"D:\Programs\Intern
|
|
46
45
|
# 开始任务队列
|
47
46
|
call([idm_engine, "/s"])
|
48
47
|
# print(f"IDM下载器:{file_name}下载任务已添加至队列...")
|
49
|
-
print("[purple]-" *
|
48
|
+
# print("[purple]-" * 150 + f"\n{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" + "[purple]-" * 150)
|
49
|
+
print("[purple]*" * 100)
|
50
|
+
time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
51
|
+
time_str = time_str.center(100, " ")
|
52
|
+
print(f"[bold purple]{time_str}")
|
50
53
|
print(f"[green]IDM Downloader: {file_name} download task has been added to the queue...[/green]")
|
54
|
+
print("[purple]*" * 100)
|
55
|
+
print('\n')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
oafuncs/__init__.py,sha256=T_-VtnWWllV3Q91twT5Yt2sUapeA051QbPNnBxmg9nw,1456
|
2
2
|
oafuncs/oa_cmap.py,sha256=OfJ2DOBOGX5X1GihE6CPcTV8bAFdDqJSXV7vbqUgV9s,7552
|
3
|
-
oafuncs/oa_data.py,sha256=
|
3
|
+
oafuncs/oa_data.py,sha256=7Mm2tFpKScs7TDgPiHDS0l_xVqb65WZvuQJCZ9BbK5Y,12953
|
4
4
|
oafuncs/oa_date.py,sha256=--3uXYq3_n9HBJbY1io1H1PE-FyiVxbQCyFUcudxQks,3210
|
5
5
|
oafuncs/oa_draw.py,sha256=d23R6OEco7EbvcrL5YsnrSupnKKUn55hLw1B_d-kxOg,12308
|
6
6
|
oafuncs/oa_file.py,sha256=nYTsMataaC790lSqxjuMB4uVqUJz_tMm_kRve4CHql4,17235
|
@@ -10,14 +10,15 @@ oafuncs/oa_python.py,sha256=Q-6UGGw_dJff7Ef8i87fsLPoGeHV5jBzfb-7HP4THR0,4018
|
|
10
10
|
oafuncs/_data/OAFuncs.png,sha256=y1_x-mUP3gFjcy6m8FqfvQO_HgjzPhQKfXjnSHjslZE,3436152
|
11
11
|
oafuncs/_data/hycom_3hourly.png,sha256=azt_uPcXtl_8CSKRLLPCIf5pPrcxMiOzvoFQnwb0zUo,12411415
|
12
12
|
oafuncs/_script/auto_optimized_parallel_executor.py,sha256=4QaEk9AM-IneHm8KKSQ6MjSLNSaAWM4AQ-8OWXYdsaI,17300
|
13
|
+
oafuncs/_script/cprogressbar.py,sha256=F3LlFsKojP58mqcAqHRw3u-ffftXaYiN5dKj7zDi0iI,5658
|
13
14
|
oafuncs/_script/netcdf_merge.py,sha256=mKHnjStCqP7bwUMVA5k9ZKwT1ZVv1PR-ehMKdpHMJ4s,14439
|
14
15
|
oafuncs/_script/parallel_example_usage.py,sha256=uLvE7iwkMn9Cyq6-wk5_RpbQk7PXM9d16-26lTknW9s,2646
|
15
16
|
oafuncs/_script/plot_dataset.py,sha256=zkSEnO_-biyagorwWXPoihts_cwuvripzEt-l9bHJ2E,13989
|
16
17
|
oafuncs/_script/replace_file_concent.py,sha256=eCFZjnZcwyRvy6b4mmIfBna-kylSZTyJRfgXd6DdCjk,5982
|
17
18
|
oafuncs/oa_down/User_Agent-list.txt,sha256=pazxSip8_lphEBOPHG902zmIBUg8sBKXgmqp_g6j_E4,661062
|
18
19
|
oafuncs/oa_down/__init__.py,sha256=kRX5eTUCbAiz3zTaQM1501paOYS_3fizDN4Pa0mtNUA,585
|
19
|
-
oafuncs/oa_down/hycom_3hourly.py,sha256=
|
20
|
-
oafuncs/oa_down/idm.py,sha256=
|
20
|
+
oafuncs/oa_down/hycom_3hourly.py,sha256=TnLyXEFJthl4NOeuCXW5DM-h0T6JxhIVATW7XOC4sqw,66837
|
21
|
+
oafuncs/oa_down/idm.py,sha256=pqktP4aKDxR3k8XLy9ceQQovvb4jjjT1VGF955PHIG8,1898
|
21
22
|
oafuncs/oa_down/literature.py,sha256=2bF9gSKQbzcci9LcKE81j8JEjIJwON7jbwQB3gDDA3E,11331
|
22
23
|
oafuncs/oa_down/test_ua.py,sha256=0IQq3NjqfNr7KkyjS_U-a4mYu-r-E7gzawwo4IfEa6Y,10851
|
23
24
|
oafuncs/oa_down/user_agent.py,sha256=TsPcAxFmMTYAEHRFjurI1bQBJfDhcA70MdHoUPwQmks,785
|
@@ -33,8 +34,8 @@ oafuncs/oa_sign/scientific.py,sha256=a4JxOBgm9vzNZKpJ_GQIQf7cokkraV5nh23HGbmTYKw
|
|
33
34
|
oafuncs/oa_tool/__init__.py,sha256=AvrCNR2-xad9ZRjthIdAoSk8UX4vOpEWLg6CV1NQNKc,161
|
34
35
|
oafuncs/oa_tool/email.py,sha256=4lJxV_KUzhxgLYfVwYTqp0qxRugD7fvsZkXDe5WkUKo,3052
|
35
36
|
oafuncs/oa_tool/parallel.py,sha256=LBFWEKPcILVCbfSulETJE4wGPiOw1P_Fl9DzjYoCqgk,21844
|
36
|
-
oafuncs-0.0.97.
|
37
|
-
oafuncs-0.0.97.
|
38
|
-
oafuncs-0.0.97.
|
39
|
-
oafuncs-0.0.97.
|
40
|
-
oafuncs-0.0.97.
|
37
|
+
oafuncs-0.0.97.12.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
|
38
|
+
oafuncs-0.0.97.12.dist-info/METADATA,sha256=sWGGWvxD_dWTX6bNz5sdMoJe4r3-GemQnSJY2P79dFw,4226
|
39
|
+
oafuncs-0.0.97.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
40
|
+
oafuncs-0.0.97.12.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
|
41
|
+
oafuncs-0.0.97.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|