kmisc 2.1.121__tar.gz → 2.1.122__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kmisc
3
- Version: 2.1.121
3
+ Version: 2.1.122
4
4
  Summary: Enginering useful library
5
5
  Home-page: https://github.com/kagepark/kmisc
6
6
  Author: Kage Park
@@ -23,12 +23,13 @@ import fnmatch
23
23
  import smtplib
24
24
  import zipfile
25
25
  import tarfile
26
+ import warnings
26
27
  import email.utils
27
28
  from sys import modules
28
29
  from pprint import pprint
29
30
  import fcntl,socket,struct
30
31
  from email import encoders
31
- from threading import Thread
32
+ from threading import Thread, Lock
32
33
  from datetime import datetime
33
34
  from http.cookies import Morsel # This module for requests when you use build by pyinstaller command
34
35
  import xml.etree.ElementTree as ET
@@ -39,6 +40,10 @@ Process=multiprocessing.Process
39
40
  Queue=multiprocessing.Queue
40
41
  #from multiprocessing import Process, Queue
41
42
  from email.mime.multipart import MIMEMultipart
43
+
44
+ warning_message='ignore'
45
+ warnings.filterwarnings(warning_message)
46
+
42
47
  try:
43
48
  from kmport import *
44
49
  import kmport
@@ -3448,7 +3453,7 @@ def Upper(src,default='org'):
3448
3453
  if default in ['org',{'org'}]: return src
3449
3454
  return default
3450
3455
 
3451
- def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certificate_error=False,username=None,password=None,auth_fields={'auth':{'type':'name','name':('username','password')},'submit':{'type':'submit','name':None}},next_do={}):
3456
+ def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certificate_error=False,username=None,password=None,auth_fields={'auth':{'type':'name','name':('username','password')},'submit':{'type':'submit','name':None}},next_do={},gpu=False,live_capture=0,capture_method='file',find_string=None,found_space='\n',log=None,ocr_enhance=False,daemon=False,backup=False):
3452
3457
  #auth_fields.submit.type : name : login button with name
3453
3458
  # : id : login button with id
3454
3459
  # : submit : submit button without name or id
@@ -3463,6 +3468,10 @@ def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certif
3463
3468
  image_size=image_size.split('x')
3464
3469
  elif ',' in image_size:
3465
3470
  image_size=image_size.split(',')
3471
+ elif '*' in image_size:
3472
+ image_size=image_size.split('*')
3473
+ elif ':' in image_size:
3474
+ image_size=image_size.split(':')
3466
3475
  if isinstance(image_size,(list,tuple)) and len(image_size) == 2:
3467
3476
  image_size=','.join([str(i) for i in image_size])
3468
3477
  else:
@@ -3472,6 +3481,13 @@ def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certif
3472
3481
  if Import('import selenium'):
3473
3482
  return False,'Can not install selenium package'
3474
3483
  else:
3484
+ if backup:
3485
+ Import('filecmp')
3486
+ Import('shutil')
3487
+
3488
+ ocr=None
3489
+ if capture_method != 'file':
3490
+ ocr=OCR(enhance=ocr_enhance)
3475
3491
  # Configure Chrome options for headless mode
3476
3492
  from selenium.webdriver.chrome.options import Options
3477
3493
  from selenium.webdriver.common.by import By
@@ -3482,6 +3498,8 @@ def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certif
3482
3498
  chrome_options.add_argument('--no-sandbox')
3483
3499
  chrome_options.add_argument('--disable-dev-shm-usage')
3484
3500
  chrome_options.add_argument(f"--window-size={image_size}") # Set window size
3501
+ if not gpu:
3502
+ chrome_options.add_argument("--disable-gpu")
3485
3503
  if ignore_certificate_error:
3486
3504
  chrome_options.add_argument('--ignore-certificate-errors') # gnore-certificate-errors
3487
3505
  chrome_options.add_argument('--allow-insecure-localhost') # gnore-certificate-errors
