Skip to content
This repository has been archived by the owner on Oct 10, 2024. It is now read-only.

Optionally add task to subset name #288

Merged
merged 11 commits into from
Mar 3, 2021
11 changes: 11 additions & 0 deletions avalon/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,17 @@ def __init__(self, name, asset, options=None, data=None):

self.data.update(data or {})

@classmethod
def get_subset_name(
cls, user_text, task_name, asset_id, project_name, host_name=None
):
# Capitalize first letter of user input
if user_text:
user_text = user_text[0].capitalize() + user_text[1:]

family = cls.family.rsplit(".", 1)[-1]
return "{}{}".format(family, user_text)

def process(self):
pass

Expand Down
129 changes: 70 additions & 59 deletions avalon/tools/creator/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@

Separator = "---separator---"

# TODO regex should be defined by schema
SubsetAllowedSymbols = "a-zA-Z0-9_."


class SubsetNameValidator(QtGui.QRegExpValidator):

invalid = QtCore.Signal(set)
pattern = "^[a-zA-Z0-9_.]*$"
pattern = "^[{}]*$".format(SubsetAllowedSymbols)

def __init__(self):
reg = QtCore.QRegExp(self.pattern)
Expand Down Expand Up @@ -118,7 +121,6 @@ def _set_status_color(self, color):
class Window(QtWidgets.QDialog):

stateChanged = QtCore.Signal(bool)
taskSubsetFamilies = ["render"]

def __init__(self, parent=None):
super(Window, self).__init__(parent)
Expand Down Expand Up @@ -280,14 +282,13 @@ def _on_action_clicked(self, action):
name.setText(action.text())

def _on_data_changed(self):

listing = self.data["Listing"]
asset_name = self.data["Asset"]
subset = self.data["Subset"]
result = self.data["Result"]

item = listing.currentItem()
subset_name = subset.text()
user_input_text = subset.text()
asset_name = asset_name.text()

# Early exit if no asset name
Expand All @@ -299,77 +300,87 @@ def _on_data_changed(self):
return

# Get the asset from the database which match with the name
asset = io.find_one({"name": asset_name, "type": "asset"},
projection={"_id": 1})
asset_doc = io.find_one(
{"name": asset_name, "type": "asset"},
projection={"_id": 1}
)
# Get plugin
plugin = item.data(PluginRole)

if asset and plugin:
# Get family
family = plugin.family.rsplit(".", 1)[-1]
regex = "{}*".format(family)
existed_subset_split = family

if family in self.taskSubsetFamilies:
task = io.Session.get('AVALON_TASK', '')
sanitized_task = re.sub('[^0-9a-zA-Z]+', '', task)
regex = "{}{}*".format(
family,
sanitized_task.capitalize()
)
existed_subset_split = "{}{}".format(
family,
sanitized_task.capitalize()
)
if asset_doc and plugin:
project_name = io.Session["AVALON_PROJECT"]
asset_id = asset_doc["_id"]
task_name = io.Session["AVALON_TASK"]

# Calculate subset name with Creator plugin
subset_name = plugin.get_subset_name(
user_input_text, task_name, asset_id, project_name
)
# Force replacement of prohibited symbols
# QUESTION should Creator care about this and here should be only
# validated with schema regex?
subset_name = re.sub(
"[^{}]+".format(SubsetAllowedSymbols),
"",
subset_name
)
result.setText(subset_name)

# Get all subsets of the current asset
subsets = io.find(filter={"type": "subset",
"name": {"$regex": regex,
"$options": "i"},
"parent": asset["_id"]}) or []

# Get all subsets' their subset name, "Default", "High", "Low"
existed_subsets = [sub["name"].split(existed_subset_split)[-1]
for sub in subsets]

if plugin.defaults and isinstance(plugin.defaults, list):
defaults = plugin.defaults[:] + [Separator]
lowered = [d.lower() for d in plugin.defaults]
for sub in [s for s in existed_subsets
if s.lower() not in lowered]:
defaults.append(sub)
else:
defaults = existed_subsets
subset_docs = io.find(
{
"type": "subset",
"parent": asset_id
},
{"name": 1}
)
existing_subset_names = set(subset_docs.distinct("name"))
existing_subset_names_low = set(
_name.lower()
for _name in existing_subset_names
)

# Defaults to dropdown
defaults = []
# Check if Creator plugin has set defaults
if (
plugin.defaults
and isinstance(plugin.defaults, (list, tuple, set))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break before binary operator

):
defaults = list(plugin.defaults)

# Replace
compare_regex = re.compile(
subset_name.replace(user_input_text, "(.+)")
)
subset_hints = set()
if user_input_text:
for _name in existing_subset_names:
_result = compare_regex.search(_name)
if _result:
subset_hints |= set(_result.groups())

subset_hints = subset_hints - set(defaults)
if subset_hints:
if defaults:
defaults.append(Separator)
defaults.extend(subset_hints)
self._build_menu(defaults)

# Update the result
if subset_name:
subset_name = subset_name[0].upper() + subset_name[1:]

if family in self.taskSubsetFamilies:
result.setText("{}{}{}".format(
family,
sanitized_task.capitalize(),
subset_name
))
else:
result.setText("{}{}".format(
family,
subset_name
))

# Indicate subset existence
if not subset_name:
if not user_input_text:
subset.as_empty()
elif subset_name in existed_subsets:
elif subset_name.lower() in existing_subset_names_low:
# validate existence of subset name with lowered text
# - "renderMain" vs. "rensermain" mean same path item for
# windows
subset.as_exists()
else:
subset.as_new()

item.setData(ExistsRole, True)

else:
subset_name = user_input_text
self._build_menu([])
item.setData(ExistsRole, False)

Expand Down
13 changes: 5 additions & 8 deletions avalon/tools/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,21 @@ def ItemClass(self):
return self.item_class
return Item

def rowCount(self, parent):
if parent.isValid():
item = parent.internalPointer()
def rowCount(self, parent=None):
if parent is None or not parent.isValid():
parent_item = self._root_item
else:
item = self._root_item

return item.childCount()
parent_item = parent.internalPointer()
return parent_item.childCount()

def columnCount(self, parent):
return len(self.Columns)

def data(self, index, role):

if not index.isValid():
return None

if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:

item = index.internalPointer()
column = index.column()

Expand Down