oafuncs 0.0.98.46__py3-none-any.whl → 0.0.98.47__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/oa_down/literature.py +1 -124
 - oafuncs/oa_linux.py +23 -1
 - {oafuncs-0.0.98.46.dist-info → oafuncs-0.0.98.47.dist-info}/METADATA +1 -1
 - {oafuncs-0.0.98.46.dist-info → oafuncs-0.0.98.47.dist-info}/RECORD +7 -7
 - {oafuncs-0.0.98.46.dist-info → oafuncs-0.0.98.47.dist-info}/WHEEL +0 -0
 - {oafuncs-0.0.98.46.dist-info → oafuncs-0.0.98.47.dist-info}/licenses/LICENSE.txt +0 -0
 - {oafuncs-0.0.98.46.dist-info → oafuncs-0.0.98.47.dist-info}/top_level.txt +0 -0
 
    
        oafuncs/oa_down/literature.py
    CHANGED
    
    | 
         @@ -12,7 +12,7 @@ from oafuncs.oa_down.user_agent import get_ua 
     | 
|
| 
       12 
12 
     | 
    
         
             
            from oafuncs.oa_file import remove
         
     | 
| 
       13 
13 
     | 
    
         
             
            from oafuncs.oa_data import ensure_list
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            __all__ = ["download5doi" 
     | 
| 
      
 15 
     | 
    
         
            +
            __all__ = ["download5doi"]
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            def _get_file_size(file_path, unit="KB"):
         
     | 
| 
         @@ -368,129 +368,6 @@ def download5doi( 
     | 
|
| 
       368 
368 
     | 
    
         
             
                    dl.download_pdf()
         
     | 
| 
       369 
369 
     | 
    
         | 
| 
       370 
370 
     | 
    
         | 
| 
       371 
     | 
    
         
            -
            # ------------------------------- 合规替代方案(Open Access 优先) -------------------------------
         
     | 
| 
       372 
     | 
    
         
            -
            def _get_oa_pdf_url_from_unpaywall(doi: str, email: str | None) -> str | None:
         
     | 
| 
       373 
     | 
    
         
            -
                """
         
     | 
| 
       374 
     | 
    
         
            -
                通过 Unpaywall 获取可开放访问的 PDF 链接(若存在)。
         
     | 
| 
       375 
     | 
    
         
            -
                需要提供 email(Unpaywall 要求标识邮件)。
         
     | 
| 
       376 
     | 
    
         
            -
                返回 PDF URL 或 None。
         
     | 
| 
       377 
     | 
    
         
            -
                """
         
     | 
| 
       378 
     | 
    
         
            -
                if not email:
         
     | 
| 
       379 
     | 
    
         
            -
                    print("[bold yellow]Unpaywall 需要 email 参数;请提供 email 以查询 OA 链接。")
         
     | 
| 
       380 
     | 
    
         
            -
                    return None
         
     | 
| 
       381 
     | 
    
         
            -
                api = f"https://api.unpaywall.org/v2/{doi}?email={email}"
         
     | 
| 
       382 
     | 
    
         
            -
                try:
         
     | 
| 
       383 
     | 
    
         
            -
                    r = requests.get(api, timeout=15)
         
     | 
| 
       384 
     | 
    
         
            -
                    if r.status_code != 200:
         
     | 
| 
       385 
     | 
    
         
            -
                        print(f"[bold yellow]Unpaywall 查询失败: HTTP {r.status_code}")
         
     | 
| 
       386 
     | 
    
         
            -
                        return None
         
     | 
| 
       387 
     | 
    
         
            -
                    data = r.json()
         
     | 
| 
       388 
     | 
    
         
            -
                    loc = data.get("best_oa_location") or {}
         
     | 
| 
       389 
     | 
    
         
            -
                    url_for_pdf = loc.get("url_for_pdf") or loc.get("url")
         
     | 
| 
       390 
     | 
    
         
            -
                    if url_for_pdf and url_for_pdf.lower().endswith(".pdf"):
         
     | 
| 
       391 
     | 
    
         
            -
                        return url_for_pdf
         
     | 
| 
       392 
     | 
    
         
            -
                    # 有些 OA 链接是落在 landing page,再尝试从记录的所有位置挑选 pdf
         
     | 
| 
       393 
     | 
    
         
            -
                    for k in ("oa_locations", "oa_location"):
         
     | 
| 
       394 
     | 
    
         
            -
                        entries = data.get(k) or []
         
     | 
| 
       395 
     | 
    
         
            -
                        if isinstance(entries, dict):
         
     | 
| 
       396 
     | 
    
         
            -
                            entries = [entries]
         
     | 
| 
       397 
     | 
    
         
            -
                        for e in entries:
         
     | 
| 
       398 
     | 
    
         
            -
                            u = e.get("url_for_pdf") or e.get("url")
         
     | 
| 
       399 
     | 
    
         
            -
                            if u and ".pdf" in u.lower():
         
     | 
| 
       400 
     | 
    
         
            -
                                return u
         
     | 
| 
       401 
     | 
    
         
            -
                except Exception as e:
         
     | 
| 
       402 
     | 
    
         
            -
                    print(f"[bold yellow]Unpaywall 查询异常: {e}")
         
     | 
| 
       403 
     | 
    
         
            -
                return None
         
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
             
     | 
| 
       406 
     | 
    
         
            -
            def _download_pdf_from_url(url: str, dest_path: Path, headers: dict | None = None) -> bool:
         
     | 
| 
       407 
     | 
    
         
            -
                """
         
     | 
| 
       408 
     | 
    
         
            -
                给定合法的 PDF 下载 URL,下载保存到 dest_path。
         
     | 
| 
       409 
     | 
    
         
            -
                返回 True/False 表示是否成功。
         
     | 
| 
       410 
     | 
    
         
            -
                """
         
     | 
| 
       411 
     | 
    
         
            -
                headers = headers or {"User-Agent": str(get_ua()), "Accept": "application/pdf"}
         
     | 
| 
       412 
     | 
    
         
            -
                try:
         
     | 
| 
       413 
     | 
    
         
            -
                    with requests.get(url, headers=headers, stream=True, timeout=30) as r:
         
     | 
| 
       414 
     | 
    
         
            -
                        if r.status_code != 200 or "application/pdf" not in r.headers.get("Content-Type", "").lower():
         
     | 
| 
       415 
     | 
    
         
            -
                            # 仍可能是 PDF(某些服务器未正确设置头),尝试保存但标注提示
         
     | 
| 
       416 
     | 
    
         
            -
                            if r.status_code != 200:
         
     | 
| 
       417 
     | 
    
         
            -
                                print(f"[bold yellow]下载失败: HTTP {r.status_code}")
         
     | 
| 
       418 
     | 
    
         
            -
                                return False
         
     | 
| 
       419 
     | 
    
         
            -
                        dest_path.parent.mkdir(parents=True, exist_ok=True)
         
     | 
| 
       420 
     | 
    
         
            -
                        with open(dest_path, "wb") as f:
         
     | 
| 
       421 
     | 
    
         
            -
                            for chunk in r.iter_content(chunk_size=8192):
         
     | 
| 
       422 
     | 
    
         
            -
                                if chunk:
         
     | 
| 
       423 
     | 
    
         
            -
                                    f.write(chunk)
         
     | 
| 
       424 
     | 
    
         
            -
                    return True
         
     | 
| 
       425 
     | 
    
         
            -
                except Exception as e:
         
     | 
| 
       426 
     | 
    
         
            -
                    print(f"[bold yellow]下载异常: {e}")
         
     | 
| 
       427 
     | 
    
         
            -
                    return False
         
     | 
| 
       428 
     | 
    
         
            -
             
     | 
| 
       429 
     | 
    
         
            -
             
     | 
| 
       430 
     | 
    
         
            -
            def download5doi_via_unpaywall(
         
     | 
| 
       431 
     | 
    
         
            -
                store_path=None,
         
     | 
| 
       432 
     | 
    
         
            -
                doi_list=None,
         
     | 
| 
       433 
     | 
    
         
            -
                txt_file=None,
         
     | 
| 
       434 
     | 
    
         
            -
                excel_file=None,
         
     | 
| 
       435 
     | 
    
         
            -
                col_name=r"DOI",
         
     | 
| 
       436 
     | 
    
         
            -
                email: str | None = None,
         
     | 
| 
       437 
     | 
    
         
            -
            ):
         
     | 
| 
       438 
     | 
    
         
            -
                """
         
     | 
| 
       439 
     | 
    
         
            -
                优先使用 Unpaywall 获取开放访问(OA)的 PDF 并下载,避免非合规站点。
         
     | 
| 
       440 
     | 
    
         
            -
             
     | 
| 
       441 
     | 
    
         
            -
                参数:
         
     | 
| 
       442 
     | 
    
         
            -
                    store_path: 保存目录
         
     | 
| 
       443 
     | 
    
         
            -
                    doi_list/txt_file/excel_file/col_name: 同 download5doi
         
     | 
| 
       444 
     | 
    
         
            -
                    email: 用于访问 Unpaywall API 的邮箱(必填,否则无法查询)
         
     | 
| 
       445 
     | 
    
         
            -
                """
         
     | 
| 
       446 
     | 
    
         
            -
                if not store_path:
         
     | 
| 
       447 
     | 
    
         
            -
                    store_path = Path.cwd()
         
     | 
| 
       448 
     | 
    
         
            -
                else:
         
     | 
| 
       449 
     | 
    
         
            -
                    store_path = Path(str(store_path))
         
     | 
| 
       450 
     | 
    
         
            -
                store_path.mkdir(parents=True, exist_ok=True)
         
     | 
| 
       451 
     | 
    
         
            -
             
     | 
| 
       452 
     | 
    
         
            -
                if doi_list:
         
     | 
| 
       453 
     | 
    
         
            -
                    doi_list = ensure_list(doi_list)
         
     | 
| 
       454 
     | 
    
         
            -
                if txt_file:
         
     | 
| 
       455 
     | 
    
         
            -
                    doi_list = _read_txt(txt_file)
         
     | 
| 
       456 
     | 
    
         
            -
                if excel_file:
         
     | 
| 
       457 
     | 
    
         
            -
                    doi_list = _read_excel(excel_file, col_name)
         
     | 
| 
       458 
     | 
    
         
            -
             
     | 
| 
       459 
     | 
    
         
            -
                if not doi_list:
         
     | 
| 
       460 
     | 
    
         
            -
                    print("[bold yellow]未提供 DOI 列表。")
         
     | 
| 
       461 
     | 
    
         
            -
                    return
         
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
                print(f"[bold cyan]通过 Unpaywall 尝试下载 {len(doi_list)} 篇 OA PDF...")
         
     | 
| 
       464 
     | 
    
         
            -
                ok, miss = 0, 0
         
     | 
| 
       465 
     | 
    
         
            -
                for doi in track(doi_list, description="OA downloading..."):
         
     | 
| 
       466 
     | 
    
         
            -
                    # 规范化文件名
         
     | 
| 
       467 
     | 
    
         
            -
                    fname = re.sub(r'[/<>:"?*|]', "_", str(doi)) + ".pdf"
         
     | 
| 
       468 
     | 
    
         
            -
                    dest = store_path / fname
         
     | 
| 
       469 
     | 
    
         
            -
                    if dest.exists() and _get_file_size(dest, unit="KB") > 10:
         
     | 
| 
       470 
     | 
    
         
            -
                        ok += 1
         
     | 
| 
       471 
     | 
    
         
            -
                        continue
         
     | 
| 
       472 
     | 
    
         
            -
             
     | 
| 
       473 
     | 
    
         
            -
                    pdf_url = _get_oa_pdf_url_from_unpaywall(str(doi), email=email)
         
     | 
| 
       474 
     | 
    
         
            -
                    if not pdf_url:
         
     | 
| 
       475 
     | 
    
         
            -
                        miss += 1
         
     | 
| 
       476 
     | 
    
         
            -
                        print(f"[bold yellow]未找到 OA PDF: {doi}")
         
     | 
| 
       477 
     | 
    
         
            -
                        continue
         
     | 
| 
       478 
     | 
    
         
            -
             
     | 
| 
       479 
     | 
    
         
            -
                    if _download_pdf_from_url(pdf_url, dest):
         
     | 
| 
       480 
     | 
    
         
            -
                        size_kb = _get_file_size(dest, unit="KB")
         
     | 
| 
       481 
     | 
    
         
            -
                        if isinstance(size_kb, (int, float)) and size_kb < 10:
         
     | 
| 
       482 
     | 
    
         
            -
                            dest.unlink(missing_ok=True)
         
     | 
| 
       483 
     | 
    
         
            -
                            miss += 1
         
     | 
| 
       484 
     | 
    
         
            -
                            print(f"[bold yellow]文件过小,疑似异常,已删除: {dest}")
         
     | 
| 
       485 
     | 
    
         
            -
                        else:
         
     | 
| 
       486 
     | 
    
         
            -
                            ok += 1
         
     | 
| 
       487 
     | 
    
         
            -
                            print(f"[bold green]已下载: {dest}")
         
     | 
| 
       488 
     | 
    
         
            -
                    else:
         
     | 
| 
       489 
     | 
    
         
            -
                        miss += 1
         
     | 
| 
       490 
     | 
    
         
            -
             
     | 
| 
       491 
     | 
    
         
            -
                print(f"[bold]完成。成功 {ok} 篇,未获取 {miss} 篇(可能无 OA 版本或需机构访问)。")
         
     | 
| 
       492 
     | 
    
         
            -
             
     | 
| 
       493 
     | 
    
         
            -
             
     | 
| 
       494 
371 
     | 
    
         
             
            if __name__ == "__main__":
         
     | 
| 
       495 
372 
     | 
    
         
             
                store_path = r"F:\AAA-Delete\DOI_Reference\5\pdf"
         
     | 
| 
       496 
373 
     | 
    
         
             
                excel_file = r"F:\AAA-Delete\DOI_Reference\5\savedrecs.xls"
         
     | 
    
        oafuncs/oa_linux.py
    CHANGED
    
    | 
         @@ -68,11 +68,18 @@ def running_jobs(): 
     | 
|
| 
       68 
68 
     | 
    
         
             
                ids = [job.split()[0] for job in Jobs if job != '']
         
     | 
| 
       69 
69 
     | 
    
         
             
                return ids
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
            def submit_job(working_dir, script_tmp='run.slurm', script_run='run.slurm', need_node=1, queue_tmp='<queue_name>', queue_list=['dcu', 'bigmem', 'cpu_parallel', 'cpu_single'], max_job=38):
         
     | 
| 
      
 71 
     | 
    
         
            +
            def submit_job(working_dir=None, script_tmp='run.slurm', script_run='run.slurm', need_node=1, queue_tmp='<queue_name>', queue_list=['dcu', 'bigmem', 'cpu_parallel', 'cpu_single'], max_job=38, wait=False): 
         
     | 
| 
      
 72 
     | 
    
         
            +
                '''提交任务到集群,并返回任务ID'''
         
     | 
| 
       72 
73 
     | 
    
         
             
                from .oa_file import replace_content
         
     | 
| 
       73 
74 
     | 
    
         
             
                import datetime
         
     | 
| 
      
 75 
     | 
    
         
            +
                if working_dir is None:
         
     | 
| 
      
 76 
     | 
    
         
            +
                    working_dir = os.getcwd()
         
     | 
| 
       74 
77 
     | 
    
         
             
                os.chdir(working_dir)
         
     | 
| 
       75 
78 
     | 
    
         
             
                print(f'切换工作目录到: {working_dir}')
         
     | 
| 
      
 79 
     | 
    
         
            +
                
         
     | 
| 
      
 80 
     | 
    
         
            +
                if need_node > 1 and 'cpu_single' in queue_list:
         
     | 
| 
      
 81 
     | 
    
         
            +
                    queue_list.remove('cpu_single')
         
     | 
| 
      
 82 
     | 
    
         
            +
                
         
     | 
| 
       76 
83 
     | 
    
         
             
                while True:
         
     | 
| 
       77 
84 
     | 
    
         
             
                    running_job = running_jobs()
         
     | 
| 
       78 
85 
     | 
    
         
             
                    if not running_job or len(running_job) < max_job:
         
     | 
| 
         @@ -94,6 +101,7 @@ def submit_job(working_dir, script_tmp='run.slurm', script_run='run.slurm', need 
     | 
|
| 
       94 
101 
     | 
    
         
             
                                    time.sleep(30)
         
     | 
| 
       95 
102 
     | 
    
         
             
                                else:
         
     | 
| 
       96 
103 
     | 
    
         
             
                                    print(f'提交任务成功,{content_sub.strip()}')
         
     | 
| 
      
 104 
     | 
    
         
            +
                                    job_id = content_sub.strip().split()[-1]
         
     | 
| 
       97 
105 
     | 
    
         
             
                                    break
         
     | 
| 
       98 
106 
     | 
    
         
             
                        else:
         
     | 
| 
       99 
107 
     | 
    
         
             
                            print('没有足够的计算资源,等待30秒后重试!')
         
     | 
| 
         @@ -103,6 +111,20 @@ def submit_job(working_dir, script_tmp='run.slurm', script_run='run.slurm', need 
     | 
|
| 
       103 
111 
     | 
    
         
             
                        time.sleep(60)
         
     | 
| 
       104 
112 
     | 
    
         
             
                print(f'等待10秒后,继续检查任务状态!')
         
     | 
| 
       105 
113 
     | 
    
         
             
                time.sleep(10)
         
     | 
| 
      
 114 
     | 
    
         
            +
                
         
     | 
| 
      
 115 
     | 
    
         
            +
                if wait:
         
     | 
| 
      
 116 
     | 
    
         
            +
                    while True:
         
     | 
| 
      
 117 
     | 
    
         
            +
                        if job_id in running_jobs():
         
     | 
| 
      
 118 
     | 
    
         
            +
                            print(f'Time: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
         
     | 
| 
      
 119 
     | 
    
         
            +
                            print(f'任务{job_id}正在任务队列中...')
         
     | 
| 
      
 120 
     | 
    
         
            +
                            time.sleep(60)
         
     | 
| 
      
 121 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 122 
     | 
    
         
            +
                            print(f'任务{job_id}已完成!')
         
     | 
| 
      
 123 
     | 
    
         
            +
                            break
         
     | 
| 
      
 124 
     | 
    
         
            +
                else:
         
     | 
| 
      
 125 
     | 
    
         
            +
                    print(f'任务{job_id}已提交,不等待其完成,继续执行后续操作!')
         
     | 
| 
      
 126 
     | 
    
         
            +
                
         
     | 
| 
      
 127 
     | 
    
         
            +
                return job_id
         
     | 
| 
       106 
128 
     | 
    
         | 
| 
       107 
129 
     | 
    
         
             
            if __name__ == "__main__":
         
     | 
| 
       108 
130 
     | 
    
         
             
                pass
         
     | 
| 
         @@ -6,7 +6,7 @@ oafuncs/oa_draw.py,sha256=zal0Y3RPpN0TCGN4Gw9qLtjQdT6V0ZqpSUBFVOPL0x4,13952 
     | 
|
| 
       6 
6 
     | 
    
         
             
            oafuncs/oa_file.py,sha256=j9NOjxPOeAJsD5Zk4ODmFdVSSgr1CHVPvM1IHXy9RQA,17546
         
     | 
| 
       7 
7 
     | 
    
         
             
            oafuncs/oa_geo.py,sha256=UbzvUqgT2QP_9B7XSJRL1HDmGu0HnLC5nSP6ZrA5WH4,7177
         
     | 
| 
       8 
8 
     | 
    
         
             
            oafuncs/oa_help.py,sha256=0J5VaZX-cB0c090KxgmktQJBc0o00FsY-4wB8l5y00k,4178
         
     | 
| 
       9 
     | 
    
         
            -
            oafuncs/oa_linux.py,sha256= 
     | 
| 
      
 9 
     | 
    
         
            +
            oafuncs/oa_linux.py,sha256=reQYcjMff6mHuM5RXzoxM-4lgIYUcOoHp0u2fLY0cnU,5431
         
     | 
| 
       10 
10 
     | 
    
         
             
            oafuncs/oa_nc.py,sha256=j501NlTuvrDIwNLXbMfE7nPPXdbbL7u9PGDj2l5AtnI,16277
         
     | 
| 
       11 
11 
     | 
    
         
             
            oafuncs/oa_python.py,sha256=xYMQnM0cGq9xUCtcoMpnN0LG5Rc_s94tai5nC6CNJ3E,4831
         
     | 
| 
       12 
12 
     | 
    
         
             
            oafuncs/oa_tool.py,sha256=VHx15VqpbzNlVXh0-3nJqcDgLVaECMD1FvxJ_CrV39E,8046
         
     | 
| 
         @@ -26,7 +26,7 @@ oafuncs/oa_down/User_Agent-list.txt,sha256=pHaMlElMvZ8TG4vf4BqkZYKqe0JIGkr4kCN0l 
     | 
|
| 
       26 
26 
     | 
    
         
             
            oafuncs/oa_down/__init__.py,sha256=IT6oTqaxuV_mC6AwBut0HtkmnVtEu1MyX0x0oS7TKoA,218
         
     | 
| 
       27 
27 
     | 
    
         
             
            oafuncs/oa_down/hycom_3hourly.py,sha256=dFXSC_5o-Dic616KrLXir4tEHvCiZt8vGKPEYpXFMmA,57356
         
     | 
| 
       28 
28 
     | 
    
         
             
            oafuncs/oa_down/idm.py,sha256=vAhRjt_Sb-rKhzFShmSf29QcFTqsHpHXCvTSD1uSXyQ,1455
         
     | 
| 
       29 
     | 
    
         
            -
            oafuncs/oa_down/literature.py,sha256= 
     | 
| 
      
 29 
     | 
    
         
            +
            oafuncs/oa_down/literature.py,sha256=bqRSwYjsPO28WIohGIwPcj0xo9vAz5yhc8Ojx8ybh08,14924
         
     | 
| 
       30 
30 
     | 
    
         
             
            oafuncs/oa_down/read_proxy.py,sha256=HQpr-Mwn0Z8ICAuf63NUUY9p05E_uNWyWmOK46-73Ec,2866
         
     | 
| 
       31 
31 
     | 
    
         
             
            oafuncs/oa_down/test_ua.py,sha256=l8MCD6yU2W75zRPTDKUZTJhCWNF9lfk-MiSFqAqKH1M,1398
         
     | 
| 
       32 
32 
     | 
    
         
             
            oafuncs/oa_down/user_agent.py,sha256=LCVQUA60ukUqeJXgLktDHB2sh-ngk7AiX4sKj8w-X4A,416
         
     | 
| 
         @@ -39,8 +39,8 @@ oafuncs/oa_sign/__init__.py,sha256=JSx1fcWpmNhQBvX_Bmq3xysfSkkFMrjbJASxV_V6aqE,1 
     | 
|
| 
       39 
39 
     | 
    
         
             
            oafuncs/oa_sign/meteorological.py,sha256=3MSjy7HTcvz2zsITkjUMr_0Y027Gas1LFE9pk99990k,6110
         
     | 
| 
       40 
40 
     | 
    
         
             
            oafuncs/oa_sign/ocean.py,sha256=3uYEzaq-27yVy23IQoqy-clhWu1I_fhPFBAQyT-OF4M,5562
         
     | 
| 
       41 
41 
     | 
    
         
             
            oafuncs/oa_sign/scientific.py,sha256=moIl2MEY4uitbXoD596JmXookXGQtQsS-8_1NBBTx84,4689
         
     | 
| 
       42 
     | 
    
         
            -
            oafuncs-0.0.98. 
     | 
| 
       43 
     | 
    
         
            -
            oafuncs-0.0.98. 
     | 
| 
       44 
     | 
    
         
            -
            oafuncs-0.0.98. 
     | 
| 
       45 
     | 
    
         
            -
            oafuncs-0.0.98. 
     | 
| 
       46 
     | 
    
         
            -
            oafuncs-0.0.98. 
     | 
| 
      
 42 
     | 
    
         
            +
            oafuncs-0.0.98.47.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
         
     | 
| 
      
 43 
     | 
    
         
            +
            oafuncs-0.0.98.47.dist-info/METADATA,sha256=iJT9zUhIKuQGVu3zNAoQvKq9DyB6oMm-mlptyweqRR0,4446
         
     | 
| 
      
 44 
     | 
    
         
            +
            oafuncs-0.0.98.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
         
     | 
| 
      
 45 
     | 
    
         
            +
            oafuncs-0.0.98.47.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
         
     | 
| 
      
 46 
     | 
    
         
            +
            oafuncs-0.0.98.47.dist-info/RECORD,,
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |