Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workfiles tool: Artists can see users #640

Merged
merged 4 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
106 changes: 93 additions & 13 deletions client/ayon_core/tools/common_models/users.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,80 @@
import json
import collections

import ayon_api
from ayon_api.graphql import FIELD_VALUE, GraphQlQuery, fields_to_dict

from ayon_core.lib import NestedCacheItem


# --- Implementation that should be in ayon-python-api ---
# The implementation is not available in all versions of ayon-python-api.
def users_graphql_query(fields):
query = GraphQlQuery("Users")
names_var = query.add_variable("userNames", "[String!]")
project_name_var = query.add_variable("projectName", "String!")

users_field = query.add_field_with_edges("users")
users_field.set_filter("names", names_var)
users_field.set_filter("projectName", project_name_var)

nested_fields = fields_to_dict(set(fields))

query_queue = collections.deque()
for key, value in nested_fields.items():
query_queue.append((key, value, users_field))

while query_queue:
item = query_queue.popleft()
key, value, parent = item
field = parent.add_field(key)
if value is FIELD_VALUE:
continue

for k, v in value.items():
query_queue.append((k, v, field))
return query


def get_users(project_name=None, usernames=None, fields=None):
"""Get Users.

Only administrators and managers can fetch all users. For other users
it is required to pass in 'project_name' filter.

from ayon_core.lib import CacheItem
Args:
project_name (Optional[str]): Project name.
usernames (Optional[Iterable[str]]): Filter by usernames.
fields (Optional[Iterable[str]]): Fields to be queried
for users.

Returns:
Generator[dict[str, Any]]: Queried users.

"""
filters = {}
if usernames is not None:
usernames = set(usernames)
if not usernames:
return
filters["userNames"] = list(usernames)

if project_name is not None:
filters["projectName"] = project_name

con = ayon_api.get_server_api_connection()
if not fields:
fields = con.get_default_fields_for_type("user")

query = users_graphql_query(set(fields))
for attr, filter_value in filters.items():
query.set_variable_value(attr, filter_value)

for parsed_data in query.continuous_query(con):
for user in parsed_data["users"]:
user["accessGroups"] = json.loads(user["accessGroups"])
yield user
# --- END of ayon-python-api implementation ---


class UserItem:
Expand Down Expand Up @@ -32,19 +106,19 @@ def from_entity_data(cls, user_data):
class UsersModel:
def __init__(self, controller):
self._controller = controller
self._users_cache = CacheItem(default_factory=list)
self._users_cache = NestedCacheItem(default_factory=list)

def get_user_items(self):
def get_user_items(self, project_name):
"""Get user items.

Returns:
List[UserItem]: List of user items.

"""
self._invalidate_cache()
return self._users_cache.get_data()
self._invalidate_cache(project_name)
return self._users_cache[project_name].get_data()

def get_user_items_by_name(self):
def get_user_items_by_name(self, project_name):
"""Get user items by name.

Implemented as most of cases using this model will need to find
Expand All @@ -56,10 +130,10 @@ def get_user_items_by_name(self):
"""
return {
user_item.username: user_item
for user_item in self.get_user_items()
for user_item in self.get_user_items(project_name)
}

def get_user_item_by_username(self, username):
def get_user_item_by_username(self, project_name, username):
"""Get user item by username.

Args:
Expand All @@ -70,15 +144,21 @@ def get_user_item_by_username(self, username):

"""
self._invalidate_cache()
iLLiCiTiT marked this conversation as resolved.
Show resolved Hide resolved
for user_item in self.get_user_items():
for user_item in self.get_user_items(project_name):
if user_item.username == username:
return user_item
return None

def _invalidate_cache(self):
if self._users_cache.is_valid:
def _invalidate_cache(self, project_name):
cache = self._users_cache[project_name]
if cache.is_valid:
return
self._users_cache.update_data([

if project_name is None:
cache.update_data([])
return

self._users_cache[project_name].update_data([
UserItem.from_entity_data(user)
for user in ayon_api.get_users()
for user in get_users(project_name)
])
3 changes: 2 additions & 1 deletion client/ayon_core/tools/workfiles/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ def set_save_enabled(self, enabled):
)

def get_user_items_by_name(self):
return self._users_model.get_user_items_by_name()
project_name = self.get_current_project_name()
return self._users_model.get_user_items_by_name(project_name)

# Host information
def get_workfile_extensions(self):
Expand Down
Loading