ayon-core/openpype/widgets/project_settings.py
2021-04-01 18:54:46 +02:00

495 lines
19 KiB
Python

from avalon.vendor.Qt import QtCore, QtGui, QtWidgets
import os
import getpass
import platform
from avalon import style
import ftrack_api
class Project_name_getUI(QtWidgets.QWidget):
'''
Project setting ui: here all the neceserry ui widgets are created
they are going to be used i later proces for dynamic linking of project
in list to project's attributes
'''
def __init__(self, parent=None):
super(Project_name_getUI, self).__init__(parent)
self.platform = platform.system()
self.new_index = 0
# get projects from ftrack
self.session = ftrack_api.Session()
self.projects_from_ft = self.session.query(
'Project where status is active')
self.disks_from_ft = self.session.query('Disk')
self.schemas_from_ft = self.session.query('ProjectSchema')
self.projects = self._get_projects_ftrack()
# define window geometry
self.setWindowTitle('Set project attributes')
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.resize(550, 340)
self.setStyleSheet(style.load_stylesheet())
# define disk combobox widget
self.disks = self._get_all_disks()
self.disk_combobox_label = QtWidgets.QLabel('Destination storage:')
self.disk_combobox = QtWidgets.QComboBox()
# define schema combobox widget
self.schemas = self._get_all_schemas()
self.schema_combobox_label = QtWidgets.QLabel('Project schema:')
self.schema_combobox = QtWidgets.QComboBox()
# define fps widget
self.fps_label = QtWidgets.QLabel('Fps:')
self.fps_label.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.fps = QtWidgets.QLineEdit()
# define project dir widget
self.project_dir_label = QtWidgets.QLabel('Project dir:')
self.project_dir_label.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.project_dir = QtWidgets.QLineEdit()
self.project_path_label = QtWidgets.QLabel(
'Project_path (if not then created):')
self.project_path_label.setAlignment(
QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
project_path_font = QtGui.QFont(
"Helvetica [Cronyx]", 12, QtGui.QFont.Bold)
self.project_path = QtWidgets.QLabel()
self.project_path.setObjectName('nom_plan_label')
self.project_path.setStyleSheet(
'QtWidgets.QLabel#nom_plan_label {color: red}')
self.project_path.setAlignment(
QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
self.project_path.setFont(project_path_font)
# define handles widget
self.handles_label = QtWidgets.QLabel('Handles:')
self.handles_label.setAlignment(
QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.handles = QtWidgets.QLineEdit()
# define resolution widget
self.resolution_w_label = QtWidgets.QLabel('W:')
self.resolution_w = QtWidgets.QLineEdit()
self.resolution_h_label = QtWidgets.QLabel('H:')
self.resolution_h = QtWidgets.QLineEdit()
devider = QtWidgets.QFrame()
# devider.Shape(QFrame.HLine)
devider.setFrameShape(QtWidgets.QFrame.HLine)
devider.setFrameShadow(QtWidgets.QFrame.Sunken)
self.generate_lines()
# define push buttons
self.set_pushbutton = QtWidgets.QPushButton('Set project')
self.cancel_pushbutton = QtWidgets.QPushButton('Cancel')
# definition of layouts
############################################
action_layout = QtWidgets.QHBoxLayout()
action_layout.addWidget(self.set_pushbutton)
action_layout.addWidget(self.cancel_pushbutton)
# schema property
schema_layout = QtWidgets.QGridLayout()
schema_layout.addWidget(self.schema_combobox, 0, 1)
schema_layout.addWidget(self.schema_combobox_label, 0, 0)
# storage property
storage_layout = QtWidgets.QGridLayout()
storage_layout.addWidget(self.disk_combobox, 0, 1)
storage_layout.addWidget(self.disk_combobox_label, 0, 0)
# fps property
fps_layout = QtWidgets.QGridLayout()
fps_layout.addWidget(self.fps, 1, 1)
fps_layout.addWidget(self.fps_label, 1, 0)
# project dir property
project_dir_layout = QtWidgets.QGridLayout()
project_dir_layout.addWidget(self.project_dir, 1, 1)
project_dir_layout.addWidget(self.project_dir_label, 1, 0)
# project path property
project_path_layout = QtWidgets.QGridLayout()
spacer_1_item = QtWidgets.QSpacerItem(10, 10)
project_path_layout.addItem(spacer_1_item, 0, 1)
project_path_layout.addWidget(self.project_path_label, 1, 1)
project_path_layout.addWidget(self.project_path, 2, 1)
spacer_2_item = QtWidgets.QSpacerItem(20, 20)
project_path_layout.addItem(spacer_2_item, 3, 1)
# handles property
handles_layout = QtWidgets.QGridLayout()
handles_layout.addWidget(self.handles, 1, 1)
handles_layout.addWidget(self.handles_label, 1, 0)
# resolution property
resolution_layout = QtWidgets.QGridLayout()
resolution_layout.addWidget(self.resolution_w_label, 1, 1)
resolution_layout.addWidget(self.resolution_w, 2, 1)
resolution_layout.addWidget(self.resolution_h_label, 1, 2)
resolution_layout.addWidget(self.resolution_h, 2, 2)
# form project property layout
p_layout = QtWidgets.QGridLayout()
p_layout.addLayout(storage_layout, 1, 0)
p_layout.addLayout(schema_layout, 2, 0)
p_layout.addLayout(project_dir_layout, 3, 0)
p_layout.addLayout(fps_layout, 4, 0)
p_layout.addLayout(handles_layout, 5, 0)
p_layout.addLayout(resolution_layout, 6, 0)
p_layout.addWidget(devider, 7, 0)
spacer_item = QtWidgets.QSpacerItem(
150,
40,
QtWidgets.QSizePolicy.Minimum,
QtWidgets.QSizePolicy.Expanding
)
p_layout.addItem(spacer_item, 8, 0)
# form with list to one layout with project property
list_layout = QtWidgets.QGridLayout()
list_layout.addLayout(p_layout, 1, 0)
list_layout.addWidget(self.listWidget, 1, 1)
root_layout = QtWidgets.QVBoxLayout()
root_layout.addLayout(project_path_layout)
root_layout.addWidget(devider)
root_layout.addLayout(list_layout)
root_layout.addLayout(action_layout)
self.setLayout(root_layout)
def generate_lines(self):
'''
Will generate lines of project list
'''
self.listWidget = QtWidgets.QListWidget()
for self.index, p in enumerate(self.projects):
item = QtWidgets.QListWidgetItem("{full_name}".format(**p))
# item.setSelected(False)
self.listWidget.addItem(item)
print(self.listWidget.indexFromItem(item))
# self.listWidget.setCurrentItem(self.listWidget.itemFromIndex(1))
# add options to schemas widget
self.schema_combobox.addItems(self.schemas)
# add options to disk widget
self.disk_combobox.addItems(self.disks)
# populate content of project info widgets
self.projects[1] = self._fill_project_attributes_widgets(p, None)
def _fill_project_attributes_widgets(self, p=None, index=None):
'''
will generate actual informations wich are saved on ftrack
'''
if index is None:
self.new_index = 1
if not p:
pass
# change schema selection
for i, schema in enumerate(self.schemas):
if p['project_schema']['name'] in schema:
break
self.schema_combobox.setCurrentIndex(i)
disk_name, disk_path = self._build_disk_path()
for i, disk in enumerate(self.disks):
if disk_name in disk:
break
# change disk selection
self.disk_combobox.setCurrentIndex(i)
# change project_dir selection
if "{root}".format(**p):
self.project_dir.setPlaceholderText("{root}".format(**p))
else:
print("not root so it was replaced with name")
self.project_dir.setPlaceholderText("{name}".format(**p))
p['root'] = p['name']
# set project path to show where it will be created
self.project_path.setText(
os.path.join(self.disks[i].split(' ')[-1],
self.project_dir.text()))
# change fps selection
self.fps.setPlaceholderText("{custom_attributes[fps]}".format(**p))
# change handles selection
self.handles.setPlaceholderText(
"{custom_attributes[handles]}".format(**p))
# change resolution selection
self.resolution_w.setPlaceholderText(
"{custom_attributes[resolution_width]}".format(**p))
self.resolution_h.setPlaceholderText(
"{custom_attributes[resolution_height]}".format(**p))
self.update_disk()
return p
def fix_project_path_literals(self, dir):
return dir.replace(' ', '_').lower()
def update_disk(self):
disk = self.disk_combobox.currentText().split(' ')[-1]
dir = self.project_dir.text()
if not dir:
dir = "{root}".format(**self.projects[self.new_index])
self.projects[self.new_index]['project_path'] = os.path.normpath(
self.fix_project_path_literals(os.path.join(disk, dir)))
else:
self.projects[self.new_index]['project_path'] = os.path.normpath(
self.fix_project_path_literals(os.path.join(disk, dir)))
self.projects[self.new_index]['disk'] = self.disks_from_ft[
self.disk_combobox.currentIndex()]
self.projects[self.new_index]['disk_id'] = self.projects[
self.new_index]['disk']['id']
# set project path to show where it will be created
self.project_path.setText(
self.projects[self.new_index]['project_path'])
def update_resolution(self):
# update all values in resolution
if self.resolution_w.text():
self.projects[self.new_index]['custom_attributes'][
"resolutionWidth"] = int(self.resolution_w.text())
if self.resolution_h.text():
self.projects[self.new_index]['custom_attributes'][
"resolutionHeight"] = int(self.resolution_h.text())
def _update_attributes_by_list_selection(self):
# generate actual selection index
self.new_index = self.listWidget.currentRow()
self.project_dir.setText('')
self.fps.setText('')
self.handles.setText('')
self.resolution_w.setText('')
self.resolution_h.setText('')
# update project properities widgets and write changes
# into project dictionaries
self.projects[self.new_index] = self._fill_project_attributes_widgets(
self.projects[self.new_index], self.new_index)
self.update_disk()
def _build_disk_path(self):
if self.platform == "Windows":
print(self.projects[self.index].keys())
print(self.projects[self.new_index]['disk'])
return self.projects[self.new_index]['disk'][
'name'], self.projects[self.new_index]['disk']['windows']
else:
return self.projects[self.new_index]['disk'][
'name'], self.projects[self.new_index]['disk']['unix']
def _get_all_schemas(self):
schemas_list = []
for s in self.schemas_from_ft:
# print d.keys()
# if 'Pokus' in s['name']:
# continue
schemas_list.append('{}'.format(s['name']))
print("\nschemas in ftrack: {}\n".format(schemas_list))
return schemas_list
def _get_all_disks(self):
disks_list = []
for d in self.disks_from_ft:
# print d.keys()
if self.platform == "Windows":
if 'Local drive' in d['name']:
d['windows'] = os.path.join(d['windows'],
os.getenv('USERNAME')
or os.getenv('USER')
or os.getenv('LOGNAME'))
disks_list.append('"{}" at {}'.format(d['name'], d['windows']))
else:
if 'Local drive' in d['name']:
d['unix'] = os.path.join(d['unix'], getpass.getuser())
disks_list.append('"{}" at {}'.format(d['name'], d['unix']))
return disks_list
def _get_projects_ftrack(self):
projects_lst = []
for project in self.projects_from_ft:
# print project.keys()
projects_dict = {}
for k in project.keys():
''' # TODO: delete this in production version '''
# if 'test' not in project['name']:
# continue
# print '{}: {}\n'.format(k, project[k])
if '_link' == k:
# print project[k]
content = project[k]
for kc in content[0].keys():
if content[0]['name']:
content[0][kc] = content[0][kc].encode(
'ascii', 'ignore').decode('ascii')
print('{}: {}\n'.format(kc, content[0][kc]))
projects_dict[k] = content
print(project[k])
print(projects_dict[k])
elif 'root' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'disk' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'name' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k].encode(
'ascii', 'ignore').decode('ascii')
elif 'disk_id' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'id' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'full_name' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k].encode(
'ascii', 'ignore').decode('ascii')
elif 'project_schema_id' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'project_schema' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
elif 'custom_attributes' == k:
print('{}: {}\n'.format(k, project[k]))
projects_dict[k] = project[k]
else:
pass
if projects_dict:
projects_lst.append(projects_dict)
return projects_lst
class Project_name_get(Project_name_getUI):
def __init__(self, parent=None):
super(Project_name_get, self).__init__(parent)
# self.input_project_name.textChanged.connect(self.input_project_name.placeholderText)
self.set_pushbutton.clicked.connect(lambda: self.execute())
self.cancel_pushbutton.clicked.connect(self.close)
self.listWidget.itemSelectionChanged.connect(
self._update_attributes_by_list_selection)
self.disk_combobox.currentIndexChanged.connect(self.update_disk)
self.schema_combobox.currentIndexChanged.connect(self.update_schema)
self.project_dir.textChanged.connect(self.update_disk)
self.fps.textChanged.connect(self.update_fps)
self.handles.textChanged.connect(self.update_handles)
self.resolution_w.textChanged.connect(self.update_resolution)
self.resolution_h.textChanged.connect(self.update_resolution)
def update_handles(self):
self.projects[self.new_index]['custom_attributes']['handles'] = int(
self.handles.text())
def update_fps(self):
self.projects[self.new_index]['custom_attributes']['fps'] = int(
self.fps.text())
def update_schema(self):
self.projects[self.new_index]['project_schema'] = self.schemas_from_ft[
self.schema_combobox.currentIndex()]
self.projects[self.new_index]['project_schema_id'] = self.projects[
self.new_index]['project_schema']['id']
def execute(self):
# import ft_utils
# import hiero
# get the project which has been selected
print("well and what")
# set the project as context and create entity
# entity is task created with the name of user which is creating it
# get the project_path and create dir if there is not any
print(self.projects[self.new_index]['project_path'].replace(
self.disk_combobox.currentText().split(' ')[-1].lower(), ''))
# get the schema and recreate a starting project regarding the selection
# set_hiero_template(project_schema=self.projects[self.new_index][
# 'project_schema']['name'])
# set all project properities
# project = hiero.core.Project()
# project.setFramerate(
# int(self.projects[self.new_index]['custom_attributes']['fps']))
# project.projectRoot()
# print 'handles: {}'.format(self.projects[self.new_index]['custom_attributes']['handles'])
# print 'resolution_width: {}'.format(self.projects[self.new_index]['custom_attributes']["resolutionWidth"])
# print 'resolution_width: {}'.format(self.projects[self.new_index]['custom_attributes']["resolutionHeight"])
# print "<< {}".format(self.projects[self.new_index])
# get path for the hrox file
# root = context.data('ftrackData')['Project']['root']
# hrox_script_path = ft_utils.getPathsYaml(taskid, templateList=templates, root=root)
# save the hrox into the correct path
self.session.commit()
self.close()
#
# def set_hiero_template(project_schema=None):
# import hiero
# hiero.core.closeAllProjects()
# hiero_plugin_path = [
# p for p in os.environ['HIERO_PLUGIN_PATH'].split(';')
# if 'hiero_plugin_path' in p
# ][0]
# path = os.path.normpath(
# os.path.join(hiero_plugin_path, 'Templates', project_schema + '.hrox'))
# print('---> path to template: {}'.format(path))
# return hiero.core.openProject(path)
# def set_out_ft_session():
# session = ftrack_api.Session()
# projects_to_ft = session.query('Project where status is active')
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
panel = Project_name_get()
panel.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()