Blender Kitsu: Set Custom Thumbnail during Playblast #77
@ -2,16 +2,11 @@ from . import client as raw
|
||||
from . import cache
|
||||
from . import helpers
|
||||
|
||||
try:
|
||||
from . import events
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from . import asset
|
||||
from . import casting
|
||||
from . import context
|
||||
from . import edit
|
||||
from . import entity
|
||||
from . import edit
|
||||
from . import files
|
||||
from . import project
|
||||
from . import person
|
||||
@ -21,11 +16,7 @@ from . import task
|
||||
from . import user
|
||||
from . import playlist
|
||||
|
||||
from .exception import (
|
||||
AuthFailedException,
|
||||
ParameterException,
|
||||
NotAuthenticatedException,
|
||||
)
|
||||
from .exception import AuthFailedException, ParameterException
|
||||
from .__version__ import __version__
|
||||
|
||||
|
||||
@ -37,30 +28,13 @@ def set_host(url, client=raw.default_client):
|
||||
raw.set_host(url, client=client)
|
||||
|
||||
|
||||
def log_in(
|
||||
email,
|
||||
password,
|
||||
totp=None,
|
||||
email_otp=None,
|
||||
fido_authentication_response=None,
|
||||
recovery_code=None,
|
||||
client=raw.default_client,
|
||||
):
|
||||
def log_in(email, password, client=raw.default_client):
|
||||
tokens = {}
|
||||
try:
|
||||
tokens = raw.post(
|
||||
"auth/login",
|
||||
{
|
||||
"email": email,
|
||||
"password": password,
|
||||
"totp": totp,
|
||||
"email_otp": email_otp,
|
||||
"fido_authentication_response": fido_authentication_response,
|
||||
"recovery_code": recovery_code,
|
||||
},
|
||||
client=client,
|
||||
"auth/login", {"email": email, "password": password}, client=client
|
||||
)
|
||||
except (NotAuthenticatedException, ParameterException):
|
||||
except ParameterException:
|
||||
pass
|
||||
|
||||
if not tokens or (
|
||||
@ -72,10 +46,6 @@ def log_in(
|
||||
return tokens
|
||||
|
||||
|
||||
def send_email_otp(email, client=raw.default_client):
|
||||
return raw.get("auth/email-otp", params={"email": email}, client=client)
|
||||
|
||||
|
||||
def log_out(client=raw.default_client):
|
||||
tokens = {}
|
||||
try:
|
||||
@ -86,24 +56,6 @@ def log_out(client=raw.default_client):
|
||||
return tokens
|
||||
|
||||
|
||||
def refresh_token(client=raw.default_client):
|
||||
headers = {"User-Agent": "CGWire Gazu %s" % __version__}
|
||||
if "refresh_token" in client.tokens:
|
||||
headers["Authorization"] = "Bearer %s" % client.tokens["refresh_token"]
|
||||
|
||||
response = client.session.get(
|
||||
raw.get_full_url("auth/refresh-token", client=client),
|
||||
headers=headers,
|
||||
)
|
||||
raw.check_status(response, "auth/refresh-token")
|
||||
|
||||
tokens = response.json()
|
||||
|
||||
client.tokens["access_token"] = tokens["access_token"]
|
||||
|
||||
return tokens
|
||||
|
||||
|
||||
def get_event_host(client=raw.default_client):
|
||||
return raw.get_event_host(client=client)
|
||||
|
||||
|
@ -1 +1 @@
|
||||
__version__ = "0.9.3"
|
||||
__version__ = "0.8.30"
|
||||
|
@ -124,7 +124,7 @@ def get_asset_by_name(project, name, asset_type=None, client=default):
|
||||
def get_asset(asset_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
asset_id (str): ID of claimed asset.
|
||||
asset_id (str): Id of claimed asset.
|
||||
|
||||
Returns:
|
||||
dict: Asset matching given ID.
|
||||
@ -270,7 +270,6 @@ def all_asset_types_for_project(project, client=default):
|
||||
Returns:
|
||||
list: Asset types from assets listed in given project.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
path = "projects/%s/asset-types" % project["id"]
|
||||
return sort_by_name(raw.fetch_all(path, client=client))
|
||||
|
||||
@ -292,7 +291,7 @@ def all_asset_types_for_shot(shot, client=default):
|
||||
def get_asset_type(asset_type_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
asset_type_id (str/): ID of claimed asset type.
|
||||
asset_type_id (str/): Id of claimed asset type.
|
||||
|
||||
Returns:
|
||||
dict: Asset Type matching given ID.
|
||||
@ -359,7 +358,7 @@ def remove_asset_type(asset_type, client=default):
|
||||
def get_asset_instance(asset_instance_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
asset_instance_id (str): ID of claimed asset instance.
|
||||
asset_instance_id (str): Id of claimed asset instance.
|
||||
|
||||
Returns:
|
||||
dict: Asset Instance matching given ID.
|
||||
|
@ -181,6 +181,7 @@ def cache(function, maxsize=300, expire=120):
|
||||
|
||||
@wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
if is_cache_enabled(state):
|
||||
key = get_cache_key(args, kwargs)
|
||||
|
||||
|
@ -3,10 +3,14 @@ import functools
|
||||
import json
|
||||
import shutil
|
||||
import urllib
|
||||
import os
|
||||
|
||||
from .encoder import CustomJSONEncoder
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
from json import JSONDecodeError
|
||||
else:
|
||||
JSONDecodeError = ValueError
|
||||
|
||||
from .__version__ import __version__
|
||||
|
||||
from .exception import (
|
||||
@ -20,13 +24,6 @@ from .exception import (
|
||||
UploadFailedException,
|
||||
)
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
from json import JSONDecodeError
|
||||
else:
|
||||
JSONDecodeError = ValueError
|
||||
|
||||
DEBUG = os.getenv("GAZU_DEBUG", "false").lower() == "true"
|
||||
|
||||
|
||||
class KitsuClient(object):
|
||||
def __init__(self, host, ssl_verify=True, cert=None):
|
||||
@ -50,7 +47,10 @@ try:
|
||||
requests.models.complexjson.dumps = functools.partial(
|
||||
json.dumps, cls=CustomJSONEncoder
|
||||
)
|
||||
host = "http://gazu.change.serverhost/api"
|
||||
# Set host to "" otherwise requests.Session() takes a long time during Blender startup
|
||||
# Whyever that is.
|
||||
# host = "http://gazu.change.serverhost/api"
|
||||
host = ""
|
||||
default_client = create_client(host)
|
||||
except Exception:
|
||||
print("Warning, running in setup mode!")
|
||||
@ -77,9 +77,9 @@ def host_is_valid(client=default_client):
|
||||
if not host_is_up(client):
|
||||
return False
|
||||
try:
|
||||
post("auth/login", {"email": ""})
|
||||
post("auth/login", {"email": "", "password": ""})
|
||||
except Exception as exc:
|
||||
return isinstance(exc, (NotAuthenticatedException, ParameterException))
|
||||
return type(exc) == ParameterException
|
||||
|
||||
|
||||
def get_host(client=default_client):
|
||||
@ -196,8 +196,6 @@ def get(path, json_response=True, params=None, client=default_client):
|
||||
Returns:
|
||||
The request result.
|
||||
"""
|
||||
if DEBUG:
|
||||
print("GET", get_full_url(path, client))
|
||||
path = build_path_with_params(path, params)
|
||||
response = client.session.get(
|
||||
get_full_url(path, client=client),
|
||||
@ -218,10 +216,6 @@ def post(path, data, client=default_client):
|
||||
Returns:
|
||||
The request result.
|
||||
"""
|
||||
if DEBUG:
|
||||
print("POST", get_full_url(path, client))
|
||||
if not "password" in data:
|
||||
print("Body:", data)
|
||||
response = client.session.post(
|
||||
get_full_url(path, client),
|
||||
json=data,
|
||||
@ -243,9 +237,6 @@ def put(path, data, client=default_client):
|
||||
Returns:
|
||||
The request result.
|
||||
"""
|
||||
if DEBUG:
|
||||
print("PUT", get_full_url(path, client))
|
||||
print("Body:", data)
|
||||
response = client.session.put(
|
||||
get_full_url(path, client),
|
||||
json=data,
|
||||
@ -262,8 +253,6 @@ def delete(path, params=None, client=default_client):
|
||||
Returns:
|
||||
The request result.
|
||||
"""
|
||||
if DEBUG:
|
||||
print("DELETE", get_full_url(path, client))
|
||||
path = build_path_with_params(path, params)
|
||||
|
||||
response = client.session.delete(
|
||||
|
@ -1,147 +1,59 @@
|
||||
from blender_kitsu import gazu
|
||||
from . import client as raw
|
||||
from .sorting import sort_by_name
|
||||
|
||||
from .cache import cache
|
||||
from .helpers import normalize_model_parameter
|
||||
|
||||
default = raw.default_client
|
||||
|
||||
@cache
|
||||
def get_all_edits(relations=False, client=default):
|
||||
"""
|
||||
Retrieve all edit entries.
|
||||
"""
|
||||
params = {}
|
||||
if relations:
|
||||
params = {"relations": "true"}
|
||||
path = "edits/all"
|
||||
edits = raw.fetch_all(path, params, client=client)
|
||||
return sort_by_name(edits)
|
||||
|
||||
@cache
|
||||
def get_edit(edit_id, client=default):
|
||||
def get_edit(edit_id, relations=False, client=default):
|
||||
"""
|
||||
Args:
|
||||
edit_id (str): ID of claimed edit.
|
||||
|
||||
Returns:
|
||||
dict: Edit corresponding to given edit ID.
|
||||
Retrieve all edit entries.
|
||||
"""
|
||||
return raw.fetch_one("edits", edit_id, client=client)
|
||||
|
||||
edit_entry = normalize_model_parameter(edit_id)
|
||||
params = {}
|
||||
if relations:
|
||||
params = {"relations": "true"}
|
||||
path = f"edits/{edit_entry['id']}"
|
||||
edit_entry = raw.fetch_all(path, params, client=client)
|
||||
return edit_entry
|
||||
|
||||
@cache
|
||||
def get_edit_by_name(project, edit_name, client=default):
|
||||
def get_all_edits_with_tasks(relations=False, client=default):
|
||||
"""
|
||||
Args:
|
||||
project (str / dict): The project dict or the project ID.
|
||||
edit_name (str): Name of claimed edit.
|
||||
|
||||
Returns:
|
||||
dict: Edit corresponding to given name and sequence.
|
||||
Retrieve all edit entries.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
return raw.fetch_first(
|
||||
"edits/all",
|
||||
{"project_id": project["id"], "name": edit_name},
|
||||
client=client,
|
||||
)
|
||||
|
||||
params = {}
|
||||
if relations:
|
||||
params = {"relations": "true"}
|
||||
path = "edits/with-tasks"
|
||||
edits_with_tasks = raw.fetch_all(path, params, client=client)
|
||||
return sort_by_name(edits_with_tasks)
|
||||
|
||||
@cache
|
||||
def get_edit_url(edit, client=default):
|
||||
def get_all_previews_for_edit(edit, client=default):
|
||||
"""
|
||||
Args:
|
||||
edit (str / dict): The edit dict or the edit ID.
|
||||
|
||||
Returns:
|
||||
url (str): Web url associated to the given edit
|
||||
"""
|
||||
edit = normalize_model_parameter(edit)
|
||||
edit = get_edit(edit["id"])
|
||||
path = "{host}/productions/{project_id}/"
|
||||
if edit["episode_id"] is None:
|
||||
path += "edits/{edit_id}/"
|
||||
else:
|
||||
path += "episodes/{episode_id}/edits/{edit_id}/"
|
||||
return path.format(
|
||||
host=raw.get_api_url_from_host(client=client),
|
||||
project_id=edit["project_id"],
|
||||
edit_id=edit["id"],
|
||||
episode_id=edit["episode_id"],
|
||||
)
|
||||
|
||||
|
||||
def new_edit(
|
||||
project,
|
||||
name,
|
||||
description=None,
|
||||
data={},
|
||||
episode=None,
|
||||
client=default,
|
||||
):
|
||||
"""
|
||||
Create an edit for given project (and episode if given).
|
||||
Allow to set metadata too.
|
||||
|
||||
Args:
|
||||
project (str / dict): The project dict or the project ID.
|
||||
name (str): The name of the edit to create.
|
||||
description (str): The description of the edit to create.
|
||||
data (dict): Free field to set metadata of any kind.
|
||||
episode (str / dict): The episode dict or the episode ID.
|
||||
|
||||
Returns:
|
||||
Created edit.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
if episode is not None:
|
||||
episode = normalize_model_parameter(episode)
|
||||
|
||||
data = {"name": name, "data": data, "parent_id": episode["id"]}
|
||||
|
||||
if description is not None:
|
||||
data["description"] = description
|
||||
|
||||
edit = get_edit_by_name(project, name, client=client)
|
||||
if edit is None:
|
||||
path = "data/projects/%s/edits" % project["id"]
|
||||
return raw.post(path, data, client=client)
|
||||
else:
|
||||
return edit
|
||||
|
||||
|
||||
def remove_edit(edit, force=False, client=default):
|
||||
"""
|
||||
Remove given edit from database.
|
||||
|
||||
Args:
|
||||
edit (dict / str): Edit to remove.
|
||||
list: Shots which are children of given episode.
|
||||
"""
|
||||
edit = normalize_model_parameter(edit)
|
||||
path = "data/edits/%s" % edit["id"]
|
||||
params = {}
|
||||
if force:
|
||||
params = {"force": "true"}
|
||||
return raw.delete(path, params, client=client)
|
||||
|
||||
|
||||
def update_edit(edit, client=default):
|
||||
"""
|
||||
Save given edit data into the API. Metadata are fully replaced by the ones
|
||||
set on given edit.
|
||||
|
||||
Args:
|
||||
edit (dict): The edit dict to update.
|
||||
|
||||
Returns:
|
||||
dict: Updated edit.
|
||||
"""
|
||||
return raw.put("data/entities/%s" % edit["id"], edit, client=client)
|
||||
|
||||
|
||||
def update_edit_data(edit, data={}, client=default):
|
||||
"""
|
||||
Update the metadata for the provided edit. Keys that are not provided are
|
||||
not changed.
|
||||
|
||||
Args:
|
||||
edit (dict / ID): The edit dict or ID to save in database.
|
||||
data (dict): Free field to set metadata of any kind.
|
||||
|
||||
Returns:
|
||||
dict: Updated edit.
|
||||
"""
|
||||
edit = normalize_model_parameter(edit)
|
||||
current_edit = get_edit(edit["id"], client=client)
|
||||
updated_edit = {"id": current_edit["id"], "data": current_edit["data"]}
|
||||
updated_edit["data"].update(data)
|
||||
return update_edit(updated_edit, client=client)
|
||||
edit_previews = (raw.fetch_all(f"edits/{edit['id']}/preview-files", client=client))
|
||||
for key in [key for key in enumerate(edit_previews.keys())]:
|
||||
return edit_previews[key[1]]
|
@ -29,36 +29,33 @@ def all_entity_types(client=default):
|
||||
def get_entity(entity_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
entity_id (str): ID of claimed entity.
|
||||
id (str, client=default): ID of claimed entity.
|
||||
|
||||
Returns:
|
||||
dict: Retrieve entity matching given ID (it can be an entity of any
|
||||
dict: Retrieve entity matching given ID (It can be an entity of any
|
||||
kind: asset, shot, sequence or episode).
|
||||
"""
|
||||
return raw.fetch_one("entities", entity_id, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
def get_entity_by_name(entity_name, project=None, client=default):
|
||||
def get_entity_by_name(entity_name, client=default):
|
||||
"""
|
||||
Args:
|
||||
name (str): The name of the claimed entity.
|
||||
project (str, dict): Project ID or dict.
|
||||
name (str, client=default): The name of the claimed entity.
|
||||
|
||||
Returns:
|
||||
Retrieve entity matching given name (and project if given).
|
||||
Retrieve entity matching given name.
|
||||
"""
|
||||
params = {"name": entity_name}
|
||||
if project is not None:
|
||||
project = normalize_model_parameter(project)
|
||||
params["project_id"] = project["id"]
|
||||
return raw.fetch_first("entities", params, client=client)
|
||||
return raw.fetch_first("entities", {"name": entity_name}, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
def get_entity_type(entity_type_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
entity_type_id (str): ID of claimed entity type.
|
||||
id (str, client=default): ID of claimed entity type.
|
||||
, client=client
|
||||
Returns:
|
||||
Retrieve entity type matching given ID (It can be an entity type of any
|
||||
kind).
|
||||
@ -80,41 +77,6 @@ def get_entity_type_by_name(entity_type_name, client=default):
|
||||
)
|
||||
|
||||
|
||||
@cache
|
||||
def guess_from_path(project_id, path, sep="/"):
|
||||
"""
|
||||
Get list of possible project file tree templates matching a file path
|
||||
and data ids corresponding to template tokens.
|
||||
|
||||
Args:
|
||||
project_id (str): Project id of given file
|
||||
file_path (str): Path to a file
|
||||
sep (str): File path separator, defaults to "/"
|
||||
Returns:
|
||||
list: dictionnaries with the corresponding entities and template name.
|
||||
|
||||
Example:
|
||||
.. code-block:: text
|
||||
|
||||
[
|
||||
{
|
||||
'Asset': '<asset_id>',
|
||||
'Project': '<project_id>',
|
||||
'Template': 'asset'
|
||||
},
|
||||
{
|
||||
'Project': '<project_id>',
|
||||
'Template': 'instance'
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
return raw.post(
|
||||
"/data/entities/guess_from_path",
|
||||
{"project_id": project_id, "file_path": path, "sep": sep},
|
||||
)
|
||||
|
||||
|
||||
def new_entity_type(name, client=default):
|
||||
"""
|
||||
Creates an entity type with the given name.
|
||||
@ -142,3 +104,16 @@ def remove_entity(entity, force=False, client=default):
|
||||
if force:
|
||||
params = {"force": "true"}
|
||||
return raw.delete(path, params, client=client)
|
||||
|
||||
def update_entity(entity, client=default):
|
||||
"""
|
||||
Save given shot data into the API. Metadata are fully replaced by the ones
|
||||
set on given shot.
|
||||
|
||||
Args:
|
||||
Entity (dict): The shot dict to update.
|
||||
|
||||
Returns:
|
||||
dict: Updated entity.
|
||||
"""
|
||||
return raw.put(f"data/entities/{entity['id']}", entity, client=client)
|
@ -1,71 +0,0 @@
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
raise ImportError(
|
||||
"The events part of Gazu is not available for Python 2.7"
|
||||
)
|
||||
from .exception import AuthFailedException
|
||||
from .client import default_client, get_event_host
|
||||
from gazu.client import make_auth_header
|
||||
import socketio
|
||||
|
||||
|
||||
class EventsNamespace(socketio.ClientNamespace):
|
||||
def on_connect(self):
|
||||
pass
|
||||
|
||||
def on_disconnect(self):
|
||||
pass
|
||||
|
||||
def on_error(self, data):
|
||||
return connect_error(data)
|
||||
|
||||
|
||||
def init(
|
||||
client=default_client,
|
||||
ssl_verify=False,
|
||||
reconnection=True,
|
||||
logger=False,
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
Init configuration for SocketIO client.
|
||||
|
||||
Returns:
|
||||
Event client that will be able to set listeners.
|
||||
"""
|
||||
params = {"ssl_verify": ssl_verify}
|
||||
params.update(kwargs)
|
||||
event_client = socketio.Client(
|
||||
logger=logger, reconnection=reconnection, **params
|
||||
)
|
||||
event_client.on("connect_error", connect_error)
|
||||
event_client.register_namespace(EventsNamespace("/events"))
|
||||
event_client.connect(get_event_host(client), make_auth_header())
|
||||
return event_client
|
||||
|
||||
|
||||
def connect_error(data):
|
||||
print("The connection failed!")
|
||||
return data
|
||||
|
||||
|
||||
def add_listener(event_client, event_name, event_handler):
|
||||
"""
|
||||
Set a listener that reacts to a given event.
|
||||
"""
|
||||
event_client.on(event_name, event_handler, "/events")
|
||||
return event_client
|
||||
|
||||
|
||||
def run_client(event_client):
|
||||
"""
|
||||
Run event client (it blocks current thread). It listens to all events
|
||||
configured.
|
||||
"""
|
||||
try:
|
||||
print("Listening to Kitsu events...")
|
||||
event_client.wait()
|
||||
except TypeError:
|
||||
raise AuthFailedException
|
||||
return event_client
|
@ -79,7 +79,7 @@ class TooBigFileException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TaskStatusNotFoundException(Exception):
|
||||
class TaskStatusNotFound(Exception):
|
||||
"""
|
||||
Error raised when a task status is not found.
|
||||
"""
|
||||
@ -91,9 +91,3 @@ class DownloadFileException(Exception):
|
||||
"""
|
||||
Error raised when a file can't be downloaded.
|
||||
"""
|
||||
|
||||
|
||||
class TaskMustBeADictException(Exception):
|
||||
"""
|
||||
Error raised when a task should be a dict.
|
||||
"""
|
||||
|
@ -1083,7 +1083,7 @@ def download_preview_file(preview_file, file_path, client=default):
|
||||
file_path (str): Location on hard drive where to save the file.
|
||||
"""
|
||||
return raw.download(
|
||||
get_preview_file_url(preview_file, client=client),
|
||||
get_preview_file_url(preview_file),
|
||||
file_path,
|
||||
client=client,
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import sys
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import datetime
|
||||
import shutil
|
||||
|
@ -38,61 +38,15 @@ def all_persons(client=default):
|
||||
|
||||
|
||||
@cache
|
||||
def get_time_spents_range(person_id, start_date, end_date, client=default):
|
||||
"""
|
||||
Gets the time spents of the current user for the given date range.
|
||||
|
||||
Args:
|
||||
person_id (str): An uuid identifying a person.
|
||||
start_date (str): The first day of the date range as a date string with
|
||||
the following format: YYYY-MM-DD
|
||||
end_date (str): The last day of the date range as a date string with
|
||||
the following format: YYYY-MM-DD
|
||||
Returns:
|
||||
list: All of the person's time spents
|
||||
"""
|
||||
date_range = {
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
}
|
||||
return raw.get(
|
||||
"/data/persons/{}/time-spents".format(person_id),
|
||||
params=date_range,
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
||||
def get_all_month_time_spents(id, date, client=default):
|
||||
def get_person(id, client=default):
|
||||
"""
|
||||
Args:
|
||||
id (str): An uuid identifying a person.
|
||||
date (datetime.date): The date of the month to query.
|
||||
|
||||
Returns:
|
||||
list: All of the person's time spents for the given month.
|
||||
"""
|
||||
date = date.strftime("%Y/%m")
|
||||
return raw.get(
|
||||
"data/persons/{}/time-spents/month/all/{}".format(id, date),
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
||||
@cache
|
||||
def get_person(id, relations=False, client=default):
|
||||
"""
|
||||
Args:
|
||||
id (str): An uuid identifying a person.
|
||||
relations (bool): Whether to get the relations for the given person.
|
||||
|
||||
Returns:
|
||||
dict: Person corresponding to given id.
|
||||
"""
|
||||
params = {"id": id}
|
||||
if relations:
|
||||
params["relations"] = "true"
|
||||
|
||||
return raw.fetch_first("persons", params=params, client=client)
|
||||
return raw.fetch_one("persons", id, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
@ -198,7 +152,7 @@ def new_person(
|
||||
Returns:
|
||||
dict: Created person.
|
||||
"""
|
||||
person = get_person_by_email(email, client=client)
|
||||
person = get_person_by_email(email)
|
||||
if person is None:
|
||||
person = raw.post(
|
||||
"data/persons/new",
|
||||
|
@ -256,7 +256,6 @@ def add_metadata_descriptor(
|
||||
project,
|
||||
name,
|
||||
entity_type,
|
||||
data_type="string",
|
||||
choices=[],
|
||||
for_client=False,
|
||||
departments=[],
|
||||
@ -279,7 +278,6 @@ def add_metadata_descriptor(
|
||||
project = normalize_model_parameter(project)
|
||||
data = {
|
||||
"name": name,
|
||||
"data_type": data_type,
|
||||
"choices": choices,
|
||||
"for_client": for_client,
|
||||
"entity_type": entity_type,
|
||||
@ -294,27 +292,7 @@ def add_metadata_descriptor(
|
||||
|
||||
def get_metadata_descriptor(project, metadata_descriptor_id, client=default):
|
||||
"""
|
||||
Retrieve a the metadata descriptor matching given ID.
|
||||
|
||||
Args:
|
||||
project (dict / ID): The project dict or id.
|
||||
metadata_descriptor_id (dict / ID): The metadata descriptor dict or id.
|
||||
|
||||
Returns:
|
||||
dict: The metadata descriptor matching the ID.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
metadata_descriptor = normalize_model_parameter(metadata_descriptor_id)
|
||||
return raw.fetch_one(
|
||||
"projects/%s/metadata-descriptors" % project["id"],
|
||||
metadata_descriptor["id"],
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
||||
def get_metadata_descriptor_by_field_name(project, field_name, client=default):
|
||||
"""
|
||||
Get a metadata descriptor matchind given project and name.
|
||||
Get a metadata descriptor matchind it's ID.
|
||||
|
||||
Args:
|
||||
project (dict / ID): The project dict or id.
|
||||
@ -324,12 +302,10 @@ def get_metadata_descriptor_by_field_name(project, field_name, client=default):
|
||||
dict: The metadata descriptor matchind the ID.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
return raw.fetch_first(
|
||||
"metadata-descriptors",
|
||||
params={
|
||||
"project_id": project["id"],
|
||||
"field_name": field_name,
|
||||
},
|
||||
metadata_descriptor = normalize_model_parameter(metadata_descriptor_id)
|
||||
return raw.fetch_one(
|
||||
"projects/%s/metadata-descriptors" % project["id"],
|
||||
metadata_descriptor["id"],
|
||||
client=client,
|
||||
)
|
||||
|
||||
@ -399,46 +375,3 @@ def remove_metadata_descriptor(
|
||||
params,
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
||||
def get_team(project, client=default):
|
||||
"""
|
||||
Get team for project.
|
||||
|
||||
Args:
|
||||
project (dict / ID): The project dict or id.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
return raw.fetch_all("projects/%s/team" % project["id"], client=client)
|
||||
|
||||
|
||||
def add_person_to_team(project, person, client=default):
|
||||
"""
|
||||
Add a person to the team project.
|
||||
|
||||
Args:
|
||||
project (dict / ID): The project dict or id.
|
||||
person (dict / ID): The person dict or id.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
person = normalize_model_parameter(person)
|
||||
data = {"person_id": person["id"]}
|
||||
return raw.post(
|
||||
"data/projects/%s/team" % project["id"], data, client=client
|
||||
)
|
||||
|
||||
|
||||
def remove_person_from_team(project, person, client=default):
|
||||
"""
|
||||
Remove a person from the team project.
|
||||
|
||||
Args:
|
||||
project (dict / ID): The project dict or id.
|
||||
person (dict / ID): The person dict or id.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
person = normalize_model_parameter(person)
|
||||
return raw.delete(
|
||||
"data/projects/%s/team/%s" % (project["id"], person["id"]),
|
||||
client=client,
|
||||
)
|
||||
|
@ -14,9 +14,9 @@ def new_scene(project, sequence, name, client=default):
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
sequence = normalize_model_parameter(sequence)
|
||||
scene = {"name": name, "sequence_id": sequence["id"]}
|
||||
shot = {"name": name, "sequence_id": sequence["id"]}
|
||||
return raw.post(
|
||||
"data/projects/%s/scenes" % project["id"], scene, client=client
|
||||
"data/projects/%s/scenes" % project["id"], shot, client=client
|
||||
)
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ def all_episodes_for_project(project, client=default):
|
||||
def get_episode(episode_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
episode_id (str): ID of claimed episode.
|
||||
episode_id (str): Id of claimed episode.
|
||||
|
||||
Returns:
|
||||
dict: Episode corresponding to given episode ID.
|
||||
@ -205,7 +205,7 @@ def get_sequence_from_shot(shot, client=default):
|
||||
def get_shot(shot_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
shot_id (str): ID of claimed shot.
|
||||
shot_id (str): Id of claimed shot.
|
||||
|
||||
Returns:
|
||||
dict: Shot corresponding to given shot ID.
|
||||
|
@ -1,15 +1,4 @@
|
||||
import os
|
||||
|
||||
from .helpers import normalize_model_parameter
|
||||
|
||||
from . import client as raw
|
||||
from . import asset as asset_module
|
||||
from . import casting as casting_module
|
||||
from . import person as person_module
|
||||
from . import project as project_module
|
||||
from . import files as files_module
|
||||
from . import shot as shot_module
|
||||
from . import task as task_module
|
||||
|
||||
from .helpers import normalize_model_parameter, validate_date_format
|
||||
|
||||
@ -17,12 +6,7 @@ default = raw.default_client
|
||||
|
||||
|
||||
def get_last_events(
|
||||
page_size=20000,
|
||||
project=None,
|
||||
after=None,
|
||||
before=None,
|
||||
only_files=False,
|
||||
client=default,
|
||||
page_size=20000, project=None, after=None, before=None, client=default
|
||||
):
|
||||
"""
|
||||
Get last events that occured on the machine.
|
||||
@ -32,13 +16,13 @@ def get_last_events(
|
||||
project (dict/id): Get only events related to this project.
|
||||
after (dict/id): Get only events occuring after given date.
|
||||
before (dict/id): Get only events occuring before given date.
|
||||
only_files (bool): Get only events related to files.
|
||||
|
||||
|
||||
Returns:
|
||||
dict: Last events matching criterions.
|
||||
"""
|
||||
path = "/data/events/last"
|
||||
params = {"page_size": page_size, "only_files": only_files}
|
||||
params = {"page_size": page_size}
|
||||
if project is not None:
|
||||
project = normalize_model_parameter(project)
|
||||
params["project_id"] = project["id"]
|
||||
@ -183,447 +167,6 @@ def get_id_map_by_id(source_list, target_list, field="name"):
|
||||
|
||||
|
||||
def is_changed(source_model, target_model):
|
||||
"""
|
||||
Args:
|
||||
source_model (dict): Model from the source API.
|
||||
target_model (dict): Matching model from the target API.
|
||||
|
||||
Returns:
|
||||
bool: True if the source model is older than the target model (based on
|
||||
`updated_at` field)
|
||||
"""
|
||||
source_date = source_model["updated_at"]
|
||||
target_date = target_model["updated_at"]
|
||||
return source_date > target_date
|
||||
|
||||
|
||||
def get_sync_department_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source departments ids with target department ids
|
||||
"""
|
||||
departments_source = person_module.all_departments(client=source_client)
|
||||
departments_target = person_module.all_departments(client=target_client)
|
||||
return get_id_map_by_id(departments_source, departments_target)
|
||||
|
||||
|
||||
def get_sync_asset_type_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source asset type ids with target asset type ids
|
||||
"""
|
||||
asset_types_source = asset_module.all_asset_types(client=source_client)
|
||||
asset_types_target = asset_module.all_asset_types(client=target_client)
|
||||
return get_id_map_by_id(asset_types_source, asset_types_target)
|
||||
|
||||
|
||||
def get_sync_project_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source project ids with target project ids
|
||||
"""
|
||||
projects_source = project_module.all_projects(client=source_client)
|
||||
projects_target = project_module.all_projects(client=target_client)
|
||||
return get_id_map_by_id(projects_source, projects_target)
|
||||
|
||||
|
||||
def get_sync_task_type_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source task type ids with target task type ids
|
||||
"""
|
||||
task_types_source = task_module.all_task_types(client=source_client)
|
||||
task_types_target = task_module.all_task_types(client=target_client)
|
||||
return get_id_map_by_id(task_types_source, task_types_target)
|
||||
|
||||
|
||||
def get_sync_task_status_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source task status ids with target task status
|
||||
ids
|
||||
"""
|
||||
task_statuses_source = task_module.all_task_statuses(client=source_client)
|
||||
task_statuses_target = task_module.all_task_statuses(client=target_client)
|
||||
return get_id_map_by_id(task_statuses_source, task_statuses_target)
|
||||
|
||||
|
||||
def get_sync_person_id_map(source_client, target_client):
|
||||
"""
|
||||
Args:
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: A dict matching source person ids with target person ids
|
||||
"""
|
||||
persons_source = person_module.all_persons(client=source_client)
|
||||
persons_target = person_module.all_persons(client=target_client)
|
||||
return get_id_map_by_id(persons_source, persons_target, field="email")
|
||||
|
||||
|
||||
def push_assets(project_source, project_target, client_source, client_target):
|
||||
"""
|
||||
Copy assets from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed assets
|
||||
"""
|
||||
asset_types_map = get_sync_asset_type_id_map(client_source, client_target)
|
||||
task_types_map = get_sync_task_type_id_map(client_source, client_target)
|
||||
assets = asset_module.all_assets_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for asset in assets:
|
||||
asset["entity_type_id"] = asset_types_map[asset["entity_type_id"]]
|
||||
if asset["ready_for"] is not None:
|
||||
asset["ready_for"] = task_types_map[asset["ready_for"]]
|
||||
asset["project_id"] = project_target["id"]
|
||||
return import_entities(assets, client=client_target)
|
||||
|
||||
|
||||
def push_episodes(
|
||||
project_source, project_target, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Copy episodes from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get episodes from
|
||||
project_target (dict): The project to push episodes to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed episodes
|
||||
"""
|
||||
episodes = shot_module.all_episodes_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for episode in episodes:
|
||||
episode["project_id"] = project_target["id"]
|
||||
return import_entities(episodes, client=client_target)
|
||||
|
||||
|
||||
def push_sequences(
|
||||
project_source, project_target, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Copy sequences from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get sequences from
|
||||
project_target (dict): The project to push sequences to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed sequences
|
||||
"""
|
||||
sequences = shot_module.all_sequences_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for sequence in sequences:
|
||||
sequence["project_id"] = project_target["id"]
|
||||
return import_entities(sequences, client=client_target)
|
||||
|
||||
|
||||
def push_shots(project_source, project_target, client_source, client_target):
|
||||
"""
|
||||
Copy shots from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get shots from
|
||||
project_target (dict): The project to push shots to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed shots
|
||||
"""
|
||||
shots = shot_module.all_shots_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for shot in shots:
|
||||
shot["project_id"] = project_target["id"]
|
||||
return import_entities(shots, client=client_target)
|
||||
|
||||
|
||||
def push_entity_links(
|
||||
project_source, project_target, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Copy assets from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed entity links
|
||||
"""
|
||||
links = casting_module.all_entity_links_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
return import_entity_links(links, client=client_target)
|
||||
|
||||
|
||||
def push_project_entities(
|
||||
project_source, project_target, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Copy assets, episodes, sequences, shots and entity links from source to
|
||||
target and preserve audit fields (`id`, `created_at`, and `updated_at`)
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
dict: Pushed data
|
||||
"""
|
||||
assets = push_assets(project_source, project_target)
|
||||
episodes = []
|
||||
if project_source["production_type"] == "tvshow":
|
||||
episodes = push_episodes(project_source, project_target)
|
||||
sequences = push_sequences(project_source, project_target)
|
||||
shots = push_shots(project_source, project_target)
|
||||
entity_links = push_entity_links(project_source, project_target)
|
||||
return {
|
||||
"assets": assets,
|
||||
"episodes": episodes,
|
||||
"sequences": sequences,
|
||||
"shots": shots,
|
||||
"entity_links": entity_links,
|
||||
}
|
||||
|
||||
|
||||
def push_tasks(
|
||||
project_source,
|
||||
project_target,
|
||||
default_status,
|
||||
client_source,
|
||||
client_target,
|
||||
):
|
||||
"""
|
||||
Copy tasks from source to target and preserve audit fields (`id`,
|
||||
`created_at`, and `updated_at`)
|
||||
Attachments and previews are created too.
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Pushed entity links
|
||||
"""
|
||||
|
||||
default_status_id = normalize_model_parameter(default_status)["id"]
|
||||
task_type_map = get_sync_task_type_id_map(client_source, client_target)
|
||||
task_status_map = get_sync_task_status_id_map(client_source, client_target)
|
||||
person_map = get_sync_person_id_map(client_source, client_target)
|
||||
|
||||
tasks = task_module.all_tasks_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for task in tasks:
|
||||
task["task_type_id"] = task_type_map[task["task_type_id"]]
|
||||
task["task_status_id"] = default_status_id
|
||||
task["assigner_id"] = person_map[task["assigner_id"]]
|
||||
task["project_id"] = project_target["id"]
|
||||
|
||||
task["assignees"] = [
|
||||
person_map[person_id] for person_id in task["assignees"]
|
||||
]
|
||||
return import_tasks(tasks, client=client_target)
|
||||
|
||||
|
||||
def push_tasks_comments(project_source, client_source, client_target):
|
||||
"""
|
||||
Create a new comment into target api for each comment in source project
|
||||
but preserve only `created_at` field.
|
||||
Attachments and previews are created too.
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Created comments
|
||||
"""
|
||||
|
||||
task_status_map = get_sync_task_status_id_map(client_source, client_target)
|
||||
person_map = get_sync_person_id_map(client_source, client_target)
|
||||
tasks = task_module.all_tasks_for_project(
|
||||
project_source, client=client_source
|
||||
)
|
||||
for task in tasks:
|
||||
push_task_comments(
|
||||
task_status_map, person_map, task, client_source, client_target
|
||||
)
|
||||
return tasks
|
||||
|
||||
|
||||
def push_task_comments(
|
||||
task_status_map, person_map, task, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Create a new comment into target api for each comment in source task
|
||||
but preserve only `created_at` field.
|
||||
Attachments and previews are created too.
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Created comments
|
||||
"""
|
||||
comments = task_module.all_comments_for_task(task, client=client_source)
|
||||
comments.reverse()
|
||||
comments_target = []
|
||||
for comment in comments:
|
||||
comment_target = push_task_comment(
|
||||
task_status_map,
|
||||
person_map,
|
||||
task,
|
||||
comment,
|
||||
client_source,
|
||||
client_target,
|
||||
)
|
||||
comments_target.append(comment_target)
|
||||
return comments_target
|
||||
|
||||
|
||||
def push_task_comment(
|
||||
task_status_map, person_map, task, comment, client_source, client_target
|
||||
):
|
||||
"""
|
||||
Create a new comment into target api for each comment in source task
|
||||
but preserve only `created_at` field.
|
||||
Attachments and previews are created too.
|
||||
Args:
|
||||
project_source (dict): The project to get assets from
|
||||
project_target (dict): The project to push assets to
|
||||
source_client (KitsuClient): client to get data from source API
|
||||
target_client (KitsuClient): client to push data to target API
|
||||
|
||||
Returns:
|
||||
list: Created comments
|
||||
"""
|
||||
attachments = []
|
||||
for attachment_id in comment["attachment_files"]:
|
||||
if type(attachment_id) == dict:
|
||||
attachment_id = attachment_id["id"]
|
||||
attachment_file = gazu.files.get_attachment_file(
|
||||
attachment_id, client=client_source
|
||||
)
|
||||
file_path = "/tmp/zou/sync/" + attachment_file["name"]
|
||||
files_module.download_attachment_file(
|
||||
attachment_file, file_path, client=client_source
|
||||
)
|
||||
attachments.append(file_path)
|
||||
|
||||
previews = []
|
||||
for preview_file in comment["previews"]:
|
||||
if type(preview_file) is str:
|
||||
preview_file_id = preview_file
|
||||
else:
|
||||
preview_file_id = preview_file["id"]
|
||||
preview_file = files_module.get_preview_file(
|
||||
preview_file_id, client=client_source
|
||||
)
|
||||
if (
|
||||
preview_file["original_name"] is not None
|
||||
and preview_file["extension"] is not None
|
||||
):
|
||||
file_path = (
|
||||
"/tmp/zou/sync/"
|
||||
+ preview_file["original_name"]
|
||||
+ "."
|
||||
+ preview_file["extension"]
|
||||
)
|
||||
files_module.download_preview_file(
|
||||
preview_file, file_path, client=client_source
|
||||
)
|
||||
previews.append(
|
||||
{
|
||||
"file_path": file_path,
|
||||
"annotations": preview_file["annotations"],
|
||||
}
|
||||
)
|
||||
|
||||
task_status = {"id": task_status_map[comment["task_status_id"]]}
|
||||
author_id = person_map[comment["person_id"]]
|
||||
person = {"id": author_id}
|
||||
|
||||
comment_target = task_module.add_comment(
|
||||
task,
|
||||
task_status,
|
||||
attachments=attachments,
|
||||
comment=comment["text"],
|
||||
created_at=comment["created_at"],
|
||||
person=person,
|
||||
checklist=comment["checklist"] or [],
|
||||
client=client_target,
|
||||
)
|
||||
|
||||
for preview in previews:
|
||||
new_preview_file = task_module.add_preview(
|
||||
task, comment_target, preview["file_path"], client=client_target
|
||||
)
|
||||
files_module.update_preview(
|
||||
new_preview_file,
|
||||
{"annotations": preview["annotations"]},
|
||||
client=client_target,
|
||||
)
|
||||
os.remove(preview["file_path"])
|
||||
|
||||
for attachment_path in attachments:
|
||||
os.remove(attachment_path)
|
||||
|
||||
return comment
|
||||
|
||||
|
||||
def convert_id_list(ids, model_map):
|
||||
"""
|
||||
Args:
|
||||
ids (list): Ids to convert.
|
||||
model_map (dict): Map matching ids to another value.c
|
||||
|
||||
Returns:
|
||||
list: Ids converted through given model map.
|
||||
"""
|
||||
return [model_map[id] for id in ids]
|
||||
|
@ -46,9 +46,7 @@ def all_task_types_for_project(project, client=default):
|
||||
list: Task types stored in database.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
task_types = raw.fetch_all(
|
||||
"projects/%s/task-types" % project["id"], client=client
|
||||
)
|
||||
task_types = raw.fetch_all("projects/%s/task-types" % project["id"], client=client)
|
||||
return sort_by_name(task_types)
|
||||
|
||||
|
||||
@ -150,6 +148,20 @@ def all_tasks_for_episode(episode, relations=False, client=default):
|
||||
return sort_by_name(tasks)
|
||||
|
||||
|
||||
@cache
|
||||
def all_tasks_for_edit(edit, relations=False, client=default):
|
||||
"""
|
||||
Retrieve all tasks directly linked to given edit.
|
||||
"""
|
||||
edit = normalize_model_parameter(edit)
|
||||
params = {}
|
||||
if relations:
|
||||
params = {"relations": "true"}
|
||||
path = "edits/%s/tasks" % edit["id"]
|
||||
tasks = raw.fetch_all(path, params, client=client)
|
||||
return sort_by_name(tasks)
|
||||
|
||||
|
||||
@cache
|
||||
def all_shot_tasks_for_sequence(sequence, relations=False, client=default):
|
||||
"""
|
||||
@ -264,9 +276,7 @@ def all_task_types_for_asset(asset, client=default):
|
||||
list: Task types of tasks related to given asset.
|
||||
"""
|
||||
asset = normalize_model_parameter(asset)
|
||||
task_types = raw.fetch_all(
|
||||
"assets/%s/task-types" % asset["id"], client=client
|
||||
)
|
||||
task_types = raw.fetch_all("assets/%s/task-types" % asset["id"], client=client)
|
||||
return sort_by_name(task_types)
|
||||
|
||||
|
||||
@ -383,7 +393,7 @@ def get_task_by_name(entity, task_type, name="main", client=default):
|
||||
def get_task_type(task_type_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
task_type_id (str): ID of claimed task type.
|
||||
task_type_id (str): Id of claimed task type.
|
||||
|
||||
Returns:
|
||||
dict: Task type matching given ID.
|
||||
@ -400,9 +410,7 @@ def get_task_type_by_name(task_type_name, client=default):
|
||||
Returns:
|
||||
dict: Task type object for given name.
|
||||
"""
|
||||
return raw.fetch_first(
|
||||
"task-types", {"name": task_type_name}, client=client
|
||||
)
|
||||
return raw.fetch_first("task-types", {"name": task_type_name}, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
@ -426,22 +434,11 @@ def get_task_by_path(project, file_path, entity_type="shot", client=default):
|
||||
return raw.post("data/tasks/from-path/", data, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
def get_default_task_status(client=default):
|
||||
"""
|
||||
Returns:
|
||||
dict: The unique task status flagged with `is_default`.
|
||||
"""
|
||||
return raw.fetch_first(
|
||||
"task-status", params={"is_default": True}, client=client
|
||||
)
|
||||
|
||||
|
||||
@cache
|
||||
def get_task_status(task_status_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
task_status_id (str): ID of claimed task status.
|
||||
task_status_id (str): Id of claimed task status.
|
||||
|
||||
Returns:
|
||||
dict: Task status matching given ID.
|
||||
@ -521,7 +518,7 @@ def remove_task_status(task_status, client=default):
|
||||
def get_task(task_id, client=default):
|
||||
"""
|
||||
Args:
|
||||
task_id (str): ID of claimed task.
|
||||
task_id (str): Id of claimed task.
|
||||
|
||||
Returns:
|
||||
dict: Task matching given ID.
|
||||
@ -599,11 +596,9 @@ def start_task(task, started_task_status=None, client=default):
|
||||
dict: Created comment.
|
||||
"""
|
||||
if started_task_status is None:
|
||||
started_task_status = get_task_status_by_short_name(
|
||||
"wip", client=client
|
||||
)
|
||||
started_task_status = get_task_status_by_short_name("wip", client=client)
|
||||
if started_task_status is None:
|
||||
raise TaskStatusNotFoundException(
|
||||
raise TaskStatusNotFound(
|
||||
(
|
||||
"started_task_status is None : 'wip' task status is "
|
||||
"non-existent. You have to create it or to set an other "
|
||||
@ -647,9 +642,9 @@ def task_to_review(
|
||||
|
||||
|
||||
@cache
|
||||
def get_time_spent(task, date=None, client=default):
|
||||
def get_time_spent(task, date, client=default):
|
||||
"""
|
||||
Get the time spent by CG artists on a task at a given date if given. A field contains
|
||||
Get the time spent by CG artists on a task at a given date. A field contains
|
||||
the total time spent. Durations are given in seconds. Date format is
|
||||
YYYY-MM-DD.
|
||||
|
||||
@ -661,9 +656,7 @@ def get_time_spent(task, date=None, client=default):
|
||||
dict: A dict with person ID as key and time spent object as value.
|
||||
"""
|
||||
task = normalize_model_parameter(task)
|
||||
path = "actions/tasks/%s/time-spents" % (task["id"])
|
||||
if date is not None:
|
||||
path += "/%s" % (date)
|
||||
path = "actions/tasks/%s/time-spents/%s" % (task["id"], date)
|
||||
return raw.get(path, client=client)
|
||||
|
||||
|
||||
@ -736,9 +729,7 @@ def add_comment(
|
||||
task_status (str / dict): The task status dict or ID.
|
||||
comment (str): Comment text
|
||||
person (str / dict): Comment author
|
||||
checklist (list): Comment checklist
|
||||
attachments (list[file_path]): Attachments file paths
|
||||
created_at (str): Comment date
|
||||
date (str): Comment date
|
||||
|
||||
Returns:
|
||||
dict: Created comment.
|
||||
@ -759,9 +750,7 @@ def add_comment(
|
||||
data["created_at"] = created_at
|
||||
|
||||
if len(attachments) == 0:
|
||||
return raw.post(
|
||||
"actions/tasks/%s/comment" % task["id"], data, client=client
|
||||
)
|
||||
return raw.post("actions/tasks/%s/comment" % task["id"], data, client=client)
|
||||
else:
|
||||
attachment = attachments.pop()
|
||||
data["checklist"] = json.dumps(checklist)
|
||||
@ -774,9 +763,7 @@ def add_comment(
|
||||
)
|
||||
|
||||
|
||||
def add_attachment_files_to_comment(
|
||||
task, comment, attachments=[], client=default
|
||||
):
|
||||
def add_attachment_files_to_comment(task, comment, attachments=[], client=default):
|
||||
"""
|
||||
Add attachments files to a given comment.
|
||||
|
||||
@ -796,8 +783,7 @@ def add_attachment_files_to_comment(
|
||||
comment = normalize_model_parameter(comment)
|
||||
attachment = attachments.pop()
|
||||
return raw.upload(
|
||||
"actions/tasks/%s/comments/%s/add-attachment"
|
||||
% (task["id"], comment["id"]),
|
||||
"actions/tasks/%s/comments/%s/add-attachment" % (task["id"], comment["id"]),
|
||||
attachment,
|
||||
extra_files=attachments,
|
||||
client=client,
|
||||
@ -849,9 +835,7 @@ def create_preview(task, comment, client=default):
|
||||
return raw.post(path, {}, client=client)
|
||||
|
||||
|
||||
def upload_preview_file(
|
||||
preview, file_path, normalize_movie=True, client=default
|
||||
):
|
||||
def upload_preview_file(preview, file_path, normalize_movie=True, client=default):
|
||||
"""
|
||||
Create a preview into given comment.
|
||||
|
||||
@ -859,9 +843,7 @@ def upload_preview_file(
|
||||
task (str / dict): The task dict or the task ID.
|
||||
file_path (str): Path of the file to upload as preview.
|
||||
"""
|
||||
path = (
|
||||
"pictures/preview-files/%s" % normalize_model_parameter(preview)["id"]
|
||||
)
|
||||
path = "pictures/preview-files/%s" % normalize_model_parameter(preview)["id"]
|
||||
if not normalize_movie:
|
||||
path += "?normalize=false"
|
||||
return raw.upload(path, file_path, client=client)
|
||||
@ -882,9 +864,7 @@ def add_preview(
|
||||
task (str / dict): The task dict or the task ID.
|
||||
comment (str / dict): The comment or the comment ID.
|
||||
preview_file_path (str): Path of the file to upload as preview.
|
||||
preview_file_path (str): Path of the file to upload as preview.
|
||||
preview_file_url (str): Url to download the preview file if no path is
|
||||
given.
|
||||
|
||||
Returns:
|
||||
dict: Created preview file model.
|
||||
"""
|
||||
@ -902,74 +882,19 @@ def add_preview(
|
||||
)
|
||||
|
||||
|
||||
def publish_preview(
|
||||
task,
|
||||
task_status,
|
||||
comment="",
|
||||
person=None,
|
||||
checklist=[],
|
||||
attachments=[],
|
||||
created_at=None,
|
||||
client=default,
|
||||
preview_file_path=None,
|
||||
preview_file_url=None,
|
||||
normalize_movie=True,
|
||||
):
|
||||
"""
|
||||
Publish a comment and include given preview for given task and set given
|
||||
task status.
|
||||
|
||||
Args:
|
||||
task (str / dict): The task dict or the task ID.
|
||||
task_status (str / dict): The task status dict or ID.
|
||||
comment (str): Comment text
|
||||
person (str / dict): Comment author
|
||||
checklist (list): Comment checklist
|
||||
attachments (list[file_path]): Attachments file paths
|
||||
created_at (str): Comment date
|
||||
preview_file_path (str): Path of the file to upload as preview.
|
||||
preview_file_url (str): Url to download the preview file if no path is
|
||||
given.
|
||||
normalize_movie (bool): Set to false to not do operations on it on the
|
||||
server side.
|
||||
Returns:
|
||||
dict: Created preview file model.
|
||||
"""
|
||||
new_comment = add_comment(
|
||||
task,
|
||||
task_status,
|
||||
comment=comment,
|
||||
person=person,
|
||||
checklist=checklist,
|
||||
attachments=[],
|
||||
created_at=created_at,
|
||||
client=client,
|
||||
)
|
||||
add_preview(
|
||||
task,
|
||||
new_comment,
|
||||
preview_file_path=preview_file_path,
|
||||
preview_file_url=preview_file_url,
|
||||
normalize_movie=normalize_movie,
|
||||
)
|
||||
return new_comment
|
||||
|
||||
|
||||
def set_main_preview(preview_file, frame_number, client=default):
|
||||
def set_main_preview(preview_file, client=default):
|
||||
"""
|
||||
Set given preview as thumbnail of given entity.
|
||||
|
||||
Args:
|
||||
preview_file (str / dict): The preview file dict or ID.
|
||||
frame_number (int): Frame of preview video to set as main preview
|
||||
|
||||
Returns:
|
||||
dict: Created preview file model.
|
||||
"""
|
||||
data = {"frame_number": frame_number} if frame_number > 1 else {}
|
||||
preview_file = normalize_model_parameter(preview_file)
|
||||
path = "actions/preview-files/%s/set-main-preview" % preview_file["id"]
|
||||
return raw.put(path, data, client=client)
|
||||
return raw.put(path, {}, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
@ -1015,19 +940,17 @@ def assign_task(task, person, client=default):
|
||||
return raw.put(path, {"task_ids": task["id"]}, client=client)
|
||||
|
||||
|
||||
def new_task_type(name, color="#000000", client=default):
|
||||
def new_task_type(name, client=default):
|
||||
"""
|
||||
Create a new task type with the given name.
|
||||
|
||||
Args:
|
||||
name (str): The name of the task type
|
||||
color (str): The color of the task type as an hexadecimal string
|
||||
with # as first character. ex : #00FF00
|
||||
|
||||
Returns:
|
||||
dict: The created task type
|
||||
"""
|
||||
data = {"name": name, "color": color}
|
||||
data = {"name": name}
|
||||
return raw.post("data/task-types", data, client=client)
|
||||
|
||||
|
||||
@ -1038,7 +961,7 @@ def new_task_status(name, short_name, color, client=default):
|
||||
Args:
|
||||
name (str): The name of the task status
|
||||
short_name (str): The short name of the task status
|
||||
color (str): The color of the task status as an hexadecimal string
|
||||
color (str): The color of the task status has an hexadecimal string
|
||||
with # as first character. ex : #00FF00
|
||||
|
||||
Returns:
|
||||
@ -1063,9 +986,7 @@ def update_task(task, client=default):
|
||||
dict: Updated task.
|
||||
"""
|
||||
if "assignees" in task:
|
||||
task["assignees"] = normalize_list_of_models_for_links(
|
||||
task["assignees"]
|
||||
)
|
||||
task["assignees"] = normalize_list_of_models_for_links(task["assignees"])
|
||||
return raw.put("data/tasks/%s" % task["id"], task, client=client)
|
||||
|
||||
|
||||
@ -1095,13 +1016,12 @@ def update_task_data(task, data={}, client=default):
|
||||
def get_task_url(task, client=default):
|
||||
"""
|
||||
Args:
|
||||
task (dict): The task dict.
|
||||
task (str / dict): The task dict or the task ID.
|
||||
|
||||
Returns:
|
||||
url (str): Web url associated to the given task
|
||||
"""
|
||||
if not isinstance(task, dict):
|
||||
raise TaskMustBeADictException
|
||||
task = normalize_model_parameter(task)
|
||||
path = "{host}/productions/{project_id}/shots/tasks/{task_id}/"
|
||||
return path.format(
|
||||
host=raw.get_api_url_from_host(client=client),
|
||||
|
@ -247,26 +247,6 @@ def all_done_tasks(client=default):
|
||||
return raw.fetch_all("user/done-tasks", client=client)
|
||||
|
||||
|
||||
@cache
|
||||
def get_timespents_range(start_date, end_date, client=default):
|
||||
"""
|
||||
Gets the timespents of the current user for the given date range.
|
||||
|
||||
Args:
|
||||
start_date (str): The first day of the date range as a date string with
|
||||
the following format: YYYY-MM-DD
|
||||
end_date (str): The last day of the date range as a date string with
|
||||
the following format: YYYY-MM-DD
|
||||
Returns:
|
||||
list: All of the person's time spents
|
||||
"""
|
||||
date_range = {
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
}
|
||||
return raw.get("/data/user/time-spents", params=date_range, client=client)
|
||||
|
||||
|
||||
def log_desktop_session_log_in(client=default):
|
||||
"""
|
||||
Add a log entry to mention that the user logged in his computer.
|
||||
|
Loading…
Reference in New Issue
Block a user