xconv: Make profile system more flexible

Can now select from multiple profiles per file and import from arbitrary modules
master
Taeyeon Mori 7 years ago
parent 010ea8b43f
commit 2b963e7b0f
  1. 5
      lib/python/xconv/profile.py
  2. 76
      lib/python/xconv/profileman.py

@ -25,7 +25,7 @@ xconv ffmpeg wrapper based on AdvancedAV
Decorators for defining xconv profiles
"""
from .profileman import index
from .profileman import index, make_qname
from functools import wraps
@ -39,6 +39,7 @@ __all__ = [
"singleaudio"
]
# == Misc. helpers ==
def __update(f, name, update):
if hasattr(f, name):
@ -65,7 +66,7 @@ def profile(f):
ext=None,
defines={},
features={})
index[f.__name__] = f
index[make_qname(f.__module__, f.__name__)] = f
return f

@ -32,33 +32,85 @@ from pathlib import Path
# == Profile Index ==
index = {}
profiles_package = __package__ + ".profiles"
def make_qname(module, name):
"""
Create a qualified name for a profile
"""
# The global profiles package is omitted from the front
if module.startswith("%s." % profiles_package):
module = module[len(profiles_package) + 1:]
# But arbitrary packages can be specified by prepending :
# This, among other things, allows to use profiles defined
# in .py files in the working dir.
else:
module = ":" + module
# If it's not deeply nested and the module name
# and profile name are the same, the latter
# can be omitted.
if module.strip(":") != name:
return "%s.%s" % (module, name)
else:
return module
# Examples:
# Profile xconv.profiles.opus/opus:
# - opus
# - opus.opus
# - :xconv.profiles.opus.opus
# Watch out for xconv.profiles/opus (not valid):
# - :xconv.profiles.opus
# Profile xconv.profiles.opus/stuff:
# - opus.stuff
# - :xconv.profiles.opus.stuff
# Profile test/test:
# - :test
# - :test.test
def load_profile(name):
"""
Find and load a XConv profile.
"""
# Check if it's already loaded
if name in index:
return index[name]
try:
import_module(".profiles.%s" % name, __package__)
except ImportError as e:
print(e)
pass
# See if it's a qualified name
module = name.rsplit(".", 1)[0] if "." in name[1:] else name
if name in index:
return index[name]
# Check if it's in the global profiles package or not
if module[0] == ":":
module = module[1:]
else:
module = "." + module
load_all_profiles()
# Try to import the module
import_module(module, profiles_package)
if name in index:
# Return the profile
try:
return index[name]
raise ImportError("Could not find XConv profile '%s'" % name)
except KeyError:
# Fully qualifying the global profiles package is technically valid.
if name.startswith(":%s." % profiles_package):
qname = make_qname(*name[1:].rsplit(".", 1))
if qname in index:
return index[qname]
raise ImportError("Module %s doesn't contain XConv profile %s" % (module, name))
def load_all_profiles():
"""
Load all profile definitions
"""
for location in profilepaths:
for mod in (x for x in Path(location).iterdir() if x.is_file() and x.suffix == ".py"):
try:
import_module(".profiles.%s" % mod.stem, __package__)
import_module(".%s" % mod.stem, profiles_package)
except ImportError:
pass

Loading…
Cancel
Save