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

Module: Kitsu module #2650

Merged
merged 84 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
e2076c0
Module: Kitsu module
Tilix4 Feb 3, 2022
7044029
Fist step to sync from Zou to local
Tilix4 Feb 8, 2022
719afdc
black
Tilix4 Feb 8, 2022
7c63d3a
Add tasks to asset
Tilix4 Feb 8, 2022
9a1dd4f
All bulk write. Updating assets
Tilix4 Feb 8, 2022
206bf9f
Delete assets
Tilix4 Feb 9, 2022
e882de5
Assets hierarchy
Tilix4 Feb 10, 2022
ee281f7
Project tasks
Tilix4 Feb 10, 2022
d63c5fc
Optim: bulkwrite and queries mutualization
Tilix4 Feb 11, 2022
4e68bcf
cleaning
Tilix4 Feb 11, 2022
294b93f
Create episode
Tilix4 Feb 12, 2022
bad1665
Create asset, ep, seq and shot in zou
Tilix4 Feb 14, 2022
9af6264
Update and delete in zou
Tilix4 Feb 15, 2022
b2ce0ac
Shot naming matching
Tilix4 Feb 15, 2022
9dcfab2
cleaning
Tilix4 Feb 15, 2022
a8611c0
Clean sync zou
Tilix4 Feb 16, 2022
c74b62c
Fix sync
Tilix4 Feb 16, 2022
93fb1ac
Use substitutes id
Tilix4 Feb 17, 2022
c058ba5
Project sync and code DRYing
Tilix4 Feb 22, 2022
0d38ccc
Listen asset and DRY
Tilix4 Feb 23, 2022
fe54868
Listen Episode, Sequence and Shot
Tilix4 Feb 23, 2022
de153a0
Listen tasks, clean code
Tilix4 Feb 24, 2022
6cf38e1
Publish comment to kitsu
Tilix4 Feb 25, 2022
cb01f83
Sign in dialog, credentials as local setting and cleaning
Tilix4 Mar 1, 2022
6b39877
Moved to modules
Tilix4 Mar 1, 2022
a33b3d3
Remove AddonSettingsDef
Tilix4 Mar 2, 2022
4907ce1
Moved up module 'base' changes
Tilix4 Mar 2, 2022
a15c4d2
import gazu only at start
Tilix4 Mar 2, 2022
44100b0
line length to 79
Tilix4 Mar 2, 2022
c26c2f0
fix import
Tilix4 Mar 2, 2022
e883194
Fix __all__
Tilix4 Mar 2, 2022
cde925c
Use OpenPypeSecureRegistry for authentication
Tilix4 Mar 2, 2022
c9ea0b3
Line length max 79
Tilix4 Mar 2, 2022
ae78377
Rename module to Kitsu Connect
Tilix4 Mar 2, 2022
c39bdee
Refactor for login system following recommendations.
Tilix4 Mar 3, 2022
f6e2716
Cleaning.
Tilix4 Mar 3, 2022
5db0c1d
Python 2 compat and cleaning
Tilix4 Mar 4, 2022
8c3b510
Cleaning
Tilix4 Mar 4, 2022
e5ae545
Kitsu docs
Tilix4 Mar 4, 2022
0515858
Add pyblish comment to kitsu
Tilix4 Mar 8, 2022
1591b91
Python2 compat
Tilix4 Mar 8, 2022
9c0c43a
fix first sync crash
ClementHector Mar 15, 2022
17dd018
Build project code
Tilix4 Mar 16, 2022
093e801
Sync project FPS and resolution
Tilix4 Mar 16, 2022
bd06809
Fix shot syncs
Tilix4 Mar 16, 2022
84a13e4
shots and assets custom folders root
Tilix4 Mar 17, 2022
3970229
Fix fps fallback to project's value
Tilix4 Mar 17, 2022
78bda28
frame_in/out fallbacks
Tilix4 Mar 17, 2022
527f4a7
Sync only open projects
Tilix4 Mar 25, 2022
63096b4
change avalon API
Tilix4 May 4, 2022
0359ec6
create kitsu collector
ClementHector Apr 7, 2022
196c81a
collect all kitsu entities in context
ClementHector Apr 8, 2022
eb28895
integrate note and status
ClementHector Apr 9, 2022
ff6c8a6
Add kitsu log out
ClementHector Apr 10, 2022
ed8c01c
upload file to kitsu
ClementHector Apr 20, 2022
2e0f6ce
use task type if no task data in OP
ClementHector Apr 20, 2022
f72cb8b
fix log out
ClementHector Apr 20, 2022
3d6a6fc
upload review
ClementHector Apr 20, 2022
db8719b
remove unused import
ClementHector Apr 20, 2022
7787056
Do some cleanup
ClementHector Apr 20, 2022
d9062b7
Update openpype/modules/kitsu/utils/update_zou_with_op.py
Tilix4 May 5, 2022
26fcd19
use dbcon.Session instead of collection
Tilix4 May 11, 2022
765546e
fix unused var
Tilix4 May 11, 2022
27d9e9b
Fix delete project
Tilix4 May 11, 2022
af77d5a
fix wrong name entities makes crash: they are skipped
Tilix4 May 11, 2022
eb5605a
fix updated asset skipped because of wrong name
Tilix4 May 11, 2022
70bb0fd
fix flake
Tilix4 May 11, 2022
987b5df
optim get_project_settings
Tilix4 May 12, 2022
e0bd877
pop useless item_data
Tilix4 May 12, 2022
63fe5a0
Merge pull request #3 from quadproduction/mod_kitsu_implement_pyblish…
Tilix4 May 12, 2022
ae69db2
black pyblish
Tilix4 May 12, 2022
3583d85
black pyblish
Tilix4 May 12, 2022
687f726
optim publish status intent
Tilix4 May 12, 2022
20f819c
change intent wrongly used as status choice
Tilix4 May 12, 2022
330d434
black
Tilix4 May 12, 2022
631ccf6
Update openpype/modules/kitsu/plugins/publish/integrate_kitsu_review.py
Tilix4 May 16, 2022
15aa570
cleaning
Tilix4 May 16, 2022
e628616
remove default intent effect on review integration
Tilix4 May 16, 2022
05cb2e4
waiting approval status can be set in project settings
ClementHector May 16, 2022
0b0a9ca
by default use task status if not specified in config
ClementHector May 16, 2022
5059c0c
Update openpype/modules/kitsu/plugins/publish/integrate_kitsu_note.py
ClementHector May 17, 2022
21c123f
Merge pull request #4 from quadproduction/mod_kitsu_custom_status_app…
Tilix4 May 17, 2022
667cff3
black
Tilix4 May 17, 2022
6976546
cleaning
Tilix4 May 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions openpype/modules/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,7 @@ class TrayModulesManager(ModulesManager):
modules_menu_order = (
"user",
"ftrack",
"kitsu",
"muster",
"launcher_tool",
"avalon",
Expand Down
9 changes: 9 additions & 0 deletions openpype/modules/kitsu/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
""" Addon class definition and Settings definition must be imported here.

If addon class or settings definition won't be here their definition won't
be found by OpenPype discovery.
"""

from .kitsu_module import KitsuModule

__all__ = ("KitsuModule",)
136 changes: 136 additions & 0 deletions openpype/modules/kitsu/kitsu_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
"""Kitsu module."""

import click
import os

from openpype.modules import OpenPypeModule
from openpype_interfaces import IPluginPaths, ITrayAction


class KitsuModule(OpenPypeModule, IPluginPaths, ITrayAction):
"""Kitsu module class."""

label = "Kitsu Connect"
name = "kitsu"

def initialize(self, settings):
"""Initialization of module."""
module_settings = settings[self.name]

# Enabled by settings
self.enabled = module_settings.get("enabled", False)

# Add API URL schema
kitsu_url = module_settings["server"].strip()
if kitsu_url:
# Ensure web url
if not kitsu_url.startswith("http"):
kitsu_url = "https://" + kitsu_url

# Check for "/api" url validity
if not kitsu_url.endswith("api"):
kitsu_url = "{}{}api".format(
kitsu_url, "" if kitsu_url.endswith("/") else "/"
)

self.server_url = kitsu_url

# UI which must not be created at this time
self._dialog = None

def tray_init(self):
"""Tray init."""

self._create_dialog()

def tray_start(self):
"""Tray start."""
from .utils.credentials import (
load_credentials,
validate_credentials,
set_credentials_envs,
)

login, password = load_credentials()

# Check credentials, ask them if needed
if validate_credentials(login, password):
set_credentials_envs(login, password)
else:
self.show_dialog()

def get_global_environments(self):
"""Kitsu's global environments."""
return {"KITSU_SERVER": self.server_url}

def _create_dialog(self):
# Don't recreate dialog if already exists
if self._dialog is not None:
return

from .kitsu_widgets import KitsuPasswordDialog

self._dialog = KitsuPasswordDialog()

def show_dialog(self):
"""Show dialog to log-in."""

# Make sure dialog is created
self._create_dialog()

# Show dialog
self._dialog.open()

def on_action_trigger(self):
"""Implementation of abstract method for `ITrayAction`."""
self.show_dialog()

def get_plugin_paths(self):
"""Implementation of abstract method for `IPluginPaths`."""
current_dir = os.path.dirname(os.path.abspath(__file__))

return {"publish": [os.path.join(current_dir, "plugins", "publish")]}

def cli(self, click_group):
click_group.add_command(cli_main)


@click.group(KitsuModule.name, help="Kitsu dynamic cli commands.")
def cli_main():
pass


@cli_main.command()
@click.option("--login", envvar="KITSU_LOGIN", help="Kitsu login")
@click.option(
"--password", envvar="KITSU_PWD", help="Password for kitsu username"
)
def push_to_zou(login, password):
"""Synchronize Zou database (Kitsu backend) with openpype database.

Args:
login (str): Kitsu user login
password (str): Kitsu user password
"""
from .utils.update_zou_with_op import sync_zou

sync_zou(login, password)


@cli_main.command()
@click.option("-l", "--login", envvar="KITSU_LOGIN", help="Kitsu login")
@click.option(
"-p", "--password", envvar="KITSU_PWD", help="Password for kitsu username"
)
def sync_service(login, password):
"""Synchronize openpype database from Zou sever database.

Args:
login (str): Kitsu user login
password (str): Kitsu user password
"""
from .utils.update_op_with_zou import sync_all_project
from .utils.sync_service import start_listeners

sync_all_project(login, password)
start_listeners(login, password)
188 changes: 188 additions & 0 deletions openpype/modules/kitsu/kitsu_widgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
from Qt import QtWidgets, QtCore, QtGui

from openpype import style
from openpype.modules.kitsu.utils.credentials import (
clear_credentials,
load_credentials,
save_credentials,
set_credentials_envs,
validate_credentials,
)
from openpype.resources import get_resource
from openpype.settings.lib import (
get_system_settings,
)

from openpype.widgets.password_dialog import PressHoverButton


class KitsuPasswordDialog(QtWidgets.QDialog):
"""Kitsu login dialog."""

finished = QtCore.Signal(bool)

def __init__(self, parent=None):
super(KitsuPasswordDialog, self).__init__(parent)

self.setWindowTitle("Kitsu Credentials")
self.resize(300, 120)

system_settings = get_system_settings()
user_login, user_pwd = load_credentials()
remembered = bool(user_login or user_pwd)

self._final_result = None
self._connectable = bool(
system_settings["modules"].get("kitsu", {}).get("server")
)

# Server label
server_message = (
system_settings["modules"]["kitsu"]["server"]
if self._connectable
else "no server url set in Studio Settings..."
)
server_label = QtWidgets.QLabel(
f"Server: {server_message}",
self,
)

# Login input
login_widget = QtWidgets.QWidget(self)

login_label = QtWidgets.QLabel("Login:", login_widget)

login_input = QtWidgets.QLineEdit(
login_widget,
text=user_login if remembered else None,
)
login_input.setPlaceholderText("Your Kitsu account login...")

login_layout = QtWidgets.QHBoxLayout(login_widget)
login_layout.setContentsMargins(0, 0, 0, 0)
login_layout.addWidget(login_label)
login_layout.addWidget(login_input)

# Password input
password_widget = QtWidgets.QWidget(self)

password_label = QtWidgets.QLabel("Password:", password_widget)

password_input = QtWidgets.QLineEdit(
password_widget,
text=user_pwd if remembered else None,
)
password_input.setPlaceholderText("Your password...")
password_input.setEchoMode(QtWidgets.QLineEdit.Password)

show_password_icon_path = get_resource("icons", "eye.png")
show_password_icon = QtGui.QIcon(show_password_icon_path)
show_password_btn = PressHoverButton(password_widget)
show_password_btn.setObjectName("PasswordBtn")
show_password_btn.setIcon(show_password_icon)
show_password_btn.setFocusPolicy(QtCore.Qt.ClickFocus)

password_layout = QtWidgets.QHBoxLayout(password_widget)
password_layout.setContentsMargins(0, 0, 0, 0)
password_layout.addWidget(password_label)
password_layout.addWidget(password_input)
password_layout.addWidget(show_password_btn)

# Message label
message_label = QtWidgets.QLabel("", self)

# Buttons
buttons_widget = QtWidgets.QWidget(self)

remember_checkbox = QtWidgets.QCheckBox("Remember", buttons_widget)
remember_checkbox.setObjectName("RememberCheckbox")
remember_checkbox.setChecked(remembered)

ok_btn = QtWidgets.QPushButton("Ok", buttons_widget)
cancel_btn = QtWidgets.QPushButton("Cancel", buttons_widget)

buttons_layout = QtWidgets.QHBoxLayout(buttons_widget)
buttons_layout.setContentsMargins(0, 0, 0, 0)
buttons_layout.addWidget(remember_checkbox)
buttons_layout.addStretch(1)
buttons_layout.addWidget(ok_btn)
buttons_layout.addWidget(cancel_btn)

# Main layout
layout = QtWidgets.QVBoxLayout(self)
layout.addSpacing(5)
layout.addWidget(server_label, 0)
layout.addSpacing(5)
layout.addWidget(login_widget, 0)
layout.addWidget(password_widget, 0)
layout.addWidget(message_label, 0)
layout.addStretch(1)
layout.addWidget(buttons_widget, 0)

ok_btn.clicked.connect(self._on_ok_click)
cancel_btn.clicked.connect(self._on_cancel_click)
show_password_btn.change_state.connect(self._on_show_password)

self.login_input = login_input
self.password_input = password_input
self.remember_checkbox = remember_checkbox
self.message_label = message_label

self.setStyleSheet(style.load_stylesheet())

def result(self):
return self._final_result

def keyPressEvent(self, event):
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
self._on_ok_click()
return event.accept()
super(KitsuPasswordDialog, self).keyPressEvent(event)

def closeEvent(self, event):
super(KitsuPasswordDialog, self).closeEvent(event)
self.finished.emit(self.result())

def _on_ok_click(self):
# Check if is connectable
if not self._connectable:
self.message_label.setText(
"Please set server url in Studio Settings!"
)
return

# Collect values
login_value = self.login_input.text()
pwd_value = self.password_input.text()
remember = self.remember_checkbox.isChecked()

# Authenticate
if validate_credentials(login_value, pwd_value):
set_credentials_envs(login_value, pwd_value)
else:
self.message_label.setText("Authentication failed...")
return

# Remember password cases
if remember:
save_credentials(login_value, pwd_value)
else:
# Clear local settings
clear_credentials()

# Clear input fields
self.login_input.clear()
self.password_input.clear()

self._final_result = True
self.close()

def _on_show_password(self, show_password):
if show_password:
echo_mode = QtWidgets.QLineEdit.Normal
else:
echo_mode = QtWidgets.QLineEdit.Password
self.password_input.setEchoMode(echo_mode)

def _on_cancel_click(self):
self.close()
18 changes: 18 additions & 0 deletions openpype/modules/kitsu/plugins/publish/collect_kitsu_credential.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import os

import gazu
import pyblish.api


class CollectKitsuSession(pyblish.api.ContextPlugin): # rename log in
"""Collect Kitsu session using user credentials"""

order = pyblish.api.CollectorOrder
label = "Kitsu user session"
# families = ["kitsu"]

def process(self, context):

gazu.client.set_host(os.environ["KITSU_SERVER"])
gazu.log_in(os.environ["KITSU_LOGIN"], os.environ["KITSU_PWD"])
Loading