py2ls 0.1.10.2__py3-none-any.whl → 0.1.10.4__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.
py2ls/batman.py
CHANGED
@@ -11,6 +11,21 @@ from pprint import pp
|
|
11
11
|
import json
|
12
12
|
|
13
13
|
|
14
|
+
# Helper to convert text or list of text to HTML
|
15
|
+
def convert_to_html(text_list):
|
16
|
+
if not isinstance(text_list, list):
|
17
|
+
text_list = [text_list]
|
18
|
+
|
19
|
+
# Convert each element into HTML and add line breaks
|
20
|
+
html_content = "" # "<html><body>\n"
|
21
|
+
html_content += "".join(
|
22
|
+
text.replace("\n", "<br>") for text in text_list if text.strip()
|
23
|
+
)
|
24
|
+
# html_content += "\n</body></html>"
|
25
|
+
|
26
|
+
return html_content
|
27
|
+
|
28
|
+
|
14
29
|
def extract_kv(
|
15
30
|
dir_data="/Users/macjianfeng/Dropbox/github/python/py2ls/confidential_data/gmail_login.json",
|
16
31
|
idx=0,
|
@@ -36,14 +51,18 @@ def email_to(**kwargs):
|
|
36
51
|
:param what: Email what
|
37
52
|
:param attachments: List of file paths to attach
|
38
53
|
"""
|
39
|
-
who, what, subject = None, None, None
|
54
|
+
who, what, subject, signature = None, None, None, None
|
40
55
|
attachments = False
|
41
56
|
pause_sec = False # default 10 seconds pause
|
42
57
|
|
43
58
|
signature_styles = extract_kv(idx=1)[1] # signature list
|
44
59
|
signature = signature_styles[0] # default signature,None
|
45
60
|
verbose = True
|
46
|
-
|
61
|
+
if not kwargs:
|
62
|
+
print(
|
63
|
+
f'\nUsage:\nemail_to(who="example@gmail.com",\n subject="test",\n what="this is the body",\n attachments="/Users/test.pdf"\n )'
|
64
|
+
)
|
65
|
+
return None
|
47
66
|
# params config
|
48
67
|
for k, v in kwargs.items():
|
49
68
|
if any(
|
@@ -80,15 +99,26 @@ def email_to(**kwargs):
|
|
80
99
|
message["To"] = who
|
81
100
|
message["Subject"] = subject
|
82
101
|
|
83
|
-
# add signature
|
84
|
-
if signature:
|
85
|
-
what += f"\n\n{signature}\n"
|
86
|
-
|
87
102
|
# the eamil's body
|
88
|
-
|
103
|
+
if what is None:
|
104
|
+
what = ""
|
105
|
+
if isinstance(what, list):
|
106
|
+
what = convert_to_html(what)
|
107
|
+
if 'class="dataframe"' in str(attachments):
|
108
|
+
# Combine HTML content correctly
|
109
|
+
html_content = "<html><body>\n"
|
110
|
+
html_content += f"{convert_to_html(what)}<br>{attachments}"
|
111
|
+
html_content += f"<br><br>{convert_to_html([signature])}"
|
112
|
+
html_content += "\n</body></html>"
|
113
|
+
message.attach(MIMEText(html_content, "html"))
|
114
|
+
else:
|
115
|
+
# add signature
|
116
|
+
if signature:
|
117
|
+
what += f"\n\n{signature}\n"
|
118
|
+
message.attach(MIMEText(what, "plain"))
|
89
119
|
|
90
120
|
# attach files
|
91
|
-
if attachments:
|
121
|
+
if attachments and not 'class="dataframe"' in str(attachments):
|
92
122
|
if isinstance(attachments, str):
|
93
123
|
attachments = [attachments]
|
94
124
|
for file in attachments:
|
py2ls/ips.py
CHANGED
@@ -9,6 +9,8 @@ from cycler import cycler
|
|
9
9
|
from mpl_toolkits.mplot3d import Axes3D
|
10
10
|
import seaborn as sns
|
11
11
|
|
12
|
+
from sklearn.kernel_approximation import KERNEL_PARAMS
|
13
|
+
from sympy import is_increasing
|
12
14
|
import sys, os, shutil, re, yaml, json, subprocess
|
13
15
|
import importlib.util
|
14
16
|
import time
|
@@ -3039,7 +3041,6 @@ def apply_format(ws, cell, cell_range):
|
|
3039
3041
|
cell_font, cell_fill, cell_alignment, border = None, None, None, None
|
3040
3042
|
kws_cell = ["font", "fill", "alignment", "border"]
|
3041
3043
|
for K, _ in cell.items():
|
3042
|
-
print(strcmp(K, kws_cell)[0])
|
3043
3044
|
if strcmp(K, kws_cell)[0] == "font":
|
3044
3045
|
#! font
|
3045
3046
|
font_color = "000000"
|
@@ -3289,9 +3290,9 @@ def apply_format(ws, cell, cell_range):
|
|
3289
3290
|
None,
|
3290
3291
|
)
|
3291
3292
|
# get styles config
|
3292
|
-
for k, v in cell.get(
|
3293
|
-
if not "style" in k:
|
3294
|
-
|
3293
|
+
for k, v in cell.get(K, {}).items():
|
3294
|
+
# if not "style" in k:
|
3295
|
+
# break
|
3295
3296
|
if strcmp(k, kws_border)[0] in ["style"]:
|
3296
3297
|
border_style_all = strcmp(v, border_styles)[0]
|
3297
3298
|
# 如果设置了style,表示其它的所有的都设置成为一样的
|
@@ -3635,13 +3636,19 @@ format_excel(
|
|
3635
3636
|
|
3636
3637
|
# !Add comment
|
3637
3638
|
if comment:
|
3638
|
-
|
3639
|
-
|
3639
|
+
if not isinstance(comment, list):
|
3640
|
+
comment = [comment]
|
3641
|
+
for comment_ in comment:
|
3642
|
+
for (row, col), comment_str in comment_.items():
|
3643
|
+
ws.cell(row=row, column=col).comment = Comment(comment_str, "Author")
|
3640
3644
|
|
3641
3645
|
# !Add link
|
3642
3646
|
if link:
|
3643
|
-
|
3644
|
-
|
3647
|
+
if not isinstance(link, list):
|
3648
|
+
link = [link]
|
3649
|
+
for link_ in link:
|
3650
|
+
for (row, col), link_str in link_.items():
|
3651
|
+
ws.cell(row=row, column=col).hyperlink = link_str
|
3645
3652
|
|
3646
3653
|
# !Apply data validation
|
3647
3654
|
if data_validation:
|
@@ -3654,16 +3661,16 @@ format_excel(
|
|
3654
3661
|
# !Protect sheet with a password
|
3655
3662
|
if protect:
|
3656
3663
|
ws.protection.password = protect.get("password", False)
|
3657
|
-
ws.protection.objects = protect.get("objects",
|
3658
|
-
ws.protection.sheet = protect.get("sheet",
|
3659
|
-
ws.protection.scenarios = protect.get("scenarios",
|
3664
|
+
ws.protection.objects = protect.get("objects", True)
|
3665
|
+
ws.protection.sheet = protect.get("sheet", True)
|
3666
|
+
ws.protection.scenarios = protect.get("scenarios", True)
|
3660
3667
|
ws.protection.formatCells = protect.get("formatCells", False)
|
3661
3668
|
ws.protection.formatColumns = protect.get("formatColumns", False)
|
3662
3669
|
ws.protection.formatRows = protect.get("formatRows", False)
|
3663
|
-
ws.protection.insertColumns = protect.get("insertColumns",
|
3664
|
-
ws.protection.insertRows = protect.get("insertRows",
|
3665
|
-
ws.protection.deleteColumns = protect.get("deleteColumns",
|
3666
|
-
ws.protection.deleteRows = protect.get("deleteRows",
|
3670
|
+
ws.protection.insertColumns = protect.get("insertColumns", True)
|
3671
|
+
ws.protection.insertRows = protect.get("insertRows", True)
|
3672
|
+
ws.protection.deleteColumns = protect.get("deleteColumns", True)
|
3673
|
+
ws.protection.deleteRows = protect.get("deleteRows", True)
|
3667
3674
|
|
3668
3675
|
# !conditional formatting
|
3669
3676
|
if conditional_format:
|
py2ls/ocr.py
CHANGED
@@ -12,6 +12,12 @@ import re
|
|
12
12
|
from PIL import Image, ImageDraw, ImageFont
|
13
13
|
import PIL.PngImagePlugin
|
14
14
|
import pytesseract
|
15
|
+
from paddleocr import PaddleOCR
|
16
|
+
import logging
|
17
|
+
|
18
|
+
logging.getLogger("ppocr").setLevel(
|
19
|
+
logging.WARNING
|
20
|
+
) # or logging.ERROR to show only error messages
|
15
21
|
|
16
22
|
"""
|
17
23
|
Optical Character Recognition (OCR)
|
@@ -31,6 +37,25 @@ lang_valid = {
|
|
31
37
|
"kannada": "kn",
|
32
38
|
"german": "de",
|
33
39
|
},
|
40
|
+
"paddleocr": {
|
41
|
+
"chinese": "ch",
|
42
|
+
"chinese_traditional": "chinese_cht",
|
43
|
+
"english": "en",
|
44
|
+
"french": "fr",
|
45
|
+
"german": "de",
|
46
|
+
"korean": "korean",
|
47
|
+
"japanese": "japan",
|
48
|
+
"russian": "ru",
|
49
|
+
"italian": "it",
|
50
|
+
"portuguese": "pt",
|
51
|
+
"spanish": "es",
|
52
|
+
"polish": "pl",
|
53
|
+
"dutch": "nl",
|
54
|
+
"arabic": "ar",
|
55
|
+
"vietnamese": "vi",
|
56
|
+
"tamil": "ta",
|
57
|
+
"turkish": "tr",
|
58
|
+
},
|
34
59
|
"pytesseract": {
|
35
60
|
"afrikaans": "afr",
|
36
61
|
"amharic": "amh",
|
@@ -133,6 +158,8 @@ def lang_auto_detect(
|
|
133
158
|
lang,
|
134
159
|
model="easyocr", # "easyocr" or "pytesseract"
|
135
160
|
):
|
161
|
+
models = ["easyocr", "paddleocr", "pytesseract"]
|
162
|
+
model = strcmp(model, models)[0]
|
136
163
|
res_lang = []
|
137
164
|
if isinstance(lang, str):
|
138
165
|
lang = [lang]
|
@@ -254,7 +281,14 @@ def undistort_image(image, camera_matrix, dist_coeffs):
|
|
254
281
|
return cv2.undistort(image, camera_matrix, dist_coeffs)
|
255
282
|
|
256
283
|
|
257
|
-
def add_text_pil(
|
284
|
+
def add_text_pil(
|
285
|
+
image,
|
286
|
+
text,
|
287
|
+
position,
|
288
|
+
font_size=12,
|
289
|
+
color=(255, 0, 0),
|
290
|
+
bg_color=(173, 216, 230, 120),
|
291
|
+
):
|
258
292
|
# Convert the image to PIL format
|
259
293
|
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
|
260
294
|
# Create a drawing context
|
@@ -270,17 +304,32 @@ def add_text_pil(image, text, position, font_size=10, color=(255, 0, 0)):
|
|
270
304
|
# cal top_left position
|
271
305
|
# Measure text size using textbbox
|
272
306
|
text_bbox = draw.textbbox((0, 0), text, font=font)
|
307
|
+
# # 或者只画 text, # Calculate text size
|
308
|
+
# text_width, text_height = draw.textsize(text, font=font)
|
273
309
|
text_width = text_bbox[2] - text_bbox[0]
|
274
310
|
text_height = text_bbox[3] - text_bbox[1]
|
311
|
+
|
312
|
+
# Draw background rectangle
|
313
|
+
x, y = position
|
275
314
|
# Calculate 5% of the text height for upward adjustment
|
276
|
-
offset = int(
|
315
|
+
offset = int(
|
316
|
+
0.1 * text_height
|
317
|
+
) # 这就不再上移动了; # int(0.5 * text_height) # 上移动 50%
|
318
|
+
|
277
319
|
# Adjust position to match OpenCV's bottom-left alignment
|
278
320
|
adjusted_position = (position[0], position[1] - text_height - offset)
|
279
321
|
|
322
|
+
background_rect = [
|
323
|
+
adjusted_position[0],
|
324
|
+
adjusted_position[1],
|
325
|
+
x + text_width,
|
326
|
+
y + text_height,
|
327
|
+
]
|
328
|
+
draw.rectangle(background_rect, fill=bg_color)
|
280
329
|
# Add text to the image
|
281
330
|
draw.text(adjusted_position, text, font=font, fill=color)
|
282
331
|
# Convert the image back to OpenCV format
|
283
|
-
image = cv2.cvtColor(np.array(pil_image), cv2.
|
332
|
+
image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGBA2BGR)
|
284
333
|
return image
|
285
334
|
|
286
335
|
|
@@ -479,8 +528,8 @@ def text_postprocess(
|
|
479
528
|
def get_text(
|
480
529
|
image,
|
481
530
|
lang=["ch_sim", "en"],
|
482
|
-
model="
|
483
|
-
thr=0.
|
531
|
+
model="paddleocr", # "pytesseract","paddleocr","easyocr"
|
532
|
+
thr=0.1,
|
484
533
|
gpu=True,
|
485
534
|
decoder="wordbeamsearch", #'greedy', 'beamsearch' and 'wordbeamsearch'(hightly accurate)
|
486
535
|
output="all",
|
@@ -493,7 +542,9 @@ def get_text(
|
|
493
542
|
font_scale=0.8,
|
494
543
|
thickness_text=2, # Line thickness of 2 px
|
495
544
|
color_box=(0, 255, 0), # draw_box
|
496
|
-
color_text=(
|
545
|
+
color_text=(203, 44, 57), # draw_box
|
546
|
+
bg_color=(173, 216, 230, 128),
|
547
|
+
usage=False,
|
497
548
|
**kwargs,
|
498
549
|
):
|
499
550
|
"""
|
@@ -513,34 +564,38 @@ def get_text(
|
|
513
564
|
kwargs: 传递给 EasyOCR readtext 函数的其他参数。
|
514
565
|
|
515
566
|
# Uage
|
516
|
-
image_path = 'car_plate.jpg' # 替换为你的图像路径
|
517
|
-
results = get_text(
|
518
|
-
image_path,
|
519
|
-
lang=["en"],
|
520
|
-
gpu=False,
|
521
|
-
output="text",
|
522
|
-
preprocess={
|
523
|
-
"grayscale": True,
|
524
|
-
"threshold": True,
|
525
|
-
"threshold_method": 'adaptive',
|
526
|
-
"denoise": True,
|
527
|
-
"blur_ksize": (5, 5),
|
528
|
-
"morph": True,
|
529
|
-
"morph_op": 'close',
|
530
|
-
"morph_kernel_size": (3, 3),
|
531
|
-
"enhance_contrast": True,
|
532
|
-
"clahe_clip": 2.0,
|
533
|
-
"clahe_grid_size": (8, 8),
|
534
|
-
"edge_detection": False
|
535
|
-
},
|
536
|
-
adjust_contrast=0.7
|
537
|
-
)
|
538
567
|
"""
|
568
|
+
if usage:
|
569
|
+
print(
|
570
|
+
"""
|
571
|
+
image_path = 'car_plate.jpg' # 替换为你的图像路径
|
572
|
+
results = get_text(
|
573
|
+
image_path,
|
574
|
+
lang=["en"],
|
575
|
+
gpu=False,
|
576
|
+
output="text",
|
577
|
+
preprocess={
|
578
|
+
"grayscale": True,
|
579
|
+
"threshold": True,
|
580
|
+
"threshold_method": 'adaptive',
|
581
|
+
"blur": True,
|
582
|
+
"blur_ksize": (5, 5),
|
583
|
+
"morph": True,
|
584
|
+
"morph_op": 'close',
|
585
|
+
"morph_kernel_size": (3, 3),
|
586
|
+
"enhance_contrast": True,
|
587
|
+
"clahe_clip": 2.0,
|
588
|
+
"clahe_grid_size": (8, 8),
|
589
|
+
"edge_detection": False
|
590
|
+
},
|
591
|
+
adjust_contrast=0.7
|
592
|
+
)
|
593
|
+
"""
|
594
|
+
)
|
539
595
|
|
540
|
-
|
541
|
-
|
596
|
+
models = ["easyocr", "paddleocr", "pytesseract"]
|
597
|
+
model = strcmp(model, models)[0]
|
542
598
|
lang = lang_auto_detect(lang, model)
|
543
|
-
print(f"detecting language(s):{lang}")
|
544
599
|
if isinstance(image, str):
|
545
600
|
image = cv2.imread(image)
|
546
601
|
|
@@ -553,6 +608,7 @@ def get_text(
|
|
553
608
|
preprocess = {}
|
554
609
|
image_process = preprocess_img(image, **preprocess)
|
555
610
|
if "easy" in model.lower():
|
611
|
+
print(f"detecting language(s):{lang}")
|
556
612
|
# Perform OCR on the image
|
557
613
|
reader = easyocr.Reader(lang, gpu=gpu)
|
558
614
|
detections = reader.readtext(image_process, decoder=decoder, **kwargs)
|
@@ -565,12 +621,104 @@ def get_text(
|
|
565
621
|
merge=True,
|
566
622
|
)
|
567
623
|
text_corr = []
|
568
|
-
|
624
|
+
[
|
625
|
+
text_corr.extend(text_postprocess(text, **postprocess))
|
626
|
+
for _, text, _ in detections
|
627
|
+
]
|
628
|
+
if show:
|
629
|
+
if ax is None:
|
630
|
+
ax = plt.gca()
|
631
|
+
for bbox, text, score in detections:
|
632
|
+
if score > thr:
|
633
|
+
top_left = tuple(map(int, bbox[0]))
|
634
|
+
bottom_right = tuple(map(int, bbox[2]))
|
635
|
+
image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
|
636
|
+
# image = cv2.putText(
|
637
|
+
# image, text, top_left, font, font_scale, color_text, thickness_text
|
638
|
+
# )
|
639
|
+
image = add_text_pil(
|
640
|
+
image,
|
641
|
+
text,
|
642
|
+
top_left,
|
643
|
+
font_size=font_scale * 32,
|
644
|
+
color=color_text,
|
645
|
+
)
|
646
|
+
img_cmp = cv2.cvtColor(image, cmap)
|
647
|
+
ax.imshow(img_cmp)
|
648
|
+
ax.axis("off")
|
649
|
+
# plt.show()
|
650
|
+
# 根据输出类型返回相应的结果
|
651
|
+
if output == "all":
|
652
|
+
return ax, detections
|
653
|
+
elif "t" in output.lower() and "x" in output.lower():
|
654
|
+
# 提取文本,过滤低置信度的结果
|
655
|
+
text = [text_ for _, text_, score_ in detections if score_ >= thr]
|
656
|
+
if postprocess:
|
657
|
+
return ax, text
|
658
|
+
else:
|
659
|
+
return text_corr
|
660
|
+
elif "score" in output.lower() or "prob" in output.lower():
|
661
|
+
# 提取分数
|
662
|
+
scores = [score_ for _, _, score_ in detections]
|
663
|
+
return ax, scores
|
664
|
+
elif "box" in output.lower():
|
665
|
+
# 提取边界框,过滤低置信度的结果
|
666
|
+
bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
|
667
|
+
return ax, bboxes
|
668
|
+
else:
|
669
|
+
# 默认返回所有检测信息
|
670
|
+
return ax, detections
|
671
|
+
else:
|
672
|
+
# 根据输出类型返回相应的结果
|
673
|
+
if output == "all":
|
674
|
+
return detections
|
675
|
+
elif "t" in output.lower() and "x" in output.lower():
|
676
|
+
# 提取文本,过滤低置信度的结果
|
677
|
+
text = [text_ for _, text_, score_ in detections if score_ >= thr]
|
678
|
+
return text
|
679
|
+
elif "score" in output.lower() or "prob" in output.lower():
|
680
|
+
# 提取分数
|
681
|
+
scores = [score_ for _, _, score_ in detections]
|
682
|
+
return scores
|
683
|
+
elif "box" in output.lower():
|
684
|
+
# 提取边界框,过滤低置信度的结果
|
685
|
+
bboxes = [bbox_ for bbox_, _, score_ in detections if score_ >= thr]
|
686
|
+
return bboxes
|
687
|
+
else:
|
688
|
+
# 默认返回所有检测信息
|
689
|
+
return detections
|
690
|
+
elif "pad" in model.lower():
|
691
|
+
ocr = PaddleOCR(
|
692
|
+
use_angle_cls=True,
|
693
|
+
cls=True,
|
694
|
+
) # PaddleOCR supports only one language at a time
|
695
|
+
result = ocr.ocr(image_process, **kwargs)
|
696
|
+
detections = []
|
697
|
+
for line in result[0]:
|
698
|
+
bbox, (text, score) = line
|
699
|
+
detections.append((bbox, text, score))
|
700
|
+
if postprocess is None:
|
701
|
+
postprocess = dict(
|
702
|
+
spell_check=True,
|
703
|
+
clean=True,
|
704
|
+
filter=dict(min_length=2),
|
705
|
+
pattern=None,
|
706
|
+
merge=True,
|
707
|
+
)
|
708
|
+
text_corr = []
|
709
|
+
[
|
569
710
|
text_corr.extend(text_postprocess(text, **postprocess))
|
711
|
+
for _, text, _ in detections
|
712
|
+
]
|
570
713
|
if show:
|
714
|
+
if ax is None:
|
715
|
+
ax = plt.gca()
|
571
716
|
for bbox, text, score in detections:
|
572
717
|
if score > thr:
|
573
718
|
top_left = tuple(map(int, bbox[0]))
|
719
|
+
bottom_left = tuple(
|
720
|
+
map(int, bbox[1])
|
721
|
+
) # Bottom-left for more accurate placement
|
574
722
|
bottom_right = tuple(map(int, bbox[2]))
|
575
723
|
image = cv2.rectangle(image, top_left, bottom_right, color_box, 2)
|
576
724
|
# image = cv2.putText(
|
@@ -582,6 +730,7 @@ def get_text(
|
|
582
730
|
top_left,
|
583
731
|
font_size=font_scale * 32,
|
584
732
|
color=color_text,
|
733
|
+
bg_color=bg_color,
|
585
734
|
)
|
586
735
|
img_cmp = cv2.cvtColor(image, cmap)
|
587
736
|
ax.imshow(img_cmp)
|
@@ -627,7 +776,10 @@ def get_text(
|
|
627
776
|
else:
|
628
777
|
# 默认返回所有检测信息
|
629
778
|
return detections
|
779
|
+
|
630
780
|
else: # "pytesseract"
|
781
|
+
if ax is None:
|
782
|
+
ax = plt.gca()
|
631
783
|
text = pytesseract.image_to_string(image_process, lang="+".join(lang), **kwargs)
|
632
784
|
bboxes = pytesseract.image_to_boxes(image_process, **kwargs)
|
633
785
|
if show:
|
@@ -649,7 +801,7 @@ def get_text(
|
|
649
801
|
image = add_text_pil(
|
650
802
|
image,
|
651
803
|
char,
|
652
|
-
|
804
|
+
left,
|
653
805
|
font_size=font_scale * 32,
|
654
806
|
color=color_text,
|
655
807
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: py2ls
|
3
|
-
Version: 0.1.10.
|
3
|
+
Version: 0.1.10.4
|
4
4
|
Summary: py(thon)2(too)ls
|
5
5
|
Author: Jianfeng
|
6
6
|
Author-email: Jianfeng.Liu0413@gmail.com
|
@@ -29,8 +29,8 @@ Requires-Dist: Pygments (>=2.18.0)
|
|
29
29
|
Requires-Dist: QtPy (>=2.4.1)
|
30
30
|
Requires-Dist: SciencePlots (>=2.1.1)
|
31
31
|
Requires-Dist: XlsxWriter (>=3.2.0)
|
32
|
-
Requires-Dist: appnope (>=0.1.4)
|
33
|
-
Requires-Dist: appscript (>=1.2.5)
|
32
|
+
Requires-Dist: appnope (>=0.1.4) ; sys_platform == "darwin"
|
33
|
+
Requires-Dist: appscript (>=1.2.5) ; sys_platform == "darwin"
|
34
34
|
Requires-Dist: asciitree (>=0.3.3)
|
35
35
|
Requires-Dist: asttokens (>=2.4.1)
|
36
36
|
Requires-Dist: attrs (>=23.2.0)
|
@@ -234,7 +234,7 @@ Requires-Dist: websocket-client (>=1.8.0)
|
|
234
234
|
Requires-Dist: wrapt (>=1.16.0)
|
235
235
|
Requires-Dist: wsproto (>=1.2.0)
|
236
236
|
Requires-Dist: xarray (>=2024.6.0)
|
237
|
-
Requires-Dist: xattr (>=0.10.1)
|
237
|
+
Requires-Dist: xattr (>=0.10.1) ; sys_platform == "darwin"
|
238
238
|
Requires-Dist: zarr (>=2.17.2)
|
239
239
|
Description-Content-Type: text/markdown
|
240
240
|
|
@@ -172,7 +172,7 @@ py2ls/.gitignore,sha256=y7GvbD_zZkjPVVIue8AyiuFkDMuUbvMaV65Lgu89To8,2763
|
|
172
172
|
py2ls/LICENSE,sha256=UOZ1F5fFDe3XXvG4oNnkL1-Ecun7zpHzRxjp-XsMeAo,11324
|
173
173
|
py2ls/README.md,sha256=CwvJWAnSXnCnrVHlnEbrxxi6MbjbE_MT6DH2D53S818,11572
|
174
174
|
py2ls/__init__.py,sha256=Nn8jTIvySX7t7DMJ8VNRVctTStgXGjHldOIdZ35PdW8,165
|
175
|
-
py2ls/batman.py,sha256=
|
175
|
+
py2ls/batman.py,sha256=8IMtCDUVCusdlmE5OWsG1CmBjH-sBHwkEcns_u-CsD8,7440
|
176
176
|
py2ls/brain_atlas.py,sha256=w1o5EelRjq89zuFJUNSz4Da8HnTCwAwDAZ4NU4a-bAY,5486
|
177
177
|
py2ls/chat.py,sha256=Yr22GoIvoWhpV3m4fdwV_I0Mn77La346_ymSinR-ORA,3793
|
178
178
|
py2ls/correlators.py,sha256=RbOaJIPLCHJtUm5SFi_4dCJ7VFUPWR0PErfK3K26ad4,18243
|
@@ -206,15 +206,15 @@ py2ls/doc.py,sha256=xN3g1OWfoaGUhikbJ0NqbN5eKy1VZVvWwRlhHMgyVEc,4243
|
|
206
206
|
py2ls/export_requirements.py,sha256=x2WgUF0jYKz9GfA1MVKN-MdsM-oQ8yUeC6Ua8oCymio,2325
|
207
207
|
py2ls/freqanalysis.py,sha256=F4218VSPbgL5tnngh6xNCYuNnfR-F_QjECUUxrPYZss,32594
|
208
208
|
py2ls/ich2ls.py,sha256=3E9R8oVpyYZXH5PiIQgT3CN5NxLe4Dwtm2LwaeacE6I,21381
|
209
|
-
py2ls/ips.py,sha256=
|
209
|
+
py2ls/ips.py,sha256=xheqYJJkF3LHFS216YWU-iBVMCj4UPaT3uNhP1wSnlk,135905
|
210
210
|
py2ls/netfinder.py,sha256=_stenzqRZsB4m5FDE7YsSkC2jvkmrUOsq48BRQB2mPM,55369
|
211
|
-
py2ls/ocr.py,sha256=
|
211
|
+
py2ls/ocr.py,sha256=T1C589yPF07lJ6EFpGgKq5Dw0vLIZ_-ffH_WZZVIz5o,31026
|
212
212
|
py2ls/plot.py,sha256=J8hRKLpQXHQRG_xE_nmT0mQvc1IxCMJ21tJmKsUKFl4,96155
|
213
213
|
py2ls/setuptools-70.1.0-py3-none-any.whl,sha256=2bi3cUVal8ip86s0SOvgspteEF8SKLukECi-EWmFomc,882588
|
214
214
|
py2ls/sleep_events_detectors.py,sha256=bQA3HJqv5qnYKJJEIhCyhlDtkXQfIzqksnD0YRXso68,52145
|
215
215
|
py2ls/stats.py,sha256=fJmXQ9Lq460StOn-kfEljE97cySq7876HUPTnpB5hLs,38123
|
216
216
|
py2ls/translator.py,sha256=zBeq4pYZeroqw3DT-5g7uHfVqKd-EQptT6LJ-Adi8JY,34244
|
217
217
|
py2ls/wb_detector.py,sha256=7y6TmBUj9exCZeIgBAJ_9hwuhkDh1x_-yg4dvNY1_GQ,6284
|
218
|
-
py2ls-0.1.10.
|
219
|
-
py2ls-0.1.10.
|
220
|
-
py2ls-0.1.10.
|
218
|
+
py2ls-0.1.10.4.dist-info/METADATA,sha256=9ZOh-62yxlctFb0c7_Imxm0mBbpfurvL1s4OrDc-DV0,20099
|
219
|
+
py2ls-0.1.10.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
220
|
+
py2ls-0.1.10.4.dist-info/RECORD,,
|
File without changes
|