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

Commit

Permalink
Merge pull request #608 from pypeclub/feature/ftrack_server_action
Browse files Browse the repository at this point in the history
Ftrack server action improvement
  • Loading branch information
mkolar authored Oct 8, 2020
2 parents 0524891 + 2f3d164 commit e032fea
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 94 deletions.
5 changes: 3 additions & 2 deletions pype/modules/ftrack/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from . import ftrack_server
from .ftrack_server import FtrackServer, check_ftrack_url
from .lib import BaseHandler, BaseEvent, BaseAction
from .lib import BaseHandler, BaseEvent, BaseAction, ServerAction

__all__ = (
"ftrack_server",
"FtrackServer",
"check_ftrack_url",
"BaseHandler",
"BaseEvent",
"BaseAction"
"BaseAction",
"ServerAction"
)
42 changes: 3 additions & 39 deletions pype/modules/ftrack/events/action_push_frame_values_to_task.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import json
import collections
import ftrack_api
from pype.modules.ftrack.lib import BaseAction
from pype.modules.ftrack.lib import ServerAction


class PushFrameValuesToTaskAction(BaseAction):
class PushFrameValuesToTaskAction(ServerAction):
"""Action for testing purpose or as base for new actions."""

# Ignore event handler by default
Expand Down Expand Up @@ -34,50 +34,14 @@ class PushFrameValuesToTaskAction(BaseAction):
"frameStart": "fstart",
"frameEnd": "fend"
}
discover_role_list = {"Pypeclub", "Administrator", "Project Manager"}

def register(self):
modified_role_names = set()
for role_name in self.discover_role_list:
modified_role_names.add(role_name.lower())
self.discover_role_list = modified_role_names

self.session.event_hub.subscribe(
"topic=ftrack.action.discover",
self._discover,
priority=self.priority
)

launch_subscription = (
"topic=ftrack.action.launch and data.actionIdentifier={0}"
).format(self.identifier)
self.session.event_hub.subscribe(launch_subscription, self._launch)
role_list = {"Pypeclub", "Administrator", "Project Manager"}

def discover(self, session, entities, event):
""" Validation """
# Check if selection is valid
valid_selection = False
for ent in event["data"]["selection"]:
# Ignore entities that are not tasks or projects
if ent["entityType"].lower() == "show":
valid_selection = True
break

if not valid_selection:
return False

# Get user and check his roles
user_id = event.get("source", {}).get("user", {}).get("id")
if not user_id:
return False

user = session.query("User where id is \"{}\"".format(user_id)).first()
if not user:
return False

for role in user["user_security_roles"]:
lowered_role = role["security_role"]["name"].lower()
if lowered_role in self.discover_role_list:
return True
return False

Expand Down
36 changes: 3 additions & 33 deletions pype/modules/ftrack/events/action_sync_to_avalon.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import time
import traceback

from pype.modules.ftrack import BaseAction
from pype.modules.ftrack import ServerAction
from pype.modules.ftrack.lib.avalon_sync import SyncEntitiesFactory


class SyncToAvalonServer(BaseAction):
class SyncToAvalonServer(ServerAction):
"""
Synchronizing data action - from Ftrack to Avalon DB
Expand Down Expand Up @@ -36,48 +36,18 @@ class SyncToAvalonServer(BaseAction):
variant = "- Sync To Avalon (Server)"
#: Action description.
description = "Send data from Ftrack to Avalon"
role_list = {"Pypeclub", "Administrator", "Project Manager"}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.entities_factory = SyncEntitiesFactory(self.log, self.session)

def register(self):
self.session.event_hub.subscribe(
"topic=ftrack.action.discover",
self._discover,
priority=self.priority
)

launch_subscription = (
"topic=ftrack.action.launch and data.actionIdentifier={0}"
).format(self.identifier)
self.session.event_hub.subscribe(launch_subscription, self._launch)

def discover(self, session, entities, event):
""" Validation """
# Check if selection is valid
valid_selection = False
for ent in event["data"]["selection"]:
# Ignore entities that are not tasks or projects
if ent["entityType"].lower() in ["show", "task"]:
valid_selection = True
break

if not valid_selection:
return False

# Get user and check his roles
user_id = event.get("source", {}).get("user", {}).get("id")
if not user_id:
return False

user = session.query("User where id is \"{}\"".format(user_id)).first()
if not user:
return False

role_list = ["Pypeclub", "Administrator", "Project Manager"]
for role in user["user_security_roles"]:
if role["security_role"]["name"] in role_list:
return True
return False

Expand Down
3 changes: 2 additions & 1 deletion pype/modules/ftrack/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from . import credentials
from .ftrack_base_handler import BaseHandler
from .ftrack_event_handler import BaseEvent
from .ftrack_action_handler import BaseAction, statics_icon
from .ftrack_action_handler import BaseAction, ServerAction, statics_icon
from .ftrack_app_handler import AppAction

__all__ = (
Expand All @@ -11,6 +11,7 @@
"BaseHandler",
"BaseEvent",
"BaseAction",
"ServerAction",
"statics_icon",
"AppAction"
)
79 changes: 79 additions & 0 deletions pype/modules/ftrack/lib/ftrack_action_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,82 @@ def _handle_result(self, result):
).format(str(type(result))))

return result


class ServerAction(BaseAction):
"""Action class meant to be used on event server.
Unlike the `BaseAction` roles are not checked on register but on discover.
For the same reason register is modified to not filter topics by username.
"""

def __init__(self, *args, **kwargs):
if not self.role_list:
self.role_list = set()
else:
self.role_list = set(
role_name.lower()
for role_name in self.role_list
)
super(ServerAction, self).__init__(*args, **kwargs)

def _register_role_check(self):
# Skip register role check.
return

def _discover(self, event):
"""Check user discover availability."""
if not self._check_user_discover(event):
return
return super(ServerAction, self)._discover(event)

def _check_user_discover(self, event):
"""Should be action discovered by user trying to show actions."""
if not self.role_list:
return True

user_entity = self._get_user_entity(event)
if not user_entity:
return False

for role in user_entity["user_security_roles"]:
lowered_role = role["security_role"]["name"].lower()
if lowered_role in self.role_list:
return True
return False

def _get_user_entity(self, event):
"""Query user entity from event."""
not_set = object()

# Check if user is already stored in event data
user_entity = event["data"].get("user_entity", not_set)
if user_entity is not_set:
# Query user entity from event
user_info = event.get("source", {}).get("user", {})
user_id = user_info.get("id")
username = user_info.get("username")
if user_id:
user_entity = self.session.query(
"User where id is {}".format(user_id)
).first()
if not user_entity and username:
user_entity = self.session.query(
"User where username is {}".format(username)
).first()
event["data"]["user_entity"] = user_entity

return user_entity

def register(self):
"""Register subcription to Ftrack event hub."""
self.session.event_hub.subscribe(
"topic=ftrack.action.discover",
self._discover,
priority=self.priority
)

launch_subscription = (
"topic=ftrack.action.launch and data.actionIdentifier={0}"
).format(self.identifier)
self.session.event_hub.subscribe(launch_subscription, self._launch)
45 changes: 26 additions & 19 deletions pype/modules/ftrack/lib/ftrack_base_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class BaseHandler(object):
type = 'No-type'
ignore_me = False
preactions = []
role_list = []

def __init__(self, session, plugins_presets=None):
'''Expects a ftrack_api.Session instance'''
Expand Down Expand Up @@ -148,20 +149,27 @@ def session(self):
def reset_session(self):
self.session.reset()

def _register_role_check(self):
if not self.role_list or not isinstance(self.role_list, (list, tuple)):
return

user_entity = self.session.query(
"User where username is \"{}\"".format(self.session.api_user)
).one()
available = False
lowercase_rolelist = [
role_name.lower()
for role_name in self.role_list
]
for role in user_entity["user_security_roles"]:
if role["security_role"]["name"].lower() in lowercase_rolelist:
available = True
break
if available is False:
raise MissingPermision

def _preregister(self):
if hasattr(self, "role_list") and len(self.role_list) > 0:
username = self.session.api_user
user = self.session.query(
'User where username is "{}"'.format(username)
).one()
available = False
lowercase_rolelist = [x.lower() for x in self.role_list]
for role in user['user_security_roles']:
if role['security_role']['name'].lower() in lowercase_rolelist:
available = True
break
if available is False:
raise MissingPermision
self._register_role_check()

# Custom validations
result = self.preregister()
Expand All @@ -172,12 +180,11 @@ def _preregister(self):
).format(self.__class__.__name__))
return

if result is True:
return
msg = None
if isinstance(result, str):
msg = result
raise PreregisterException(msg)
if result is not True:
msg = None
if isinstance(result, str):
msg = result
raise PreregisterException(msg)

def preregister(self):
'''
Expand Down

0 comments on commit e032fea

Please sign in to comment.