getavalon / launcher Goto Github PK
View Code? Open in Web Editor NEWEnvironment management platform
License: MIT License
Environment management platform
License: MIT License
Problem
When no label is specified in the project config, the name of the application is used.
Solution
Often a label is defined in the toml files which can be utilized as well.
Goal
Simplify clutter by utilizing visualParent
data member.
Motivation
With lots of episodes/shots, the navigation can become difficult.
Implementation
Similar to walking the hierarchy of;
project
> silo
> asset
We would need to include the visual parents;
project
> silo
> visualParent
> asset
The issue might be implementing the potential of unlimited visual parent levels.
Save the user time and grief when having to restart the application.
Save window size, location and the current selection. E.g. having browsed your way to a particular task and exited the GUI, maintain this selection when booting it back up.
Enable customising the GUI and advanced launcher options.
Add a menubar to the top of the window with various options.
Enable configuring of the project, such as thumbnail, title and description.
The projects deserve a greater spotlight than just the name.
Currently, shot, task and application metadata is stored within a project and is loaded upon entering the project. The project metadata is also located within the project, but isn't available until after entering it. The brute force approach would be to load all metadata for every project upon listing it, but it would come at a performance penalty.
Best to hold on until the implementation of the remote asset service, at which point we could do exactly this, but cache the results server-side and save on performance that way.
Avoid accidental launch.
At the moment, an application is launched by pressing the name. If you double-click, you'll launch two applications. Since some applications take a minute to appear running, one may accidentally click many times and cause many applications to launch all at once.
Implement a press-and-hold type mechanism, such that you press-and-hold on your application for a second or so in order to launch it, along with some visual indicator of how long you need to press and whether you've pressed long enough.
Optimise time to start task.
Help the user understand when something goes wrong.
At the moment, an error may occur or a warning may appear in the terminal, but the user has no way of knowing, causing potential confusion in such situations.
Add a warning message in the footer of the window, shake the window or otherwise notify the user when something has gone wrong.
Currently the only way in Avalon to set up a project's environment is to actually launch into the application through the Launcher. I believe this should be simplified and separated so that it becomes trivial to initialize an application's environment for an asset in code, e.g. when trying to batch prepare a lot of assets.
This would also increase the readability of launching an application itself, since it would just rely on the library functions for initializing the environment, like lib.create_environment(asset, task, app)
.
This is not reliable pseudocode, but would present the idea.
# pseudocode
import os
import errno
import traceback
import shutil
from avalon import io
# A mockup maya application (should be loaded from .toml)
app = {
"default_dirs": [
"scenes",
"data",
"renderData/shaders",
"images",
"sourceimages"
],
"copy": {
"{AVALON_CORE}/res/workspace.mel": "workspace.mel"
}
}
asset = io.find_one({"type": "asset"})
create_environment(app, asset, task="model")
def create_environment(app, asset, task):
"""Create a work environment for application in asset's task.
Arguments:
app (dict): Application specification.
asset (bson.ObjectID): The asset database id.
task (str): The name of the task to operate in.
"""
# todo: actually get the workdir using project's config and the asset itself
# this would format the template for "work" files.
workdir = _get_workdir(asset, task, app)
try:
os.makedirs(workdir)
log.info("Creating working directory '%s'", workdir)
except OSError as e:
# An already existing working directory is fine.
if e.errno == errno.EEXIST:
log.info("Existing working directory found.")
else:
log.error("Could not create working directory.")
log.error(traceback.format_exc())
else:
log.info("Creating default directories..")
for dirname in app.get("default_dirs", []):
log.debug(" - %s", dirname)
os.makedirs(os.path.join(workdir, dirname))
# Perform application copy
for src, dst in app.get("copy", {}).items():
# Format source by environment
# TODO: Formatting shouldn't be done here!
src = src.format(**os.environ)
dst = os.path.join(workdir, dst)
try:
log.info("Copying %s -> %s", src, dst)
shutil.copy(src, dst)
except OSError as e:
log.error("Could not copy application file: %s", e)
log.error(" - %s -> %s", src, dst)
I might even want to propose to have this logic be part of the avalon's core API, which would also make it an issue for avalon core.
The issue was reported here by Gitter user anilreddyg2
. The error message was:
C:\>avalon
Using Python @ 'C:\Users\Anil\AppData\Local\Programs\Python\Python36-32\python.e
xe'
Using PyQt5 @ 'C:\Users\Anil\AppData\Local\Programs\Python\Python36-32\lib\site-
packages\PyQt5'
Using core @ 'C:\avalon-setup\git\avalon-core'
Using launcher @ 'C:\avalon-setup\git\avalon-launcher'
Using root @ 'C:\avalon-setup\git\avalon-examples\projects'
Using config: 'polly'
Starting avalon-launcher
QQmlApplicationEngine failed to load component
file:///C:/avalon-setup/git/avalon-launcher/launcher/res/qml/main.qml:79 Type My
Button unavailable
file:///C:/avalon-setup/git/avalon-launcher/launcher/res/qml/MyButton.qml:8 Cann
ot override FINAL property
Could not load QML file..
This seems related to an icon variable being added to Qt5.10.
We should fix this so we are forward compatible with these versions. We could likely rename our "icon" property so it doesn't conflict with the new one implemented on AbstractButton
.
The current workaround would be to downgrade to lower than version PyQt 5.10.
Hi,
i am using Python 3.7, PyQT 5.11.1 and getting below error
Starting avalon-launcher
Warning: QT_DEVICE_PIXEL_RATIO is deprecated. Instead use:
QT_AUTO_SCREEN_SCALE_FACTOR to enable platform plugin controlled per-screen factors.
QT_SCREEN_SCALE_FACTORS to set per-screen factors.
QT_SCALE_FACTOR to set the application global scale factor.
QQmlApplicationEngine failed to load component
file:///E:/code/avalon/avalon-setup/git/avalon-launcher/launcher/res/qml/main.qml:79 Type MyButton unavailable
file:///E:/code/avalon/avalon-setup/git/avalon-launcher/launcher/res/qml/MyButton.qml:8 Cannot override FINAL property
Could not load QML file..
Problem
Currently you can't generate multiple actions with code.
Solution
Have Launcher run the register
method when found in modules.
The idea is to run register
once on initialization, so actions can be dynamically generated.
Notify user on available update, potentially perform one in the background.
At startup, check for commits made since the currently checked out version on disk, and show comments made per commit. Like what a GitHub pull-request does.
Registering actions derived from the studio configuration to be accessible in the launcher
It is debatable where to call actions.register_defaullt_actions
and actions.register_config_actions
. This is entirely based on the approach of calling the launcher.
Option 1
Do this in the __init__
module but this would mean it would not be relying on avalon.pipeline.find_config
but on the os.environ
.
Option 2
Call the functions in the Application.__init__
method of the launcher but this would require deregister_actions
for both default and config related actions. The plus side of this approach would be that the user can call the launcher from python without the need of first
At Colorbleed we want the user to be able to start a Fusion Render Node
from the launcher but the location and specific commands will differ per studio it would be better call a function from within the configuration.
In our actions
module we have use register_config_actions
to checks for a register_launcher_actions
and runs it if found.
Example of register_launcher_actions:
def register_launcher_actions():
"""Register specific actions which should be accessible in the launcher"""
# Register fusion actions
from .fusion import rendernode
pipeline.register_plugin(api.Action, rendernode.FusionRenderNode)
Shorten the time taken to launch an application.
Begin typing to select the "best match", based on both the order of character - e.g. "gr" = "Gravity" - and character content - e.g. "gtsby" = "Great Gatsby".
Use cases
โAs a , I want so that .โ
Operational modes
Gain a better understanding of your (optional) user directory.
Visualise the name of the currently logged on user, potentially provide a drop-down enabling a user to choose being a different user. Such as a shared user, like Mindbender.
Increase awareness of connectivity to Mindbender
Remote artists can sometimes experience issues with connecting to Mindbender, if they for example suffer from severe (500ms+) latency or a slow (<1mbit) connection. We should make this information apparent in the GUI such that they can see and report these numbers to us. I'd also like them to be sent along to Sentry for a full picture of why things go wrong.
Add a little widget in the main GUI with the following..
Reduce clutter for active projects, by letting old/inactive projects and assets disappear from view.
Mindbender has accumulated a few past projects, along with a few misspelled projects and assets. Rather than deleting things, which is dangerous for all sorts of reasons, it's better to simply hide them. That way, no references are broken, there is no need for undo or cautious backups.
project["data"]["visible"] = False # Defaults to True
asset["data"]["visible"] = False
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.