oafuncs 0.0.97.11__tar.gz → 0.0.97.12__tar.gz

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.
Files changed (47) hide show
  1. {oafuncs-0.0.97.11/oafuncs.egg-info → oafuncs-0.0.97.12}/PKG-INFO +1 -1
  2. oafuncs-0.0.97.12/oafuncs/_script/cprogressbar.py +150 -0
  3. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_data.py +22 -1
  4. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/hycom_3hourly.py +23 -6
  5. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/idm.py +9 -4
  6. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12/oafuncs.egg-info}/PKG-INFO +1 -1
  7. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs.egg-info/SOURCES.txt +1 -0
  8. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/setup.py +1 -1
  9. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/LICENSE.txt +0 -0
  10. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/MANIFEST.in +0 -0
  11. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/README.md +0 -0
  12. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/__init__.py +0 -0
  13. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_data/OAFuncs.png +0 -0
  14. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_data/hycom_3hourly.png +0 -0
  15. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_script/auto_optimized_parallel_executor.py +0 -0
  16. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_script/netcdf_merge.py +0 -0
  17. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_script/parallel_example_usage.py +0 -0
  18. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_script/plot_dataset.py +0 -0
  19. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/_script/replace_file_concent.py +0 -0
  20. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_cmap.py +0 -0
  21. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_date.py +0 -0
  22. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/User_Agent-list.txt +0 -0
  23. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/__init__.py +0 -0
  24. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/literature.py +0 -0
  25. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/test_ua.py +0 -0
  26. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_down/user_agent.py +0 -0
  27. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_draw.py +0 -0
  28. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_file.py +0 -0
  29. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_help.py +0 -0
  30. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_model/__init__.py +0 -0
  31. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_model/roms/__init__.py +0 -0
  32. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_model/roms/test.py +0 -0
  33. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_model/wrf/__init__.py +0 -0
  34. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_model/wrf/little_r.py +0 -0
  35. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_nc.py +0 -0
  36. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_python.py +0 -0
  37. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_sign/__init__.py +0 -0
  38. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_sign/meteorological.py +0 -0
  39. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_sign/ocean.py +0 -0
  40. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_sign/scientific.py +0 -0
  41. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_tool/__init__.py +0 -0
  42. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_tool/email.py +0 -0
  43. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs/oa_tool/parallel.py +0 -0
  44. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs.egg-info/dependency_links.txt +0 -0
  45. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs.egg-info/requires.txt +0 -0
  46. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/oafuncs.egg-info/top_level.txt +0 -0
  47. {oafuncs-0.0.97.11 → oafuncs-0.0.97.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.97.11
3
+ Version: 0.0.97.12
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -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)
@@ -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
@@ -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]-" * 160)
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
- time.sleep(3)
1199
- if wait_success >= 20:
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]-" * 160)
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]-" * 160)
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]-" * 160)
1234
+ print("[bold #ecdbfe]=" * mark_len)
1218
1235
 
1219
1236
 
1220
1237
  def how_to_use():
@@ -2,9 +2,9 @@
2
2
  # coding=utf-8
3
3
  """
4
4
  Author: Liu Kun && 16031215@qq.com
5
- Date: 2025-01-11 16:19:12
5
+ Date: 2025-03-27 16:51:26
6
6
  LastEditors: Liu Kun && 16031215@qq.com
7
- LastEditTime: 2025-01-11 16:25:47
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]-" * 50 + f"\n{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n" + "[purple]-" * 50)
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
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.97.11
3
+ Version: 0.0.97.12
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -19,6 +19,7 @@ oafuncs.egg-info/top_level.txt
19
19
  oafuncs/_data/OAFuncs.png
20
20
  oafuncs/_data/hycom_3hourly.png
21
21
  oafuncs/_script/auto_optimized_parallel_executor.py
22
+ oafuncs/_script/cprogressbar.py
22
23
  oafuncs/_script/netcdf_merge.py
23
24
  oafuncs/_script/parallel_example_usage.py
24
25
  oafuncs/_script/plot_dataset.py
@@ -18,7 +18,7 @@ URL = "https://github.com/Industry-Pays/OAFuncs"
18
18
  EMAIL = "liukun0312@stu.ouc.edu.cn"
19
19
  AUTHOR = "Kun Liu"
20
20
  REQUIRES_PYTHON = ">=3.9.0" # 2025/03/13
21
- VERSION = "0.0.97.11" # 下次用98.0,98.1已经被用过了
21
+ VERSION = "0.0.97.12" # 下次用98.0,98.1已经被用过了
22
22
 
23
23
  # What packages are required for this module to be executed?
24
24
  REQUIRED = [
File without changes
File without changes
File without changes
File without changes