mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-31 15:05:47 -08:00
fix: update menu loading mechanism to support pkgutil for dynamic imports
This commit is contained in:
@@ -5,10 +5,11 @@ block_cipher = None
|
||||
|
||||
# Collect all required data files
|
||||
datas = [
|
||||
('../viu_media/assets/*', 'viu_media/assets'),
|
||||
('../viu_media/assets', 'viu_media/assets'),
|
||||
]
|
||||
|
||||
# Collect all required hidden imports
|
||||
# Include viu_media and all its submodules to ensure menu modules are bundled
|
||||
hiddenimports = [
|
||||
'click',
|
||||
'rich',
|
||||
@@ -16,8 +17,10 @@ hiddenimports = [
|
||||
'yt_dlp',
|
||||
'python_mpv',
|
||||
'fuzzywuzzy',
|
||||
'viu',
|
||||
] + collect_submodules('viu')
|
||||
'viu_media',
|
||||
'viu_media.cli.interactive.menu',
|
||||
'viu_media.cli.interactive.menu.media',
|
||||
] + collect_submodules('viu_media')
|
||||
|
||||
a = Analysis(
|
||||
['../viu_media/viu.py'], # Changed entry point
|
||||
|
||||
1
viu_media/cli/interactive/menu/__init__.py
Normal file
1
viu_media/cli/interactive/menu/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Menu package for interactive session
|
||||
1
viu_media/cli/interactive/menu/media/__init__.py
Normal file
1
viu_media/cli/interactive/menu/media/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Media menu modules
|
||||
@@ -1,6 +1,9 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
import logging
|
||||
import os
|
||||
import pkgutil
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import TYPE_CHECKING, Callable, List, Optional, Union
|
||||
|
||||
@@ -309,30 +312,41 @@ class Session:
|
||||
return decorator
|
||||
|
||||
def load_menus_from_folder(self, package: str):
|
||||
package_path = MENUS_DIR / package
|
||||
package_name = package_path.name
|
||||
logger.debug(f"Loading menus from '{package_path}'...")
|
||||
"""Load menu modules from a subfolder.
|
||||
|
||||
Uses pkgutil to discover modules, which works correctly with both
|
||||
regular Python installations and PyInstaller frozen executables.
|
||||
"""
|
||||
full_package_name = f"viu_media.cli.interactive.menu.{package}"
|
||||
logger.debug(f"Loading menus from package '{full_package_name}'...")
|
||||
|
||||
for filename in os.listdir(package_path):
|
||||
if filename.endswith(".py") and not filename.startswith("__"):
|
||||
module_name = filename[:-3]
|
||||
full_module_name = (
|
||||
f"viu_media.cli.interactive.menu.{package_name}.{module_name}"
|
||||
try:
|
||||
# Import the parent package first
|
||||
parent_package = importlib.import_module(full_package_name)
|
||||
except ImportError as e:
|
||||
logger.error(f"Failed to import menu package '{full_package_name}': {e}")
|
||||
return
|
||||
|
||||
# Use pkgutil to iterate over all modules in the package
|
||||
# This works with PyInstaller because it respects the module's __path__
|
||||
package_path = getattr(parent_package, "__path__", None)
|
||||
if package_path is None:
|
||||
logger.error(f"Package '{full_package_name}' has no __path__ attribute.")
|
||||
return
|
||||
|
||||
for importer, module_name, ispkg in pkgutil.iter_modules(package_path):
|
||||
if ispkg or module_name.startswith("_"):
|
||||
continue
|
||||
|
||||
full_module_name = f"{full_package_name}.{module_name}"
|
||||
try:
|
||||
# Simply importing the module will execute it,
|
||||
# which runs the @session.menu decorators
|
||||
importlib.import_module(full_module_name)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Failed to load menu module '{full_module_name}': {e}"
|
||||
)
|
||||
file_path = package_path / filename
|
||||
|
||||
try:
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
full_module_name, file_path
|
||||
)
|
||||
if spec and spec.loader:
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
# The act of executing the module runs the @session.menu decorators
|
||||
spec.loader.exec_module(module)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Failed to load menu module '{full_module_name}': {e}"
|
||||
)
|
||||
|
||||
|
||||
# Create a single, global instance of the Session to be imported by menu modules.
|
||||
|
||||
Reference in New Issue
Block a user