Skip to content

Commit

Permalink
modules import optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
zak-45 committed Sep 25, 2024
1 parent 1dd0c59 commit 0e0c3d2
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 129 deletions.
83 changes: 16 additions & 67 deletions CastAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
# 27/05/2024: cv2.imshow with import av freeze
"""
import logging
import logging.config

import concurrent_log_handler
import threading

from threading import current_thread
import traceback
import asyncio
from asyncio import set_event_loop_policy,WindowsSelectorEventLoopPolicy,sleep,create_task

from subprocess import Popen

Expand All @@ -37,8 +37,8 @@
import time
import sys
import os
import socket
import cv2
from socket import gethostbyname

import configparser
from pathlib import Path as PathLib

Expand Down Expand Up @@ -77,7 +77,7 @@
Netdevice = Net()

if sys.platform.lower() == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
set_event_loop_policy(WindowsSelectorEventLoopPolicy())

class_to_test = ['Desktop', 'Media', 'Netdevice']
action_to_test = ['stop', 'shot', 'info', 'close_preview', 'open_preview', 'reset']
Expand Down Expand Up @@ -144,7 +144,7 @@
async def init_actions():
""" Done at start of app and before GUI available """

logger.info(f'Main running {threading.current_thread().name}')
logger.info(f'Main running {current_thread().name}')

# Apply some default params only once
if str2bool(app_config['init_config_done']) is not True:
Expand Down Expand Up @@ -392,7 +392,7 @@ async def buffer_image_save(class_obj: str = Path(description=f'Class name, shou
raise HTTPException(status_code=400, detail=f"Image number : {number} not exist for Class name: {class_obj} ")

try:
await save_image(class_name, 'frame_buffer', number)
await CV2Utils.save_image(class_name, 'frame_buffer', number)
except Exception as b_error:
raise HTTPException(status_code=400, detail=f"Class name: {class_obj} provide this error : {b_error}")

Expand All @@ -417,7 +417,7 @@ async def buffer_image_save_ascii(class_obj: str = Path(description=f'Class name
raise HTTPException(status_code=400, detail=f"Image number : {number} not exist for Class name: {class_obj} ")

try:
await save_image(class_name, 'frame_buffer', number, ascii_art=True)
await CV2Utils.save_image(class_name, 'frame_buffer', number, ascii_art=True)
except Exception as b_error:
raise HTTPException(status_code=400, detail=f"Class name: {class_obj} provide this error : {b_error}")

Expand Down Expand Up @@ -909,9 +909,9 @@ def cast_image(image_number,
logger.debug(f"Image from buffer: {buffer_name}")

if device_number == -1: # instruct to use IP from the class.host
ip = socket.gethostbyname(class_obj.host)
ip = gethostbyname(class_obj.host)
else:
ip = socket.gethostbyname(class_obj.cast_devices[device_number][1])
ip = gethostbyname(class_obj.cast_devices[device_number][1])

if ip == '127.0.0.1':
logger.warning('WEBSOCKET: Nothing to do for localhost 127.0.0.1')
Expand Down Expand Up @@ -2788,57 +2788,6 @@ async def cast_to_wled(class_obj, image_number):
)


async def save_image(class_obj, buffer, image_number, ascii_art=False, interactive=False):
"""
Save image from Buffer
used on the buffer images
"""
folder = app_config['img_folder']
if folder[-1] == '/':
pass
else:
logger.error("The last character of the folder name is not '/'.")
return

# Get the absolute path of the folder relative to the current working directory
absolute_img_folder = os.path.abspath(folder)
if os.path.isdir(absolute_img_folder):
pass
else:
logger.error(f"The folder {absolute_img_folder} does not exist.")
return

# select buffer
if buffer == 'frame_buffer':
buffer = class_obj.frame_buffer
else:
buffer = class_obj.cast_frame_buffer

w, h = buffer[image_number].shape[:2]
date_time = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
class_name = class_obj.__module__

if ascii_art:
img = buffer[image_number]
img = Image.fromarray(img)
img = ImageUtils.image_to_ascii(img)
t_filename = folder + class_name + "_" + str(image_number) + "_" + str(w) + "_" + str(
h) + "_" + date_time + ".txt"
with open(t_filename, 'w') as ascii_file:
ascii_file.write(img)

else:
t_filename = folder + class_name + "_" + str(image_number) + "_" + str(w) + "_" + str(
h) + "_" + date_time + ".jpg"
img = cv2.cvtColor(buffer[image_number], cv2.COLOR_RGB2BGR)
cv2.imwrite(t_filename, img)

if interactive:
ui.notify(f"Image saved to {t_filename}")

logger.debug(f"Image saved to {t_filename}")


async def discovery_net_notify():
""" Call Run zero conf net discovery """

Expand Down Expand Up @@ -2920,10 +2869,10 @@ async def light_box_image(index, image, txt1, txt2, class_obj, buffer):
ui.button(on_click=lambda: cast_to_wled(class_obj, index), icon='cast') \
.props('flat fab color=white') \
.tooltip('Cast to WLED')
ui.button(on_click=lambda: save_image(class_obj, buffer, index, False, True), icon='save') \
ui.button(on_click=lambda: CV2Utils.save_image(class_obj, buffer, index, False), icon='save') \
.props('flat fab color=white') \
.tooltip('Save Image')
ui.button(on_click=lambda: save_image(class_obj, buffer, index, True, True),
ui.button(on_click=lambda: CV2Utils.save_image(class_obj, buffer, index, True),
icon='text_format') \
.props('flat fab color=white') \
.tooltip('Save Image as Ascii ART')
Expand All @@ -2948,7 +2897,7 @@ async def bar_get_size():

CastAPI.progress_bar.value = 1 - (Utils.yt_file_size_remain_bytes / Utils.yt_file_size_bytes)
CastAPI.progress_bar.update()
await asyncio.sleep(.1)
await sleep(.1)


async def download_url(url):
Expand All @@ -2962,7 +2911,7 @@ async def download_url(url):
if 'https://www.youtu' in url:

# this will run async loop in background and continue...
run_get_size = asyncio.create_task(bar_get_size())
run_get_size = create_task(bar_get_size())

# wait YT download finished
yt = await Utils.youtube_download(url, interactive=True)
Expand Down
7 changes: 2 additions & 5 deletions WLEDVideoSync.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@
pystray : put on systray if requested
"""

import logging
import logging.config
import pkgutil
from pkgutil import find_loader

import concurrent_log_handler

Expand Down Expand Up @@ -473,7 +470,7 @@ def on_exit():
Utils.update_ini_key(config_file, 'app', 'uvicorn', 'False')

# Apply YouTube settings if yt_dlp not imported
if not pkgutil.find_loader('yt_dlp'):
if not find_loader('yt_dlp'):
Utils.update_ini_key(config_file, 'custom', 'yt-enable', 'False')

# global
Expand Down
90 changes: 58 additions & 32 deletions cv2utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
import cv2
from multiprocessing.shared_memory import ShareableList
import numpy as np
import logging
import logging.config
import concurrent_log_handler
from PIL import Image
import io
import base64
import os
import cfg_load as cfg
from datetime import datetime
from str2bool import str2bool

from utils import CASTUtils as Utils

class CV2Utils:

Expand All @@ -39,7 +36,7 @@ def cv2_win_close(server_port, class_name, t_name, t_viinput):
window_name = f"{server_port}-{t_name}-" + str(t_viinput)

# check if window run into sub process to instruct it by ShareableList
config_data = CV2Utils.read_config()
config_data = Utils.read_config()
preview_proc = str2bool(config_data[1]['preview_proc'])

# for window into sub process
Expand Down Expand Up @@ -417,35 +414,52 @@ def pixelart_image(image_np, width_x, height_y):
return pixelart_img

@staticmethod
def setup_logging(config_path='logging_config.ini', handler_name: str = None):
if os.path.exists(config_path):
logging.config.fileConfig(config_path, disable_existing_loggers=False)
# trick: use the same name for all modules, ui.log will receive message from alls
config_data = CV2Utils.read_config()
if str2bool(config_data[1]['log_to_main']):
v_logger = logging.getLogger('WLEDLogger')
else:
v_logger = logging.getLogger(handler_name)
v_logger.info(f"Logging configured using {config_path} for {handler_name}")
async def save_image(class_obj, buffer, image_number, ascii_art=False):
"""
Save image from Buffer
used on the buffer images
"""
folder = app_config['img_folder']
if folder[-1] == '/':
pass
else:
logger.error("The last character of the folder name is not '/'.")
return

# Get the absolute path of the folder relative to the current working directory
absolute_img_folder = os.path.abspath(folder)
if os.path.isdir(absolute_img_folder):
pass
else:
logging.basicConfig(level=logging.INFO)
v_logger = logging.getLogger(handler_name)
v_logger.warning(f"Logging config file {config_path} not found. Using basic configuration.")
logger.error(f"The folder {absolute_img_folder} does not exist.")
return

return v_logger
# select buffer
if buffer == 'frame_buffer':
buffer = class_obj.frame_buffer
else:
buffer = class_obj.cast_frame_buffer

@staticmethod
def read_config():
# load config file
cast_config = cfg.load('config/WLEDVideoSync.ini')
# config keys
server_config = cast_config.get('server')
app_config = cast_config.get('app')
colors_config = cast_config.get('colors')
custom_config = cast_config.get('custom')
preset_config = cast_config.get('presets')
w, h = buffer[image_number].shape[:2]
date_time = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
class_name = class_obj.__module__

return server_config, app_config, colors_config, custom_config, preset_config
if ascii_art:
img = buffer[image_number]
img = Image.fromarray(img)
img = ImageUtils.image_to_ascii(img)
t_filename = folder + class_name + "_" + str(image_number) + "_" + str(w) + "_" + str(
h) + "_" + date_time + ".txt"
with open(t_filename, 'w') as ascii_file:
ascii_file.write(img)

else:
t_filename = folder + class_name + "_" + str(image_number) + "_" + str(w) + "_" + str(
h) + "_" + date_time + ".jpg"
img = cv2.cvtColor(buffer[image_number], cv2.COLOR_RGB2BGR)
cv2.imwrite(t_filename, img)

logger.debug(f"Image saved to {t_filename}")


class ImageUtils:
Expand Down Expand Up @@ -783,4 +797,16 @@ def get_thumbnails(self):
if "NUITKA_ONEFILE_PARENT" not in os.environ:
# read config
# create logger
logger = CV2Utils.setup_logging('config/logging.ini', 'WLEDLogger.utils')
logger = Utils.setup_logging('config/logging.ini', 'WLEDLogger.utils')
# load config file
cast_config = Utils.read_config()

# config keys
server_config = cast_config[0] # server key
app_config = cast_config[1] # app key
color_config = cast_config[2] # colors key
custom_config = cast_config[3] # custom key
preset_config = cast_config[4] # presets key
desktop_config = cast_config[5] # desktop key
ws_config = cast_config[6] # websocket key

4 changes: 0 additions & 4 deletions ddp_queue.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import logging
import logging.config
import concurrent_log_handler
import traceback
import struct
import socket
import numpy as np
Expand Down
10 changes: 5 additions & 5 deletions desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import cv2
import logging
import logging.config
import concurrent_log_handler

from multiprocessing.shared_memory import ShareableList
import traceback

Expand All @@ -41,7 +41,7 @@

import threading

import asyncio
from asyncio import run
import concurrent.futures

from ddp_queue import DDPDevice
Expand Down Expand Up @@ -274,9 +274,9 @@ def send_multicast_images_to_ips(images_buffer, to_ip_addresses):

# retrieve matrix setup from wled and set w/h
if self.wled:
status = asyncio.run(Utils.put_wled_live(self.host, on=True, live=True, timeout=1))
status = run(Utils.put_wled_live(self.host, on=True, live=True, timeout=1))
if status:
self.scale_width, self.scale_height = asyncio.run(Utils.get_wled_matrix_dimensions(self.host))
self.scale_width, self.scale_height = run(Utils.get_wled_matrix_dimensions(self.host))
else:
logger.error(f"{t_name} ERROR to set WLED device {self.host} on 'live' mode")
return False
Expand All @@ -296,7 +296,7 @@ def send_multicast_images_to_ips(images_buffer, to_ip_addresses):
valid_ip = Utils.check_ip_alive(cast_ip, port=80, timeout=2)
if valid_ip:
if self.wled:
status = asyncio.run(Utils.put_wled_live(cast_ip, on=True, live=True, timeout=1))
status = run(Utils.put_wled_live(cast_ip, on=True, live=True, timeout=1))
if not status:
logger.error(f"{t_name} ERROR to set WLED device {self.host} on 'live' mode")
return False
Expand Down
10 changes: 5 additions & 5 deletions media.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import logging
import logging.config
import concurrent_log_handler

from multiprocessing.shared_memory import ShareableList
import traceback
import numpy as np
Expand All @@ -35,7 +35,7 @@

import threading

import asyncio
from asyncio import run
import concurrent.futures

from ddp_queue import DDPDevice
Expand Down Expand Up @@ -280,9 +280,9 @@ def send_multicast_images_to_ips(images_buffer, to_ip_addresses):

# retrieve matrix setup from wled and set w/h
if self.wled:
status = asyncio.run(Utils.put_wled_live(self.host, on=True, live=True, timeout=1))
status = run(Utils.put_wled_live(self.host, on=True, live=True, timeout=1))
if status is True:
self.scale_width, self.scale_height = asyncio.run(Utils.get_wled_matrix_dimensions(self.host))
self.scale_width, self.scale_height = run(Utils.get_wled_matrix_dimensions(self.host))
else:
logger.error(f"{t_name} ERROR to set WLED device {self.host} on 'live' mode")
return False
Expand All @@ -302,7 +302,7 @@ def send_multicast_images_to_ips(images_buffer, to_ip_addresses):
valid_ip = Utils.check_ip_alive(cast_ip, port=80, timeout=2)
if valid_ip:
if self.wled:
status = asyncio.run(Utils.put_wled_live(cast_ip, on=True, live=True, timeout=1))
status = run(Utils.put_wled_live(cast_ip, on=True, live=True, timeout=1))
if not status:
logger.error(f"{t_name} ERROR to set WLED device {self.host} on 'live' mode")
return False
Expand Down
Loading

0 comments on commit 0e0c3d2

Please sign in to comment.