Skip to content

Commit

Permalink
Merge pull request #116 from masqu3rad3/107-ability-to-have-templated…
Browse files Browse the repository at this point in the history
…-files

107 ability to have templated files
  • Loading branch information
masqu3rad3 authored Jun 8, 2024
2 parents 3dccdfd + b5cce46 commit 1de09a8
Show file tree
Hide file tree
Showing 21 changed files with 296 additions and 13 deletions.
16 changes: 15 additions & 1 deletion tik_manager4/dcc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import os
from importlib import reload

EXTENSION_DICT = {
"3dsmax": [".max"],
"blender": [".blend"],
"gaffer": [".gfr"],
"houdini": [".hip", ".hipnc", ".hiplc"],
"katana": [".katana"],
"mari": [".mri"],
"maya": [".ma", ".mb"],
"nuke": [".nk"],
"photoshop": [".psd", ".psb"],
"standalone": [".*"],
"substance": [".spp"],
"trigger": [".trg"]
}

NAME = os.getenv("TIK_DCC").lower()

Expand Down
43 changes: 42 additions & 1 deletion tik_manager4/objects/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def is_empty(self):

def create_work_from_path(self, name, file_path, notes="", ignore_checks=True):
"""Register a given path (file or folder) as a work"""

_ignore_checks = ignore_checks
constructed_name = self.construct_name(name)
# creating work from an arbitrary path is always considered as a 'standalone' process
abs_path = self.get_abs_database_path("standalone", f"{constructed_name}.twork")
Expand Down Expand Up @@ -92,6 +92,47 @@ def create_work_from_path(self, name, file_path, notes="", ignore_checks=True):
work.new_version_from_path(file_path=file_path, notes=notes)
return work

def create_work_from_template(self, name, template_file, dcc, notes="", ignore_checks=True):
""" Creates a task under the category.
Args:
name (str): Name of the work
template_file (str): Path to the template file
dcc (str): DCC name.
notes (str): Notes for the work
ignore_checks (bool): Ignore the checks for the work creation
Returns:
tik_manager4.objects.work: Work object
"""
_ignore_checks = ignore_checks
constructed_name = self.construct_name(name)
abs_path = self.get_abs_database_path(dcc, f"{constructed_name}.twork")

if Path(abs_path).exists():
# in that case instantiate the work and iterate the version.
work = Work(absolute_path=abs_path, parent_task=self.parent_task)
work.new_version_from_path(file_path=template_file, notes=notes)
return work

relative_path = self.get_relative_work_path(override_dcc=dcc)
work = Work(abs_path, name=constructed_name, path=relative_path, parent_task=self.parent_task)

work.add_property("name", constructed_name)
work.add_property("creator", self.guard.user)
work.add_property("category", self.name)
work.add_property("dcc", dcc)
work.add_property("dcc_version", "NA")
work.add_property("versions", [])
work.add_property("work_id", work.generate_id())
work.add_property("task_name", self.parent_task.name)
work.add_property("task_id", self.parent_task.id)
work.add_property("path", relative_path)
work.add_property("state", "working")
work.init_properties()
work.new_version_from_path(file_path=template_file, notes=notes)
return work

def create_work(self, name, file_format=None, notes="", ignore_checks=True):
"""Creates a task under the category"""

Expand Down
52 changes: 52 additions & 0 deletions tik_manager4/objects/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,55 @@ def set_project(self, absolute_path):
self.user.add_recent_project(absolute_path)
self.user.last_project = absolute_path
self.dcc.set_project(absolute_path)

def collect_template_paths(self):
"""Collect all template files from common, project and user folders."""
# if the dcc is standalone, collect all applicable extensions from the extension dictionary
# otherwise, collect the extensions from the dcc object
if self.dcc.name.lower() == "standalone":
extensions = [ext for ext_list in dcc.EXTENSION_DICT.values() for ext in ext_list]
else:
extensions = self.dcc.formats
user_templates = [p for p in Path(self.user.settings.get("user_templates_directory")).rglob("*.*") if
p.suffix in extensions]
project_templates = [p for p in Path(self.project.absolute_path).joinpath("_templates").rglob("*.*") if
p.suffix in extensions]
common_templates = [p for p in Path(self.user.common_directory).joinpath("_templates").rglob("*.*") if
p.suffix in extensions]
# user_templates = list(Path(self.user.settings.get("user_templates_directory")).rglob("*.*"))
# project_templates = list((Path(self.project.absolute_path)/"_templates").rglob("*.*"))
# common_templates = list((Path(self.user.common_directory)/"_templates").rglob("*.*"))

return project_templates + common_templates + user_templates

def get_template_names(self):
"""Get the names of the templates."""
all_templates = self.collect_template_paths()
return list(set([template.stem for template in all_templates]))

def get_template_path_by_name(self, name):
"""Gets the template file by name.
Resolution order is project > common > user.
Args:
name (str): Name of the template.
Returns:
tuple: Dcc Name, Path to the template file.
"""
all_templates = self.collect_template_paths()
for template_path in all_templates:
if template_path.stem == name:
dcc_name = self.__resolve_dcc_name_from_extension(template_path.suffix)
return dcc_name, template_path.as_posix()

return None, None

def __resolve_dcc_name_from_extension(self, extension):
"""Resolve the DCC name from the extension."""
for key, value in dcc.EXTENSION_DICT.items():
if extension in value:
return key
# for anything else, return standalone
return "standalone"
2 changes: 1 addition & 1 deletion tik_manager4/objects/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ def _validate_user_data(self):
"""Finds or creates user directories and files"""

_user_root = utils.get_home_dir()
# self.user_directory = str((Path(_user_root, "TikManager4").mkdir(exist_ok=True)))
_user_dir = Path(_user_root, "TikManager4")
_user_dir.mkdir(exist_ok=True)
self.user_directory = str(_user_dir)
Expand Down Expand Up @@ -212,6 +211,7 @@ def _validate_user_data(self):
else:
raise Exception("Commons Directory does not exist. Exiting...")
self.settings.edit_property("commonFolder", self.common_directory)
self.settings.add_property("user_templates_directory", self.user_directory, force=False)
self.settings.apply_settings()

self.commons = Commons(self.common_directory)
Expand Down
62 changes: 56 additions & 6 deletions tik_manager4/objects/work.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,58 @@ def get_version(self, version_number):
if version.get("version_number") == version_number:
return version

# def new_version_from_template(self, file_path, notes=""):
# """Register a given path as a new version of the work.
#
# Args:
# file_path:
# notes:
#
# Returns:
#
# """
# state = self.check_permissions(level=1)
# if state != 1:
# return -1
#
# file_format = Path(file_path).suffix
# version_number, version_name, thumbnail_name = self.construct_names(file_format)
#
# abs_version_path = self.get_abs_project_path(self.name, version_name)
# thumbnail_path = self.get_abs_database_path("thumbnails", thumbnail_name)
# Path(abs_version_path).parent.mkdir(parents=True, exist_ok=True)
#
# # copy the file to the location
# output_path = self._standalone_handler.save_as(abs_version_path, source_path=file_path)
#
# # generate thumbnail
# # create the thumbnail folder if it doesn't exist
# Path(thumbnail_path).parent.mkdir(parents=True, exist_ok=True)
#
# # FIXME: CREATE A THUMBNAIL SPECIFIC TO TEMPLATE
# # # add it to the versions
# # extension = Path(output_path).suffix or "Folder"
# # get the name of the file
# file_name = Path(file_path).name
# self._standalone_handler.text_to_image(file_name, thumbnail_path, 220, 124)
#
# version = {
# "version_number": version_number,
# "workstation": socket.gethostname(),
# "notes": notes,
# "thumbnail": Path("thumbnails", thumbnail_name).as_posix(),
# "scene_path": Path(self.name, str(version_name)).as_posix(),
# "user": self.guard.user,
# "previews": {},
# "file_format": file_format,
# "dcc_version": "NA",
# }
#
# self._versions.append(version)
# self.edit_property("versions", self._versions)
# self.apply_settings(force=True)
# return version

def new_version_from_path(self, file_path, notes=""):
"""Register a given path (file or folder) as a new version of the work.
Expand Down Expand Up @@ -596,7 +648,6 @@ def delete_version(self, version_number):
self.apply_settings(force=True)
return 1


def __generate_thumbnail_paths(self, version_obj, override_extension=None):
"""Return the thumbnail paths of the given version."""
# if there is no previous thumbnail, generate a new one
Expand All @@ -608,7 +659,6 @@ def __generate_thumbnail_paths(self, version_obj, override_extension=None):
Path(abs_path).parent.mkdir(parents=True, exist_ok=True)
return relative_path, abs_path


def replace_thumbnail(self, version_number, new_thumbnail_path=None):
"""Replace the thumbnail of the given version.
Args:
Expand Down Expand Up @@ -647,9 +697,9 @@ def check_dcc_version_mismatch(self):
metadata_key = f"{self.guard.dcc.lower()}_version"
# if a dcc version defined in metadata, use that. Otherwise use the current dcc version.
defined_dcc_version = self.get_metadata(self.parent_task, metadata_key) or self.dcc_version
# compare this against the current dcc version
if defined_dcc_version != current_dcc:
return (defined_dcc_version, current_dcc)
return False
if defined_dcc_version in ["NA", "", current_dcc]:
return False
return defined_dcc_version, current_dcc



1 change: 0 additions & 1 deletion tik_manager4/ui/dialog/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,6 @@ def _add_category_item():
horizontal_layout = QtWidgets.QHBoxLayout()
dialog_layout.addLayout(horizontal_layout)
name_label = QtWidgets.QLabel("Name: ")
# name_line_edit = QtWidgets.QLineEdit(self)
name_line_edit = ValidatedString("name")
name_line_edit.allow_spaces = False
name_line_edit.allow_special_characters = False
Expand Down
44 changes: 42 additions & 2 deletions tik_manager4/ui/dialog/work_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,8 @@ def update_labels(self, validation_status):
_name = self.primary_content.settings_data.get_property("name")
if not _name:
self.widgets.resolved_name_lbl.setText("No Name Entered")
# return
elif not validation_status:
self.widgets.resolved_name_lbl.setText("Invalid name")
# return
else:
_file_format = self.primary_content.settings_data.get_property(
"file_format"
Expand Down Expand Up @@ -431,6 +429,48 @@ def on_format_changed(self, file_format):
) = self.work_object.construct_names(file_format)
self.name_label.setText(version_name)

class WorkFromTemplateDialog(NewWorkDialog):
"""Dialog to create a work file from a template file."""
def __init__(self, main_object, template_names=None, *args, **kwargs):
self.template_names = template_names
super().__init__(main_object, *args, **kwargs)
self.setWindowTitle("Create Work From Template")
self.widgets.header_lbl.setText("Create Work From Template")
self.widgets.header_lbl.set_color("green")

# hide the file_format widget
self.file_format_widget = self.primary_content.find("file_format")
self.file_format_widget.hide()
self.file_format_widget.label.hide()

def define_primary_ui(self):

# available_templates = self.main_object.get_template_names()

_primary_ui = {
"template": {
"display_name": "Template",
"type": "combo",
"items": self.template_names,
"value": self.template_names[0],
"tooltip": "Template file to create the work from",
}
}
_orig_dict = super().define_primary_ui()
_primary_ui.update(_orig_dict)
return _primary_ui

def on_create_work(self):
"""Create the work file."""
template_name = self.primary_data.get_property("template")
name = self.primary_data.get_property("name")
notes = self.widgets.notes_te.toPlainText()
#
# resolve the template file.
dcc_name, template_path = self.main_object.get_template_path_by_name(template_name)
self.category.create_work_from_template(name, template_path, dcc=dcc_name, ignore_checks=True, notes=notes)
self.accept()


class SaveAnyFileDialog(NewWorkDialog):
"""Dialog to save any file or folder to the tik manager 4 project."""
Expand Down
Loading

0 comments on commit 1de09a8

Please sign in to comment.