@@ -3541,20 +3559,133 @@ def web_capture(url,output_file,image_size='1920,1080',wait_time=3,ignore_certif
3541
3559
  next_do_button = driver.find_element(By.XPATH, "//button[@type='submit']")
3542
3560
  next_do_button.click()
3543
3561
 
3544
- # Wait for the page to load
3545
- time.sleep(wait_time)
3562
+ def _capture_(live_capture,driver,output_file,wait_time,capture_method,backup,ocr,log,find_string,daemon):
3563
+ def wait_body(driver,timeout=10):
3564
+ #wait until get screen data
3565
+ try:
3566
+ selenium.webdriver.support.ui.WebDriverWait(driver,timeout).until(
3567
+ EC.presence_of_element_located((By.TAG_NAME,"body"))
3568
+ )
3569
+ return
3570
+ except:
3571
+ try:
3572
+ selenium.webdriver.support.ui.WebDriverWait(driver,timeout).until(
3573
+ lambda d: d.execute_script("return document.readyState") == "complete"
3574
+ )
3575
+ return
3576
+ except:
3577
+ pass
3578
+ time.sleep(timeout)
3579
+
3580
+ live_capture=Int(live_capture)
3581
+ wait_time=Int(wait_time,10)
3582
+ backup_idx=0
3583
+ if backup:
3584
+ backup=Int(backup,2)
3585
+ if isinstance(live_capture,int) and live_capture > wait_time*2:
3586
+ Time=TIME()
3587
+ while True:
3588
+ if Time.Out(live_capture):
3589
+ driver.quit()
3590
+ return False
3591
+ # Capture screenshot
3592
+ if log:
3593
+ if log in ['screen','log','print',print]:
3594
+ printf(Dot(),direct=True)
3595
+ else:
3596
+ printf(Dot(),log=log,direct=True)
3597
+ if backup:
3598
+ save_file='{}.{}'.format(output_file,backup_idx%backup)
3599
+ else:
3600
+ save_file=output_file
3601
+ #wait
3602
+ wait_body(driver,timeout=wait_time)
3603
+ #capture
3604
+ driver.save_screenshot(save_file)
3605
+ if backup:
3606
+ if backup == 2:
3607
+ comp_a=f'{output_file}.0'
3608
+ comp_b=f'{output_file}.1'
3609
+ if os.path.isfile(comp_a) and os.path.isfile(comp_b):
3610
+ if filecmp.cmp(comp_a,comp_b):
3611
+ if log:
3612
+ if log in ['screen','log','print',print]:
3613
+ printf(Dot(),direct=True)
3614
+ else:
3615
+ printf(Dot(),log=log,direct=True)
3616
+ time.sleep(wait_time)
3617
+ backup_idx+=1
3618
+ continue
3619
+ shutil.copy2(save_file,output_file)
3620
+ if IsIn(capture_method,['log','screen','text']):
3621
+ found_words=ocr.Text(image_file=save_file)
3622
+ found_strings=found_space.join(found_words)
3623
+ printf(found_strings,log=log,mode='d' if log else 's')
3624
+ if find_string:
3625
+ if find_string in found_strings:
3626
+ driver.quit()
3627
+ return True
3628
+ time.sleep(wait_time)
3629
+ backup_idx+=1
3630
+ else:
3631
+ #wait
3632
+ wait_body(driver,timeout=wait_time)
3633
+ #capture
3634
+ driver.save_screenshot(output_file)
3635
+ driver.quit()
3636
+ if daemon:
3637
+ t=kThread(target=_capture_, args=(live_capture,driver,output_file,wait_time,capture_method,backup,ocr,log,find_string,daemon))
3638
+ return t
3639
+ else:
3640
+ _capture_(live_capture,driver,output_file,wait_time,capture_method,backup,ocr,log,find_string,daemon)
3641
+ return True,output_file
3546
3642
 
3547
- # Capture screenshot
3548
- driver.save_screenshot(output_file)
3549
- #print(f"Screenshot saved to {output_file}")
3550
- rc=True,output_file
3551
3643
  except Exception as e:
3552
3644
  #print(f"Error capturing screenshot: {str(e)}")
3553
- rc=False,str(e)
3554
- finally:
3555
- # Close the browser
3556
3645
  driver.quit()
3557
- return rc
3646
+ return False,str(e)
3647
+ # finally:
3648
+ # # Close the browser
3649
+ # driver.quit()
3650
+ # return rc
3651
+
3652
+ class OCR:
3653
+ def __init__(self,image_file=None,enhance=False,language=['en'],gpu=False,model_storage_directory=None,**opts):
3654
+ self.enhance=enhance
3655
+ self.image_file=image_file
3656
+ Import('easyocr')
3657
+ if self.enhance:
3658
+ Import('PIL',install_name='Pillow')
3659
+ Import('numpy')
3660
+ self.reader = easyocr.Reader(language,gpu=gpu,model_storage_directory=model_storage_directory)
3661
+ # Suppress Torch pin_memory warning
3662
+ warnings.filterwarnings("ignore", category=UserWarning, module="torch.utils.data.dataloader")
3663
+
3664
+ # Suppress EasyOCR CPU warning
3665
+ #warnings.filterwarnings("ignore", message="WARNING:easyocr.easyocr:Using CPU. Note: This module is much faster with a GPU.")
3666
+
3667
+ # Suppress NetworkX backend warning
3668
+ warnings.filterwarnings("ignore", category=RuntimeWarning, module="networkx.utils.backends")
3669
+
3670
+ def Text(self,detail=0,low_text=None,contrast_ths=None,image_file=None):
3671
+ if not image_file: image_file=self.image_file
3672
+ if not image_file: return False
3673
+ opts={}
3674
+ opts['detail']=detail
3675
+ if isinstance(low_text,float): opts['low_text']=low_test
3676
+ if isinstance(contrast_ths,float): opts['contrast_ths']=contrast_ths
3677
+ if self.enhance:
3678
+ image = PIL.Image.open(image_file)
3679
+ image = image.convert('L') #Grayscale
3680
+ image = PIL.ImageEnhance.Contrast(image).enhance(3.0) #high contrast
3681
+ image = PIL.ImageEnhance.Sharpness(image).enhance(2.0)#Sharpen
3682
+ image = image.convert('RGB').point(lambda p: 255 if p > 140 else 0) # Adjust threshold if needed
3683
+ # image = image.resize((800, int(800 * image.height / image.width)), PIL.Image.Resampling.LANCZOS)
3684
+ image.save(image_file)
3685
+ # image_np = numpy.array(image)
3686
+ # return self.reader.readtext(image_np,**opts)
3687
+ # else:
3688
+ return self.reader.readtext(image_file,**opts)
3558
3689
 
3559
3690
  ############################################
3560
3691
  #Temporary function map for replacement
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kmisc
3
- Version: 2.1.121
3
+ Version: 2.1.122
4
4
  Summary: Enginering useful library
5
5
  Home-page: https://github.com/kagepark/kmisc
6
6
  Author: Kage Park
File without changes
File without changes
File without changes
File without changes
File without changes