mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
handle missing directory
This commit is contained in:
parent
7ad9e1bd5b
commit
bcf75bf37e
24 changed files with 443 additions and 105 deletions
|
|
@ -6,9 +6,11 @@ import re
|
|||
import logging as log
|
||||
import shutil
|
||||
import tempfile
|
||||
from typing import Union, Callable, Dict
|
||||
from typing import Union, Callable, List
|
||||
from zipfile import ZipFile
|
||||
from pathlib import Path
|
||||
import functools
|
||||
|
||||
from speedcopy import copyfile
|
||||
|
||||
from appdirs import user_data_dir
|
||||
|
|
@ -17,6 +19,125 @@ from pype.lib import PypeSettingsRegistry
|
|||
from .tools import load_environments
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class PypeVersion:
|
||||
"""Class for storing information about Pype version.
|
||||
|
||||
Attributes:
|
||||
major (int): [1].2.3-variant-client
|
||||
minor (int): 1.[2].3-variant-client
|
||||
subversion (int): 1.2.[3]-variant-client
|
||||
variant (str): 1.2.3-[variant]-client
|
||||
client (str): 1.2.3-variant-[client]
|
||||
path (str): path to Pype
|
||||
|
||||
"""
|
||||
major = 0
|
||||
minor = 0
|
||||
subversion = 0
|
||||
variant = "production"
|
||||
client = None
|
||||
path = None
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
"""return formatted version string."""
|
||||
return self._compose_version()
|
||||
|
||||
@version.setter
|
||||
def version(self, val):
|
||||
decomposed = self._decompose_version(val)
|
||||
self.major = decomposed[0]
|
||||
self.minor = decomposed[1]
|
||||
self.subversion = decomposed[2]
|
||||
self.variant = decomposed[3]
|
||||
self.client = decomposed[4]
|
||||
|
||||
def __init__(self, major: int = None, minor: int = None,
|
||||
subversion: int = None, version: str = None,
|
||||
variant: str = "production", client: str = None,
|
||||
path: Path = None):
|
||||
self.path = path
|
||||
self._version_regex = re.compile(
|
||||
r"(?P<major>\d+)\.(?P<minor>\d+)\.(?P<sub>\d+)(-?((?P<variant>staging)|(?P<client>.+))(-(?P<cli>.+))?)?") # noqa: E501
|
||||
|
||||
if major is None or minor is None or subversion is None:
|
||||
if version is None:
|
||||
raise ValueError("Need version specified in some way.")
|
||||
if version:
|
||||
values = self._decompose_version(version)
|
||||
self.major = values[0]
|
||||
self.minor = values[1]
|
||||
self.subversion = values[2]
|
||||
self.variant = values[3]
|
||||
self.client = values[4]
|
||||
else:
|
||||
self.major = major
|
||||
self.minor = minor
|
||||
self.subversion = subversion
|
||||
# variant is set only if it is "staging", otherwise "production" is
|
||||
# implied and no need to mention it in version string.
|
||||
if variant == "staging":
|
||||
self.variant = variant
|
||||
self.client = client
|
||||
|
||||
def _compose_version(self):
|
||||
version = "{}.{}.{}".format(self.major, self.minor, self.subversion)
|
||||
if self.variant == "staging":
|
||||
version = "{}-{}".format(version, self.variant)
|
||||
|
||||
if self.client:
|
||||
version = "{}-{}".format(version, self.client)
|
||||
|
||||
return version
|
||||
|
||||
def _decompose_version(self, version_string: str) -> tuple:
|
||||
m = re.match(self._version_regex, version_string)
|
||||
if not m:
|
||||
raise ValueError(
|
||||
"Cannot parse version string: {}".format(version_string))
|
||||
|
||||
variant = None
|
||||
if m.group("variant") == "staging":
|
||||
variant = "staging"
|
||||
|
||||
client = m.group("client") or m.group("cli")
|
||||
|
||||
return (int(m.group("major")), int(m.group("minor")),
|
||||
int(m.group("sub")), variant, client)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
return False
|
||||
return self.version == other.version
|
||||
|
||||
def __str__(self):
|
||||
return self.version
|
||||
|
||||
def __repr__(self):
|
||||
return "{}, {}: {}".format(
|
||||
self.__class__.__name__, self.version, self.path)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.version)
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.major < other.major:
|
||||
return True
|
||||
|
||||
if self.major <= other.major and self.minor < other.minor:
|
||||
return True
|
||||
if self.major <= other.major and self.minor <= other.minor and self.subversion < other.subversion:
|
||||
return True
|
||||
|
||||
if self.major == other.major and self.minor == other.minor and \
|
||||
self.subversion == other.subversion and \
|
||||
self.variant == "staging":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class BootstrapRepos:
|
||||
"""Class for bootstrapping local Pype installation.
|
||||
|
||||
|
|
@ -55,6 +176,22 @@ class BootstrapRepos:
|
|||
else:
|
||||
self.live_repo_dir = Path(Path(__file__).parent / ".." / "repos")
|
||||
|
||||
@staticmethod
|
||||
def get_version_path_from_list(version:str, version_list:list) -> Path:
|
||||
"""Get path for specific version in list of Pype versions.
|
||||
|
||||
Args:
|
||||
version (str): Version string to look for (1.2.4-staging)
|
||||
version_list (list of PypeVersion): list of version to search.
|
||||
|
||||
Returns:
|
||||
Path: Path to given version.
|
||||
|
||||
"""
|
||||
for v in version_list:
|
||||
if str(v) == version:
|
||||
return v.path
|
||||
|
||||
@staticmethod
|
||||
def get_local_version() -> str:
|
||||
"""Get version of local Pype."""
|
||||
|
|
@ -162,7 +299,8 @@ class BootstrapRepos:
|
|||
assert repo_files != 0, f"No repositories to include in {include_dir}"
|
||||
pype_inc = 0
|
||||
if include_pype:
|
||||
pype_files = sum(len(files) for _, _, files in os.walk('pype'))
|
||||
pype_files = sum(len(files) for _, _, files in os.walk(
|
||||
include_dir.parent))
|
||||
repo_inc = 48.0 / float(repo_files)
|
||||
pype_inc = 48.0 / float(pype_files)
|
||||
else:
|
||||
|
|
@ -224,7 +362,7 @@ class BootstrapRepos:
|
|||
os.environ["PYTHONPATH"] = os.pathsep.join(paths)
|
||||
|
||||
def find_pype(
|
||||
self, pype_path: Path = None) -> Union[Dict[str, Path], None]:
|
||||
self, pype_path: Path = None) -> Union[List[PypeVersion], None]:
|
||||
"""Get ordered dict of detected Pype version.
|
||||
|
||||
Resolution order for Pype is following:
|
||||
|
|
@ -265,15 +403,23 @@ class BootstrapRepos:
|
|||
if not dir_to_search.exists():
|
||||
return None
|
||||
|
||||
_pype_versions = {}
|
||||
_pype_versions = []
|
||||
file_pattern = re.compile(r"^pype-repositories-v(?P<version>\d+\.\d+\.\d*.+?).zip$") # noqa: E501
|
||||
for file in dir_to_search.iterdir():
|
||||
m = re.match(
|
||||
r"^pype-repositories-v(?P<version>\d+\.\d+\.\d+).zip$",
|
||||
file_pattern,
|
||||
file.name)
|
||||
if m:
|
||||
_pype_versions[m.group("version")] = file
|
||||
try:
|
||||
_pype_versions.append(
|
||||
PypeVersion(
|
||||
version=m.group("version"), path=file))
|
||||
except ValueError:
|
||||
# cannot parse version string
|
||||
print(m)
|
||||
pass
|
||||
|
||||
return dict(sorted(_pype_versions.items()))
|
||||
return sorted(_pype_versions)
|
||||
|
||||
@staticmethod
|
||||
def _get_pype_from_mongo(mongo_url: str) -> Union[Path, None]:
|
||||
|
|
@ -336,12 +482,10 @@ class BootstrapRepos:
|
|||
# either "live" Pype repository, or multiple zip files.
|
||||
versions = self.find_pype(pype_path)
|
||||
if versions:
|
||||
latest_version = (
|
||||
list(versions.keys())[-1], list(versions.values())[-1])
|
||||
self._log.info(f"found Pype zips in [ {pype_path} ].")
|
||||
self._log.info(f"latest version found is [ {latest_version[0]} ]")
|
||||
self._log.info(f"latest version found is [ {versions[-1]} ]")
|
||||
|
||||
destination = self.data_dir / latest_version[1].name
|
||||
destination = self.data_dir / versions[-1].path.name
|
||||
|
||||
# test if destination file already exist, if so lets delete it.
|
||||
# we consider path on location as authoritative place.
|
||||
|
|
@ -359,7 +503,7 @@ class BootstrapRepos:
|
|||
destination.parent.mkdir(parents=True)
|
||||
|
||||
try:
|
||||
copyfile(latest_version[1].as_posix(), destination.as_posix())
|
||||
copyfile(versions[-1].path.as_posix(), destination.as_posix())
|
||||
except OSError:
|
||||
self._log.error(
|
||||
"cannot copy detected version to user data directory",
|
||||
|
|
|
|||
63
pype.py
63
pype.py
|
|
@ -32,6 +32,9 @@ Pype depends on connection to `MongoDB`_. You can specify MongoDB connection
|
|||
string via `AVALON_MONGO` set in environment or it can be set in user
|
||||
settings or via **Igniter** GUI.
|
||||
|
||||
Todo:
|
||||
Move or remove bootstrapping environments out of the code.
|
||||
|
||||
.. _MongoDB:
|
||||
https://www.mongodb.com/
|
||||
|
||||
|
|
@ -40,6 +43,7 @@ import os
|
|||
import re
|
||||
import sys
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
|
||||
from igniter.tools import load_environments
|
||||
|
||||
|
|
@ -79,7 +83,6 @@ def boot():
|
|||
"""
|
||||
|
||||
print(art)
|
||||
print(">>> loading environments ...")
|
||||
set_environments()
|
||||
# find pype versions
|
||||
bootstrap = BootstrapRepos()
|
||||
|
|
@ -89,7 +92,7 @@ def boot():
|
|||
use_version = None
|
||||
|
||||
for arg in sys.argv:
|
||||
m = re.search(r"--use-version=(?P<version>\d+\.\d+\.\d+)", arg)
|
||||
m = re.search(r"--use-version=(?P<version>\d+\.\d+\.\d*.+?)", arg)
|
||||
if m and m.group('version'):
|
||||
use_version = m.group('version')
|
||||
break
|
||||
|
|
@ -115,28 +118,32 @@ def boot():
|
|||
import igniter
|
||||
igniter.run()
|
||||
|
||||
if use_version in pype_versions.keys():
|
||||
version_path = BootstrapRepos.get_version_path_from_list(
|
||||
use_version, pype_versions)
|
||||
if version_path:
|
||||
# use specified
|
||||
bootstrap.add_paths_from_archive(pype_versions[use_version])
|
||||
use_version = pype_versions[use_version]
|
||||
bootstrap.add_paths_from_archive(version_path)
|
||||
|
||||
else:
|
||||
if use_version is not None:
|
||||
print(("!!! Specified version was not found, using "
|
||||
"latest available"))
|
||||
# use latest
|
||||
bootstrap.add_paths_from_archive(list(pype_versions.values())[-1])
|
||||
use_version = list(pype_versions.keys())[-1]
|
||||
version_path = pype_versions[-1].path
|
||||
bootstrap.add_paths_from_archive(version_path)
|
||||
use_version = str(pype_versions[-1])
|
||||
|
||||
os.environ["PYPE_ROOT"] = pype_versions[use_version].as_posix()
|
||||
os.environ["PYPE_ROOT"] = version_path.as_posix()
|
||||
else:
|
||||
# run through repos and add them to sys.path and PYTHONPATH
|
||||
pype_root = os.path.dirname(os.path.realpath(__file__))
|
||||
local_version = bootstrap.get_local_version()
|
||||
if use_version and use_version != local_version:
|
||||
if use_version in pype_versions.keys():
|
||||
version_path = BootstrapRepos.get_version_path_from_list(
|
||||
use_version, pype_versions)
|
||||
if version_path:
|
||||
# use specified
|
||||
bootstrap.add_paths_from_archive(pype_versions[use_version])
|
||||
use_version = pype_versions[use_version]
|
||||
bootstrap.add_paths_from_archive(version_path)
|
||||
|
||||
os.environ["PYPE_ROOT"] = pype_root
|
||||
repos = os.listdir(os.path.join(pype_root, "repos"))
|
||||
|
|
@ -149,6 +156,18 @@ def boot():
|
|||
paths += repos
|
||||
os.environ["PYTHONPATH"] = os.pathsep.join(paths)
|
||||
|
||||
# DEPRECATED: remove when `pype-config` dissolves into Pype for good.
|
||||
# .-=-----------------------=-=. ^ .=-=--------------------------=-.
|
||||
os.environ["PYPE_CONFIG"] = os.path.join(
|
||||
os.environ["PYPE_ROOT"], "repos", "pype-config")
|
||||
os.environ["PYPE_MODULE_ROOT"] = os.environ["PYPE_ROOT"]
|
||||
# ------------------------------------------------------------------
|
||||
# HARDCODED:
|
||||
os.environ["AVALON_DB"] = "Avalon"
|
||||
os.environ["AVALON_LABEL"] = "Pype"
|
||||
os.environ["AVALON_TIMEOUT"]= "1000"
|
||||
# .-=-----------------------=-=. v .=-=--------------------------=-.
|
||||
|
||||
# delete Pype module from cache so it is used from specific version
|
||||
try:
|
||||
del sys.modules["pype"]
|
||||
|
|
@ -159,10 +178,17 @@ def boot():
|
|||
from pype import cli
|
||||
from pype.lib import terminal as t
|
||||
from pype.version import __version__
|
||||
print(">>> loading environments ...")
|
||||
set_environments()
|
||||
|
||||
t.echo(f"*** Pype [{__version__}] --------------------------------------")
|
||||
t.echo(">>> Using Pype from [ {} ]".format(os.path.dirname(cli.__file__)))
|
||||
print_info()
|
||||
info = get_info()
|
||||
info.insert(0, ">>> Using Pype from [ {} ]".format(
|
||||
os.path.dirname(cli.__file__)))
|
||||
|
||||
info_length = len(max(info, key=len))
|
||||
info.insert(0, f"*** Pype [{__version__}] " + "-" * info_length)
|
||||
for i in info:
|
||||
t.echo(i)
|
||||
|
||||
try:
|
||||
cli.main(obj={}, prog_name="pype")
|
||||
|
|
@ -173,9 +199,8 @@ def boot():
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def print_info() -> None:
|
||||
def get_info() -> list:
|
||||
"""Print additional information to console."""
|
||||
from pype.lib import terminal as t
|
||||
from pype.lib.mongo import get_default_components
|
||||
from pype.lib.log import LOG_DATABASE_NAME, LOG_COLLECTION_NAME
|
||||
|
||||
|
|
@ -211,10 +236,12 @@ def print_info() -> None:
|
|||
infos.append((" - auth source", components["auth_db"]))
|
||||
|
||||
maximum = max([len(i[0]) for i in infos])
|
||||
formatted = []
|
||||
for info in infos:
|
||||
padding = (maximum - len(info[0])) + 1
|
||||
t.echo("... {}:{}[ {} ]".format(info[0], " " * padding, info[1]))
|
||||
print('\n')
|
||||
formatted.append(
|
||||
"... {}:{}[ {} ]".format(info[0], " " * padding, info[1]))
|
||||
return formatted
|
||||
|
||||
|
||||
boot()
|
||||
|
|
|
|||
|
|
@ -48,12 +48,16 @@ from .lib import (
|
|||
# Special naming case for subprocess since its a built-in method.
|
||||
from .lib import _subprocess as subprocess
|
||||
|
||||
# for backward compatibility with Pype 2
|
||||
Logger = PypeLogger
|
||||
|
||||
__all__ = [
|
||||
"system_settings",
|
||||
"project_settings",
|
||||
"environments",
|
||||
|
||||
"PypeLogger",
|
||||
"Logger",
|
||||
"Anatomy",
|
||||
"config",
|
||||
"execute",
|
||||
|
|
|
|||
|
|
@ -17,10 +17,15 @@ def main(ctx):
|
|||
ctx.invoke(tray)
|
||||
|
||||
|
||||
@main.command()
|
||||
@click.option("-d", "--dev", is_flag=True, help="Settings in Dev mode")
|
||||
def settings(dev=False):
|
||||
PypeCommands().launch_settings_gui(dev)
|
||||
|
||||
@main.command()
|
||||
@click.option("-d", "--debug",
|
||||
is_flag=True, help=("Run pype tray in debug mode"))
|
||||
def tray(debug):
|
||||
def tray(debug=False):
|
||||
"""Launch pype tray.
|
||||
|
||||
Default action of pype command is to launch tray widget to control basic
|
||||
|
|
|
|||
|
|
@ -1,7 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Pype module API."""
|
||||
|
||||
from .ffmpeg_utils import ffprobe_streams
|
||||
from .terminal import Terminal
|
||||
from .execute import execute
|
||||
from .log import PypeLogger, timeit
|
||||
from .mongo import (
|
||||
decompose_url,
|
||||
compose_url,
|
||||
get_default_components
|
||||
)
|
||||
from .anatomy import Anatomy
|
||||
|
||||
from .config import (
|
||||
get_datetime_data,
|
||||
load_json,
|
||||
collect_json_from_path,
|
||||
get_presets,
|
||||
get_init_presets,
|
||||
update_dict
|
||||
)
|
||||
|
||||
from .path_tools import (
|
||||
version_up,
|
||||
get_version_from_path,
|
||||
|
|
@ -9,6 +27,7 @@ from .path_tools import (
|
|||
get_paths_from_environ,
|
||||
get_ffmpeg_tool_path
|
||||
)
|
||||
from .ffmpeg_utils import ffprobe_streams
|
||||
from .plugin_tools import filter_pyblish_plugins, source_hash
|
||||
from .applications import (
|
||||
ApplicationLaunchFailed,
|
||||
|
|
@ -30,23 +49,8 @@ from .deprecated import (
|
|||
get_avalon_database,
|
||||
set_io_database
|
||||
)
|
||||
from .terminal import Terminal
|
||||
from .anatomy import Anatomy
|
||||
from .config import (
|
||||
get_datetime_data,
|
||||
load_json,
|
||||
collect_json_from_path,
|
||||
get_presets,
|
||||
get_init_presets,
|
||||
update_dict
|
||||
)
|
||||
from .execute import execute
|
||||
from .log import PypeLogger
|
||||
from .mongo import (
|
||||
decompose_url,
|
||||
compose_url,
|
||||
get_default_components
|
||||
)
|
||||
|
||||
|
||||
|
||||
from .user_settings import IniSettingRegistry
|
||||
from .user_settings import JSONSettingRegistry
|
||||
|
|
@ -104,5 +108,6 @@ __all__ = [
|
|||
"get_default_components",
|
||||
"IniSettingRegistry",
|
||||
"JSONSettingRegistry",
|
||||
"PypeSettingsRegistry"
|
||||
"PypeSettingsRegistry",
|
||||
"timeit"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,11 +6,7 @@ import platform
|
|||
import logging
|
||||
import subprocess
|
||||
|
||||
import acre
|
||||
|
||||
import avalon.lib
|
||||
|
||||
from ..api import Anatomy, Logger, config
|
||||
from . import Anatomy, config
|
||||
from .hooks import execute_hook
|
||||
from .deprecated import get_avalon_database
|
||||
|
||||
|
|
@ -27,6 +23,9 @@ def launch_application(project_name, asset_name, task_name, app_name):
|
|||
TODO(iLLiCiT): This should be split into more parts.
|
||||
"""
|
||||
# `get_avalon_database` is in Pype 3 replaced with using `AvalonMongoDB`
|
||||
import acre
|
||||
import avalon.lib
|
||||
|
||||
database = get_avalon_database()
|
||||
project_document = database[project_name].find_one({"type": "project"})
|
||||
asset_document = database[project_name].find_one({
|
||||
|
|
@ -193,7 +192,7 @@ def launch_application(project_name, asset_name, task_name, app_name):
|
|||
return popen
|
||||
|
||||
|
||||
class ApplicationAction(avalon.api.Action):
|
||||
class ApplicationAction:
|
||||
"""Default application launcher
|
||||
|
||||
This is a convenience application Action that when "config" refers to a
|
||||
|
|
@ -213,7 +212,7 @@ class ApplicationAction(avalon.api.Action):
|
|||
@property
|
||||
def log(self):
|
||||
if self._log is None:
|
||||
self._log = Logger().get_logger(self.__class__.__name__)
|
||||
self._log = logging.getLogger(self.__class__.__name__)
|
||||
return self._log
|
||||
|
||||
def is_compatible(self, session):
|
||||
|
|
|
|||
|
|
@ -3,14 +3,22 @@ import json
|
|||
import re
|
||||
import logging
|
||||
import collections
|
||||
import functools
|
||||
|
||||
from . import config
|
||||
|
||||
from avalon import io, pipeline
|
||||
from ..api import config
|
||||
import avalon.api
|
||||
|
||||
log = logging.getLogger("AvalonContext")
|
||||
|
||||
|
||||
def with_avalon(func):
|
||||
@functools.wraps(func)
|
||||
def wrap_avalon(*args, **kwargs):
|
||||
from avalon import api, io, pipeline
|
||||
return func(*args, **kwargs)
|
||||
pass
|
||||
|
||||
@with_avalon
|
||||
def is_latest(representation):
|
||||
"""Return whether the representation is from latest version
|
||||
|
||||
|
|
@ -37,7 +45,7 @@ def is_latest(representation):
|
|||
else:
|
||||
return False
|
||||
|
||||
|
||||
@with_avalon
|
||||
def any_outdated():
|
||||
"""Return whether the current scene has any outdated content"""
|
||||
|
||||
|
|
@ -65,7 +73,7 @@ def any_outdated():
|
|||
checked.add(representation)
|
||||
return False
|
||||
|
||||
|
||||
@with_avalon
|
||||
def get_asset(asset_name=None):
|
||||
""" Returning asset document from database by its name.
|
||||
|
||||
|
|
@ -91,6 +99,7 @@ def get_asset(asset_name=None):
|
|||
return asset_document
|
||||
|
||||
|
||||
@with_avalon
|
||||
def get_hierarchy(asset_name=None):
|
||||
"""
|
||||
Obtain asset hierarchy path string from mongo db
|
||||
|
|
@ -138,6 +147,7 @@ def get_hierarchy(asset_name=None):
|
|||
return "/".join(hierarchy_items)
|
||||
|
||||
|
||||
@with_avalon
|
||||
def get_linked_assets(asset_entity):
|
||||
"""Return linked assets for `asset_entity` from DB
|
||||
|
||||
|
|
@ -152,6 +162,7 @@ def get_linked_assets(asset_entity):
|
|||
return inputs
|
||||
|
||||
|
||||
@with_avalon
|
||||
def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None):
|
||||
"""Retrieve latest version from `asset_name`, and `subset_name`.
|
||||
|
||||
|
|
@ -257,6 +268,7 @@ class BuildWorkfile:
|
|||
|
||||
return containers
|
||||
|
||||
@with_avalon
|
||||
def build_workfile(self):
|
||||
"""Prepares and load containers into workfile.
|
||||
|
||||
|
|
@ -396,6 +408,7 @@ class BuildWorkfile:
|
|||
# Return list of loaded containers
|
||||
return loaded_containers
|
||||
|
||||
@with_avalon
|
||||
def get_build_presets(self, task_name):
|
||||
""" Returns presets to build workfile for task name.
|
||||
|
||||
|
|
@ -654,6 +667,7 @@ class BuildWorkfile:
|
|||
"containers": containers
|
||||
}
|
||||
|
||||
@with_avalon
|
||||
def _load_containers(
|
||||
self, repres_by_subset_id, subsets_by_id,
|
||||
profiles_per_subset_id, loaders_by_name
|
||||
|
|
@ -774,6 +788,7 @@ class BuildWorkfile:
|
|||
|
||||
return loaded_containers
|
||||
|
||||
@with_avalon
|
||||
def _collect_last_version_repres(self, asset_entities):
|
||||
"""Collect subsets, versions and representations for asset_entities.
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ def get_presets(project=None, first_run=False):
|
|||
def get_init_presets(project=None):
|
||||
"""Loads content of presets.
|
||||
|
||||
Llike :func:`get_presets()`` but also evaluate `init.json`
|
||||
Like :func:`get_presets()`` but also evaluate `init.json`
|
||||
pointer to default presets.
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import os
|
||||
|
||||
from avalon import io
|
||||
|
||||
|
||||
def get_avalon_database():
|
||||
"""Mongo database used in avalon's io.
|
||||
|
|
@ -9,6 +7,7 @@ def get_avalon_database():
|
|||
* Function is not used in pype 3.0 where was replaced with usage of
|
||||
AvalonMongoDB.
|
||||
"""
|
||||
from avalon import io
|
||||
if io._database is None:
|
||||
set_io_database()
|
||||
return io._database
|
||||
|
|
@ -20,6 +19,7 @@ def set_io_database():
|
|||
* Function is not used in pype 3.0 where was replaced with usage of
|
||||
AvalonMongoDB.
|
||||
"""
|
||||
from avalon import io
|
||||
required_keys = ["AVALON_PROJECT", "AVALON_ASSET", "AVALON_SILO"]
|
||||
for key in required_keys:
|
||||
os.environ[key] = os.environ.get(key, "")
|
||||
|
|
|
|||
|
|
@ -379,3 +379,22 @@ class PypeLogger:
|
|||
_mongo_logging = False
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
def timeit(method):
|
||||
""" Decorator to print how much time function took.
|
||||
For debugging.
|
||||
Depends on presence of 'log' object
|
||||
"""
|
||||
def timed(*args, **kw):
|
||||
ts = time.time()
|
||||
result = method(*args, **kw)
|
||||
te = time.time()
|
||||
if 'log_time' in kw:
|
||||
name = kw.get('log_name', method.__name__.upper())
|
||||
kw['log_time'][name] = int((te - ts) * 1000)
|
||||
else:
|
||||
log.debug('%r %2.2f ms' % (method.__name__, (te - ts) * 1000))
|
||||
print('%r %2.2f ms' % (method.__name__, (te - ts) * 1000))
|
||||
return result
|
||||
return timed
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import os
|
|||
import inspect
|
||||
import logging
|
||||
|
||||
from ..api import config
|
||||
from . import get_presets
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
@ -25,7 +25,7 @@ def filter_pyblish_plugins(plugins):
|
|||
|
||||
host = api.current_host()
|
||||
|
||||
presets = config.get_presets().get('plugins', {})
|
||||
presets = get_presets().get('plugins', {})
|
||||
|
||||
# iterate over plugins
|
||||
for plugin in plugins[:]:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
import os
|
||||
|
||||
from . import ftrack_server
|
||||
from .ftrack_server import FtrackServer, check_ftrack_url
|
||||
from .lib import BaseHandler, BaseEvent, BaseAction, ServerAction
|
||||
|
||||
from pype.api import system_settings
|
||||
|
||||
os.environ["FTRACK_SERVER"] = (
|
||||
system_settings()["global"]["modules"]["Ftrack"]["ftrack_server"]
|
||||
)
|
||||
__all__ = (
|
||||
"ftrack_server",
|
||||
"FtrackServer",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import collections
|
||||
from Qt import QtCore, QtGui
|
||||
from pype.api import Logger
|
||||
from pypeapp.lib.log import _bootstrap_mongo_log, LOG_COLLECTION_NAME
|
||||
from pype.lib.log import _bootstrap_mongo_log, LOG_COLLECTION_NAME
|
||||
|
||||
log = Logger().get_logger("LogModel", "LoggingModule")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ import os
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
from pype.lib import PypeLogger as Logger
|
||||
from pype.lib import execute
|
||||
|
||||
|
||||
class PypeCommands:
|
||||
"""Class implementing commands used by Pype.
|
||||
|
|
@ -14,7 +11,9 @@ class PypeCommands:
|
|||
Most of its methods are called by :mod:`cli` module.
|
||||
"""
|
||||
@staticmethod
|
||||
def launch_tray(debug):
|
||||
def launch_tray(debug=False):
|
||||
from pype.lib import PypeLogger as Logger
|
||||
from pype.lib import execute
|
||||
if debug:
|
||||
execute([
|
||||
sys.executable,
|
||||
|
|
@ -50,6 +49,16 @@ class PypeCommands:
|
|||
creationflags=detached_process
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def launch_settings_gui(dev):
|
||||
from pype.lib import execute
|
||||
|
||||
args = [sys.executable, "-m", "pype.tools.settings"]
|
||||
if dev:
|
||||
args.append("--develop")
|
||||
return_code = execute(args)
|
||||
return return_code
|
||||
|
||||
def launch_eventservercli(self, args):
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"PYPE_APP_ROOT": "{PYPE_SETUP_PATH}/pypeapp",
|
||||
"PYPE_MODULE_ROOT": "{PYPE_SETUP_PATH}/repos/pype",
|
||||
"PYPE_PROJECT_PLUGINS": "",
|
||||
"STUDIO_SOFT": "{PYP_SETUP_ROOT}/soft",
|
||||
"STUDIO_SOFT": "{PYPE_SETUP_ROOT}/soft",
|
||||
"FFMPEG_PATH": {
|
||||
"windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/windows/bin",
|
||||
"darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin",
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
"environment": {
|
||||
"__environment_keys__": {
|
||||
"global": [
|
||||
"PYPE_APP_ROOT",
|
||||
"PYPE_MODULE_ROOT",
|
||||
"FFMPEG_PATH",
|
||||
"PATH",
|
||||
"PYTHONPATH",
|
||||
|
|
@ -24,8 +22,6 @@
|
|||
"PYBLISH_GUI"
|
||||
]
|
||||
},
|
||||
"PYPE_APP_ROOT": "{PYPE_SETUP_PATH}/pypeapp",
|
||||
"PYPE_MODULE_ROOT": "{PYPE_SETUP_PATH}/repos/pype",
|
||||
"FFMPEG_PATH": {
|
||||
"windows": "{VIRTUAL_ENV}/localized/ffmpeg_exec/windows/bin;{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/windows/bin",
|
||||
"darwin": "{VIRTUAL_ENV}/localized/ffmpeg_exec/darwin/bin:{PYPE_SETUP_PATH}/vendor/bin/ffmpeg_exec/darwin/bin",
|
||||
|
|
@ -33,7 +29,6 @@
|
|||
},
|
||||
"PATH": [
|
||||
"{PYPE_CONFIG}/launchers",
|
||||
"{PYPE_APP_ROOT}",
|
||||
"{FFMPEG_PATH}",
|
||||
"{PATH}"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -102,3 +102,6 @@ def register_environment_actions():
|
|||
module, str(e)
|
||||
)
|
||||
)
|
||||
|
||||
class ApplicationLaunchFailed(Exception):
|
||||
pass
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from settings import style, MainWidget
|
||||
from .settings import style, MainWidget
|
||||
|
||||
|
||||
__all__ = (
|
||||
|
|
|
|||
|
|
@ -120,21 +120,9 @@ class TrayManager:
|
|||
self.start_modules()
|
||||
|
||||
def _add_version_item(self):
|
||||
config_file_path = os.path.join(
|
||||
os.environ["PYPE_SETUP_PATH"], "pypeapp", "config.ini"
|
||||
)
|
||||
|
||||
default_config = {}
|
||||
if os.path.exists(config_file_path):
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_file_path)
|
||||
try:
|
||||
default_config = config["CLIENT"]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
subversion = default_config.get("subversion")
|
||||
client_name = default_config.get("client_name")
|
||||
subversion = os.environ.get("PYPE_SUBVERSION")
|
||||
client_name = os.environ.get("PYPE_CLIENT")
|
||||
|
||||
version_string = pype.version.__version__
|
||||
if subversion:
|
||||
|
|
@ -224,7 +212,7 @@ class TrayManager:
|
|||
"Module \"{}\" does not have attribute \"{}\"."
|
||||
" Check your settings please."
|
||||
).format(import_path, key))
|
||||
|
||||
p = os.environ["AVALON_SCHEMA"]
|
||||
obj = module.tray_init(self.tray_widget, self.main_window)
|
||||
name = obj.__class__.__name__
|
||||
if hasattr(obj, 'tray_menu'):
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit d2fcbe96efbca3676ff09a824ef9f5c61483f960
|
||||
Subproject commit 3c10ad50aa1905dcd06959e08e7e0994561eb3e4
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit f0298b2d0757e1ae126d740cbe08835f6a4ee5e0
|
||||
Subproject commit 178f5cdd1859d079bc16094b321f8f06c1306c36
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
aiohttp
|
||||
appdirs
|
||||
arrow
|
||||
certifi
|
||||
|
|
@ -5,13 +6,16 @@ Click
|
|||
clique==1.5.0
|
||||
coverage
|
||||
cx_Freeze
|
||||
ftrack-python-api
|
||||
ffmpeg-python
|
||||
google-api-python-client
|
||||
jsonschema
|
||||
keyring
|
||||
log4mongo
|
||||
OpenTimelineIO
|
||||
pathlib2
|
||||
Pillow
|
||||
pyinput
|
||||
pymongo
|
||||
pytest
|
||||
pytest-cov
|
||||
|
|
@ -28,3 +32,4 @@ recommonmark
|
|||
toml
|
||||
tqdm
|
||||
wheel
|
||||
wsrpc_aiohttp
|
||||
|
|
|
|||
1
setup.py
1
setup.py
|
|
@ -41,6 +41,7 @@ buildOptions = dict(
|
|||
excludes=[],
|
||||
bin_includes=[],
|
||||
include_files=[
|
||||
"igniter",
|
||||
"pype",
|
||||
"repos",
|
||||
"schema",
|
||||
|
|
|
|||
|
|
@ -6,17 +6,116 @@ from pathlib import Path
|
|||
import pytest
|
||||
import appdirs
|
||||
from igniter.bootstrap_repos import BootstrapRepos
|
||||
from igniter.bootstrap_repos import PypeVersion
|
||||
from pype.lib import PypeSettingsRegistry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fix_bootstrap(tmp_path):
|
||||
def fix_bootstrap(tmp_path, pytestconfig):
|
||||
bs = BootstrapRepos()
|
||||
bs.live_repo_dir = Path(os.path.abspath('repos'))
|
||||
bs.live_repo_dir = pytestconfig.rootpath / 'repos'
|
||||
bs.data_dir = tmp_path
|
||||
return bs
|
||||
|
||||
|
||||
def test_pype_version():
|
||||
v1 = PypeVersion(1, 2, 3)
|
||||
assert str(v1) == "1.2.3"
|
||||
|
||||
v2 = PypeVersion(1, 2, 3, client="x")
|
||||
assert str(v2) == "1.2.3-x"
|
||||
|
||||
v3 = PypeVersion(1, 2, 3, variant="staging")
|
||||
assert str(v3) == "1.2.3-staging"
|
||||
|
||||
v4 = PypeVersion(1, 2, 3, variant="staging", client="client")
|
||||
assert str(v4) == "1.2.3-staging-client"
|
||||
|
||||
v5 = PypeVersion(1, 2, 3, variant="foo", client="x")
|
||||
assert str(v5) == "1.2.3-x"
|
||||
assert v4 < v5
|
||||
|
||||
v6 = PypeVersion(1, 2, 3, variant="foo")
|
||||
assert str(v6) == "1.2.3"
|
||||
|
||||
v7 = PypeVersion(2, 0, 0)
|
||||
assert v1 < v7
|
||||
|
||||
v8 = PypeVersion(0, 1, 5)
|
||||
assert v8 < v7
|
||||
|
||||
v9 = PypeVersion(1, 2, 4)
|
||||
assert v9 > v1
|
||||
|
||||
v10 = PypeVersion(1, 2, 2)
|
||||
assert v10 < v1
|
||||
|
||||
assert v5 == v2
|
||||
|
||||
sort_versions = [
|
||||
PypeVersion(3, 2, 1),
|
||||
PypeVersion(1, 2, 3),
|
||||
PypeVersion(0, 0, 1),
|
||||
PypeVersion(4, 8, 10),
|
||||
PypeVersion(4, 8, 20),
|
||||
PypeVersion(4, 8, 9),
|
||||
PypeVersion(1, 2, 3, variant="staging"),
|
||||
PypeVersion(1, 2, 3, client="client")
|
||||
]
|
||||
res = sorted(sort_versions)
|
||||
|
||||
assert res[0] == sort_versions[2]
|
||||
assert res[1] == sort_versions[6]
|
||||
assert res[2] == sort_versions[1]
|
||||
assert res[-1] == sort_versions[4]
|
||||
|
||||
str_versions = [
|
||||
"5.5.1",
|
||||
"5.5.2-client",
|
||||
"5.5.3-client-strange",
|
||||
"5.5.4-staging",
|
||||
"5.5.5-staging-client",
|
||||
"5.6.3",
|
||||
"5.6.3-staging"
|
||||
]
|
||||
res_versions = []
|
||||
for v in str_versions:
|
||||
res_versions.append(PypeVersion(version=v))
|
||||
|
||||
sorted_res_versions = sorted(res_versions)
|
||||
|
||||
assert str(sorted_res_versions[0]) == str_versions[0]
|
||||
assert str(sorted_res_versions[-1]) == str_versions[5]
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
_ = PypeVersion()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
_ = PypeVersion(major=1)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
_ = PypeVersion(version="booobaa")
|
||||
|
||||
v11 = PypeVersion(version="4.6.7-staging-client")
|
||||
assert v11.major == 4
|
||||
assert v11.minor == 6
|
||||
assert v11.subversion == 7
|
||||
assert v11.variant == "staging"
|
||||
assert v11.client == "client"
|
||||
|
||||
|
||||
def test_get_version_path_from_list():
|
||||
versions = [
|
||||
PypeVersion(1, 2, 3, path=Path('/foo/bar')),
|
||||
PypeVersion(3, 4, 5, variant="staging", path=Path("/bar/baz")),
|
||||
PypeVersion(6, 7, 8, client="x", path=Path("boo/goo"))
|
||||
]
|
||||
path = BootstrapRepos.get_version_path_from_list(
|
||||
"3.4.5-staging", versions)
|
||||
|
||||
assert path == Path("/bar/baz")
|
||||
|
||||
|
||||
def test_install_live_repos(fix_bootstrap, printer):
|
||||
rf = fix_bootstrap.install_live_repos()
|
||||
sep = os.path.sep
|
||||
|
|
@ -50,11 +149,20 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
|
||||
test_versions_1 = [
|
||||
"pype-repositories-v5.5.1.zip",
|
||||
"pype-repositories-v5.5.2-client.zip",
|
||||
"pype-repositories-v5.5.3-client-strange.zip",
|
||||
"pype-repositories-v5.5.4-staging.zip",
|
||||
"pype-repositories-v5.5.5-staging-client.zip",
|
||||
"pype-repositories-v5.6.3.zip",
|
||||
"pype-repositories-v5.6.3-staging.zip"
|
||||
]
|
||||
|
||||
test_versions_2 = [
|
||||
"pype-repositories-v7.2.6.zip",
|
||||
"pype-repositories-v7.2.7-client.zip",
|
||||
"pype-repositories-v7.2.8-client-strange.zip",
|
||||
"pype-repositories-v7.2.9-staging.zip",
|
||||
"pype-repositories-v7.2.10-staging-client.zip",
|
||||
"pype-repositories-v7.0.1.zip",
|
||||
]
|
||||
|
||||
|
|
@ -63,6 +171,10 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
"pype-repositories-v3.0.1.zip",
|
||||
"pype-repositories-v4.1.0.zip",
|
||||
"pype-repositories-v4.1.2.zip",
|
||||
"pype-repositories-v3.0.1-client.zip",
|
||||
"pype-repositories-v3.0.1-client-strange.zip",
|
||||
"pype-repositories-v3.0.1-staging.zip",
|
||||
"pype-repositories-v3.0.1-staging-client.zip",
|
||||
"pype-repositories-v3.2.0.zip",
|
||||
]
|
||||
|
||||
|
|
@ -87,7 +199,7 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
# we should have results as file were created
|
||||
assert result is not None, "no Pype version found"
|
||||
# latest item in `result` should be latest version found.
|
||||
assert list(result.values())[-1] == Path(
|
||||
assert result[-1].path == Path(
|
||||
fix_bootstrap.data_dir / test_versions_3[3]
|
||||
), "not a latest version of Pype 3"
|
||||
|
||||
|
|
@ -97,8 +209,8 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
# we should have results as file were created
|
||||
assert result is not None, "no Pype version found"
|
||||
# latest item in `result` should be latest version found.
|
||||
assert list(result.values())[-1] == Path(
|
||||
e_path / test_versions_1[1]
|
||||
assert result[-1].path == Path(
|
||||
e_path / test_versions_1[5]
|
||||
), "not a latest version of Pype 1"
|
||||
|
||||
monkeypatch.delenv("PYPE_PATH", raising=False)
|
||||
|
|
@ -115,12 +227,12 @@ def test_find_pype(fix_bootstrap, tmp_path_factory, monkeypatch, printer):
|
|||
# we should have results as file were created
|
||||
assert result is not None, "no Pype version found"
|
||||
# latest item in `result` should be latest version found.
|
||||
assert list(result.values())[-1] == Path(
|
||||
r_path / test_versions_2[0]
|
||||
assert result[-1].path == Path(
|
||||
r_path / test_versions_2[4]
|
||||
), "not a latest version of Pype 2"
|
||||
|
||||
result = fix_bootstrap.find_pype(e_path)
|
||||
assert result is not None, "no Pype version found"
|
||||
assert list(result.values())[-1] == Path(
|
||||
e_path / test_versions_1[1]
|
||||
assert result[-1].path == Path(
|
||||
e_path / test_versions_1[5]
|
||||
), "not a latest version of Pype 1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue