mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 13:24:54 +01:00
feat(ppro): wip publishing from premiere
This commit is contained in:
parent
ba9524d06f
commit
a22ae98ee2
11 changed files with 363 additions and 176 deletions
|
|
@ -1,10 +1,13 @@
|
|||
import os
|
||||
import pyblish.api
|
||||
from avalon import api as avalon
|
||||
from avalon import (
|
||||
io,
|
||||
api as avalon
|
||||
)
|
||||
from pype import api as pype
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from pprint import pformat
|
||||
|
||||
class CollectContextDataFromAport(pyblish.api.ContextPlugin):
|
||||
"""
|
||||
|
|
@ -18,32 +21,36 @@ class CollectContextDataFromAport(pyblish.api.ContextPlugin):
|
|||
|
||||
"""
|
||||
|
||||
label = "Collect Aport Context"
|
||||
label = "AdobeCommunicator Collect Context"
|
||||
order = pyblish.api.CollectorOrder - 0.49
|
||||
|
||||
def process(self, context):
|
||||
|
||||
io.install()
|
||||
# get json paths from data
|
||||
rqst_json_data_path = Path(context.data['rqst_json_data_path'])
|
||||
post_json_data_path = Path(context.data['post_json_data_path'])
|
||||
input_json_path = os.environ.get("AC_PUBLISH_INPATH")
|
||||
output_json_path = os.environ.get("AC_PUBLISH_OUTPATH")
|
||||
|
||||
rqst_json_data_path = Path(input_json_path)
|
||||
post_json_data_path = Path(output_json_path)
|
||||
|
||||
# get avalon session data and convert \ to /
|
||||
session = avalon.session
|
||||
self.log.info(os.environ['AVALON_PROJECTS'])
|
||||
projects = Path(session['AVALON_PROJECTS']).resolve()
|
||||
wd = Path(session['AVALON_WORKDIR']).resolve()
|
||||
session['AVALON_PROJECTS'] = str(projects)
|
||||
session['AVALON_WORKDIR'] = str(wd)
|
||||
_S = avalon.session
|
||||
|
||||
context.data["avalonSession"] = session
|
||||
self.log.debug("avalonSession: {}".format(session))
|
||||
projects = Path(_S["AVALON_PROJECTS"]).resolve()
|
||||
asset = _S["AVALON_ASSET"]
|
||||
workdir = Path(_S["AVALON_WORKDIR"]).resolve()
|
||||
_S["AVALON_PROJECTS"] = str(projects)
|
||||
_S["AVALON_WORKDIR"] = str(workdir)
|
||||
|
||||
context.data["avalonSession"] = _S
|
||||
self.log.info(f"__ avalonSession: `{_S}`")
|
||||
|
||||
# get stagin directory from recieved path to json
|
||||
context.data["stagingDir"] = staging_dir = post_json_data_path.parent
|
||||
context.data["stagingDir"] = post_json_data_path.parent
|
||||
|
||||
# get data from json file recieved
|
||||
with rqst_json_data_path.open(mode='r') as f:
|
||||
context.data['jsonData'] = json_data = json.load(f)
|
||||
context.data["jsonData"] = json_data = json.load(f)
|
||||
assert json_data, "No `data` in json file"
|
||||
|
||||
# get and check host type
|
||||
|
|
@ -51,50 +58,32 @@ class CollectContextDataFromAport(pyblish.api.ContextPlugin):
|
|||
host_version = json_data.get("hostVersion", None)
|
||||
assert host, "No `host` data in json file"
|
||||
assert host_version, "No `hostVersion` data in json file"
|
||||
context.data["host"] = session["AVALON_APP"] = host
|
||||
context.data["host"] = _S["AVALON_APP"] = host
|
||||
context.data["hostVersion"] = \
|
||||
session["AVALON_APP_VERSION"] = host_version
|
||||
_S["AVALON_APP_VERSION"] = host_version
|
||||
|
||||
# register pyblish for filtering of hosts in plugins
|
||||
pyblish.api.deregister_all_hosts()
|
||||
pyblish.api.register_host(host)
|
||||
|
||||
# get path to studio templates
|
||||
templates_dir = os.getenv("PYPE_STUDIO_TEMPLATES", None)
|
||||
assert templates_dir, "Missing `PYPE_STUDIO_TEMPLATES` in os.environ"
|
||||
|
||||
# get presets for host
|
||||
presets_dir = os.path.join(templates_dir, "presets", host)
|
||||
assert os.path.exists(
|
||||
presets_dir), "Required path `{}` doesn't exist".format(presets_dir)
|
||||
|
||||
# load all available preset json files
|
||||
preset_data = dict()
|
||||
for file in os.listdir(presets_dir):
|
||||
name, ext = os.path.splitext(file)
|
||||
with open(os.path.join(presets_dir, file)) as prst:
|
||||
preset_data[name] = json.load(prst)
|
||||
|
||||
context.data['presets'] = preset_data
|
||||
assert preset_data, "No `presets` data in json file"
|
||||
self.log.debug("preset_data: {}".format(preset_data))
|
||||
|
||||
# get current file
|
||||
current_file = json_data.get("currentFile", None)
|
||||
assert current_file, "No `currentFile` data in json file"
|
||||
context.data["currentFile"] = Path(current_file).resolve()
|
||||
|
||||
# get project data from avalon
|
||||
project_data = pype.get_project_data()
|
||||
project_data = io.find_one({'type': 'project'})
|
||||
assert project_data, "No `project_data` data in avalon db"
|
||||
context.data["projectData"] = project_data
|
||||
self.log.debug("project_data: {}".format(project_data))
|
||||
|
||||
# get asset data from avalon and fix all paths
|
||||
asset_data = pype.get_asset_data()
|
||||
asset_data = io.find_one({
|
||||
"type": 'asset',
|
||||
"name": asset
|
||||
})["data"]
|
||||
assert asset_data, "No `asset_data` data in avalon db"
|
||||
asset_data = {k: v.replace("\\", "/") for k, v in asset_data.items()
|
||||
if isinstance(v, str)}
|
||||
|
||||
context.data["assetData"] = asset_data
|
||||
|
||||
self.log.debug("asset_data: {}".format(asset_data))
|
||||
|
|
@ -1,12 +1,5 @@
|
|||
import os
|
||||
import json
|
||||
import pyblish.api
|
||||
from avalon import (
|
||||
io,
|
||||
api as avalon
|
||||
)
|
||||
|
||||
from pype import api as pype
|
||||
|
||||
|
||||
class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
||||
|
|
@ -26,7 +19,11 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
|
||||
def process(self, context):
|
||||
|
||||
a_session = context.data.get("avalonSession")
|
||||
_S = context.data["avalonSession"]
|
||||
asset = _S["AVALON_ASSET"]
|
||||
task = _S["AVALON_TASK"]
|
||||
host = _S["AVALON_APP"]
|
||||
|
||||
json_data = context.data.get("jsonData", None)
|
||||
assert json_data, "No `json_data` data in json file"
|
||||
|
||||
|
|
@ -36,56 +33,49 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
staging_dir = json_data.get("stagingDir", None)
|
||||
assert staging_dir, "No `stagingDir` path in json file"
|
||||
|
||||
presets = context.data["presets"]
|
||||
host = context.data["host"]
|
||||
presets = context.data["presets"][host]
|
||||
|
||||
rules_tasks = presets["rules_tasks"]
|
||||
ftrack_types = rules_tasks["ftrackTypes"]
|
||||
assert ftrack_types, "No `ftrack_types` data in `/templates/presets/[host]/rules_tasks.json` file"
|
||||
assert ftrack_types, ("No `ftrack_types` data in"
|
||||
"`/presets/[host]/rules_tasks.json` file")
|
||||
|
||||
context.data["ftrackTypes"] = ftrack_types
|
||||
|
||||
asset_default = presets["asset_default"]
|
||||
assert asset_default, "No `asset_default` data in `/templates/presets/[host]/asset_default.json` file"
|
||||
|
||||
asset_name = a_session["AVALON_ASSET"]
|
||||
entity = io.find_one({"name": asset_name,
|
||||
"type": "asset"})
|
||||
assert asset_default, ("No `asset_default` data in"
|
||||
"`/presets/[host]/asset_default.json` file")
|
||||
|
||||
# get frame start > first try from asset data
|
||||
frame_start = context.data["assetData"].get("fstart", None)
|
||||
frame_start = context.data["assetData"].get("frameStart", None)
|
||||
if not frame_start:
|
||||
self.log.debug("frame_start not on assetData")
|
||||
# get frame start > second try from parent data
|
||||
frame_start = pype.get_data_hierarchical_attr(entity, "fstart")
|
||||
if not frame_start:
|
||||
self.log.debug("frame_start not on any parent entity")
|
||||
# get frame start > third try from parent data
|
||||
frame_start = asset_default["fstart"]
|
||||
self.log.debug("frame_start not on any parent entity")
|
||||
# get frame start > third try from parent data
|
||||
frame_start = asset_default["frameStart"]
|
||||
|
||||
assert frame_start, "No `frame_start` data found, "
|
||||
"please set `fstart` on asset"
|
||||
self.log.debug("frame_start: `{}`".format(frame_start))
|
||||
|
||||
# get handles > first try from asset data
|
||||
handles = context.data["assetData"].get("handles", None)
|
||||
if not handles:
|
||||
handle_start = context.data["assetData"].get("handleStart", None)
|
||||
handle_end = context.data["assetData"].get("handleEnd", None)
|
||||
if not all([handle_start, handle_end]):
|
||||
# get frame start > second try from parent data
|
||||
handles = pype.get_data_hierarchical_attr(entity, "handles")
|
||||
if not handles:
|
||||
# get frame start > third try from parent data
|
||||
handles = asset_default["handles"]
|
||||
handle_start = asset_default["handleStart"]
|
||||
handle_end = asset_default["handleEnd"]
|
||||
|
||||
assert handles, "No `handles` data found, "
|
||||
"please set `fstart` on asset"
|
||||
self.log.debug("handles: `{}`".format(handles))
|
||||
assert all([
|
||||
handle_start,
|
||||
handle_end]), ("No `handle_start, handle_end` data found")
|
||||
|
||||
instances = []
|
||||
|
||||
task = a_session["AVALON_TASK"]
|
||||
current_file = os.path.basename(context.data.get("currentFile"))
|
||||
name, ext = os.path.splitext(current_file)
|
||||
|
||||
# get current file host
|
||||
host = a_session["AVALON_APP"]
|
||||
family = "projectfile"
|
||||
families = "filesave"
|
||||
subset_name = "{0}{1}".format(task, 'Default')
|
||||
|
|
@ -109,7 +99,7 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
"task": task,
|
||||
"representation": ext[1:],
|
||||
"host": host,
|
||||
"asset": asset_name,
|
||||
"asset": asset,
|
||||
"label": label,
|
||||
"name": name,
|
||||
# "hierarchy": hierarchy,
|
||||
|
|
@ -152,6 +142,7 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
tasks = [t["task"] for t in tags
|
||||
if t.get("task")]
|
||||
else:
|
||||
self.log.debug("defaultTasks: `{}`".format(rules_tasks["defaultTasks"]))
|
||||
tasks = rules_tasks["defaultTasks"]
|
||||
self.log.debug("tasks: `{}`".format(tasks))
|
||||
|
||||
|
|
@ -197,7 +188,7 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
family = subset
|
||||
subset_name = "{0}{1}".format(subset, "Main")
|
||||
elif "reference" in subset:
|
||||
family ="render"
|
||||
family = "render"
|
||||
subset_name = "{0}{1}".format(family, "Reference")
|
||||
else:
|
||||
subset_name = "{0}{1}".format(subset, 'Default')
|
||||
|
|
@ -218,7 +209,8 @@ class CollectInstancesFromJson(pyblish.api.ContextPlugin):
|
|||
"tasks": subset_dict[subset],
|
||||
"taskTypes": inst['tasksTypes'],
|
||||
"fstart": frame_start,
|
||||
"handles": handles,
|
||||
"handleStart": handle_start,
|
||||
"handleEnd": handle_end,
|
||||
"host": host,
|
||||
"asset": asset,
|
||||
"hierarchy": hierarchy,
|
||||
|
|
@ -42,8 +42,6 @@ if os.getenv("PUBLISH_PATH", None):
|
|||
)
|
||||
else:
|
||||
os.environ["PUBLISH_PATH"] = self.PUBLISH_PATH
|
||||
log.debug("PUBLISH_PATH: `{}`".format(os.environ["PUBLISH_PATH"]))
|
||||
|
||||
|
||||
_clearing_cache = ["com.pype", "com.pype.rename"]
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ function convertPathString (path) {
|
|||
new RegExp('\\\\', 'g'), '/').replace(new RegExp('//\\?/', 'g'), '');
|
||||
}
|
||||
|
||||
function publish () {
|
||||
function _publish () {
|
||||
var $ = querySelector('#publish');
|
||||
// var gui = $.querySelector('input[name=gui]').checked;
|
||||
var gui = true;
|
||||
|
|
@ -213,16 +213,26 @@ function publish () {
|
|||
setTimeout(function () {
|
||||
if (fs.existsSync(path)) {
|
||||
displayResult('path were rendered: ' + path);
|
||||
// register publish path
|
||||
pras.register_plugin_path(publishPath).then(displayResult);
|
||||
// send json to pyblish
|
||||
pras.publish(jsonSendPath, jsonGetPath, gui).then(function (result) {
|
||||
var dataToPublish = {
|
||||
"adobePublishJsonPathSend": jsonSendPath,
|
||||
"adobePublishJsonPathGet": jsonGetPath,
|
||||
"gui": gui,
|
||||
"publishPath": publishPath,
|
||||
"project": _pype.ENV.AVALON_PROJECT,
|
||||
"asset": _pype.ENV.AVALON_ASSET,
|
||||
"task": _pype.ENV.AVALON_TASK,
|
||||
"workdir": _pype.ENV.AVALON_WORKDIR
|
||||
}
|
||||
pras.publish(dataToPublish).then(function (result) {
|
||||
displayResult(
|
||||
'pype.js:publish < pras.publish: ' + JSON.stringify(result));
|
||||
// check if resulted path exists as file
|
||||
if (fs.existsSync(result.get_json_path)) {
|
||||
if (fs.existsSync(result.return_data_path)) {
|
||||
// read json data from resulted path
|
||||
displayResult('Updating metadata of clips after publishing');
|
||||
|
||||
jsonfile.readFile(result.get_json_path, function (json) {
|
||||
jsonfile.readFile(result.return_data_path, function (json) {
|
||||
_pype.csi.evalScript('$.pype.dumpPublishedInstancesToMetadata(' + JSON.stringify(json) + ');');
|
||||
});
|
||||
|
||||
|
|
@ -336,7 +346,7 @@ $('#btn-deregister').click(function () {
|
|||
});
|
||||
|
||||
$('#btn-publish').click(function () {
|
||||
publish();
|
||||
_publish();
|
||||
});
|
||||
|
||||
$('#btn-send-reset').click(function () {
|
||||
|
|
@ -396,7 +406,15 @@ $('#btn-newWorkfileVersion').click(function () {
|
|||
});
|
||||
|
||||
$('#btn-testing').click(function () {
|
||||
pras.get_presets(_pype.ENV.AVALON_PROJECT);
|
||||
var data = {
|
||||
"adobePublishJsonPathSend": "C:/Users/jezsc/_PYPE_testing/testing_data/premiere/95478408-91ee-4522-81f6-f1689060664f_send.json",
|
||||
"adobePublishJsonPathGet": "C:/Users/jezsc/_PYPE_testing/testing_data/premiere/95478408-91ee-4522-81f6-f1689060664f_get.json",
|
||||
"gui": true,
|
||||
"project": "J01_jakub_test",
|
||||
"asset": "editorial",
|
||||
"task": "conforming"
|
||||
}
|
||||
pras.publish(data);
|
||||
});
|
||||
|
||||
_pype.getEnv();
|
||||
|
|
|
|||
|
|
@ -11,33 +11,39 @@ var pras = {
|
|||
var url = _pype.ENV.PYPE_REST_API_URL;
|
||||
return url
|
||||
},
|
||||
getRequestFromRestApiServer: function (url, callback) {
|
||||
getRequestFromRestApiServer: function (url, options, callback) {
|
||||
_pype.displayResult('url: ' + url);
|
||||
_pype.displayResult('options: ' + JSON.stringify(options));
|
||||
|
||||
// define options in case there is null comming
|
||||
if (options === null) {
|
||||
options = {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
}
|
||||
_pype.displayResult('options: ' + JSON.stringify(options));
|
||||
|
||||
// send post request to rest api server
|
||||
fetch(url)
|
||||
.then(res => {
|
||||
try {
|
||||
return res.json();
|
||||
} catch(e) {
|
||||
return res.text();
|
||||
}
|
||||
})
|
||||
.then(json => {
|
||||
if (isPypeData(json)) {
|
||||
_pype.displayResult(
|
||||
'json: ' + JSON.stringify(json.data));
|
||||
fetch(url, options).then(res => {
|
||||
try {
|
||||
return res.json();
|
||||
} catch (e) {
|
||||
return res.text();
|
||||
}
|
||||
}).then(json => {
|
||||
if (isPypeData(json)) {
|
||||
_pype.displayResult('json: ' + JSON.stringify(json.data));
|
||||
|
||||
// send it to callback function
|
||||
callback(json.data);
|
||||
} else {
|
||||
_pype.displayError(
|
||||
'Data comming from `{url}` are not correct'.format({url: url}));
|
||||
callback(null)
|
||||
}
|
||||
})
|
||||
.catch(err => _pype.displayError(
|
||||
'Data comming from `{url}` are not correct.\n\nError: {error}'.format({url: url, error: err}))
|
||||
);
|
||||
// send it to callback function
|
||||
callback(json.data);
|
||||
} else {
|
||||
_pype.displayError('Data comming from `{url}` are not correct'.format({url: url}));
|
||||
callback(null)
|
||||
}
|
||||
}).catch(err => _pype.displayError('Data comming from `{url}` are not correct.\n\nError: {error}'.format({url: url, error: err})));
|
||||
},
|
||||
load_representations: function (projectName, requestList) {
|
||||
// preparation for getting representations from api server
|
||||
|
|
@ -46,50 +52,55 @@ var pras = {
|
|||
},
|
||||
get_presets: function (projectName, callback) {
|
||||
var template = '{serverUrl}/adobe/presets/{projectName}';
|
||||
var url = template.format({
|
||||
serverUrl: pras.getApiServerUrl(),
|
||||
projectName: projectName,
|
||||
});
|
||||
var url = template.format({serverUrl: pras.getApiServerUrl(), projectName: projectName});
|
||||
_pype.displayResult(url);
|
||||
|
||||
// send request to server
|
||||
pras.getRequestFromRestApiServer(url, function (result) {
|
||||
pras.getRequestFromRestApiServer(url, options = null, function (result) {
|
||||
if (result === null) {
|
||||
_pype.displayError(
|
||||
'No data for `{projectName}` project in database'.format(
|
||||
{projectName: projectName}));
|
||||
_pype.displayError('No data for `{projectName}` project in database'.format({projectName: projectName}));
|
||||
return null
|
||||
} else {
|
||||
// send the data into jsx and write to module's global variable
|
||||
_pype.csi.evalScript(
|
||||
'$.pype.setProjectPreset(' + JSON.stringify(result) + ');',
|
||||
function (resultBack) {
|
||||
_pype.displayResult(
|
||||
'$.pype.setProjectPreset(): ' + resultBack);
|
||||
callback(resultBack);
|
||||
// test the returning presets data from jsx if they are there
|
||||
// _pype.csi.evalScript(
|
||||
// '$.pype.getProjectPreset();',
|
||||
// function (resultedPresets) {
|
||||
// _pype.displayResult(
|
||||
// '$.pype.getProjectPreset(): ' + resultedPresets);
|
||||
// });
|
||||
_pype.csi.evalScript('$.pype.setProjectPreset(' + JSON.stringify(result) + ');', function (resultBack) {
|
||||
_pype.displayResult('$.pype.setProjectPreset(): ' + resultBack);
|
||||
callback(resultBack);
|
||||
// test the returning presets data from jsx if they are there
|
||||
// _pype.csi.evalScript(
|
||||
// '$.pype.getProjectPreset();',
|
||||
// function (resultedPresets) {
|
||||
// _pype.displayResult(
|
||||
// '$.pype.getProjectPreset(): ' + resultedPresets);
|
||||
// });
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
register_plugin_path: function (publishPath) {
|
||||
_pype.displayResult('_ publishPath: ' + publishPath);
|
||||
// preparation for getting representations from api server
|
||||
},
|
||||
deregister_plugin_path: function () {
|
||||
// preparation for getting representations from api server
|
||||
},
|
||||
publish: function (jsonSendPath, jsonGetPath, gui) {
|
||||
// preparation for publishing with rest api server
|
||||
_pype.displayResult('__ publish:jsonSendPath: ' + jsonSendPath);
|
||||
_pype.displayResult('__ publish:jsonGetPath ' + jsonGetPath);
|
||||
_pype.displayResult('__ publish:gui ' + gui);
|
||||
publish: function (data) {
|
||||
var template = '{serverUrl}/adobe/publish';
|
||||
var url = template.format({serverUrl: pras.getApiServerUrl()});
|
||||
var _options = {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
_pype.displayResult('__ publish:url ' + url);
|
||||
_pype.displayResult('__ publish:_options ' + JSON.stringify(_options));
|
||||
|
||||
// publish data with rest api server
|
||||
pras.getRequestFromRestApiServer(url, _options, function (result) {
|
||||
if (result === null) {
|
||||
_pype.displayError('No data for `{projectName}` project in database'.format({projectName: projectName}));
|
||||
return null
|
||||
} else {
|
||||
_pype.displayResult('pras.publish.getRequestFromRestApiServer: ' + JSON.stringify(result));
|
||||
return result
|
||||
}
|
||||
// preparation for publishing with rest api server
|
||||
|
||||
});
|
||||
},
|
||||
context: function (project, asset, task, app) {
|
||||
// getting context of project
|
||||
|
|
@ -97,24 +108,23 @@ var pras = {
|
|||
};
|
||||
|
||||
String.prototype.format = function (arguments) {
|
||||
var this_string = '';
|
||||
for (var char_pos = 0; char_pos < this.length; char_pos++) {
|
||||
this_string = this_string + this[char_pos];
|
||||
}
|
||||
var this_string = '';
|
||||
for (var char_pos = 0; char_pos < this.length; char_pos++) {
|
||||
this_string = this_string + this[char_pos];
|
||||
}
|
||||
|
||||
for (var key in arguments) {
|
||||
var string_key = '{' + key + '}'
|
||||
this_string = this_string.replace(new RegExp(string_key, 'g'), arguments[key]);
|
||||
}
|
||||
return this_string;
|
||||
for (var key in arguments) {
|
||||
var string_key = '{' + key + '}'
|
||||
this_string = this_string.replace(new RegExp(string_key, 'g'), arguments[key]);
|
||||
}
|
||||
return this_string;
|
||||
};
|
||||
|
||||
function isPypeData(v) {
|
||||
try{
|
||||
return Object.prototype.hasOwnProperty.call(
|
||||
v, 'success');
|
||||
} catch(e){
|
||||
/*console.error("not a dict",e);*/
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return Object.prototype.hasOwnProperty.call(v, 'success');
|
||||
} catch (e) {
|
||||
/* console.error("not a dict",e); */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
from .lib import PUBLISH_PATHS
|
||||
|
||||
from .adobe_comunicator import AdobeCommunicator
|
||||
|
||||
__all__ = [
|
||||
"PUBLISH_PATHS"
|
||||
]
|
||||
|
||||
|
||||
def tray_init(tray_widget, main_widget):
|
||||
return AdobeCommunicator()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import os
|
||||
import pype
|
||||
from pypeapp import config, Logger
|
||||
from . import PUBLISH_PATHS
|
||||
|
||||
log = Logger().get_logger("AdobeCommunicator")
|
||||
|
||||
|
|
@ -18,6 +20,12 @@ class AdobeCommunicator:
|
|||
" Using defaults \"{}\""
|
||||
).format(str(self.presets)))
|
||||
|
||||
# solve publish paths
|
||||
PUBLISH_PATHS.clear()
|
||||
PUBLISH_PATHS.append(os.path.sep.join(
|
||||
[pype.PLUGINS_DIR, "adobecommunicator", "publish"]
|
||||
))
|
||||
|
||||
def tray_start(self):
|
||||
return
|
||||
|
||||
|
|
@ -26,6 +34,14 @@ class AdobeCommunicator:
|
|||
if rest_api_module:
|
||||
self.rest_api_registration(rest_api_module)
|
||||
|
||||
# adding ftrack publish path
|
||||
if "FtrackModule" in modules:
|
||||
PUBLISH_PATHS.append(os.path.sep.join(
|
||||
[pype.PLUGINS_DIR, "ftrack", "publish"]
|
||||
))
|
||||
log.info((f"Adobe Communicator Registered PUBLISH_PATHS"
|
||||
f"> `{PUBLISH_PATHS}`"))
|
||||
|
||||
def rest_api_registration(self, module):
|
||||
for prefix, static_path in self.presets["statics"].items():
|
||||
static_path = static_path.format(
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
from .publishing import PUBLISH_PATHS
|
||||
from .lib import AdobeRestApi
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@ import bson
|
|||
import bson.json_util
|
||||
from pype.services.rest_api import RestApi, abort, CallbackResult
|
||||
from .io_nonsingleton import DbConnector
|
||||
from pypeapp import config
|
||||
from .publishing import run_publish, set_context
|
||||
|
||||
from pypeapp import config, Logger
|
||||
|
||||
|
||||
log = Logger().get_logger("AdobeCommunicator")
|
||||
|
||||
|
||||
class AdobeRestApi(RestApi):
|
||||
|
|
@ -15,7 +20,9 @@ class AdobeRestApi(RestApi):
|
|||
super().__init__(*args, **kwargs)
|
||||
self.dbcon.install()
|
||||
|
||||
@RestApi.route("/projects/<project_name>", url_prefix="/adobe", methods="GET")
|
||||
@RestApi.route("/projects/<project_name>",
|
||||
url_prefix="/adobe",
|
||||
methods="GET")
|
||||
def get_project(self, request):
|
||||
project_name = request.url_data["project_name"]
|
||||
if not project_name:
|
||||
|
|
@ -54,7 +61,7 @@ class AdobeRestApi(RestApi):
|
|||
|
||||
project = self.dbcon[project_name].find_one({"type": "project"})
|
||||
presets = config.get_presets(project=project["name"])
|
||||
|
||||
|
||||
if presets:
|
||||
return CallbackResult(data=self.result_to_json(presets))
|
||||
|
||||
|
|
@ -93,22 +100,26 @@ class AdobeRestApi(RestApi):
|
|||
_asset, identificator, _project_name
|
||||
))
|
||||
|
||||
@RestApi.route("/publish/<asset_name>", url_prefix="/adobe", methods="GET")
|
||||
@RestApi.route("/publish", url_prefix="/adobe", methods="POST")
|
||||
def publish(self, request):
|
||||
"""
|
||||
http://localhost:8021/premiere/publish/shot021?json_in=this/path/file_in.json&json_out=this/path/file_out.json
|
||||
http://localhost:8021/adobe/publish
|
||||
"""
|
||||
asset_name = request.url_data["asset_name"]
|
||||
query = request.query
|
||||
data = request.request_data
|
||||
|
||||
output = {
|
||||
"message": "Got your data. Thanks.",
|
||||
"your_data": data,
|
||||
"your_query": query,
|
||||
"your_asset_is": asset_name
|
||||
}
|
||||
return CallbackResult(data=self.result_to_json(output))
|
||||
log.info('Pyblish is running')
|
||||
try:
|
||||
set_context(
|
||||
self.dbcon,
|
||||
data,
|
||||
'adobecommunicator'
|
||||
)
|
||||
result = run_publish(data)
|
||||
|
||||
if result:
|
||||
return CallbackResult(data=self.result_to_json(result))
|
||||
finally:
|
||||
log.info('Pyblish have stopped')
|
||||
|
||||
def result_to_json(self, result):
|
||||
""" Converts result of MongoDB query to dict without $oid (ObjectId)
|
||||
|
|
|
|||
146
pype/services/adobe_communicator/lib/publishing.py
Normal file
146
pype/services/adobe_communicator/lib/publishing.py
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import tempfile
|
||||
import random
|
||||
import string
|
||||
from avalon import api
|
||||
import pype
|
||||
from pypeapp import execute
|
||||
import pyblish.api
|
||||
from pypeapp import Logger
|
||||
from pprint import pformat
|
||||
log = Logger().get_logger(__name__)
|
||||
|
||||
PUBLISH_PATHS = []
|
||||
|
||||
self = sys.modules[__name__]
|
||||
self.dbcon = False
|
||||
|
||||
|
||||
def set_context(dbcon_in, data, app):
|
||||
''' Sets context for pyblish (must be done before pyblish is launched)
|
||||
:param project: Name of `Project` where instance should be published
|
||||
:type project: str
|
||||
:param asset: Name of `Asset` where instance should be published
|
||||
:type asset: str
|
||||
'''
|
||||
self.dbcon = dbcon_in
|
||||
S = self.dbcon.Session
|
||||
project = data["project"]
|
||||
os.environ["AVALON_PROJECT"] = project
|
||||
S["AVALON_PROJECT"] = project
|
||||
|
||||
asset = data["asset"]
|
||||
os.environ["AVALON_ASSET"] = asset
|
||||
|
||||
self.dbcon.install()
|
||||
av_project = self.dbcon.find_one({'type': 'project'})
|
||||
av_asset = self.dbcon.find_one({
|
||||
"type": 'asset',
|
||||
"name": asset
|
||||
})
|
||||
parents = av_asset['data']['parents']
|
||||
log.debug(f"__ session: {av_asset}")
|
||||
log.debug(f"__ session: {parents}")
|
||||
hierarchy = ''
|
||||
if parents and len(parents) > 0:
|
||||
hierarchy = os.path.sep.join(parents)
|
||||
self.dbcon.uninstall()
|
||||
|
||||
os.environ["AVALON_TASK"] = data["task"]
|
||||
os.environ["AVALON_WORKDIR"] = data["workdir"]
|
||||
os.environ["AVALON_HIERARCHY"] = hierarchy
|
||||
os.environ["AVALON_PROJECTCODE"] = av_project['data'].get('code', '')
|
||||
os.environ["AVALON_APP"] = app
|
||||
|
||||
self.dbcon.install()
|
||||
S["current_dir"] = os.path.normpath(os.getcwd())
|
||||
log.debug(f"__ session: {S}")
|
||||
|
||||
self.dbcon.uninstall()
|
||||
|
||||
|
||||
def run_publish(data, gui=True):
|
||||
# cli pyblish seems like better solution
|
||||
return cli_publish(data, gui)
|
||||
|
||||
|
||||
def cli_publish(data, gui=True):
|
||||
self.dbcon.install()
|
||||
S = self.dbcon.Session
|
||||
# unregister previouse plugins
|
||||
pyblish.api.deregister_all_plugins()
|
||||
|
||||
# Registers Global pyblish plugins
|
||||
pype.install()
|
||||
|
||||
if data.get("publishPath"):
|
||||
PUBLISH_PATHS.append(data.get("publishPath"))
|
||||
|
||||
# Registers AdobeCommunicator pyblish plugins
|
||||
for path in PUBLISH_PATHS:
|
||||
pyblish.api.register_plugin_path(path)
|
||||
|
||||
project_plugins_paths = os.environ.get("PYPE_PROJECT_PLUGINS")
|
||||
project_name = os.environ["AVALON_PROJECT"]
|
||||
if project_plugins_paths and project_name:
|
||||
for path in project_plugins_paths.split(os.pathsep):
|
||||
if not path:
|
||||
continue
|
||||
plugin_path = os.path.join(path, project_name, "plugins")
|
||||
if os.path.exists(plugin_path):
|
||||
pyblish.api.register_plugin_path(plugin_path)
|
||||
api.register_plugin_path(api.Loader, plugin_path)
|
||||
api.register_plugin_path(api.Creator, plugin_path)
|
||||
|
||||
if data.get("adobePublishJsonPathGet"):
|
||||
return_data_path = data.get("adobePublishJsonPathGet")
|
||||
else:
|
||||
# Create hash name folder in temp
|
||||
chars = "".join([random.choice(string.ascii_letters)
|
||||
for i in range(15)])
|
||||
staging_dir = tempfile.mkdtemp(chars)
|
||||
|
||||
# create json for return data
|
||||
return_data_path = (
|
||||
staging_dir + os.path.basename(staging_dir) + 'return.json'
|
||||
)
|
||||
|
||||
if data.get("adobePublishJsonPathSend"):
|
||||
json_data_path = data.get("adobePublishJsonPathSend")
|
||||
else:
|
||||
# create also json and fill with data
|
||||
json_data_path = staging_dir + os.path.basename(staging_dir) + '.json'
|
||||
with open(json_data_path, 'w') as outfile:
|
||||
json.dump(data, outfile)
|
||||
|
||||
args = [
|
||||
"-pp", os.pathsep.join(pyblish.api.registered_paths())
|
||||
]
|
||||
|
||||
if gui:
|
||||
args += ["gui"]
|
||||
|
||||
envcopy = os.environ.copy()
|
||||
envcopy["PYBLISH_HOSTS"] = "adobecommunicator"
|
||||
envcopy["AC_PUBLISH_INPATH"] = json_data_path
|
||||
envcopy["AC_PUBLISH_OUTPATH"] = return_data_path
|
||||
envcopy["PYBLISH_GUI"] = "pyblish_lite"
|
||||
|
||||
# print testing env
|
||||
for k, v in envcopy.items():
|
||||
if ("AVALON" in k) or ("PYPE" in k):
|
||||
log.debug(f"env: {k}: {v}")
|
||||
|
||||
log.debug(f"__ session: {S}")
|
||||
|
||||
while not execute(
|
||||
[sys.executable, "-u", "-m", "pyblish"] + args, env=envcopy):
|
||||
self.dbcon.uninstall()
|
||||
|
||||
# check if data are returned back
|
||||
if os.path.exists(return_data_path):
|
||||
return {"return_data_path": return_data_path}
|
||||
else:
|
||||
return False
|
||||
Loading…
Add table
Add a link
Reference in a new issue