oafuncs 0.0.98.4__tar.gz → 0.0.98.6__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 (51) hide show
  1. {oafuncs-0.0.98.4/oafuncs.egg-info → oafuncs-0.0.98.6}/PKG-INFO +1 -1
  2. oafuncs-0.0.98.4/oafuncs/oa_down/hycom_3hourly_20250416.py → oafuncs-0.0.98.6/oafuncs/oa_down/hycom_3hourly.py +149 -122
  3. oafuncs-0.0.98.4/oafuncs/oa_down/hycom_3hourly.py → oafuncs-0.0.98.6/oafuncs/oa_down/hycom_3hourly_proxy.py +125 -111
  4. oafuncs-0.0.98.6/oafuncs/oa_down/read_proxy.py +108 -0
  5. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6/oafuncs.egg-info}/PKG-INFO +1 -1
  6. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs.egg-info/SOURCES.txt +2 -2
  7. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/setup.py +1 -1
  8. oafuncs-0.0.98.4/oafuncs/oa_down/hycom_3hourly_20250407.py +0 -1295
  9. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/LICENSE.txt +0 -0
  10. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/MANIFEST.in +0 -0
  11. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/README.md +0 -0
  12. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/__init__.py +0 -0
  13. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_data/hycom.png +0 -0
  14. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_data/oafuncs.png +0 -0
  15. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/cprogressbar.py +0 -0
  16. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/email.py +0 -0
  17. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/netcdf_merge.py +0 -0
  18. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/netcdf_modify.py +0 -0
  19. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/netcdf_write.py +0 -0
  20. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/parallel.py +0 -0
  21. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/parallel_test.py +0 -0
  22. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/plot_dataset.py +0 -0
  23. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/_script/replace_file_content.py +0 -0
  24. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_cmap.py +0 -0
  25. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_data.py +0 -0
  26. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_date.py +0 -0
  27. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/User_Agent-list.txt +0 -0
  28. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/__init__.py +0 -0
  29. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/idm.py +0 -0
  30. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/literature.py +0 -0
  31. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/test_ua.py +0 -0
  32. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_down/user_agent.py +0 -0
  33. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_draw.py +0 -0
  34. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_file.py +0 -0
  35. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_help.py +0 -0
  36. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_model/__init__.py +0 -0
  37. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_model/roms/__init__.py +0 -0
  38. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_model/roms/test.py +0 -0
  39. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_model/wrf/__init__.py +0 -0
  40. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_model/wrf/little_r.py +0 -0
  41. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_nc.py +0 -0
  42. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_python.py +0 -0
  43. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_sign/__init__.py +0 -0
  44. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_sign/meteorological.py +0 -0
  45. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_sign/ocean.py +0 -0
  46. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_sign/scientific.py +0 -0
  47. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs/oa_tool.py +0 -0
  48. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs.egg-info/dependency_links.txt +0 -0
  49. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs.egg-info/requires.txt +0 -0
  50. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/oafuncs.egg-info/top_level.txt +0 -0
  51. {oafuncs-0.0.98.4 → oafuncs-0.0.98.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.98.4
3
+ Version: 0.0.98.6
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -2,9 +2,9 @@
2
2
  # coding=utf-8
3
3
  """
4
4
  Author: Liu Kun && 16031215@qq.com
5
- Date: 2025-04-16 11:36:15
5
+ Date: 2025-04-07 10:51:09
6
6
  LastEditors: Liu Kun && 16031215@qq.com
7
- LastEditTime: 2025-04-16 11:36:16
7
+ LastEditTime: 2025-04-07 10:51:09
8
8
  FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\hycom_3hourly copy.py
9
9
  Description:
10
10
  EditPlatform: vscode
@@ -13,9 +13,9 @@ SystemInfo: Windows 11
13
13
  Python Version: 3.12
14
14
  """
15
15
 
16
-
17
-
16
+ import asyncio
18
17
  import datetime
18
+ import logging
19
19
  import os
20
20
  import random
21
21
  import re
@@ -24,15 +24,15 @@ import warnings
24
24
  from concurrent.futures import ThreadPoolExecutor, as_completed
25
25
  from pathlib import Path
26
26
  from threading import Lock
27
+ from oafuncs.oa_tool import pbar
27
28
 
29
+ import httpx
28
30
  import matplotlib.pyplot as plt
29
31
  import netCDF4 as nc
30
32
  import numpy as np
31
33
  import pandas as pd
32
- import requests
33
34
  import xarray as xr
34
35
  from rich import print
35
- from rich.progress import Progress
36
36
 
37
37
  from oafuncs.oa_down.idm import downloader as idm_downloader
38
38
  from oafuncs.oa_down.user_agent import get_ua
@@ -40,6 +40,9 @@ from oafuncs.oa_file import file_size
40
40
  from oafuncs.oa_nc import check as check_nc
41
41
  from oafuncs.oa_nc import modify as modify_nc
42
42
 
43
+ logging.getLogger("httpx").setLevel(logging.WARNING) # 关闭 httpx 的 INFO 日志,只显示 WARNING 及以上
44
+
45
+
43
46
  warnings.filterwarnings("ignore", category=RuntimeWarning, message="Engine '.*' loading failed:.*")
44
47
 
45
48
  __all__ = ["draw_time_range", "download"]
@@ -416,13 +419,13 @@ def _check_time_in_dataset_and_version(time_input, time_end=None):
416
419
  trange_list.append(f"{time_s}-{time_e}")
417
420
  have_data = True
418
421
 
419
- # 输出结果
420
- if match_time is None:
421
- print(f"[bold red]{time_input_str} is in the following dataset and version:")
422
422
  if have_data:
423
423
  if match_time is None:
424
+ print(f"[bold red]Time {time_input_str} included in:")
425
+ dv_num = 1
424
426
  for d, v, trange in zip(d_list, v_list, trange_list):
425
- print(f"[bold blue]{d} {v} {trange}")
427
+ print(f"{dv_num} -> [bold blue]{d} - {v} : {trange}")
428
+ dv_num += 1
426
429
  if is_single_time:
427
430
  return True
428
431
  else:
@@ -434,7 +437,7 @@ def _check_time_in_dataset_and_version(time_input, time_end=None):
434
437
  print(f"[bold red]{time_start} to {time_end} is in different datasets or versions, so you can't download them together")
435
438
  return False
436
439
  else:
437
- print(f"[bold red]{time_input_str} is not in any dataset and version")
440
+ print(f"[bold red]Time {time_input_str} has no data")
438
441
  return False
439
442
 
440
443
 
@@ -509,7 +512,8 @@ def _direct_choose_dataset_and_version(time_input, time_end=None):
509
512
 
510
513
  if dataset_name_out is not None and version_name_out is not None:
511
514
  if match_time is None:
512
- print(f"[bold purple]dataset: {dataset_name_out}, version: {version_name_out} is chosen")
515
+ # print(f"[bold purple]dataset: {dataset_name_out}, version: {version_name_out} is chosen")
516
+ print(f"[bold purple]Chosen dataset: {dataset_name_out} - {version_name_out}")
513
517
 
514
518
  # 如果没有找到匹配的数据集和版本,会返回 None
515
519
  return dataset_name_out, version_name_out
@@ -664,117 +668,138 @@ def _correct_time(nc_file):
664
668
  modify_nc(nc_file, "time", None, time_difference)
665
669
 
666
670
 
671
+ def setup_logger(level=logging.INFO):
672
+ logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=level)
673
+
674
+
675
+ class _HycomDownloader:
676
+ def __init__(self, tasks, delay_range=(3, 6), timeout_factor=120, max_var_count=5, max_retries=3):
677
+ self.tasks = tasks
678
+ self.delay_range = delay_range
679
+ self.timeout_factor = timeout_factor
680
+ self.max_var_count = max_var_count
681
+ self.max_retries = max_retries
682
+ self.count = {"success": 0, "fail": 0}
683
+ setup_logger()
684
+
685
+ def user_agent(self):
686
+ return get_ua()
687
+
688
+ async def _download_one(self, url, save_path):
689
+ file_name = os.path.basename(save_path)
690
+ headers = {"User-Agent": self.user_agent()}
691
+ var_count = min(max(url.count("var="), 1), self.max_var_count)
692
+ timeout_max = self.timeout_factor * var_count
693
+
694
+ retry = 0
695
+ while retry <= self.max_retries:
696
+ timeout = random.randint(timeout_max // 2, timeout_max)
697
+ try:
698
+ await asyncio.sleep(random.uniform(*self.delay_range))
699
+ start = datetime.datetime.now()
700
+
701
+ async with httpx.AsyncClient(
702
+ timeout=httpx.Timeout(timeout),
703
+ limits=httpx.Limits(max_connections=2, max_keepalive_connections=2),
704
+ transport=httpx.AsyncHTTPTransport(retries=2),
705
+ ) as client:
706
+ logging.info(f"Requesting {file_name} (Attempt {retry + 1}) ...")
707
+ response = await client.get(url, headers=headers, follow_redirects=True)
708
+ response.raise_for_status()
709
+ if not response.content:
710
+ raise ValueError("Empty response received")
711
+
712
+ logging.info(f"Downloading {file_name} ...")
713
+ with open(save_path, "wb") as f:
714
+ total = int(response.headers.get("Content-Length", 0))
715
+ downloaded = 0
716
+ last_percent = -1
717
+
718
+ async for chunk in response.aiter_bytes(32 * 1024):
719
+ f.write(chunk)
720
+ downloaded += len(chunk)
721
+
722
+ if total > 0:
723
+ percent = int(downloaded * 100 / total)
724
+ if percent != last_percent:
725
+ logging.info(f"{file_name}: {percent}% ({downloaded / 1024:.1f} KB / {total / 1024:.1f} KB)")
726
+ last_percent = percent
727
+
728
+
729
+ elapsed = datetime.datetime.now() - start
730
+ # logging.info(f"File {file_name} downloaded, Time: {elapsed}")
731
+ logging.info(f"Saving {file_name}, Time: {elapsed}")
732
+ self.count["success"] += 1
733
+ count_dict["success"] += 1
734
+ return
735
+
736
+ except Exception as e:
737
+ logging.error(f"Failed ({type(e).__name__}): {e}")
738
+ if retry < self.max_retries:
739
+ backoff = 2**retry
740
+ logging.warning(f"Retrying in {backoff:.1f}s ...")
741
+ await asyncio.sleep(backoff)
742
+ retry += 1
743
+ else:
744
+ logging.error(f"Giving up on {file_name}")
745
+ self.count["fail"] += 1
746
+ count_dict["fail"] += 1
747
+ return
748
+
749
+ async def run(self):
750
+ logging.info(f"📥 Starting download of {len(self.tasks)} files ...")
751
+ for url, save_path in self.tasks:
752
+ await self._download_one(url, save_path)
753
+
754
+ logging.info("✅ All tasks completed.")
755
+ logging.info(f"✔️ Success: {self.count['success']} | ❌ Fail: {self.count['fail']}")
756
+
757
+
667
758
  def _download_file(target_url, store_path, file_name, cover=False):
668
- fname = Path(store_path) / file_name
759
+ save_path = Path(store_path) / file_name
669
760
  file_name_split = file_name.split("_")
670
761
  file_name_split = file_name_split[:-1]
671
762
  same_file = "_".join(file_name_split) + "*nc"
672
763
 
673
764
  if match_time is not None:
674
- if check_nc(fname, print_messages=False):
675
- if not _check_ftime(fname, if_print=True):
765
+ if check_nc(save_path, print_messages=False):
766
+ if not _check_ftime(save_path, if_print=True):
676
767
  if match_time:
677
- _correct_time(fname)
768
+ _correct_time(save_path)
678
769
  count_dict["skip"] += 1
679
770
  else:
680
- _clear_existing_file(fname)
771
+ _clear_existing_file(save_path)
681
772
  count_dict["no_data"] += 1
682
773
  else:
683
774
  count_dict["skip"] += 1
684
775
  print(f"[bold green]{file_name} is correct")
685
776
  return
686
777
 
687
- if not cover and os.path.exists(fname):
688
- print(f"[bold #FFA54F]{fname} exists, skipping ...")
778
+ if not cover and os.path.exists(save_path):
779
+ print(f"[bold #FFA54F]{save_path} exists, skipping ...")
689
780
  count_dict["skip"] += 1
690
781
  return
691
782
 
692
783
  if same_file not in fsize_dict.keys():
693
- check_nc(fname, delete_if_invalid=True, print_messages=False)
784
+ check_nc(save_path, delete_if_invalid=True, print_messages=False)
694
785
 
695
- get_mean_size = _get_mean_size_move(same_file, fname)
786
+ get_mean_size = _get_mean_size_move(same_file, save_path)
696
787
 
697
- if _check_existing_file(fname, get_mean_size):
788
+ if _check_existing_file(save_path, get_mean_size):
698
789
  count_dict["skip"] += 1
699
790
  return
700
791
 
701
- _clear_existing_file(fname)
792
+ _clear_existing_file(save_path)
702
793
 
703
794
  if not use_idm:
704
- print(f"[bold #f0f6d0]Requesting {file_name} ...")
705
- s = requests.Session()
706
- download_success = False
707
- request_times = 0
708
-
709
- def calculate_wait_time(time_str, target_url):
710
- time_pattern = r"\d{10}"
711
- times_in_str = re.findall(time_pattern, time_str)
712
- num_times_str = len(times_in_str)
713
-
714
- if num_times_str > 1:
715
- delta_t = datetime.datetime.strptime(times_in_str[1], "%Y%m%d%H") - datetime.datetime.strptime(times_in_str[0], "%Y%m%d%H")
716
- delta_t = delta_t.total_seconds() / 3600
717
- delta_t = delta_t / 3 + 1
718
- else:
719
- delta_t = 1
720
- num_var = int(target_url.count("var="))
721
- if num_var <= 0:
722
- num_var = 1
723
- return int(delta_t * 5 * 60 * num_var)
724
-
725
- max_timeout = calculate_wait_time(file_name, target_url)
726
- print(f"[bold #912dbc]Max timeout: {max_timeout} seconds")
727
-
728
- download_time_s = datetime.datetime.now()
729
- order_list = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th"]
730
- while not download_success:
731
- if request_times >= 10:
732
- print(f"[bold #ffe5c0]Download failed after {request_times} times\nYou can skip it and try again later")
733
- count_dict["fail"] += 1
734
- break
735
- if request_times > 0:
736
- print(f"[bold #ffe5c0]Retrying the {order_list[request_times - 1]} time...")
737
- try:
738
- referer_center = target_url.split("?")[0].split("ncss/")[-1]
739
- headers = {
740
- "User-Agent": get_ua(), # 后面几项可以不加,依旧能下载
741
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
742
- "Accept-Encoding": "gzip, deflate, br, zstd",
743
- "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
744
- "Referer": rf"https://ncss.hycom.org/thredds/ncss/grid/{referer_center}/dataset.html",
745
- }
746
- response = s.get(target_url, headers=headers, stream=True, timeout=random.randint(5, max_timeout))
747
- response.raise_for_status()
748
- with open(fname, "wb") as f:
749
- print(f"[bold #96cbd7]Downloading {file_name} ...")
750
- for chunk in response.iter_content(chunk_size=1024):
751
- if chunk:
752
- f.write(chunk)
753
-
754
- f.close()
755
-
756
- if os.path.exists(fname):
757
- download_success = True
758
- download_time_e = datetime.datetime.now()
759
- download_delta = download_time_e - download_time_s
760
- print(f"[#3dfc40]File [bold #dfff73]{fname} [#3dfc40]has been downloaded successfully, Time: [#39cbdd]{download_delta}")
761
- count_dict["success"] += 1
762
-
763
- except requests.exceptions.HTTPError as errh:
764
- print(f"Http Error: {errh}")
765
- except requests.exceptions.ConnectionError as errc:
766
- print(f"Error Connecting: {errc}")
767
- except requests.exceptions.Timeout as errt:
768
- print(f"Timeout Error: {errt}")
769
- except requests.exceptions.RequestException as err:
770
- print(f"OOps: Something Else: {err}")
771
-
772
- time.sleep(3)
773
- request_times += 1
795
+ python_downloader = _HycomDownloader([(target_url, save_path)])
796
+ asyncio.run(python_downloader.run())
797
+ time.sleep(3 + random.uniform(0, 10))
774
798
  else:
775
799
  idm_downloader(target_url, store_path, file_name, given_idm_engine)
776
- idm_download_list.append(fname)
777
- print(f"[bold #3dfc40]File [bold #dfff73]{fname} [#3dfc40]has been submit to IDM for downloading")
800
+ idm_download_list.append(save_path)
801
+ # print(f"[bold #3dfc40]File [bold #dfff73]{save_path} [#3dfc40]has been submit to IDM for downloading")
802
+ time.sleep(3 + random.uniform(0, 10))
778
803
 
779
804
 
780
805
  def _check_hour_is_valid(ymdh_str):
@@ -865,7 +890,7 @@ def _prepare_url_to_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_ma
865
890
  else:
866
891
  if download_time < "2024081012":
867
892
  varlist = [_ for _ in var]
868
- for key, value in var_group.items():
893
+ for key, value in pbar(var_group.items(), description=f"Var_group {download_time} ->", total=len(var_group), cmap="bwr", next_line=True):
869
894
  current_group = []
870
895
  for v in varlist:
871
896
  if v in value:
@@ -887,7 +912,7 @@ def _prepare_url_to_download(var, lon_min=0, lon_max=359.92, lat_min=-80, lat_ma
887
912
  file_name = f"HYCOM_{key}_{download_time}-{download_time_end}.nc"
888
913
  _download_file(submit_url, store_path, file_name, cover)
889
914
  else:
890
- for v in var:
915
+ for v in pbar(var,description=f'Var {download_time} ->', total=len(var), cmap='bwr', next_line=True):
891
916
  submit_url = _get_submit_url_var(v, depth, level_num, lon_min, lon_max, lat_min, lat_max, dataset_name, version_name, download_time, download_time_end)
892
917
  file_name = f"HYCOM_{variable_info[v]['var_name']}_{download_time}.nc"
893
918
  if download_time_end is not None:
@@ -921,7 +946,7 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
921
946
  if num_workers is not None and num_workers > 1:
922
947
  global parallel_counter
923
948
  parallel_counter = 0
924
- counter_lock = Lock()
949
+ counter_lock = Lock() # noqa: F841
925
950
  if ymdh_time_s == ymdh_time_e:
926
951
  _prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, None, depth, level, store_path, dataset_name, version_name, cover)
927
952
  elif int(ymdh_time_s) < int(ymdh_time_e):
@@ -929,17 +954,19 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
929
954
  print("*" * mark_len)
930
955
  print("Downloading a series of files...")
931
956
  time_list = _get_time_list(ymdh_time_s, ymdh_time_e, interval_hour, "hour")
932
- with Progress() as progress:
933
- task = progress.add_task(f"[cyan]{bar_desc}", total=len(time_list))
934
- if num_workers is None or num_workers <= 1:
935
- for i, time_str in enumerate(time_list):
936
- _prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, None, depth, level, store_path, dataset_name, version_name, cover)
937
- progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i + 1}/{len(time_list)}")
938
- else:
939
- with ThreadPoolExecutor(max_workers=num_workers) as executor:
940
- futures = [executor.submit(_download_task, var, time_str, None, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, cover) for time_str in time_list]
941
- for feature in as_completed(futures):
942
- _done_callback(feature, progress, task, len(time_list), counter_lock)
957
+ # with Progress() as progress:
958
+ # task = progress.add_task(f"[cyan]{bar_desc}", total=len(time_list))
959
+ if num_workers is None or num_workers <= 1:
960
+ for i, time_str in pbar(enumerate(time_list), description=f"{bar_desc}", total=len(time_list), cmap='colorful_1', next_line=True):
961
+ _prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, None, depth, level, store_path, dataset_name, version_name, cover)
962
+ # progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i + 1}/{len(time_list)}")
963
+ else:
964
+ with ThreadPoolExecutor(max_workers=num_workers) as executor:
965
+ futures = [executor.submit(_download_task, var, time_str, None, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, cover) for time_str in time_list]
966
+ """ for feature in as_completed(futures):
967
+ _done_callback(feature, progress, task, len(time_list), counter_lock) """
968
+ for _ in pbar(as_completed(futures),description=f"{bar_desc}", total=len(futures),cmap='colorful_1',next_line=True):
969
+ pass
943
970
  else:
944
971
  print("[bold red]Please ensure the time_s is no more than time_e")
945
972
 
@@ -1023,7 +1050,6 @@ def download(
1023
1050
  interval_hours=3,
1024
1051
  )
1025
1052
  """
1026
- from oafuncs.oa_tool import pbar
1027
1053
 
1028
1054
  _get_initial_data()
1029
1055
 
@@ -1084,10 +1110,10 @@ def download(
1084
1110
  workers = 1
1085
1111
  given_idm_engine = idm_path
1086
1112
  idm_download_list = []
1087
- bar_desc = "Submitting to IDM ..."
1113
+ bar_desc = "Submitting to IDM ->"
1088
1114
  else:
1089
1115
  use_idm = False
1090
- bar_desc = "Downloading ..."
1116
+ bar_desc = "Downloading ->"
1091
1117
 
1092
1118
  global match_time
1093
1119
  match_time = validate_time
@@ -1099,7 +1125,7 @@ def download(
1099
1125
  workers = 1
1100
1126
  print("*" * mark_len)
1101
1127
  print("[bold red]Only checking the time of existing files.")
1102
- bar_desc = "Checking time ..."
1128
+ bar_desc = "Checking time ->"
1103
1129
 
1104
1130
  _download_hourly_func(
1105
1131
  variables,
@@ -1125,7 +1151,7 @@ def download(
1125
1151
  print("[bold #ecdbfe]*" * mark_len)
1126
1152
  if idm_download_list:
1127
1153
  remain_list = idm_download_list.copy()
1128
- for _ in pbar(range(len(idm_download_list)), cmap="diverging_1", description="Downloading: "):
1154
+ for _ in pbar(range(len(idm_download_list)), cmap="diverging_1", description="Downloading ->"):
1129
1155
  success = False
1130
1156
  while not success:
1131
1157
  for f in remain_list:
@@ -1167,20 +1193,21 @@ if __name__ == "__main__":
1167
1193
 
1168
1194
  options = {
1169
1195
  "variables": var_list,
1170
- "start_time": "2025010300",
1171
- "end_time": "2025010309",
1172
- "output_dir": r"I:\Data\HYCOM\3hourly_test",
1196
+ "start_time": "2018010100",
1197
+ "end_time": "2019063000",
1198
+ "output_dir": r"G:\Data\HYCOM\china_sea\hourly_24",
1173
1199
  "lon_min": 105,
1174
- "lon_max": 130,
1175
- "lat_min": 15,
1200
+ "lon_max": 135,
1201
+ "lat_min": 10,
1176
1202
  "lat_max": 45,
1177
1203
  "workers": 1,
1178
1204
  "overwrite": False,
1179
1205
  "depth": None,
1180
1206
  "level": None,
1181
- "validate_time": True,
1182
- "idm_path": r"D:\Programs\Internet Download Manager\IDMan.exe",
1183
- "interval_hours": 3,
1207
+ "validate_time": None,
1208
+ # "idm_path": r"D:\Programs\Internet Download Manager\IDMan.exe",
1209
+ "interval_hours": 24,
1210
+ "proxy_txt": None,
1184
1211
  }
1185
1212
 
1186
1213
  if single_var: